From e6f26581bf22e266c5056eddfb264eca2efb6ef4 Mon Sep 17 00:00:00 2001 From: Timo Wilken Date: Thu, 11 Jul 2024 17:11:25 +0200 Subject: Wayland-based desktop support Add a separate home service to configure a Wayland-based desktop instead of an X11 one. Screensharing in Zoom doesn't work unfortunately, but it worked (at least for a while) through OBS. Waybar might need some work to bring it in line with the previous polybar configuration, especially in terms of aesthetics. --- tw/services/files/foot.ini | 20 +++ tw/services/files/passmenu | 12 +- tw/services/files/rofi.rasi | 2 +- tw/services/files/sessionmenu | 34 ++++-- tw/services/files/sway.conf | 275 ++++++++++++++++++++++++++++++++++++++++++ tw/services/files/waybar.css | 77 ++++++++++++ 6 files changed, 405 insertions(+), 15 deletions(-) create mode 100644 tw/services/files/foot.ini create mode 100644 tw/services/files/sway.conf create mode 100644 tw/services/files/waybar.css (limited to 'tw/services/files') diff --git a/tw/services/files/foot.ini b/tw/services/files/foot.ini new file mode 100644 index 00000000..f1bc6d54 --- /dev/null +++ b/tw/services/files/foot.ini @@ -0,0 +1,20 @@ +[main] +font=Hermit:size=10, Noto Color Emoji:size=10 +dpi-aware=no +include=~/.config/foot/catppuccin.ini + +[scrollback] +lines=1000000 +multiplier=10.0 + +[cursor] +blink=yes + +[mouse] +hide-when-typing=yes + +[text-bindings] +# Remap Ctrl+Return and Shift+Return to Return, to avoid confusing the shell. +# These are frequently mistyped, e.g. when typing Ctrl+Space, Return. +\x0a=Shift+Return +\x0a=Control+Return diff --git a/tw/services/files/passmenu b/tw/services/files/passmenu index 9bf7f7e3..a95fcc7a 100755 --- a/tw/services/files/passmenu +++ b/tw/services/files/passmenu @@ -44,7 +44,11 @@ extract_key() { } type_stdin() { - tr -d '\n' | xdotool getactivewindow type --clearmodifiers --file - + tr -d '\n' | if [ -n "$WAYLAND_DISPLAY" ]; then + wtype -s 50 - + else + xdotool getactivewindow type --clearmodifiers --file - + fi } ## Command-line arguments @@ -82,7 +86,11 @@ case "$mode" in entry=$(pass show "$password_name") if [ "$mode" = type-all ]; then echo "$entry" | extract_key username | type_stdin - xdotool getactivewindow key Tab + if [ -n "$WAYLAND_DISPLAY" ]; then + wtype -s 50 -k Tab + else + xdotool getactivewindow key Tab + fi fi echo "$entry" | head -1 | type_stdin unset entry;; diff --git a/tw/services/files/rofi.rasi b/tw/services/files/rofi.rasi index 83363c14..b01c4c1d 100644 --- a/tw/services/files/rofi.rasi +++ b/tw/services/files/rofi.rasi @@ -1,6 +1,6 @@ /* -*- mode: css -*- */ configuration { - modi: "combi,windowcd,calc"; + modi: "combi,window"; combi-modi: "window,drun,session:sessionmenu,ssh,run"; terminal: "rofi-sensible-terminal"; icon-theme: "Papirus-Dark"; diff --git a/tw/services/files/sessionmenu b/tw/services/files/sessionmenu index 91839d8e..4f145d34 100755 --- a/tw/services/files/sessionmenu +++ b/tw/services/files/sessionmenu @@ -4,26 +4,34 @@ (ice-9 match) (ice-9 ports)) +(define wm + (cond ((getenv "SWAYSOCK") 'sway) + ((getenv "I3SOCK") 'i3) + (else #f))) + (define (call-command/stderr . command) "Call COMMAND using `system*', but redirect all output to stderr." (with-output-to-port (current-error-port) (lambda () (apply system* command)))) +(define (wm-msg . command) + (apply call-command/stderr + (match wm + (sway "swaymsg") + (i3 "i3-msg") + (_ (error "No recognised window manager running"))) + command)) + (match (command-line) ((_ "quit") (exit 0)) - ((_ "Reload i3 configuration") - (call-command/stderr "i3-msg" "reload")) + ((_ "Reload WM configuration") + (wm-msg "reload")) ((_ "Sleep") - ;; "screenlock" blocks until unlocked by the user, so run in background. - ;; TODO: write "mem" to /sys/power/state, but it's owned by root. - (let ((locker (spawn "screenlock" '("screenlock"))) - (sleepfile (open-file "/sys/power/state" "w"))) - (display "mem" sleepfile) - (close sleepfile) - (waitpid locker))) + ;; Rely on swayidle to lock the screen before going to sleep. + (call-command/stderr "loginctl" "suspend")) ((_ "Log out") - (call-command/stderr "i3-msg" "exit")) + (wm-msg "exit")) ((_ "Shutdown") (call-command/stderr "sudo" "-n" "/run/current-system/profile/sbin/shutdown")) ((_ "Reboot") @@ -31,8 +39,10 @@ (_ (format #t "\0~a\x1f~a~%~{~a\0icon\x1f~a~%~}" "prompt" "Session" - '("Reload i3 configuration" "reload" + `(,@(if wm + '("Reload WM configuration" "reload" + "Log out" "system-log-out") + '()) "Sleep" "system-suspend" - "Log out" "system-log-out" "Shutdown" "system-shutdown" "Reboot" "system-reboot")))) diff --git a/tw/services/files/sway.conf b/tw/services/files/sway.conf new file mode 100644 index 00000000..498c8cff --- /dev/null +++ b/tw/services/files/sway.conf @@ -0,0 +1,275 @@ +# sway config file +# This file is augmented by the default sway configuration in tw/system.scm, +# which is used for wlgreet's sway session. Common options should go there. + +# Appearance and Styling {{{ +title_align center +default_border pixel 3 +default_floating_border pixel 3 +hide_edge_borders smart +gaps inner 15 +gaps outer 0 +smart_gaps on +# TODO: Zoom needs XWayland despite [General]xwayland=false in zoomus.conf +# xwayland disable + +# swayfx effects +# swaymsg -r -t get_outputs | jq -r '.[0].layer_shell_surfaces | .[] | .namespace' +layer_effects "waybar" corner_radius 0 + +# Catppuccin colours +# Foregrounds +set $c_fg #cdd6f4 +set $c_inactive #7f849c +# Backgrounds +set $c_bg #11111b +set $c_active #585b70 +set $c_urgent #f9e2af + +# class border background text indicator child_border +client.focused $c_active $c_active $c_fg $c_active $c_active +client.focused_inactive $c_bg $c_bg $c_fg $c_bg $c_bg +client.unfocused $c_bg $c_bg $c_inactive $c_bg $c_bg +client.urgent $c_urgent $c_urgent $c_fg $c_urgent $c_urgent +client.placeholder $c_bg $c_bg $c_inactive $c_bg $c_bg +client.background $c_bg +# }}} + +# Output Configuration {{{ +# Laptop screen +output "AU Optronics 0x4CA3 Unknown" position 0 0 +# Displays at work +output "HP Inc. HP Z24u G3 CN42322LXZ" position -1920 0 +output "Samsung Electric Company SyncMaster H9XZ110607" position -3840 0 +# }}} + +# Basic Configuration {{{ +# use the Super key as $mod +set $mod Mod4 + +# Use Mouse+$mod to drag floating windows to their wanted position +floating_modifier $mod + +# essential applications +bindsym $mod+Return exec foot +bindsym $mod+i exec icecat --new-window +bindsym $mod+shift+i exec icecat --new-tab "$(wl-paste -np)" +bindsym $mod+e exec $ASYNC_EDITOR +# Use ASYNC_EDITOR so I can continue using ranger while the editor +# remains open in a separate window. +bindsym $mod+slash exec EDITOR=$ASYNC_EDITOR foot ranger +bindsym $mod+semicolon exec --no-startup-id nheko +bindsym $mod+shift+semicolon exec --no-startup-id foot aerc +bindsym $mod+y exec foot pulsemixer + +# volume +bindsym XF86AudioRaiseVolume exec --no-startup-id volume +5 +bindsym XF86AudioLowerVolume exec --no-startup-id volume -5 +bindsym XF86AudioMute exec --no-startup-id volume toggle-mute + +# screenshots +bindsym Print exec --no-startup-id slurp -o | grim -g- -l9 +bindsym shift+Print exec --no-startup-id swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp | grim -g- -l9 + +# notifications +bindsym $mod+n exec dunstctl close +bindsym $mod+shift+n exec dunstctl history-pop +bindsym $mod+period exec dunstctl context + +# screen locking and sleep handling +bindsym $mod+shift+slash exec loginctl lock-session +bindswitch --locked lid:on exec loginctl suspend + +# kill focused window +bindsym $mod+shift+q kill + +# rofi menus +bindsym $mod+d exec rofi -show combi +bindsym $mod+shift+e exec rofi -show session:sessionmenu +bindsym $mod+p exec passmenu --type-all +bindsym $mod+shift+p exec passmenu --type-pass +bindsym $mod+o exec passmenu --type-otp +bindsym $mod+shift+Return exec rofi -show ssh +# }}} + +# Basic Movement {{{ +# change focus +bindsym $mod+h focus left +bindsym $mod+j focus down +bindsym $mod+k focus up +bindsym $mod+l focus right +bindsym $mod+Left focus left +bindsym $mod+Down focus down +bindsym $mod+Up focus up +bindsym $mod+Right focus right + +# move focused window +bindsym $mod+shift+h move left +bindsym $mod+shift+j move down +bindsym $mod+shift+k move up +bindsym $mod+shift+l move right +bindsym $mod+shift+Left move left +bindsym $mod+shift+Down move down +bindsym $mod+shift+Up move up +bindsym $mod+shift+Right move right + +bindsym $mod+a focus parent +bindsym $mod+shift+a focus child +# }}} + +# Layout {{{ +bindsym $mod+b split h +bindsym $mod+v split v + +# enter fullscreen mode for the focused container +bindsym $mod+f fullscreen toggle +bindsym $mod+shift+f floating enable, resize set 1920 1080, move position 0 0 + +# change container layout (stacked, tabbed, toggle split) +bindsym $mod+s layout stacking +bindsym $mod+w layout tabbed +bindsym $mod+x layout toggle split + +bindsym $mod+shift+space floating toggle +# change focus between tiling / floating windows +bindsym $mod+space focus mode_toggle + +# scratchpad +bindsym $mod+numbersign scratchpad show +bindsym $mod+shift+numbersign move to scratchpad +bindsym $mod+apostrophe sticky disable, floating disable +bindsym $mod+shift+apostrophe sticky enable, floating enable + +# move workspaces +bindsym $mod+shift+comma move workspace to output left +bindsym $mod+shift+period move workspace to output right +# }}} + +# Default Workspaces {{{ +# switch to workspace +bindsym $mod+Escape workspace back_and_forth +bindsym $mod+1 workspace 1 +bindsym $mod+2 workspace 2 +bindsym $mod+3 workspace 3 +bindsym $mod+4 workspace 4 +bindsym $mod+5 workspace 5 +bindsym $mod+6 workspace 6 +bindsym $mod+7 workspace 7 +bindsym $mod+8 workspace 8 +bindsym $mod+9 workspace 9 +bindsym $mod+0 workspace 10 +bindsym $mod+parenleft workspace prev +bindsym $mod+parenright workspace next +# Swiping with 3 fingers should move workspaces. Emulate "natural scrolling" +# where swiping right moves the current workspace off to the right, so the +# previous/left-hand workspace comes into focus. +bindgesture swipe:3:right workspace prev +bindgesture swipe:3:left workspace next + +# move focused container to workspace +bindsym $mod+shift+Escape move container to workspace back_and_forth +bindsym $mod+shift+1 move container to workspace 1 +bindsym $mod+shift+2 move container to workspace 2 +bindsym $mod+shift+3 move container to workspace 3 +bindsym $mod+shift+4 move container to workspace 4 +bindsym $mod+shift+5 move container to workspace 5 +bindsym $mod+shift+6 move container to workspace 6 +bindsym $mod+shift+7 move container to workspace 7 +bindsym $mod+shift+8 move container to workspace 8 +bindsym $mod+shift+9 move container to workspace 9 +bindsym $mod+shift+0 move container to workspace 10 +bindsym $mod+shift+parenleft move container to workspace prev +bindsym $mod+shift+parenright move container to workspace next +# }}} + +# Custom Workspaces {{{ +set $ws_terminal 0:>_ +bindsym $mod+grave workspace "$ws_terminal" +bindsym $mod+shift+grave move container to workspace "$ws_terminal" + +set $ws_coding 50:🖊️ +bindsym $mod+c workspace "$ws_coding" +bindsym $mod+shift+c move container to workspace "$ws_coding" + +set $ws_games 60:🎮 +bindsym $mod+g workspace "$ws_games" +bindsym $mod+shift+g move container to workspace "$ws_games" + +set $ws_music 80:🎵 +bindsym $mod+u workspace "$ws_music" +bindsym $mod+shift+u move container to workspace "$ws_music" + +set $ws_messaging 90:💬 +bindsym $mod+m workspace "$ws_messaging" +bindsym $mod+shift+m move container to workspace "$ws_messaging" + +# Mark xwayland windows specially. +for_window [shell="xwayland"] title_format "%title (%shell)" + +assign [class="^Franz$"] "$ws_messaging" +assign [window_role="^weechat$"] "$ws_messaging" +assign [window_role="^mutt$"] "$ws_messaging" +assign [class="^evolution-initial$"] "$ws_messaging" +assign [class="^kontact$"] "$ws_messaging" + +# NOTE: no_focus will also be ignored for the first window on a workspace as +# there shouldn’t be a reason to not focus the window in this case. This allows +# for better usability in combination with workspace_layout. (From i3 docs) +#no_focus [class="^Franz$"] +#no_focus [window_role="^weechat$"] +#no_focus [window_role="^mutt$"] +#no_focus [class="^evolution-initial$"] + +## PlayOnLinux +for_window [title="PlayOnLinux"] floating enable + +## Plasma/KDE: https://ryanlue.com/posts/2019-06-13-kde-i3 +# Don’t treat Plasma pop-ups as full-sized windows +for_window [class="plasmashell"] floating enable +# Don’t spawn an empty window for the Plasma Desktop +for_window [title="Desktop — Plasma"] move scratchpad +# Don’t let notifications and non-interactive pop-up windows steal focus +#no_focus [class="plasmashell" window_type="on_screen_display"] +# https://github.com/heckelson/i3-and-kde-plasma +# Move notifications to top-right corner. +#for_window [class="plasmashell" window_type="notification"] move up 400, move right 750, no_focus +# Notifications appear in the centre of the screen. According to +# https://old.reddit.com/r/i3wm/comments/bw1yfs/kde_notifications_appearing_in_the_centre_of/, +# setting notifications to appear in the top-left corner gets placement right. +no_focus [class="plasmashell" window_type="notification"] + +for_window [class="^Pyneedle$"] floating enable +for_window [instance="^emacs-initial$"] floating enable +for_window [class="^Spotify$"] move container to workspace "$ws_music" +for_window [class="^Pidgin$"] move container to workspace "$ws_messaging" +for_window [title="^aerc$"] move container to workspace "$ws_messaging" +# annoying pop-up from Bluetooth network manager +for_window [class="^.blueman-applet-real$"] kill +# Zoom popups (e.g. "user has started sharing their screen") +# "Normal" Zoom windows have titles other than a plain "zoom". +for_window [class="^zoom$" title="^zoom$"] floating enable +no_focus [class="^zoom$" title="^zoom$"] +# }}} + +# Modes {{{ +mode "resize" { + bindsym h resize shrink width 10 px or 10 ppt + bindsym j resize grow height 10 px or 10 ppt + bindsym k resize shrink height 10 px or 10 ppt + bindsym l resize grow width 10 px or 10 ppt + + bindsym shift+h resize shrink width 5 px or 5 ppt + bindsym shift+j resize grow height 5 px or 5 ppt + bindsym shift+k resize shrink height 5 px or 5 ppt + bindsym shift+l resize grow width 5 px or 5 ppt + + bindsym left resize shrink width 10 px or 10 ppt + bindsym down resize grow height 10 px or 10 ppt + bindsym up resize shrink height 10 px or 10 ppt + bindsym right resize grow width 10 px or 10 ppt + + bindsym Return mode "default" + bindsym Escape mode "default" +} +bindsym $mod+r mode "resize" +# }}} diff --git a/tw/services/files/waybar.css b/tw/services/files/waybar.css new file mode 100644 index 00000000..c03025fe --- /dev/null +++ b/tw/services/files/waybar.css @@ -0,0 +1,77 @@ +/* See basic example at . */ +@import "catppuccin.css"; + +* { + background: @base; + color: @text; + font-family: Fira Sans, OpenMoji, Hermit; + font-size: 1em; + border-radius: 0; + border: none; +} + +tooltip { + background: @surface0; + border: 2px solid @surface2; +} + +label.module { + padding: 5px; + background: transparent; + border-top: 3px solid transparent; +} +box.module { + margin: 0 5px; /* vertical, then horizontal */ + background: transparent; +} + +#workspaces button { + padding: 0; + background: transparent; + border-top: 3px solid transparent; +} +#workspaces button { + border-top: 3px solid @base; +} +#workspaces button.urgent { + border-top: 3px solid @yellow; +} +#workspaces button.focused { + border-top: 3px solid @blue; +} + +#mode { + color: @red; + border-top: 3px solid @red; +} + +#temperature { + border-top: 3px solid transparent; +} +#temperature.critical { + border-top: 3px solid @red; +} + +#pulseaudio { + border-top: 3px solid @red; +} +#pulseaudio.bluetooth { + border-top: 3px solid @blue; +} +#pulseaudio.muted { + border-top: 3px solid transparent; +} + +#battery { + border-top: 3px solid @green; +} +#battery.discharging.medium { + border-top: 3px solid transparent; +} +#battery.discharging.critical { + border-top: 3px solid @red; +} + +#custom-dunst { + border-top: 3px solid @red; +} -- cgit v1.2.3