Add script to swap Hyprland workspaces across monitors

This introduces xmonad like workspace swapping, i.e. if the workspaces
is already focused on another monitor, a swap will occur, moving the
workspace from the other monitor to the currently focused monitor and
replacing it with the workspace originally focused on this monitor (i.e.
swapping them).

If we're only using 1 monitor, or the workspace isn't focused on any
monitor, this will behave exactly like regular workspace focus command.
This commit is contained in:
ItsDrike 2024-06-10 14:13:39 +02:00
parent 54f1c40d61
commit 9d15387d5e
Signed by: ItsDrike
GPG key ID: FA2745890B7048C0
6 changed files with 38 additions and 15 deletions

View file

@ -102,7 +102,15 @@
#
# Switch workspace (swapping to current monitor)
#
# TODO: requires script (swap-workspace)
"SUPER, 1, exec, hyprland-swap-workspace 1"
"SUPER, 2, exec, hyprland-swap-workspace 2"
"SUPER, 3, exec, hyprland-swap-workspace 3"
"SUPER, 4, exec, hyprland-swap-workspace 4"
"SUPER, 5, exec, hyprland-swap-workspace 5"
"SUPER, 6, exec, hyprland-swap-workspace 6"
"SUPER, 7, exec, hyprland-swap-workspace 7"
"SUPER, 8, exec, hyprland-swap-workspace 8"
"SUPER, 9, exec, hyprland-swap-workspace 9"
#
# Move window to workspace

View file

@ -6,7 +6,7 @@
}: let
inherit (lib) mkIf;
inherit (import ./packages {inherit pkgs;}) dbus-hyprland-env;
inherit (import ./packages {inherit pkgs;}) hyprland-swap-workspace;
cfg = osConfig.myOptions.home-manager.wms.hyprland;
in {
@ -16,7 +16,7 @@ in {
config = mkIf cfg.enable {
home.packages = with pkgs; [
dbus-hyprland-env
hyprland-swap-workspace
];
wayland.windowManager.hyprland = {

View file

@ -1,11 +0,0 @@
{pkgs, ...}:
pkgs.writeTextFile {
name = "dbus-hyprland-env";
destination = "/bin/dbus-hyprland-environment";
executable = true;
text = ''
dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=hyprland
systemctl --user stop pipewire pipewire-media-session xdg-desktop-portal xdg-desktop-portal-wlr
systemctl --user start pipewire wireplumber pipewire-media-session xdg-desktop-portal xdg-desktop-portal-hyprland
'';
}

View file

@ -3,7 +3,7 @@
...
}: let
packages = {
dbus-hyprland-env = pkgs.callPackage ./dbus-hyprland-env.nix {};
hyprland-swap-workspace = pkgs.callPackage ./hyprland-swap-workspace.nix {};
};
in
packages

View file

@ -0,0 +1,4 @@
{pkgs, ...}:
pkgs.writeShellScriptBin "hyprland-swap-workspace" ''
${builtins.readFile ./hyprland-swap-workspace.sh}
''

View file

@ -0,0 +1,22 @@
#!/bin/bash
WORKSPACE="$1"
monitors_out="$(hyprctl monitors -j)"
focused_mon="$(echo "$monitors_out" | jq '.[] | select(.focused==true) | .id')"
focused_wks="$(echo "$monitors_out" | jq '.[].activeWorkspace.id')"
# Workspace is already focused, check on which monitor
if echo "$focused_wks" | grep "$WORKSPACE" >/dev/null; then
mon_id="$(echo "$monitors_out" | jq ".[] | select(.activeWorkspace.id==$WORKSPACE) | .id")"
# If the workspace is focused on the active monitor, don't do anything (we're here).
# Otherwise, swap the workspaces.
if [ "$mon_id" -ne "$focused_mon" ]; then
hyprctl dispatch swapactiveworkspaces "$focused_mon" "$mon_id"
fi
# Switching to an unfocused workspace, always move it to focused monitor
else
hyprctl dispatch moveworkspacetomonitor "$WORKSPACE" "$focused_mon"
hyprctl dispatch workspace "$WORKSPACE"
fi