Compare commits

...

2 Commits

14 changed files with 204 additions and 104 deletions

View File

@ -765,9 +765,19 @@ in
sane-die-with-parent.sandbox.enable = false; #< it's a launcher; can't sandbox
sane-open-desktop.sandbox.enable = false; #< trivial script, and all our deps are sandboxed
sane-open-desktop.suggestedPrograms = [
sane-open.sandbox.method = "bwrap";
sane-open.sandbox.autodetectCliPaths = "existing"; # for when opening a file
sane-open.sandbox.whitelistDbus = [ "user" ];
sane-open.sandbox.extraConfig = [
"--sane-sandbox-keep-namespace" "pid" # to toggle keyboard
];
sane-open.sandbox.extraHomePaths = [
".local/share/applications"
];
sane-open.sandbox.extraRuntimePaths = [ "sway" ];
sane-open.suggestedPrograms = [
"gdbus"
"xdg-utils"
];
screen.sandbox.enable = false; #< tty; needs to run anything

View File

@ -104,6 +104,9 @@ in
"/mnt/servo/media"
"/mnt/servo/playground"
];
sandbox.extraConfig = [
"--sane-sandbox-keep-namespace" "pid" # for sane-open to toggle keyboard
];
fs.".config/rofi/config.rasi".symlink.target = ./config.rasi;
persist.byStore.cryptClearOnBoot = [
@ -118,12 +121,12 @@ in
packageUnwrapped = pkgs.static-nix-shell.mkBash {
pname = "rofi-run-command";
srcRoot = ./.;
pkgs = [ "sane-open-desktop" "xdg-utils" ];
pkgs = [ "sane-open" ];
};
sandbox.enable = false; #< trivial script, and all our deps are sandboxed
suggestedPrograms = [
"sane-open-desktop"
"sane-open"
"xdg-utils"
];
};

View File

@ -1,5 +1,5 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p sane-open-desktop -p xdg-utils
#!nix-shell -i bash -p sane-open
# use:
# rofi-run-command <handler>.desktop [cmd [args ...]]
@ -14,16 +14,10 @@ shift
binArgs=("$@")
if [ "$desktop" != .desktop ]; then
# launching an app; the file browser position is no longer interesting: clear it so it opens in ~ next time.
# better UX would be to manage this in the other branch:
# - open in ~ by default, regardless of last directory
# - after launching a *file*, when that file is closed, re-open rofi in that file's directory.
# however, `xdg-open` and the `OpenFile` xdg-desktop-portal API don't give any obvious way to block for the app to close.
rm -f ~/.cache/rofi/rofi3.filebrowsercache
exec sane-open-desktop "$desktop"
exec sane-open --auto-keyboard --application "$desktop"
elif [ "$binary" = "xdg-open" ]; then
exec xdg-open "$@"
exec sane-open --auto-keyboard --file "${binArgs[@]}"
fi
printf "no .desktop file, and unexpected binary; not invoking: %s %s" "$binary" "${binArgs[*]}" > /dev/null
printf "no .desktop file, and unexpected binary; not invoking: %s %s\n" "$binary" "${binArgs[*]}" >&2
exit 1

View File

@ -88,17 +88,18 @@ in
pname = "sane-input-handler";
srcRoot = ./.;
pkgs = {
inherit (pkgs) coreutils killall playerctl procps sane-open-desktop util-linux wireplumber;
inherit (pkgs) coreutils jq killall playerctl procps sane-open util-linux wireplumber;
sway = config.sane.programs.sway.package.sway-unwrapped;
};
};
suggestedPrograms = [
"bonsai"
# dependencies which get pulled in unconditionally:
"jq"
"killall"
"playerctl"
"procps"
"sane-open-desktop"
"sane-open"
"sway"
"wireplumber"
# optional integrations:

View File

@ -1,5 +1,5 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p coreutils -p killall -p playerctl -p procps -p sane-open-desktop -p sway -p util-linux -p wireplumber
#!nix-shell -i bash -p coreutils -p jq -p killall -p playerctl -p procps -p sane-open -p sway -p util-linux -p wireplumber
# input map considerations
# - using compound actions causes delays.
@ -79,13 +79,6 @@ isScreenOn() {
> /dev/null
}
isLandscape() {
# success if all outputs are landscape
swaymsg -t get_outputs --raw \
| jq --exit-status '. | all(.transform == "90" or .transform == "270")' \
> /dev/null
}
isAllOn() {
isTouchOn && isScreenOn
}
@ -104,7 +97,7 @@ handleWith() {
else
state="${state}off"
fi
log "state=$state action=$action: handleWith: $@"
log "state=$state action=$action: handleWith: $*"
"$@"
exit $?
}
@ -130,52 +123,15 @@ allOff() {
swaymsg -- input type:touch events disabled
}
_keyboardPid=
setKeyboard() {
if [ -z "$_keyboardPid" ]; then
# lazy init
_keyboardPid=$(pidof "$KEYBOARD")
fi
if [ -z "$_keyboardPid" ]; then
toggleKeyboard() {
local keyboardPid=$(pidof "$KEYBOARD")
if [ -z "$keyboardPid" ]; then
log "cannot find $KEYBOARD"
return
fi
case "$1" in
"toggle")
# `env` so that we get the right `kill` binary instead of bash's builtin
env kill -s RTMIN+0 "$_keyboardPid"
;;
"show")
env kill -s USR2 "$_keyboardPid"
;;
"hide")
env kill -s USR1 "$_keyboardPid"
;;
"set")
case "$2" in
"0")
setKeyboard hide
;;
"1")
setKeyboard show
;;
*)
log "setKeyboard: unknown option 'set $2'"
;;
esac
;;
"ifRoom")
if isLandscape; then
setKeyboard hide
else
setKeyboard show
fi
;;
*)
log "setKeyboard: unknown option '$1'"
;;
esac
# `env` so that we get the right `kill` binary instead of bash's builtin
env kill -s RTMIN+0 "$keyboardPid"
}
## DISPATCHERS
@ -226,11 +182,11 @@ dispatchOn() {
;;
"power_and_volup")
# power (hold) -> volup: take screenshot
handleWith sane-open-desktop sane-screenshot.desktop
handleWith sane-open --application sane-screenshot.desktop
;;
"power_and_voldown")
# power (hold) -> voldown: open camera
handleWith sane-open-desktop org.postmarketos.Megapixels.desktop
handleWith sane-open --auto-keyboard --application org.postmarketos.Megapixels.desktop
;;
"power_then_volup")
# power (tap) -> volup: rotate CCW
@ -243,25 +199,23 @@ dispatchOn() {
"volup_tap_1")
# volume up once: filesystem browser
setKeyboard ifRoom &
handleWith sane-open-desktop rofi-filebrowser.desktop
handleWith sane-open --auto-keyboard --application rofi-filebrowser.desktop
;;
"volup_hold_1")
# volume up hold: browse files and apps
setKeyboard ifRoom &
# reset fs directory: useful in case you get stuck in broken directory (e.g. one which lacks a `..` entry)
rm -f ~/.cache/rofi/rofi3.filebrowsercache
handleWith sane-open-desktop rofi.desktop
handleWith sane-open --auto-keyboard --application rofi.desktop
;;
"voldown_start")
# volume down once: toggle keyboard
handleWith setKeyboard "toggle"
handleWith toggleKeyboard
;;
"voldown_hold_1")
# hold voldown to launch terminal
# note we already triggered the keyboard; that's fine: usually keyboard + terminal go together :)
handleWith sane-open-desktop xdg-terminal-exec.desktop
handleWith sane-open --auto-keyboard --application xdg-terminal-exec.desktop
;;
"voldown_tap_1")
# swallow, to prevent keyboard from also triggering media controls

View File

@ -136,7 +136,7 @@ in
"rofi" # menu/launcher
"rofi-snippets"
"sane-screenshot"
"sane-open-desktop"
"sane-open"
# "splatmoji" # used by sway config
"sway-contrib.grimshot" # used by sway config
"swayidle" # enable if you need it

View File

@ -77,13 +77,13 @@ bindsym --locked XF86MonBrightnessUp exec brightnessctl set +5%
bindsym --locked XF86MonBrightnessDown exec brightnessctl set 5%-
#### special functions
bindsym Print exec sane-open-desktop sane-screenshot.desktop
bindsym $mod+Print exec sane-open-desktop sane-screenshot.desktop
bindsym $mod+l exec sane-open-desktop swaylock.desktop
bindsym $mod+s exec sane-open-desktop rofi-snippets.desktop
# bindsym $mod+slash exec sane-open-desktop splatmoji.desktop
bindsym $mod+d exec sane-open-desktop rofi.desktop
bindsym $mod+Return exec sane-open-desktop xdg-terminal-exec.desktop
bindsym Print exec sane-open sane-screenshot.desktop
bindsym $mod+Print exec sane-open sane-screenshot.desktop
bindsym $mod+l exec sane-open swaylock.desktop
bindsym $mod+s exec sane-open rofi-snippets.desktop
# bindsym $mod+slash exec sane-open splatmoji.desktop
bindsym $mod+d exec sane-open rofi.desktop
bindsym $mod+Return exec sane-open xdg-terminal-exec.desktop
bindsym $mod+Shift+q kill
# bindsym $mod+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'

View File

@ -20,7 +20,7 @@ let
how many seconds of idle time before triggering the command.
'';
};
config.command = lib.mkIf (config.desktop != null) "sane-open-desktop ${config.desktop}";
config.command = lib.mkIf (config.desktop != null) "sane-open --application ${config.desktop}";
});
screenOff = pkgs.writeShellScriptBin "screen-off" ''
swaymsg -- output '*' power false

View File

@ -1,6 +0,0 @@
{ static-nix-shell }:
static-nix-shell.mkBash {
pname = "sane-open-desktop";
srcRoot = ./.;
pkgs = [ "glib" ];
}

View File

@ -1,12 +0,0 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p glib
# usage: sane-open-desktop org.my.desktop
# given some .desktop file (by name, not by path), ask the xdg-desktop-portal service to open it
exec gdbus call --session --timeout 10 \
--dest org.freedesktop.portal.Desktop \
--object-path /org/freedesktop/portal/desktop \
--method org.freedesktop.portal.DynamicLauncher.Launch \
"$1" {}

View File

@ -0,0 +1,6 @@
{ static-nix-shell }:
static-nix-shell.mkBash {
pname = "sane-open";
srcRoot = ./.;
pkgs = [ "glib" "jq" "procps" "sway" "util-linux" "xdg-utils" ];
}

View File

@ -0,0 +1,150 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p glib -p jq -p procps -p sway -p util-linux -p xdg-utils
set -e
usage() {
echo "usage: sane-open [options] <org.my.desktop | /path/to/file>"
echo "given some resource, ask the xdg-desktop-portal service to open it"
echo "this could be either the name of an application, or a URI identifying a file"
echo
echo "options:"
echo "--auto-keyboard: toggle the virtual keyboard state to whatever's preferred by the app"
echo "--application <thing.desktop>: open the desktop file (by name, not path)"
echo "--file </path/to/file>: open the file using the default mime handler"
exit $1
}
configureKeyboardFor_application() {
case "$1" in
Alacritty.desktop)
setKeyboard show
;;
rofi.desktop)
setKeyboard showIfRoom
;;
rofi-filebrowser.desktop)
setKeyboard showIfRoom
;;
rofi-snippets.desktop)
setKeyboard showIfRoom
;;
sane-screenshot.desktop)
# leave unchanged
;;
xdg-terminal-exec.desktop)
setKeyboard show
;;
*)
setKeyboard hide
;;
esac
}
configureKeyboardFor_file() {
local mime=$(xdg-mime query filetype "$1")
local application=$(xdg-mime query default "$mime")
configureKeyboardFor_application "$application"
}
open_application() {
gdbus call --session --timeout 10 \
--dest org.freedesktop.portal.Desktop \
--object-path /org/freedesktop/portal/desktop \
--method org.freedesktop.portal.DynamicLauncher.Launch \
"$1" {}
}
open_file() {
# open the file, and then pass the fd to dbus
exec 3<> "$1"
gdbus call --session --timeout 10 \
--dest org.freedesktop.portal.Desktop \
--object-path /org/freedesktop/portal/desktop \
--method org.freedesktop.portal.OpenURI.OpenFile \
'' 3 "{'ask': <false>}"
}
isLandscape() {
# success if all outputs are landscape
swaymsg -t get_outputs --raw \
| jq --exit-status '. | all(.transform == "90" or .transform == "270")' \
> /dev/null
}
_keyboardPid=
setKeyboard() {
if [ -z "$KEYBOARD" ]; then
return
fi
if [ -z "$_keyboardPid" ]; then
_keyboardPid=$(pidof "$KEYBOARD")
if [ -z "$_keyboardPid" ]; then
return
fi
fi
_setKeyboard "$1"
}
_setKeyboard() {
case "$1" in
"show")
# `env` so that we get the util-linux `kill` binary instead of bash's builtin
env kill -s USR2 "$_keyboardPid"
;;
"showIfRoom")
isLandscape && _setKeyboard "hide" || _setKeyboard "show"
;;
"hide")
env kill -s USR1 "$_keyboardPid"
;;
esac
}
## ARGUMENT PARSING
autoKeyboard=
resource=
resourceType=
while [ $# -gt 0 ]; do
arg="$1"
shift
case "$arg" in
"--auto-keyboard")
autoKeyboard=1
;;
"--help")
usage 0
;;
"--application")
resourceType="application"
;;
"--file")
resourceType="file"
;;
*)
if [ $# -ne 0 ]; then
usage 1
fi
resource="$arg"
;;
esac
done
if [ -z "$resourceType" ]; then
if [ -e "$HOME/.local/share/applications/$resource" ]; then
resourceType=application
else
resourceType=file
fi
fi
## TOPLEVEL LOGIC
if [ -n "$autoKeyboard" ]; then
# do in parallel to avoid delaying app launch
configureKeyboardFor_"$resourceType" "$resource" &
fi
open_"$resourceType" "$resource"

View File

@ -1,7 +1,7 @@
# STATUS:
# - can't find any virtual keyboard it works with
# - run with `swaylock-plugin --command='/nix/store/my-virtual-keyboard-.../bin/vkbd'`
# - if it crashes, launch `sane-open-desktop swaylock.desktop` from another TTY
# - if it crashes, launch `sane-open swaylock.desktop` from another TTY
# - `cd /etc/pam.d; sudo cp swaylock swaylock-plugin`
{ lib, stdenv
, cairo

View File

@ -60,7 +60,7 @@ let
rtl8723cs-wowlan = callPackage ./additional/rtl8723cs-wowlan { };
sane-cast = callPackage ./additional/sane-cast { };
sane-die-with-parent = callPackage ./additional/sane-die-with-parent { };
sane-open-desktop = callPackage ./additional/sane-open-desktop { };
sane-open = callPackage ./additional/sane-open { };
sane-sandboxed = callPackage ./additional/sane-sandboxed { };
sane-screenshot = callPackage ./additional/sane-screenshot { };
sane-scripts = lib.recurseIntoAttrs (callPackage ./additional/sane-scripts { });