This is my linux custom desktop shell.
https://www.youtube.com/watch?v=GHU0RAx88E8
-
Bar
- CPU - See the general load and each core's load (on hover)
- Disk - See the available and used disk space (on hover)
- RAM - See the available and used RAM & Swap (on hover)
- Battery - See the percentage, power drain and time to empty/full of the battery (on hover)
- Time - See current hour, year & month (on click) and calendar (on right click)
- Media Icon - The cover url of the playing media on Spotify
- Media Metadata - The Spotify song name & arist, and album & volume (on hover)
- Media Lyrics - The spotify song line-synced lyrics when available (sourced from Musixmatch and lrclib.net)
- Speaker - Volume and device name (on hover)
- Micrphone - Volume and device name (on hover)
- Network - Wifi or ethernet info
- Notifications - Notification count and center (on click)
- Tray - Tray apps
- Power - Power actions (see session menu)
-
Notification Daemon
- Notification popup
- Notification center
-
OSD:
- Speaker volume %
- Microphone volume %
- Screen brightness %
-
Launcher
- Apps
- Calculator
-
Session Menu
- Lock Screen
- Sleep
- Logout
- Task Manager
- Hibernate
- Shutdown
- Reboot
- Reboot to Firmware (UEFI/BIOS)
-
Media Player
- Toggle Loop (both track & playlist)
- Toggle Shuffle
- Play/Pause
- Skip Previous/Next
- Volume
- Includes cover art and song title & artist
Important
ags is required to run the desktop shell.
libsoup3glib-networkinglibadwaitaAstalIO&Astal4AstalAppsAstalBatteryAstalBluetoothAstalMprisAstalNetworkAstalNotifdAstalTrayAstalWp
Important
You must be on Linux with Wayland & have the layer shell protocol enabled.
- Clone this repository and move its contents to
~/.config/ags - Install all the required libraries
- just run
ags run
An example for NixOS can be found here.
The desktop shell can be configured by creating the ~/.config/stef-shell/config.json file
the avaible properties are:
-
paths.musixmatchToken(string): The path where to store the musixmatch cookie, usertoken and expiration date (default:/tmp/musixmatch_token.json). 1 2 -
paths.backlightBaseDir(string): The path where the backlight data for all devices is stored (default:/sys/class/backlight). 1 -
paths.saveFolder(string): The folder where to save lyrics and song icons when middle clicked (default:$HOME/Music/spotifyData). 1 -
paths.lyricsFolder(string): The path where the local lyrics files will be stored (default:$HOME/.config/stef-shell/lyrics). 1 -
volumeStep.media(number): Percentage of volume increase/decrease when scrolling on the media module (default:0.05). 3 -
volumeStep.microphone(number): Percentage of volume increase/decrease when scrolling on the microphone module (default:0.05). 3 -
volumeStep.speaker(number): Percentage of volume increase/decrease when scrolling on the speaker module (default:0.05). 3 -
animationsDuration.notification(number): How long the notification animation should last (default:500). 4 -
animationsDuration.launcher(number): How long the launcher animation should last (default:300). 4 -
animationsDuration.notificationCenter(number): How long the notification center animation should last (default:500). 4 -
animationsDuration.osd(number): How long the OSD animation should last (default:300). 4 -
animationsDuration.sessionMenu(number): How long the session menu animation should last (default:300). 4 -
animationsType.notification(string): The notifications animation type (default:SLIDE_LEFT). 5 -
animationsType.launcher(string): The launcher animation type (default:CROSSFADE). 5 -
animationsType.notificationCenter(string): The notification center animation type (default:SLIDE_LEFT). 5 -
animationsType.osd(string): The OSD animation type (default:CROSSFADE). 5 -
animationsType.sessionMenu(string): The session menu animation type (default:CROSSFADE). 5 -
timeouts.osd: How long the OSD should last before disappearing (default:3000). 4 -
timeouts.defaultNotificationExpire: How long a notification should last before disappearing (default:5000). 4 6 -
sessionMenu.buttonWidth(number): How large should a button be in the session menu (default:120). 7 -
sessionMenu.buttonHeight(number): How high should a button be in the session menu (default:120). 7 -
sessionMenu.buttonGap(number): How large should the gap between buttons be in the session menu (default:120). 7 -
mediaMaxLength(number): How many characters should be displayed in the media bar module before it would start scrolling (default:25). 8 -
systemStatsUpdateInterval(number): How often system stats (CPU, Disk, RAM etc.) should be updated (default:1000). 9
windowrules:
float, class:^(gjs)$(float normal desktop shell windows)noblur, class:^(gjs)$, title:^(?!AGS Session Menu$).*(remove the blur to normal desktop shell windows (except for session manager))noanim, class:^(gjs)$(disable the animations normal desktop shell windows)pin, class:^(gjs)$, title:^(AGS Notification Center)$(pin the notification center so it always stays in the active workspace)pin, class:^(gjs)$, title:^(AGS Session Menu)$(pin th session menu so it always stays in the active workspace)
layerrules:
noanim, gtk4-layer-shell(disable the animations layered desktop shell windows)
For local lyrics to work for a song you must follow these steps:
- Copy the song's track ID (right click the media module while it's playing that song)
- Create a file
<track_id>.lrcin your lyrics folder (default is$HOME/.config/stef-shell/lyrics, can be configured through theconfig.jsonfile) - Add the lyrics in that file, for it work correctly it must follow this format:
[mm:ss.ms] Lyric here(example:[01:34.819] Lyric here)mm= minutes (padded, so1=>01)ss= seconds (padded, so1=>01)ms= milliseconds (padded, so1=>001)
Icons inside the icons folder are from Material Symbols
Footnotes
-
Must be a
.jsonfile ↩ -
Must be greater or equal to
0and defined in milliseconds ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 -
Must be one of
CROSSFADE,NONE,SLIDE_DOWN,SLIDE_LEFT,SLIDE_RIGHT,SLIDE_DOWN,SWING_UP,SWING_LEFT,SWING_RIGHT,SWING_DOWN↩ ↩2 ↩3 ↩4 ↩5 -
A notification can override this expire timeout by specifying an own expiry time (example:
notify-send "hello" -t 10000would last 10 seconds even if the timeout is 5 seconds) ↩ -
Must be greater than
0↩ -
Must be greater than
100and defined in milliseconds ↩