diff --git a/hosts/common/programs/sane-input-handler/sane-input-handler b/hosts/common/programs/sane-input-handler/sane-input-handler index 30dd3e107..a00219b92 100755 --- a/hosts/common/programs/sane-input-handler/sane-input-handler +++ b/hosts/common/programs/sane-input-handler/sane-input-handler @@ -194,6 +194,46 @@ func swayGetOutput () { return (num_power_false === 0) } +# crawls the `swaymsg -t get_tree` output recursively, to return all window objects +func swayWindowsFromTree (root) { + var windows = [] + for node in (root.nodes) { + for w in (swayWindowsFromTree (node)) { + call windows->append(w) + } + } + + if (root.type === "con") { + # windows are identified, perhaps, by type = "con" or app_id = * + call windows->append(root) + } + + return (windows) +} + +# returns a json object representing the currently focused window +func swayGetFocusedWindow () { + var nodes = null; + swaymsg -t get_tree --raw | json read (&nodes) + + var windows = swayWindowsFromTree (nodes) + for w in (windows) { + if (w.focused) { + return (w) + } + } +} + +func swayIsFullscreen () { + var w = swayGetFocusedWindow() + if (not w) { + info swayIsFullscreen ("couldn't determine focused window") + return (false) + } + debug "swayIsFullscreen" (w) + return (w.fullscreen_mode === 1) +} + # true if rofi is visible func rofiGet () { if pidof rofi { @@ -354,6 +394,12 @@ func mapDefault (action) { # power twice => toggle media player return ("togglePlayback") } + / ^ 'volup_hold_' d+ $ / { + return ("seekForward") + } + / ^ 'voldown_hold_' d+ $ / { + return ("seekBackward") + } / ^ 'volup_tap_' d+ $ / { return ("volumeUp") @@ -374,12 +420,6 @@ func mapOff (action) { # power tap->hold: escape hatch for when bonsaid locks up return ("restartBonsai") } - / ^ 'volup_hold_' d+ $ / { - return ("seekForward") - } - / ^ 'voldown_hold_' d+ $ / { - return ("seekBackward") - } } } @@ -431,6 +471,10 @@ func mapOn (action) { # swallow, to prevent keyboard from also triggering media controls return ("ignore") } + / ^ 'volup_hold_' d+ $ / { + # swallow, to prevent app launcher from also triggering media controls + return ("ignore") + } / ^ 'voldown_hold_' d+ $ / { # swallow, to prevent terminal from also triggering media controls return ("ignore") @@ -438,6 +482,23 @@ func mapOn (action) { } } +func mapFullscreen (action) { + case (action) { + ("power_tap_1_hold") { + # power tap->hold: kill active window + return ("killWindow") + } + ("power_then_volup") { + # power (tap) -> volup: rotate CCW + return ("rotateCCW") + } + ("power_then_voldown") { + # power (tap) -> voldown: rotate CW + return ("rotateCW") + } + } +} + func mapInhibited (action) { case (action) { ("power_tap_1_hold") { @@ -456,6 +517,8 @@ func mapToplevel (action) { if (isAllOn()) { if (isInhibited()) { setvar mappedTo = traceFunc("mapInhibited", mapInhibited, action) + } elif (swayIsFullscreen()) { + setvar mappedTo = traceFunc("mapFullscreen", mapFullscreen, action) } else { setvar mappedTo = traceFunc("mapOn", mapOn, action) }