moby: update improve button mappings

- power + volup: screenshot
- power + voldown: camera
- volup_hold: file browser
- remove modal media controls
This commit is contained in:
2024-04-22 04:05:48 +00:00
parent 82007c9b40
commit 95b21cbed9
3 changed files with 88 additions and 56 deletions

View File

@@ -37,6 +37,18 @@ let
hash = "sha256-gz3N4uo7IWzzqaPHHVhby/e9NbtzcFJRQwgdNYxO/Yw="; hash = "sha256-gz3N4uo7IWzzqaPHHVhby/e9NbtzcFJRQwgdNYxO/Yw=";
}) })
]; ];
nativeBuildInputs = (upstream.nativeBuildInputs or []) ++ [
pkgs.copyDesktopItems
];
desktopItems = (upstream.desktopItems or []) ++ [
(pkgs.makeDesktopItem {
name = "rofi-filebrowser";
# alternatively: `rofi -modes filebrowser -show`, however this would require theme tweaking to look good
exec = "rofi -combi-modes filebrowser -show";
desktopName = "rofi filebrowser";
})
];
}); });
# rofi-emoji = pkgs.rofi-emoji.override { # rofi-emoji = pkgs.rofi-emoji.override {
# # plugins must be compiled against the same rofi they're loaded by # # plugins must be compiled against the same rofi they're loaded by

View File

@@ -138,32 +138,27 @@ in
sane.programs.bonsai.config.transitions = lib.mkIf cfg.enabled (friendlyToBonsai { sane.programs.bonsai.config.transitions = lib.mkIf cfg.enabled (friendlyToBonsai {
# map sequences of "events" to an argument to pass to sane-input-handler # map sequences of "events" to an argument to pass to sane-input-handler
# map: power (short), power (short) x2, power (long) # map: power (short), power (short) x2
power_pressed.timeout.ms = 900; # press w/o release. this is a long timeout because it's tied to the "kill window" action. power_pressed.power_released.timeout.trigger = "power_tap_1_final";
power_pressed.timeout.trigger = "powerhold";
power_pressed.power_released.timeout.trigger = "powerbutton_one";
power_pressed.power_released.timeout.ms = 300; power_pressed.power_released.timeout.ms = 300;
power_pressed.power_released.power_pressed.trigger = "powerbutton_two"; power_pressed.power_released.power_pressed.trigger = "power_tap_2_final";
# map power (short) -> volup/voldown # map: power (short) -> volup/voldown
power_pressed.power_released.volup_pressed.trigger = "powerbutton_volup"; power_pressed.power_released.volup_pressed.trigger = "power_then_volup";
power_pressed.power_released.voldown_pressed.trigger = "powerbutton_voldown"; power_pressed.power_released.voldown_pressed.trigger = "power_then_voldown";
# map: power + volup/voldown
power_pressed.volup_pressed.trigger = "power_and_volup";
power_pressed.voldown_pressed.trigger = "power_and_voldown";
# map: power (long)
power_pressed.timeout.ms = 900; # press w/o release. this is a long timeout because it's tied to the "kill window" action.
power_pressed.timeout.power_released.trigger = "power_hold";
## remap power + volup/voldown on the long power, to decrease accidental "kill window"s
power_pressed.timeout.volup_pressed.trigger = "power_and_volup";
power_pressed.timeout.voldown_pressed.trigger = "power_and_voldown";
# map: volume taps and holds # map: volume taps and holds
volup_pressed = (recurseHold "volup" {}) // { volup_pressed = (volumeActions {}).volup_pressed // {
# this either becomes volup_hold_* (via recurseHold, above) or: trigger = "volup_start";
# - a short volup_tap_1 followed by:
# - a *finalized* volup_1 (i.e. end of action)
# - more taps/holds, in which case we prefix it with `modal_<action>`
# to denote that we very explicitly entered this state.
#
# it's clunky: i do it this way so that voldown can map to keyboard/terminal in unlock mode
# but trigger media controls in screenoff
# in a way which *still* allows media controls if explicitly entered into via a tap on volup first
volup_released = (volumeActions { prefix = "modal_"; }) // {
trigger = "volup_tap_1";
timeout.ms = 300;
timeout.trigger = "volup_1";
};
}; };
voldown_pressed = (volumeActions {}).voldown_pressed // { voldown_pressed = (volumeActions {}).voldown_pressed // {
trigger = "voldown_start"; trigger = "voldown_start";

View File

@@ -12,11 +12,16 @@
# #
# example of a design which considers these things: # example of a design which considers these things:
# - when unlocked: # - when unlocked:
# - volup toggle -> app menu # - volup tap -> app menu
# - volup hold -> file browser
# - voldown press -> keyboard # - voldown press -> keyboard
# - voldown hold -> terminal # - voldown hold -> terminal
# - power x2 -> screenoff # - power x2 -> screenoff
# - hold power -> kill app # - power hold -> kill app
# - power,volup -> screen rotate CCW
# - power,voldown -> screen rotate CW
# - power+volup -> screenshot
# - power+voldown -> camera
# - when locked: # - when locked:
# - volup tap -> volume up # - volup tap -> volume up
# - volup hold -> media seek forward # - volup hold -> media seek forward
@@ -24,15 +29,31 @@
# - voldown hold -> media seek backward # - voldown hold -> media seek backward
# - power x1 -> screen on # - power x1 -> screen on
# - power x2 -> play/pause media # - power x2 -> play/pause media
# some trickiness allows for media controls in unlocked mode:
# - volup tap -> enter media mode
# - i.e. in this state, vol tap/hold is mapped to volume/seek
# - if, after entering media mode, no more taps occur, then we trigger the default app-menu action
# limitations/downsides: # limitations/downsides:
# - power mappings means phone is artificially slow to unlock. # - power mappings means phone is artificially slow to unlock.
# - media controls when unlocked have quirks: # - alternate mapping could resolve this:
# - mashing voldown to decrease the volume will leave you with a toggled keyboard. # - power_tap_1: screen on (i.e. immediately after releasing power, if not held long)
# - seeking backward isn't possible except by first tapping volup. # - power_hold_1: play/pause media (which now works in any mode)
# - power_tap_2: screen off
# - power_tap_1_hold_1: kill
# - by hiding this behind the tap, it decreases the chance of accidental kills
# - "tap-then-hold" idiom could make sense for keyboard/terminal, too: voldown_tap_1_hold_1: terminal, instead of voldown_hold -- decreases accidental terminal launches
# - power-hold for kill means messing up the compound operations has bad consequences
#
# EXAMPLE EVENT FIRINGS:
# - double-tap voldown:
# - voldown_start
# - voldown_tap_1
# - voldown_tap_2
# - hold voldown:
# - voldown_start
# - voldown_hold_1
# - voldown_hold_2
# - voldown_hold_3
# - hold power:
# - power_hold (notice: it doesn't fire power_start)
# - double-tap power:
# - power_tap_2_final (notice: it doesn't fire power_tap_1)
# increments to use for volume adjustment (in %) # increments to use for volume adjustment (in %)
@@ -106,27 +127,26 @@ handleWith() {
dispatchDefault() { dispatchDefault() {
case "$action" in case "$action" in
"powerbutton_one") "power_tap_1_final")
# power once => unlock # power once => unlock
handleWith allOn handleWith allOn
;; ;;
"powerbutton_two") "power_tap_2_final")
# power twice => screenoff # power twice => screenoff
handleWith allOff handleWith allOff
;; ;;
# powerbutton_three: intentional no-op because overloading the kill-window handler is risky
volup_tap*|modal_volup_tap*) volup_tap*)
handleWith wpctl set-volume @DEFAULT_AUDIO_SINK@ "$VOL_INCR"%+ handleWith wpctl set-volume @DEFAULT_AUDIO_SINK@ "$VOL_INCR"%+
;; ;;
voldown_tap*|modal_voldown_tap*) voldown_tap*)
handleWith wpctl set-volume @DEFAULT_AUDIO_SINK@ "$VOL_INCR"%- handleWith wpctl set-volume @DEFAULT_AUDIO_SINK@ "$VOL_INCR"%-
;; ;;
volup_hold*|modal_volup_hold*) volup_hold*)
handleWith playerctl position 30+ handleWith playerctl position 30+
;; ;;
voldown_hold*|modal_voldown_hold*) voldown_hold*)
handleWith playerctl position 10- handleWith playerctl position 10-
;; ;;
esac esac
@@ -134,11 +154,11 @@ dispatchDefault() {
dispatchOff() { dispatchOff() {
case "$action" in case "$action" in
"powerbutton_two") "power_tap_2_final")
# power twice => toggle media player # power twice => toggle media player
handleWith playerctl play-pause handleWith playerctl play-pause
;; ;;
"powerhold") "power_hold")
# power toggle during deep sleep often gets misread as power hold, so treat same # power toggle during deep sleep often gets misread as power hold, so treat same
handleWith allOn handleWith allOn
;; ;;
@@ -147,41 +167,46 @@ dispatchOff() {
dispatchOn() { dispatchOn() {
case "$action" in case "$action" in
# powerbutton_one: intentional default to no-op # power_tap_1_final: intentional default to no-op
# powerbutton_two: intentional default to screenoff # power_tap_2_final: intentional default to screenoff
"powerhold") "power_hold")
# power thrice: kill active window # power thrice: kill active window
# TODO: disable this if locked (with e.g. schlock, swaylock, etc) # TODO: disable this if locked (with e.g. schlock, swaylock, etc)
handleWith swaymsg kill handleWith swaymsg kill
;; ;;
"powerbutton_volup") "power_and_volup")
# power (hold) -> volup: take screenshot
handleWith sane-open-desktop sane-screenshot.desktop
;;
"power_and_voldown")
# power (hold) -> voldown: open camera
handleWith sane-open-desktop org.postmarketos.Megapixels.desktop
;;
"power_then_volup")
# power (tap) -> volup: rotate CCW # power (tap) -> volup: rotate CCW
handleWith swaymsg -- output '-' transform 90 anticlockwise handleWith swaymsg -- output '-' transform 90 anticlockwise
;; ;;
"powerbutton_voldown") "power_then_voldown")
# power (tap) -> voldown: rotate CW # power (tap) -> voldown: rotate CW
handleWith swaymsg -- output '-' transform 90 clockwise handleWith swaymsg -- output '-' transform 90 clockwise
;; ;;
"volup_tap_1") "volup_tap_1")
# swallow: this could be the start to a media control (multi taps / holds),
# or it could be just a single tap -> release, handled next/below
handleWith ignore
;;
"volup_1")
# volume up once: system menu # volume up once: system menu
handleWith sane-open-desktop rofi.desktop handleWith sane-open-desktop rofi.desktop
;; ;;
"volup_hold_1")
# volume up hold: just browse files
handleWith sane-open-desktop rofi-filebrowser.desktop
;;
"voldown_start") "voldown_start")
# volume down once: toggle keyboard # volume down once: toggle keyboard
handleWith toggleKeyboard handleWith toggleKeyboard
;; ;;
"voldown_hold_2") "voldown_hold_1")
# hold voldown to launch terminal # hold voldown to launch terminal
# note we already triggered the keyboard; that's fine: usually keyboard + terminal go together :) # note we already triggered the keyboard; that's fine: usually keyboard + terminal go together :)
# voldown_hold_1 frequently triggers during short taps meant only to reveal the keyboard,
# so prefer a longer hold duration
handleWith sane-open-desktop xdg-terminal-exec.desktop handleWith sane-open-desktop xdg-terminal-exec.desktop
;; ;;
"voldown_tap_1") "voldown_tap_1")
@@ -197,8 +222,8 @@ dispatchOn() {
dispatchInhibited() { dispatchInhibited() {
case "$action" in case "$action" in
"powerhold") "power_hold")
# power thrice: escape hatch in case rofi has hung # power hold: escape hatch in case rofi has hung
handleWith killall -9 rofi handleWith killall -9 rofi
;; ;;
*) *)