Virtual desktops. Their limitations in their own example.

Before I begin, I would like to say that the developers have done an excellent job; in its current state, it is an amazing DE.

I am preparing to switch from Hyprland to KDE Plasma, but I have questions about the limitations.

I use Hyprland with automatic theme generation depending on the wallpaper (screenshots attached). I have more than 30 virtual desktops, and I am used to controlling interactions with programs using my own keyboard shortcuts (some of the keyboard shortcuts are attached).
Virtual desktops A-Z (+ one to three additional desktops to avoid duplicates of open applications or a special desktop…), each of which corresponds to the first letter of the program being opened (automatic via RegEx).

Switching between virtual desktops is done with the key combination (modifier key) “WIN|SUPER” + “A-Z”. Moving a program from one virtual desktop to another is done with the key combination (modifier key) “WIN|SUPER” + ‘CTRL’ + “A-Z”.


$mainMod = Super_L

# -----------------------------------------------------------
# Window management
# -----------------------------------------------------------
$windowManMod = $mainMod

...
bind = $windowManMod, 1, workspace, 1 #------ Switch workspace
bind = $windowManMod, 2, workspace, 2 #------ Switch workspace
bind = $windowManMod, 3, workspace, 3 #------ Switch workspace
bind = $windowManMod, 4, workspace, 4 #------ Switch workspace
bind = $windowManMod, 5, workspace, 5 #------ Switch workspace
bind = $windowManMod, 6, workspace, 6 #------ Switch workspace
bind = $windowManMod, 7, workspace, 7 #------ Switch workspace
bind = $windowManMod, 8, workspace, 8 #------ Switch workspace
bind = $windowManMod, 9, workspace, 9 #------ Switch workspace
bind = $windowManMod, 0, workspace, 10 #------ Switch workspace
#bind = $windowManMod, -, exec,  #
#bind = $windowManMod, =, exec,  #
#bind = $windowManMod, BackSpace, exec,  #
#bind = $windowManMod, Insert, exec,  #
#bind = $windowManMod, Home, exec,  #
#bind = $windowManMod, Prior, exec,  #
#bind = $windowManMod, Tab, exec,  #
bind = $windowManMod, Q, workspace, 11 #------ Switch workspace
bind = $windowManMod, W, workspace, 12 #------ Switch workspace
bind = $windowManMod, E, workspace, 13 #------ Switch workspace
bind = $windowManMod, R, workspace, 14 #------ Switch workspace
bind = $windowManMod, T, workspace, 15 #------ Switch workspace
bind = $windowManMod, Y, workspace, 16 #------ Switch workspace
bind = $windowManMod, U, workspace, 17 #------ Switch workspace
bind = $windowManMod, I, workspace, 18 #------ Switch workspace
bind = $windowManMod, O, workspace, 10 #------ Switch workspace
bind = $windowManMod, P, workspace, 20 #------ Switch workspace
#bind = $windowManMod, bracketleft, exec,  #
#bind = $windowManMod, bracketright, exec,  #
#bind = $windowManMod, backslash, exec,  #
#bind = $windowManMod, Delete, exec,  #
#bind = $windowManMod, End, exec,  #
#bind = $windowManMod, Next, exec,  #
#bind = $windowManMod, Caps_Lock, exec,  #
bind = $windowManMod, A, workspace, 21 #------ Switch workspace
bind = $windowManMod, S, workspace, 22 #------ Switch workspace
bind = $windowManMod, D, workspace, 23 #------ Switch workspace
bind = $windowManMod, F, workspace, 24 #------ Switch workspace
bind = $windowManMod, G, workspace, 25 #------ Switch workspace
bind = $windowManMod, H, workspace, 26 #------ Switch workspace
bind = $windowManMod, J, workspace, 27 #------ Switch workspace
bind = $windowManMod, K, workspace, 28 #------ Switch workspace
bind = $windowManMod, L, workspace, 29 #------ Switch workspace
#bind = $windowManMod, semicolon, exec,  #
#bind = $windowManMod, apostrophe, exec,  #
#bind = $windowManMod, Return, exec,  #
#bind = $windowManMod, Super_L, exec,  #
#bind = $windowManMod, Shift_L, exec,  #
bind = $windowManMod, Z, workspace, 30 #------ Switch workspace
bind = $windowManMod, X, workspace, 31 #------ Switch workspace
bind = $windowManMod, C, workspace, 32 #------ Switch workspace
bind = $windowManMod, V, workspace, 33 #------ Switch workspace
bind = $windowManMod, B, workspace, 34 #------ Switch workspace
bind = $windowManMod, N, workspace, 35 #------ Switch workspace
bind = $windowManMod, M, workspace, 36 #------ Switch workspace
...

# -----------------------------------------------------------
# Window management 2
# -----------------------------------------------------------
$windowManMod2 = $mainMod Control_L

...
bind = $windowManMod2, 1, movetoworkspace, 1 #------ Move active window to a workspace
bind = $windowManMod2, 2, movetoworkspace, 2 #------ Move active window to a workspace
bind = $windowManMod2, 3, movetoworkspace, 3 #------ Move active window to a workspace
bind = $windowManMod2, 4, movetoworkspace, 4 #------ Move active window to a workspace
bind = $windowManMod2, 5, movetoworkspace, 5 #------ Move active window to a workspace
bind = $windowManMod2, 6, movetoworkspace, 6 #------ Move active window to a workspace
bind = $windowManMod2, 7, movetoworkspace, 7 #------ Move active window to a workspace
bind = $windowManMod2, 8, movetoworkspace, 8 #------ Move active window to a workspace
bind = $windowManMod2, 9, movetoworkspace, 9 #------ Move active window to a workspace
bind = $windowManMod2, 0, movetoworkspace, 10 #------ Move active window to a workspace
bind = $windowManMod2, Q, movetoworkspace, 11 #------ Move active window to a workspace
bind = $windowManMod2, W, movetoworkspace, 12 #------ Move active window to a workspace
bind = $windowManMod2, E, movetoworkspace, 13 #------ Move active window to a workspace
bind = $windowManMod2, R, movetoworkspace, 14 #------ Move active window to a workspace
bind = $windowManMod2, T, movetoworkspace, 15 #------ Move active window to a workspace
bind = $windowManMod2, Y, movetoworkspace, 16 #------ Move active window to a workspace
bind = $windowManMod2, U, movetoworkspace, 17 #------ Move active window to a workspace
bind = $windowManMod2, I, movetoworkspace, 18 #------ Move active window to a workspace
bind = $windowManMod2, O, movetoworkspace, 10 #------ Move active window to a workspace
bind = $windowManMod2, P, movetoworkspace, 20 #------ Move active window to a workspace
bind = $windowManMod2, A, movetoworkspace, 21 #------ Move active window to a workspace
bind = $windowManMod2, S, movetoworkspace, 22 #------ Move active window to a workspace
bind = $windowManMod2, D, movetoworkspace, 23 #------ Move active window to a workspace
bind = $windowManMod2, F, movetoworkspace, 24 #------ Move active window to a workspace
bind = $windowManMod2, G, movetoworkspace, 25 #------ Move active window to a workspace
bind = $windowManMod2, H, movetoworkspace, 26 #------ Move active window to a workspace
bind = $windowManMod2, J, movetoworkspace, 27 #------ Move active window to a workspace
bind = $windowManMod2, K, movetoworkspace, 28 #------ Move active window to a workspace
bind = $windowManMod2, L, movetoworkspace, 29 #------ Move active window to a workspace
bind = $windowManMod2, Z, movetoworkspace, 30 #------ Move active window to a workspace
bind = $windowManMod2, X, movetoworkspace, 31 #------ Move active window to a workspace
bind = $windowManMod2, C, movetoworkspace, 32 #------ Move active window to a workspace
bind = $windowManMod2, V, movetoworkspace, 33 #------ Move active window to a workspace
bind = $windowManMod2, B, movetoworkspace, 34 #------ Move active window to a workspace
bind = $windowManMod2, N, movetoworkspace, 35 #------ Move active window to a workspace
bind = $windowManMod2, M, movetoworkspace, 36 #------ Move active window to a workspace
...

I also have a division of key combinations between opening user and system programs.

# -----------------------------------------------------------
# System application shortcuts
# -----------------------------------------------------------
$systemAppMod = $mainMod&Alt_R # SUPER + Alt_R

...
#bind = $systemAppMod, 4, exec,  #
#bind = $systemAppMod, 5, exec, #
#bind = $systemAppMod, 6, exec,  #
#bind = $systemAppMod, 7, exec,  #
#bind = $systemAppMod, 8, exec,  #
#bind = $systemAppMod, 9, exec, #
#bind = $systemAppMod, 0, exec, #
#bind = $systemAppMod, -, exec,  #
#bind = $systemAppMod, =, exec,  #
#bind = $systemAppMod, BackSpace, exec,  #
#bind = $systemAppMod, Insert, exec,  #
#bind = $systemAppMod, Home, exec,  #
#bind = $systemAppMod, Prior, exec,  #
#bind = $systemAppMod, Tab, exec,  #
#bind = $systemAppMod, Q, exec,  #
#bind = $systemAppMod, W, exec,  #
#bind = $systemAppMod, E, exec,  #
bind = $systemAppMod, R, exec, $resource_monitor # open resource monitor
bind = $systemAppMod, T, exec, $TERM  # open terminal
#bind = $systemAppMod, Y, exec,  #
#bind = $systemAppMod, U, exec,  #
#bind = $systemAppMod, I, exec,  #
#bind = $systemAppMod, O, exec,  #
#bind = $systemAppMod, P, exec,  #
#bind = $systemAppMod, bracketleft, exec,  #
#bind = $systemAppMod, bracketright, exec,  #
#bind = $systemAppMod, backslash, exec,  #
#bind = $systemAppMod, Delete, exec,  #
#bind = $systemAppMod, End, exec,  #
#bind = $systemAppMod, Next, exec,  #
#bind = $systemAppMod, Caps_Lock, exec,  #
#bind = $systemAppMod, A, exec,  #
#bind = $systemAppMod, S, exec,  $settMenu_script # open the Hyprland configuration menu (gui)
#bind = $systemAppMod, D, exec,  #
#bind = $systemAppMod, F, exec,  #
bind = $systemAppMod, G, exec, $HOME/.config/hypr/hyprland.conf.d/scripts/gamelock.sh # Motion blocking outside the main monitor (Unsuccessful native games)
#bind = $systemAppMod, H, exec,  #
#bind = $systemAppMod, J, exec,  #
#bind = $systemAppMod, K, exec,  #
#bind = $systemAppMod, L, exec,  #
#bind = $systemAppMod, semicolon, exec,  #
#bind = $systemAppMod, apostrophe, exec,  #
#bind = $systemAppMod, Return, exec,  #
#bind = $systemAppMod, Super_L, exec,  #
#bind = $systemAppMod, Shift_L, exec,  #
#bind = $systemAppMod, Z, exec,  #
#bind = $systemAppMod, X, exec,  #
bind = $systemAppMod, C, exec, pkill rofi || $HOME/.config/rofi/scripts/cliphist.sh c  # open Pasteboard in screen depending on the cursor position
bind = $systemAppMod, V, exec, pavucontrol -t 3 # open volume manager
bind = $systemAppMod, B, exec, $Bluetooth #
bind = $systemAppMod, N, exec, $net_status # open network manager
bind = $systemAppMod, Up, exec, $waybar_confgen --next # next waybar mode
bind = $systemAppMod, Left, exec, $swww_wallpaper -p # previous wallpaper
bind = $systemAppMod, Down, exec, $waybar_confgen --prev # previous waybar mode
bind = $systemAppMod, Right, exec, $swww_wallpaper -n # next wallpaper
binde = , XF86AudioMute, exec, $volumeCtl -o m # Toggle audio mute
binde = , XF86AudioMicMute, exec, $volumeCtl -i m # Toggle microphone mute
binde = , XF86AudioLowerVolume, exec, $volumeCtl -o d # Decrease volume
binde = , XF86AudioRaiseVolume, exec, $volumeCtl -o i # Increase volume
binde = , XF86AudioPlay, exec, playerctl play-pause
binde = , XF86AudioPause, exec, playerctl play-pause
binde = , XF86AudioNext, exec, playerctl next
binde = , XF86AudioPrev, exec, playerctl previous
binde = , XF86MonBrightnessUp, exec, $brightnesscontrol i # Increase brightness
binde = , XF86MonBrightnessDown, exec, $brightnesscontrol d # Decrease brightness

# -----------------------------------------------------------
# Application shortcuts
# -----------------------------------------------------------
$appMod = Alt_R
...

This division helps you manage programs without thinking, knowing only their name (or, more precisely, the first letter). Therefore, I request that the limit on virtual desktops be changed to a minimum of 30.

Now a question about the widget for displaying virtual desktops on the panel (Pager).
How can I ensure that only those virtual desktops on which at least one application is open are displayed?

That’s a great setup, I had never considered using Meta+A-Z for virtual desktop switching. Unfortunately, per-virtual desktop wallpapers are a long-standing request, it’s apparently quite technical.

Hope it’s not a deal-breaker, I noticed several scripts that attempt to address this by setting the wallpaper on the fly when the desktop is switched. Plasma can also set the theme’s accent color by wallpaper, I take that for granted sometimes.

As it were, I recently put in to have the Virtual Desktop limit raised from 20 to 25, to better pack into a square grid. We floated simply uncapping the limit, which would fit your use case since you don’t access them from a grid.

The same value I adjusted in virtualdesktops.h could be set to 30 and patched on your system. It’s not the most ideal fix since it requires a rebuild on each package update, but it would knock out that requirement for your workflow.

This is worth a feature request upstream, I don’t see an existing one like it for the Pager feature. Especially considering that Pager has text labels as an option, this would be useful and easy to identify.

Thank you for your attention! I have seen discussions and changes from 20 to 25 virtual desktops, but this post is also a response to those who believe that even 20 virtual desktops are too many.

I would be very happy if the number of virtual desktops were increased to 30 or more in the future.

If it is possible to “live” with the current state of the “pager,” then it is impossible with the limitation of virtual desktops.

I have my virtual desktops grouped by activity.

I.e. I have five activities and each one has 6 virtual desktops, resulting in 30 virtual desktop while keeping the pager “small” (shows only the 6 desktops of the current activity)

1 Like

It may be best to just remove the cap. We talked about it offhand in the merge request, but you have a definite use case. It would require a few safeguards like paginating/scrolling the Desktop Grid.

Definitely open a feature request in the bug tracker if you want to see it, and you can test for yourself by just removing this block and compiling.

If there is no other logic that could be affected by removing the restriction block, then yes, it is definitely worth checking.