From ce17961aad6f9164e5d026d19efd42b07b123bff Mon Sep 17 00:00:00 2001 From: Can <45462997+yungcxn@users.noreply.github.com> Date: Fri, 24 May 2024 20:58:26 +0200 Subject: [PATCH] keybinds: Added new dispatcher (sendshortcut) (#6174) --- hyprctl/hyprctl.bash | 6 +- hyprctl/hyprctl.fish | 6 +- hyprctl/hyprctl.usage | 1 + hyprctl/hyprctl.zsh | 5 +- src/managers/KeybindManager.cpp | 154 +++++++++++++++++++++++++++- src/managers/KeybindManager.hpp | 7 ++ src/managers/input/InputManager.cpp | 4 +- 7 files changed, 174 insertions(+), 9 deletions(-) diff --git a/hyprctl/hyprctl.bash b/hyprctl/hyprctl.bash index 279ee518..0b4e6b86 100644 --- a/hyprctl/hyprctl.bash +++ b/hyprctl/hyprctl.bash @@ -23,12 +23,12 @@ _hyprctl () { local words cword _get_comp_words_by_ref -n "$COMP_WORDBREAKS" words cword - local -a literals=("cyclenext" "globalshortcuts" "cursorpos" "bordersize" "renameworkspace" "animationstyle" "focuswindow" "0" "auto" "swapnext" "forceallowsinput" "moveactive" "activebordercolor" "alphafullscreen" "wayland" "layers" "minsize" "monitors" "1" "kill" "settiled" "3" "focusmonitor" "swapwindow" "moveoutofgroup" "notify" "movecursor" "setcursor" "seterror" "movecurrentworkspacetomonitor" "4" "nomaxsize" "forcenoanims" "setprop" "-i" "togglefloating" "workspacerules" "movetoworkspace" "disable" "setignoregrouplock" "workspaces" "movegroupwindow" "closewindow" "0" "--instance" "binds" "movewindow" "splitratio" "alpha" "denywindowfromgroup" "workspace" "configerrors" "togglegroup" "getoption" "forceopaque" "keepaspectratio" "killactive" "pass" "decorations" "devices" "focuscurrentorlast" "submap" "global" "alphafullscreenoverride" "forcerendererreload" "movewindowpixel" "headless" "version" "dpms" "resizeactive" "moveintogroup" "5" "alphaoverride" "setfloating" "rollinglog" "::=" "rounding" "layouts" "moveworkspacetomonitor" "exec" "alphainactiveoverride" "alterzorder" "fakefullscreen" "nofocus" "keyword" "forcenoborder" "forcenodim" "pin" "output" "forcenoblur" "togglespecialworkspace" "fullscreen" "toggleopaque" "focusworkspaceoncurrentmonitor" "next" "changegroupactive" "-j" "instances" "execr" "exit" "clients" "all" "--batch" "dismissnotify" "inactivebordercolor" "switchxkblayout" "movetoworkspacesilent" "movewindoworgroup" "-r" "movefocus" "focusurgentorlast" "remove" "activeworkspace" "dispatch" "create" "centerwindow" "2" "hyprpaper" "-1" "reload" "alphainactive" "systeminfo" "plugin" "dimaround" "activewindow" "swapactiveworkspaces" "splash" "maxsize" "lockactivegroup" "windowdancecompat" "forceopaqueoverriden" "lockgroups" "movecursortocorner" "x11" "prev" "1" "resizewindowpixel" "forcenoshadow") + local -a literals=("cyclenext" "globalshortcuts" "cursorpos" "bordersize" "renameworkspace" "animationstyle" "focuswindow" "0" "auto" "swapnext" "forceallowsinput" "moveactive" "activebordercolor" "alphafullscreen" "wayland" "layers" "minsize" "monitors" "1" "kill" "settiled" "3" "focusmonitor" "swapwindow" "moveoutofgroup" "notify" "movecursor" "setcursor" "seterror" "movecurrentworkspacetomonitor" "4" "nomaxsize" "forcenoanims" "setprop" "-i" "togglefloating" "workspacerules" "movetoworkspace" "disable" "setignoregrouplock" "workspaces" "movegroupwindow" "closewindow" "0" "--instance" "binds" "movewindow" "splitratio" "alpha" "denywindowfromgroup" "workspace" "configerrors" "togglegroup" "getoption" "forceopaque" "keepaspectratio" "killactive" "pass" "decorations" "devices" "focuscurrentorlast" "submap" "global" "alphafullscreenoverride" "forcerendererreload" "movewindowpixel" "headless" "version" "dpms" "resizeactive" "moveintogroup" "5" "alphaoverride" "setfloating" "rollinglog" "::=" "rounding" "layouts" "moveworkspacetomonitor" "exec" "alphainactiveoverride" "alterzorder" "fakefullscreen" "nofocus" "keyword" "forcenoborder" "forcenodim" "pin" "output" "forcenoblur" "togglespecialworkspace" "fullscreen" "toggleopaque" "focusworkspaceoncurrentmonitor" "next" "changegroupactive" "-j" "instances" "execr" "exit" "clients" "all" "--batch" "dismissnotify" "inactivebordercolor" "switchxkblayout" "movetoworkspacesilent" "movewindoworgroup" "-r" "movefocus" "focusurgentorlast" "remove" "activeworkspace" "dispatch" "create" "centerwindow" "2" "hyprpaper" "-1" "reload" "alphainactive" "systeminfo" "plugin" "dimaround" "activewindow" "swapactiveworkspaces" "splash" "maxsize" "lockactivegroup" "windowdancecompat" "forceopaqueoverriden" "lockgroups" "movecursortocorner" "x11" "prev" "1" "resizewindowpixel" "forcenoshadow" "sendshortcut") declare -A literal_transitions - literal_transitions[0]="([103]=1 [74]=2 [33]=3 [1]=2 [2]=2 [77]=2 [105]=4 [36]=2 [108]=5 [40]=2 [45]=2 [112]=2 [84]=6 [113]=8 [51]=2 [53]=2 [88]=9 [117]=2 [119]=2 [121]=2 [15]=2 [58]=10 [59]=2 [17]=11 [122]=12 [19]=2 [124]=2 [126]=2 [25]=13 [67]=2 [96]=5 [97]=2 [27]=2 [28]=14 [100]=2 [102]=5)" + literal_transitions[0]="([103]=1 [74]=2 [33]=3 [1]=2 [2]=2 [77]=2 [105]=4 [36]=2 [108]=5 [40]=2 [45]=2 [112]=2 [84]=6 [113]=8 [51]=2 [53]=2 [88]=9 [117]=2 [119]=2 [121]=2 [15]=2 [58]=10 [138]=10 [59]=2 [17]=11 [122]=12 [19]=2 [124]=2 [126]=2 [25]=13 [67]=2 [96]=5 [97]=2 [27]=2 [28]=14 [100]=2 [102]=5)" literal_transitions[3]="([72]=18 [13]=2 [32]=18 [54]=18 [55]=18 [89]=18 [104]=2 [120]=2 [76]=1 [16]=2 [123]=18 [3]=1 [5]=2 [63]=18 [127]=2 [129]=18 [80]=18 [130]=18 [83]=18 [31]=18 [48]=2 [12]=2 [85]=18 [10]=18 [86]=18 [137]=18)" - literal_transitions[7]="([103]=1 [74]=2 [33]=3 [1]=2 [2]=2 [77]=2 [105]=4 [36]=2 [40]=2 [45]=2 [112]=2 [84]=6 [113]=8 [51]=2 [53]=2 [88]=9 [117]=2 [119]=2 [121]=2 [15]=2 [58]=10 [59]=2 [17]=11 [122]=12 [19]=2 [124]=2 [126]=2 [25]=13 [67]=2 [97]=2 [27]=2 [28]=14 [100]=2)" + literal_transitions[7]="([103]=1 [74]=2 [33]=3 [1]=2 [2]=2 [77]=2 [105]=4 [36]=2 [40]=2 [45]=2 [112]=2 [84]=6 [113]=8 [51]=2 [53]=2 [88]=9 [117]=2 [119]=2 [121]=2 [15]=2 [58]=10 [138]=10 [59]=2 [17]=11 [122]=12 [19]=2 [124]=2 [126]=2 [25]=13 [67]=2 [97]=2 [27]=2 [28]=14 [100]=2)" literal_transitions[8]="([128]=2 [131]=2 [0]=2 [73]=2 [35]=2 [106]=2 [37]=2 [107]=2 [4]=2 [78]=2 [39]=2 [79]=2 [110]=2 [6]=2 [41]=2 [42]=2 [81]=2 [82]=2 [46]=2 [47]=2 [9]=2 [109]=2 [50]=2 [52]=2 [11]=2 [115]=2 [87]=2 [49]=2 [56]=2 [90]=2 [57]=2 [91]=2 [92]=2 [60]=2 [61]=2 [125]=2 [93]=2 [62]=2 [20]=2 [95]=2 [22]=2 [23]=2 [64]=2 [65]=2 [24]=2 [132]=2 [26]=2 [68]=2 [98]=2 [69]=2 [29]=2 [136]=2 [70]=2 [99]=2)" literal_transitions[9]="([114]=15 [111]=16)" literal_transitions[11]="([101]=2)" diff --git a/hyprctl/hyprctl.fish b/hyprctl/hyprctl.fish index 5d8d12cb..6d31b25a 100644 --- a/hyprctl/hyprctl.fish +++ b/hyprctl/hyprctl.fish @@ -29,7 +29,7 @@ function _hyprctl set COMP_CWORD (count $COMP_WORDS) end - set --local literals "cyclenext" "globalshortcuts" "cursorpos" "bordersize" "renameworkspace" "animationstyle" "focuswindow" "0" "auto" "swapnext" "forceallowsinput" "moveactive" "activebordercolor" "alphafullscreen" "wayland" "layers" "minsize" "monitors" "1" "kill" "settiled" "3" "focusmonitor" "swapwindow" "moveoutofgroup" "notify" "movecursor" "setcursor" "seterror" "movecurrentworkspacetomonitor" "4" "nomaxsize" "forcenoanims" "setprop" "-i" "togglefloating" "workspacerules" "movetoworkspace" "disable" "setignoregrouplock" "workspaces" "movegroupwindow" "closewindow" "0" "--instance" "binds" "movewindow" "splitratio" "alpha" "denywindowfromgroup" "workspace" "configerrors" "togglegroup" "getoption" "forceopaque" "keepaspectratio" "killactive" "pass" "decorations" "devices" "focuscurrentorlast" "submap" "global" "alphafullscreenoverride" "forcerendererreload" "movewindowpixel" "headless" "version" "dpms" "resizeactive" "moveintogroup" "5" "alphaoverride" "setfloating" "rollinglog" "::=" "rounding" "layouts" "moveworkspacetomonitor" "exec" "alphainactiveoverride" "alterzorder" "fakefullscreen" "nofocus" "keyword" "forcenoborder" "forcenodim" "pin" "output" "forcenoblur" "togglespecialworkspace" "fullscreen" "toggleopaque" "focusworkspaceoncurrentmonitor" "next" "changegroupactive" "-j" "instances" "execr" "exit" "clients" "all" "--batch" "dismissnotify" "inactivebordercolor" "switchxkblayout" "movetoworkspacesilent" "movewindoworgroup" "-r" "movefocus" "focusurgentorlast" "remove" "activeworkspace" "dispatch" "create" "centerwindow" "2" "hyprpaper" "-1" "reload" "alphainactive" "systeminfo" "plugin" "dimaround" "activewindow" "swapactiveworkspaces" "splash" "maxsize" "lockactivegroup" "windowdancecompat" "forceopaqueoverriden" "lockgroups" "movecursortocorner" "x11" "prev" "1" "resizewindowpixel" "forcenoshadow" + set --local literals "cyclenext" "globalshortcuts" "cursorpos" "bordersize" "renameworkspace" "animationstyle" "focuswindow" "0" "auto" "swapnext" "forceallowsinput" "moveactive" "activebordercolor" "alphafullscreen" "wayland" "layers" "minsize" "monitors" "1" "kill" "settiled" "3" "focusmonitor" "swapwindow" "moveoutofgroup" "notify" "movecursor" "setcursor" "seterror" "movecurrentworkspacetomonitor" "4" "nomaxsize" "forcenoanims" "setprop" "-i" "togglefloating" "workspacerules" "movetoworkspace" "disable" "setignoregrouplock" "workspaces" "movegroupwindow" "closewindow" "0" "--instance" "binds" "movewindow" "splitratio" "alpha" "denywindowfromgroup" "workspace" "configerrors" "togglegroup" "getoption" "forceopaque" "keepaspectratio" "killactive" "pass" "decorations" "devices" "focuscurrentorlast" "submap" "global" "alphafullscreenoverride" "forcerendererreload" "movewindowpixel" "headless" "version" "dpms" "resizeactive" "moveintogroup" "5" "alphaoverride" "setfloating" "rollinglog" "::=" "rounding" "layouts" "moveworkspacetomonitor" "exec" "alphainactiveoverride" "alterzorder" "fakefullscreen" "nofocus" "keyword" "forcenoborder" "forcenodim" "pin" "output" "forcenoblur" "togglespecialworkspace" "fullscreen" "toggleopaque" "focusworkspaceoncurrentmonitor" "next" "changegroupactive" "-j" "instances" "execr" "exit" "clients" "all" "--batch" "dismissnotify" "inactivebordercolor" "switchxkblayout" "movetoworkspacesilent" "movewindoworgroup" "-r" "movefocus" "focusurgentorlast" "remove" "activeworkspace" "dispatch" "create" "centerwindow" "2" "hyprpaper" "-1" "reload" "alphainactive" "systeminfo" "plugin" "dimaround" "activewindow" "swapactiveworkspaces" "splash" "maxsize" "lockactivegroup" "windowdancecompat" "forceopaqueoverriden" "lockgroups" "movecursortocorner" "x11" "prev" "1" "resizewindowpixel" "forcenoshadow" "sendshortcut" set --local descriptions set descriptions[1] "Focus the next window on a workspace" @@ -130,12 +130,14 @@ function _hyprctl set descriptions[133] "Move the cursor to the corner of the active window" set descriptions[136] "INFO" set descriptions[137] "Resize a selected window" + set descriptions[138] "On shortcut X sends shortcut Y to a specified window" + set --local literal_transitions set literal_transitions[1] "set inputs 104 75 34 2 3 78 106 37 109 41 46 113 85 114 52 54 89 118 120 122 16 59 60 18 123 20 125 127 26 68 97 98 28 29 101 103; set tos 2 3 4 3 3 3 5 3 6 3 3 3 7 9 3 3 10 3 3 3 3 11 3 12 13 3 3 3 14 3 6 3 3 15 3 6" set literal_transitions[4] "set inputs 73 14 33 55 56 90 105 121 77 17 124 4 6 64 128 130 81 131 84 32 49 13 86 11 87 138; set tos 19 3 19 19 19 19 3 3 2 3 19 2 3 19 3 19 19 19 19 19 3 3 19 19 19 19" set literal_transitions[8] "set inputs 104 75 34 2 3 78 106 37 41 46 113 85 114 52 54 89 118 120 122 16 59 60 18 123 20 125 127 26 68 98 28 29 101; set tos 2 3 4 3 3 3 5 3 3 3 3 7 9 3 3 10 3 3 3 3 11 3 12 13 3 3 3 14 3 3 3 15 3" - set literal_transitions[9] "set inputs 129 132 1 74 36 107 38 108 5 79 40 80 111 7 42 43 82 83 47 48 10 110 51 53 12 116 88 50 57 91 58 92 93 61 62 126 94 63 21 96 23 24 65 66 25 133 27 69 99 70 30 137 71 100; set tos 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3" + set literal_transitions[9] "set inputs 129 132 1 74 36 107 38 108 5 79 40 80 111 7 42 43 82 83 47 48 10 110 51 53 12 116 88 50 57 91 58 92 93 61 62 126 94 63 21 96 23 24 65 66 25 133 27 69 99 70 30 137 71 100 138; set tos 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3" set literal_transitions[10] "set inputs 115 112; set tos 16 17" set literal_transitions[12] "set inputs 102; set tos 3" set literal_transitions[14] "set inputs 22 117 31 136 119 44 72; set tos 2 2 2 2 2 2 2" diff --git a/hyprctl/hyprctl.usage b/hyprctl/hyprctl.usage index a98541dd..8e75917e 100644 --- a/hyprctl/hyprctl.usage +++ b/hyprctl/hyprctl.usage @@ -94,6 +94,7 @@ hyprctl []... ::= (exec) "Execute a shell command" | (execr) "Execute a raw shell command" | (pass) "Pass the key to a specified window" + | (sendshortcut) "On shortcut X sends shortcut Y to a specified window" | (killactive) "Close the active window" | (closewindow) "Close a specified window" | (workspace) "Change the workspace" diff --git a/hyprctl/hyprctl.zsh b/hyprctl/hyprctl.zsh index 5e2a475b..82276778 100644 --- a/hyprctl/hyprctl.zsh +++ b/hyprctl/hyprctl.zsh @@ -17,7 +17,7 @@ _hyprctl_cmd_3 () { } _hyprctl () { - local -a literals=("cyclenext" "globalshortcuts" "cursorpos" "bordersize" "renameworkspace" "animationstyle" "focuswindow" "0" "auto" "swapnext" "forceallowsinput" "moveactive" "activebordercolor" "alphafullscreen" "wayland" "layers" "minsize" "monitors" "1" "kill" "settiled" "3" "focusmonitor" "swapwindow" "moveoutofgroup" "notify" "movecursor" "setcursor" "seterror" "movecurrentworkspacetomonitor" "4" "nomaxsize" "forcenoanims" "setprop" "-i" "togglefloating" "workspacerules" "movetoworkspace" "disable" "setignoregrouplock" "workspaces" "movegroupwindow" "closewindow" "0" "--instance" "binds" "movewindow" "splitratio" "alpha" "denywindowfromgroup" "workspace" "configerrors" "togglegroup" "getoption" "forceopaque" "keepaspectratio" "killactive" "pass" "decorations" "devices" "focuscurrentorlast" "submap" "global" "alphafullscreenoverride" "forcerendererreload" "movewindowpixel" "headless" "version" "dpms" "resizeactive" "moveintogroup" "5" "alphaoverride" "setfloating" "rollinglog" "::=" "rounding" "layouts" "moveworkspacetomonitor" "exec" "alphainactiveoverride" "alterzorder" "fakefullscreen" "nofocus" "keyword" "forcenoborder" "forcenodim" "pin" "output" "forcenoblur" "togglespecialworkspace" "fullscreen" "toggleopaque" "focusworkspaceoncurrentmonitor" "next" "changegroupactive" "-j" "instances" "execr" "exit" "clients" "all" "--batch" "dismissnotify" "inactivebordercolor" "switchxkblayout" "movetoworkspacesilent" "movewindoworgroup" "-r" "movefocus" "focusurgentorlast" "remove" "activeworkspace" "dispatch" "create" "centerwindow" "2" "hyprpaper" "-1" "reload" "alphainactive" "systeminfo" "plugin" "dimaround" "activewindow" "swapactiveworkspaces" "splash" "maxsize" "lockactivegroup" "windowdancecompat" "forceopaqueoverriden" "lockgroups" "movecursortocorner" "x11" "prev" "1" "resizewindowpixel" "forcenoshadow") + local -a literals=("cyclenext" "globalshortcuts" "cursorpos" "bordersize" "renameworkspace" "animationstyle" "focuswindow" "0" "auto" "swapnext" "forceallowsinput" "moveactive" "activebordercolor" "alphafullscreen" "wayland" "layers" "minsize" "monitors" "1" "kill" "settiled" "3" "focusmonitor" "swapwindow" "moveoutofgroup" "notify" "movecursor" "setcursor" "seterror" "movecurrentworkspacetomonitor" "4" "nomaxsize" "forcenoanims" "setprop" "-i" "togglefloating" "workspacerules" "movetoworkspace" "disable" "setignoregrouplock" "workspaces" "movegroupwindow" "closewindow" "0" "--instance" "binds" "movewindow" "splitratio" "alpha" "denywindowfromgroup" "workspace" "configerrors" "togglegroup" "getoption" "forceopaque" "keepaspectratio" "killactive" "pass" "decorations" "devices" "focuscurrentorlast" "submap" "global" "alphafullscreenoverride" "forcerendererreload" "movewindowpixel" "headless" "version" "dpms" "resizeactive" "moveintogroup" "5" "alphaoverride" "setfloating" "rollinglog" "::=" "rounding" "layouts" "moveworkspacetomonitor" "exec" "alphainactiveoverride" "alterzorder" "fakefullscreen" "nofocus" "keyword" "forcenoborder" "forcenodim" "pin" "output" "forcenoblur" "togglespecialworkspace" "fullscreen" "toggleopaque" "focusworkspaceoncurrentmonitor" "next" "changegroupactive" "-j" "instances" "execr" "exit" "clients" "all" "--batch" "dismissnotify" "inactivebordercolor" "switchxkblayout" "movetoworkspacesilent" "movewindoworgroup" "-r" "movefocus" "focusurgentorlast" "remove" "activeworkspace" "dispatch" "create" "centerwindow" "2" "hyprpaper" "-1" "reload" "alphainactive" "systeminfo" "plugin" "dimaround" "activewindow" "swapactiveworkspaces" "splash" "maxsize" "lockactivegroup" "windowdancecompat" "forceopaqueoverriden" "lockgroups" "movecursortocorner" "x11" "prev" "1" "resizewindowpixel" "forcenoshadow" "sendshortcut") local -A descriptions descriptions[1]="Focus the next window on a workspace" @@ -118,12 +118,13 @@ _hyprctl () { descriptions[133]="Move the cursor to the corner of the active window" descriptions[136]="INFO" descriptions[137]="Resize a selected window" + descriptions[138]="On shortcut X sends shortcut Y to a specified window" local -A literal_transitions literal_transitions[1]="([104]=2 [75]=3 [34]=4 [2]=3 [3]=3 [78]=3 [106]=5 [37]=3 [109]=6 [41]=3 [46]=3 [113]=3 [85]=7 [114]=9 [52]=3 [54]=3 [89]=10 [118]=3 [120]=3 [122]=3 [16]=3 [59]=11 [60]=3 [18]=12 [123]=13 [20]=3 [125]=3 [127]=3 [26]=14 [68]=3 [97]=6 [98]=3 [28]=3 [29]=15 [101]=3 [103]=6)" literal_transitions[4]="([73]=19 [14]=3 [33]=19 [55]=19 [56]=19 [90]=19 [105]=3 [121]=3 [77]=2 [17]=3 [124]=19 [4]=2 [6]=3 [64]=19 [128]=3 [130]=19 [81]=19 [131]=19 [84]=19 [32]=19 [49]=3 [13]=3 [86]=19 [11]=19 [87]=19 [138]=19)" literal_transitions[8]="([104]=2 [75]=3 [34]=4 [2]=3 [3]=3 [78]=3 [106]=5 [37]=3 [41]=3 [46]=3 [113]=3 [85]=7 [114]=9 [52]=3 [54]=3 [89]=10 [118]=3 [120]=3 [122]=3 [16]=3 [59]=11 [60]=3 [18]=12 [123]=13 [20]=3 [125]=3 [127]=3 [26]=14 [68]=3 [98]=3 [28]=3 [29]=15 [101]=3)" - literal_transitions[9]="([129]=3 [132]=3 [1]=3 [74]=3 [36]=3 [107]=3 [38]=3 [108]=3 [5]=3 [79]=3 [40]=3 [80]=3 [111]=3 [7]=3 [42]=3 [43]=3 [82]=3 [83]=3 [47]=3 [48]=3 [10]=3 [110]=3 [51]=3 [53]=3 [12]=3 [116]=3 [88]=3 [50]=3 [57]=3 [91]=3 [58]=3 [92]=3 [93]=3 [61]=3 [62]=3 [126]=3 [94]=3 [63]=3 [21]=3 [96]=3 [23]=3 [24]=3 [65]=3 [66]=3 [25]=3 [133]=3 [27]=3 [69]=3 [99]=3 [70]=3 [30]=3 [137]=3 [71]=3 [100]=3)" + literal_transitions[9]="([129]=3 [132]=3 [1]=3 [74]=3 [36]=3 [107]=3 [38]=3 [108]=3 [5]=3 [79]=3 [40]=3 [80]=3 [111]=3 [7]=3 [42]=3 [43]=3 [82]=3 [83]=3 [47]=3 [48]=3 [10]=3 [110]=3 [51]=3 [53]=3 [12]=3 [116]=3 [88]=3 [50]=3 [57]=3 [91]=3 [58]=3 [92]=3 [93]=3 [61]=3 [62]=3 [126]=3 [94]=3 [63]=3 [21]=3 [96]=3 [23]=3 [24]=3 [65]=3 [66]=3 [25]=3 [133]=3 [27]=3 [69]=3 [99]=3 [70]=3 [30]=3 [137]=3 [71]=3 [100]=3 [138]=3)" literal_transitions[10]="([115]=16 [112]=17)" literal_transitions[12]="([102]=3)" literal_transitions[14]="([22]=2 [117]=2 [31]=2 [136]=2 [119]=2 [44]=2 [72]=2)" diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index e23cb500..41b82d10 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -89,6 +89,7 @@ CKeybindManager::CKeybindManager() { m_mDispatchers["focuswindow"] = focusWindow; m_mDispatchers["submap"] = setSubmap; m_mDispatchers["pass"] = pass; + m_mDispatchers["sendshortcut"] = sendshortcut; m_mDispatchers["layoutmsg"] = layoutmsg; m_mDispatchers["toggleopaque"] = toggleOpaque; m_mDispatchers["dpms"] = dpms; @@ -589,7 +590,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t modmask, const SPressedKeyWi } for (auto& k : m_lKeybinds) { - const bool SPECIALDISPATCHER = k.handler == "global" || k.handler == "pass" || k.handler == "mouse"; + const bool SPECIALDISPATCHER = k.handler == "global" || k.handler == "pass" || k.handler == "sendshortcut" || k.handler == "mouse"; const bool SPECIALTRIGGERED = std::find_if(m_vPressedSpecialBinds.begin(), m_vPressedSpecialBinds.end(), [&](const auto& other) { return other == &k; }) != m_vPressedSpecialBinds.end(); const bool IGNORECONDITIONS = @@ -2022,6 +2023,157 @@ void CKeybindManager::pass(std::string regexp) { g_pSeatManager->setPointerFocus(PWINDOW->m_pWLSurface.wlr(), SL); } +void CKeybindManager::sendshortcut(std::string args) { + // args=[,WINDOW_RULES] + const auto ARGS = CVarList(args, 3); + if (ARGS.size() != 3) { + Debug::log(ERR, "sendshortcut: invalid args"); + return; + } + + const auto MOD = g_pKeybindManager->stringToModMask(ARGS[0]); + const auto KEY = ARGS[1]; + uint32_t keycode = 0; + bool isMouse = 0; + + // similar to parseKey in ConfigManager + if (isNumber(KEY) && std::stoi(KEY) > 9) + keycode = std::stoi(KEY); + else if (KEY.compare(0, 5, "code:") == 0 && isNumber(KEY.substr(5))) + keycode = std::stoi(KEY.substr(5)); + else if (KEY.compare(0, 6, "mouse:") == 0 && isNumber(KEY.substr(6))) { + keycode = std::stoi(KEY.substr(6)); + isMouse = 1; + if (keycode < 272) { + Debug::log(ERR, "sendshortcut: invalid mouse button"); + return; + } + } else { + + // here, we need to find the keycode from the key name + // this is not possible through xkb's lib, so we need to iterate through all keycodes + // once found, we save it to the cache + + const auto KEYSYM = xkb_keysym_from_name(KEY.c_str(), XKB_KEYSYM_CASE_INSENSITIVE); + keycode = 0; + + const auto KB = g_pSeatManager->keyboard; + + if (!KB) { + Debug::log(ERR, "sendshortcut: no kb"); + return; + } + + const auto KEYPAIRSTRING = std::format("{}{}", (uintptr_t)KB.get(), KEY); + + if (!g_pKeybindManager->m_mKeyToCodeCache.contains(KEYPAIRSTRING)) { + xkb_keymap* km = KB->wlr()->keymap; + xkb_state* ks = KB->xkbTranslationState; + + xkb_keycode_t keycode_min, keycode_max; + keycode_min = xkb_keymap_min_keycode(km); + keycode_max = xkb_keymap_max_keycode(km); + + for (xkb_keycode_t kc = keycode_min; kc <= keycode_max; ++kc) { + xkb_keysym_t sym = xkb_state_key_get_one_sym(ks, kc); + + if (sym == KEYSYM) { + keycode = kc; + g_pKeybindManager->m_mKeyToCodeCache[KEYPAIRSTRING] = keycode; + } + } + + if (!keycode) { + Debug::log(ERR, "sendshortcut: key not found"); + return; + } + + } else + keycode = g_pKeybindManager->m_mKeyToCodeCache[KEYPAIRSTRING]; + } + + if (!keycode) { + Debug::log(ERR, "sendshortcut: invalid key"); + return; + } + + const std::string regexp = ARGS[2]; + PHLWINDOW PWINDOW = nullptr; + const auto LASTSURFACE = g_pCompositor->m_pLastFocus; + + //if regexp is not empty, send shortcut to current window + //else, dont change focus + if (regexp != "") { + PWINDOW = g_pCompositor->getWindowByRegex(regexp); + + if (!PWINDOW) { + Debug::log(ERR, "sendshortcut: window not found"); + return; + } + + if (!g_pSeatManager->keyboard) { + Debug::log(ERR, "No kb in sendshortcut?"); + return; + } + + if (!isMouse) + g_pSeatManager->setKeyboardFocus(PWINDOW->m_pWLSurface.wlr()); + else + g_pSeatManager->setPointerFocus(PWINDOW->m_pWLSurface.wlr(), {1, 1}); + } + + //copied the rest from pass and modified it + // if wl -> xwl, activate destination + if (PWINDOW && PWINDOW->m_bIsX11 && g_pCompositor->m_pLastWindow && !g_pCompositor->m_pLastWindow->m_bIsX11) + g_pXWaylandManager->activateSurface(PWINDOW->m_pWLSurface.wlr(), true); + // if xwl -> xwl, send to current. Timing issues make this not work. + if (PWINDOW && PWINDOW->m_bIsX11 && g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow->m_bIsX11) + PWINDOW = nullptr; + + g_pSeatManager->sendKeyboardMods(MOD, 0, 0, 0); + + if (g_pKeybindManager->m_iPassPressed == 1) { + if (!isMouse) + g_pSeatManager->sendKeyboardKey(g_pKeybindManager->m_uTimeLastMs, keycode - 8, WL_KEYBOARD_KEY_STATE_PRESSED); + else + g_pSeatManager->sendPointerButton(g_pKeybindManager->m_uTimeLastMs, keycode, WL_POINTER_BUTTON_STATE_PRESSED); + } else if (g_pKeybindManager->m_iPassPressed == 0) { + if (!isMouse) + g_pSeatManager->sendKeyboardKey(g_pKeybindManager->m_uTimeLastMs, keycode - 8, WL_KEYBOARD_KEY_STATE_RELEASED); + else + g_pSeatManager->sendPointerButton(g_pKeybindManager->m_uTimeLastMs, keycode, WL_POINTER_BUTTON_STATE_RELEASED); + } else { + // dynamic call of the dispatcher + if (!isMouse) { + g_pSeatManager->sendKeyboardKey(g_pKeybindManager->m_uTimeLastMs, keycode - 8, WL_KEYBOARD_KEY_STATE_PRESSED); + g_pSeatManager->sendKeyboardKey(g_pKeybindManager->m_uTimeLastMs, keycode - 8, WL_KEYBOARD_KEY_STATE_RELEASED); + } else { + g_pSeatManager->sendPointerButton(g_pKeybindManager->m_uTimeLastMs, keycode, WL_POINTER_BUTTON_STATE_PRESSED); + g_pSeatManager->sendPointerButton(g_pKeybindManager->m_uTimeLastMs, keycode, WL_POINTER_BUTTON_STATE_RELEASED); + } + } + + if (!PWINDOW) + return; + + if (PWINDOW->m_bIsX11) { //xwayland hack, see pass + if (!isMouse) { + g_pSeatManager->state.keyboardFocus = nullptr; + g_pSeatManager->state.keyboardFocusResource.reset(); + } else { + g_pSeatManager->state.pointerFocus = nullptr; + g_pSeatManager->state.pointerFocusResource.reset(); + } + } + + const auto SL = PWINDOW->m_vRealPosition.goal() - g_pInputManager->getMouseCoordsInternal(); + + if (!isMouse) + g_pSeatManager->setKeyboardFocus(LASTSURFACE); + else + g_pSeatManager->setPointerFocus(LASTSURFACE, SL); +} + void CKeybindManager::layoutmsg(std::string msg) { SLayoutMessageHeader hd = {g_pCompositor->m_pLastWindow.lock()}; g_pLayoutManager->getCurrentLayout()->layoutMessage(hd, msg); diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index a2025bb0..a5499987 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -95,6 +95,12 @@ class CKeybindManager { std::list m_lKeybinds; + //since we cant find keycode through keyname in xkb: + //on sendshortcut call, we once search for keyname (e.g. "g") the correct keycode (e.g. 42) + //and cache it in this map to make sendshortcut calls faster + //we also store the keyboard pointer (in the string) to differentiate between different keyboard (layouts) + std::unordered_map m_mKeyToCodeCache; + private: std::deque m_dPressedKeys; @@ -177,6 +183,7 @@ class CKeybindManager { static void focusWindow(std::string); static void setSubmap(std::string); static void pass(std::string); + static void sendshortcut(std::string); static void layoutmsg(std::string); static void toggleOpaque(std::string); static void dpms(std::string); diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index f4f97236..52927d95 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -842,8 +842,10 @@ void CInputManager::setupKeyboard(SP keeb) { auto PKEEB = ((IKeyboard*)owner)->self.lock(); const auto LAYOUT = PKEEB->getActiveLayout(); - if (PKEEB == g_pSeatManager->keyboard) + if (PKEEB == g_pSeatManager->keyboard) { g_pSeatManager->updateActiveKeyboardData(); + g_pKeybindManager->m_mKeyToCodeCache.clear(); + } g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", PKEEB->hlName + "," + LAYOUT}); EMIT_HOOK_EVENT("activeLayout", (std::vector{PKEEB, LAYOUT}));