sane-input-handler: lift command execution up to the toplevel
This commit is contained in:
@@ -115,6 +115,13 @@ proc effect (...args) {
|
||||
}
|
||||
}
|
||||
|
||||
func traceFunc (funcName, fn, ...args) {
|
||||
debug "$funcName" (...args)
|
||||
var r = fn(...args)
|
||||
debug "$[funcName] -> return" (r)
|
||||
return (r)
|
||||
}
|
||||
|
||||
## HELPERS
|
||||
|
||||
# swaySetOutput true|false
|
||||
@@ -205,7 +212,7 @@ func memoize (name, f) {
|
||||
} else {
|
||||
verbose "memoize(uncached)" (name)
|
||||
# setvar expr = f()
|
||||
setvar expr = io->evalExpr (f);
|
||||
setvar expr = io->evalExpr (f)
|
||||
verbose "memoize(uncached -> cached)" (name, expr)
|
||||
setglobal MEMOIZED[name] = expr
|
||||
}
|
||||
@@ -220,7 +227,7 @@ func isInhibited () {
|
||||
return (memoize ("rofiGet", ^[rofiGet()]))
|
||||
}
|
||||
|
||||
proc handleWith (...args) {
|
||||
proc handleWith (; ...args) {
|
||||
var state = ""
|
||||
if (isInhibited()) {
|
||||
setvar state = "inhibited+"
|
||||
@@ -233,7 +240,6 @@ proc handleWith (...args) {
|
||||
|
||||
info "handleWith" ("state=$state", "action=$action", ...args)
|
||||
@[args]
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
||||
@@ -338,125 +344,130 @@ proc killRofi {
|
||||
|
||||
## DISPATCHERS
|
||||
|
||||
proc dispatchDefault (action) {
|
||||
func mapDefault (action) {
|
||||
case (action) {
|
||||
("power_tap_2") {
|
||||
# power twice => screenoff
|
||||
handleWith allOff
|
||||
return ("allOff")
|
||||
}
|
||||
("power_hold") {
|
||||
# power twice => toggle media player
|
||||
handleWith togglePlayback
|
||||
return ("togglePlayback")
|
||||
}
|
||||
|
||||
/ ^ 'volup_tap_' d+ $ / {
|
||||
handleWith volumeUp
|
||||
return ("volumeUp")
|
||||
}
|
||||
/ ^ 'voldown_tap_' d+ $ / {
|
||||
handleWith volumeDown
|
||||
return ("volumeDown")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc dispatchOff (action) {
|
||||
func mapOff (action) {
|
||||
case (action) {
|
||||
("power_tap_1") {
|
||||
# power once => unlock
|
||||
handleWith allOn
|
||||
return ("allOn")
|
||||
}
|
||||
("power_tap_1_hold") {
|
||||
# power tap->hold: escape hatch for when bonsaid locks up
|
||||
handleWith restartBonsai
|
||||
return ("restartBonsai")
|
||||
}
|
||||
/ ^ 'volup_hold_' d+ $ / {
|
||||
handleWith seekForward
|
||||
return ("seekForward")
|
||||
}
|
||||
/ ^ 'voldown_hold_' d+ $ / {
|
||||
handleWith seekBackward
|
||||
return ("seekBackward")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc dispatchOn (action) {
|
||||
func mapOn (action) {
|
||||
case (action) {
|
||||
# power_tap_1: intentional default to no-op (it's important this be unmapped, because events can be misordered with power_tap_1 arriving *after* power_tap_2)
|
||||
# power_tap_2: intentional default to screenoff
|
||||
("power_tap_1_hold") {
|
||||
# power tap->hold: kill active window
|
||||
# TODO: disable this if locked (with e.g. schlock, swaylock, etc)
|
||||
handleWith killWindow
|
||||
return ("killWindow")
|
||||
}
|
||||
("power_and_volup") {
|
||||
# power (hold) -> volup: take screenshot
|
||||
handleWith screenshot
|
||||
return ("screenshot")
|
||||
}
|
||||
("power_and_voldown") {
|
||||
# power (hold) -> voldown: open camera
|
||||
handleWith openCamera
|
||||
return ("openCamera")
|
||||
}
|
||||
("power_then_volup") {
|
||||
# power (tap) -> volup: rotate CCW
|
||||
handleWith rotateCCW
|
||||
return ("rotateCCW")
|
||||
}
|
||||
("power_then_voldown") {
|
||||
# power (tap) -> voldown: rotate CW
|
||||
handleWith rotateCW
|
||||
return ("rotateCW")
|
||||
}
|
||||
|
||||
("volup_tap_1") {
|
||||
# volume up once: filesystem browser
|
||||
handleWith openFilebrowser
|
||||
return ("openFilebrowser")
|
||||
}
|
||||
("volup_hold_1") {
|
||||
# volume up hold: browse files and apps
|
||||
handleWith openFilebrowserWithApps
|
||||
return ("openFilebrowserWithApps")
|
||||
}
|
||||
|
||||
("voldown_start") {
|
||||
# volume down once: toggle keyboard
|
||||
handleWith toggleKeyboard
|
||||
return ("toggleKeyboard")
|
||||
}
|
||||
("voldown_hold_1") {
|
||||
# hold voldown to launch terminal
|
||||
# note we already triggered the keyboard; that's fine: usually keyboard + terminal go together :)
|
||||
handleWith openTerminal
|
||||
return ("openTerminal")
|
||||
}
|
||||
("voldown_tap_1") {
|
||||
# swallow, to prevent keyboard from also triggering media controls
|
||||
handleWith ignore
|
||||
return ("ignore")
|
||||
}
|
||||
/ ^ 'voldown_hold_' d+ $ / {
|
||||
# swallow, to prevent terminal from also triggering media controls
|
||||
handleWith ignore
|
||||
return ("ignore")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc dispatchInhibited (action) {
|
||||
func mapInhibited (action) {
|
||||
case (action) {
|
||||
("power_tap_1_hold") {
|
||||
# power hold: escape hatch in case rofi has hung
|
||||
handleWith killRofi
|
||||
return ("killRofi")
|
||||
}
|
||||
(else) {
|
||||
# eat everything else (and let rofi consume it)
|
||||
handleWith inhibited
|
||||
return ("inhibited")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc dispatchToplevel (action) {
|
||||
if (not isAllOn()) {
|
||||
trace dispatchOff "$action"
|
||||
} else {
|
||||
func mapToplevel (action) {
|
||||
var mappedTo = null
|
||||
if (isAllOn()) {
|
||||
if (isInhibited()) {
|
||||
trace dispatchInhibited "$action"
|
||||
setvar mappedTo = traceFunc("mapInhibited", mapInhibited, action)
|
||||
} else {
|
||||
trace dispatchOn "$action"
|
||||
setvar mappedTo = traceFunc("mapOn", mapOn, action)
|
||||
}
|
||||
} else {
|
||||
setvar mappedTo = traceFunc("mapOff", mapOff, action)
|
||||
}
|
||||
|
||||
trace dispatchDefault "$action"
|
||||
if (mappedTo === null) {
|
||||
setvar mappedTo = traceFunc("mapDefault", mapDefault, action)
|
||||
}
|
||||
|
||||
return (mappedTo)
|
||||
}
|
||||
|
||||
var action = null
|
||||
@@ -488,6 +499,7 @@ if is-main {
|
||||
exit 0
|
||||
}
|
||||
|
||||
trace dispatchToplevel "$action"
|
||||
handleWith unmapped
|
||||
var handler = mapToplevel (action) or unmapped
|
||||
|
||||
handleWith (handler)
|
||||
}
|
||||
|
Reference in New Issue
Block a user