From d294be9f3531d941af1e362ee163be3c21c0e5f9 Mon Sep 17 00:00:00 2001 From: Colin Date: Tue, 21 Nov 2023 08:14:52 +0000 Subject: [PATCH] sxmo: auto-scale the environment to accomodate non-mobile-friendly apps this is hacky, but it hopefully makes gnome-maps usable, quickly. an alternative fix would be to theme gnome-maps. it's likely also that it becomes more mobile-friendly in the gnome 45 release. --- hosts/common/programs/default.nix | 1 + .../programs/sway-autoscaler/default.nix | 44 ++++++++++++ .../programs/sway-autoscaler/sway-autoscaler | 69 +++++++++++++++++++ hosts/modules/gui/sxmo/default.nix | 4 ++ 4 files changed, 118 insertions(+) create mode 100644 hosts/common/programs/sway-autoscaler/default.nix create mode 100755 hosts/common/programs/sway-autoscaler/sway-autoscaler diff --git a/hosts/common/programs/default.nix b/hosts/common/programs/default.nix index 28ba630b0..986f03d30 100644 --- a/hosts/common/programs/default.nix +++ b/hosts/common/programs/default.nix @@ -67,6 +67,7 @@ ./stepmania.nix ./sublime-music.nix ./supertuxkart.nix + ./sway-autoscaler ./swaynotificationcenter.nix ./tangram.nix ./tor-browser-bundle-bin.nix diff --git a/hosts/common/programs/sway-autoscaler/default.nix b/hosts/common/programs/sway-autoscaler/default.nix new file mode 100644 index 000000000..a8cbd6c70 --- /dev/null +++ b/hosts/common/programs/sway-autoscaler/default.nix @@ -0,0 +1,44 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.sane.programs.sway-autoscaler; +in +{ + sane.programs.sway-autoscaler = { + configOption = with lib; mkOption { + default = {}; + type = types.submodule { + options.autostart = mkOption { + type = types.bool; + default = false; + }; + + options.defaultScale = mkOption { + type = types.number; + default = 1; + }; + options.interval = mkOption { + type = types.number; + default = 5; + }; + }; + }; + + package = pkgs.static-nix-shell.mkBash { + pname = "sway-autoscaler"; + pkgs = [ "jq" "sway" ]; + src = ./.; + }; + + services.sway-autoscaler = { + description = "adjust global desktop scale to match the activate application"; + wantedBy = lib.mkIf cfg.config.autostart [ "default.target" ]; + serviceConfig = { + ExecStart = "${cfg.package}/bin/sway-autoscaler --loop-sec ${builtins.toString cfg.config.interval}"; + Type = "simple"; + Restart = "always"; + RestartSec = "10s"; + }; + environment.SWAY_DEFAULT_SCALE = builtins.toString cfg.config.defaultScale; + }; + }; +} diff --git a/hosts/common/programs/sway-autoscaler/sway-autoscaler b/hosts/common/programs/sway-autoscaler/sway-autoscaler new file mode 100755 index 000000000..e4b48d126 --- /dev/null +++ b/hosts/common/programs/sway-autoscaler/sway-autoscaler @@ -0,0 +1,69 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p jq -p sway + +help() { + echo "queries the focused window and apply an appropriate display-wide scale." + echo "this should be considered a temporary workaround until more apps support small displays." + echo "" + echo "args:" + echo " -v | --verbose" + echo " --loop-sec N re-compute the scale every N seconds. else, run once and exit." + echo "" + echo "environment variables:" + echo " SWAY_DEFAULT_SCALE=N scale to apply when no known window is selected." + # TODO: could use map-style environment variables to allow external per-app config + # - SWAY_SCALE_org.gnome.Maps=1 ; ... +} + +options=$(getopt -l verbose,loop-sec: -o v -- "" "${@}") +eval "set -- ${options}" + +verbose=false +loop=false +loop_sec= +while true; do + case "$1" in + (-v|--verbose) + verbose=true + shift + ;; + (--loop-sec) + shift + loop=true + loop_sec="$1" + shift + ;; + (--) + shift + if [ $# -eq 1 ]; then + break + fi + ;; + (*) + echo "invalid arguments: '$1'" + exit 1 + ;; + esac +done + +autoscale() { + focused=$(swaymsg -t get_tree | jq --raw-output '.. | select(.type?) | select(.focused==true) | .app_id') + $verbose && echo "focused: '$focused'" + + scale=${SWAY_DEFAULT_SCALE:-1} + case "$focused" in + org.gnome.Maps) scale=1 + esac + + $verbose && echo "scaling to $scale" + swaymsg -q -- output '*' scale "$scale" +} + +if $loop; then + while true; do + autoscale + sleep "$loop_sec" + done +else + autoscale +fi diff --git a/hosts/modules/gui/sxmo/default.nix b/hosts/modules/gui/sxmo/default.nix index e99bf3972..aa5622985 100644 --- a/hosts/modules/gui/sxmo/default.nix +++ b/hosts/modules/gui/sxmo/default.nix @@ -236,6 +236,7 @@ in # SXMO_WM = mkSettingsOpt "sway" "sway or dwm. ordinarily initialized by sxmo_{x,w}init.sh"; SXMO_NO_AUDIO = mkSettingsOpt "1" "don't start pipewire/pulseaudio in sxmo_hook_start.sh"; SXMO_STATES = mkSettingsOpt "unlock screenoff" "list of states the device should support (unlock, lock, screenoff)"; + SXMO_SWAY_SCALE = mkSettingsOpt "1" "sway output scale"; }; }; default = {}; @@ -265,6 +266,7 @@ in "bemenu" # specifically to import its theming "sfeed" # want this here so that the user's ~/.sfeed/sfeedrc gets created # "superd" # make superctl (used by sxmo) be on PATH + "sway-autoscaler" ]; persist.byStore.cryptClearOnBoot = [ @@ -382,6 +384,8 @@ in sane.programs.sxmoApps.enableFor.user.colin = true; + sane.programs.sway-autoscaler.config.defaultScale = builtins.fromJSON cfg.settings.SXMO_SWAY_SCALE; + # sxmo internally uses doas instead of sudo security.doas.enable = true; security.doas.wheelNeedsPassword = false;