diff --git a/config/fuzzel/fuzzel.ini~esh b/config/fuzzel/fuzzel.ini~esh index a0631f5..4130b2d 100644 --- a/config/fuzzel/fuzzel.ini~esh +++ b/config/fuzzel/fuzzel.ini~esh @@ -2,7 +2,9 @@ [main] dpi-aware=no font=<%= $font_sans %>:size=<%= $font_size_medium %> +<% if [[ $DEPLOY_DISTRO == "arch" ]]; then -%> use-bold=yes +<% fi -%> width=72 icons-enabled=no horizontal-pad=0 diff --git a/config/scripts-desktop/spawn-terminal.sh b/config/scripts-desktop/spawn-terminal.sh index 8d81ba1..6824e8a 100755 --- a/config/scripts-desktop/spawn-terminal.sh +++ b/config/scripts-desktop/spawn-terminal.sh @@ -177,7 +177,7 @@ if [[ $TERMINAL == "alacritty" ]]; then terminal_cmd=("alacritty") if [[ "$floating" = true ]]; then - args+=("--class=floating") + args+=("--class=Alacritty.floating") args+=("-o window.dimensions.columns=120") args+=("-o window.dimensions.lines=32") fi diff --git a/config/sway/config b/config/sway/config new file mode 100644 index 0000000..385e3b0 --- /dev/null +++ b/config/sway/config @@ -0,0 +1,148 @@ +#------------------------------------------------------------------------------- +# Sway configuration +# +# See the sway(5) and swaymsg(1) man pages for complete documentation. +#------------------------------------------------------------------------------- + +# Variables +#------------------------------------------------------------------------------- + +set $config_dir $HOME/.config +set $scripts_dir $HOME/.local/scripts + +# Input configuration +#------------------------------------------------------------------------------- + +# Focus follows cursor +focus_follows_mouse yes + +# Keyboard repeat rate +input type:keyboard { + repeat_delay 300 + repeat_rate 50 +} + +# Hide inactive cursor +seat * hide_cursor 3000 + +# Zowie EC2 sensitivity +input "1189:32769:BenQ_ZOWIE_BenQ_ZOWIE_Gaming_Mouse" { + accel_profile flat + pointer_accel -0.65 +} + +# Logitech G Pro X Superlight sensitivity +input "1133:50503:Logitech_USB_Receiver" { + accel_profile flat + pointer_accel 0.05 +} + +# Trackpad sensitivity +input "43256:6199:Bastard_Keyboards_Dilemma_Max_Mouse" { + accel_profile flat + pointer_accel -0.15 +} + +# Layout configuration +#------------------------------------------------------------------------------- + +gaps inner 6 +gaps outer -6 + +default_border pixel 3 +default_floating_border pixel 3 + +smart_gaps on +smart_borders off + +# Output configuration +#------------------------------------------------------------------------------- + +include $config_dir/sway/outputs.conf + +# Workspace configuration +#------------------------------------------------------------------------------- + +include $config_dir/sway/workspace.conf + +# Startup applications +#------------------------------------------------------------------------------- + +# Adjust screen brightness +exec wlsunset -l 52.155472 -L 5.389358 + +# Clean home +exec $scripts_dir/clean-home.sh + +# Theme configuration +#------------------------------------------------------------------------------- + +include $config_dir/sway/theme.conf + +# Apply wallpaper +exec waypaper --restore & + +# Start waybar +exec pkill -x waybar +exec waybar & + +# Window rules +#------------------------------------------------------------------------------- + +# Floating windows +for_window [app_id="org.gnome.gitlab.somas.Apostrophe"] floating enable +for_window [app_id="blueman-manager"] floating enable +for_window [app_id=".*floating"] floating enable +for_window [app_id="gcr-prompter"] floating enable +for_window [app_id="org.gnome.Nautilus"] floating enable +for_window [app_id="nwg-look"] floating enable +for_window [app_id="org.gnome.seahorse.Application"] floating enable +for_window [app_id="com.transmissionbt.transmission.*"] floating enable +for_window [app_id="transmission-gtk"] floating enable +for_window [app_id="waypaper"] floating enable +for_window [app_id="xdg-desktop-portal-gtk"] floating enable +for_window [app_id="yad"] floating enable +for_window [app_id="nm-connection-editor"] floating enable + +# Window sizes +for_window [app_id="blueman-manager"] resize set 800 600 +for_window [app_id="org.gnome.Nautilus"] resize set 1024 960 +for_window [app_id="nwg-look"] resize set 1024 960 +for_window [app_id="org.qutebrowser.qutebrowser"] resize set 1600 1200 + +# Server-side decorations +for_window [app_id="Alacritty"] border pixel 3 +for_window [app_id="org.gnome.gitlab.somas.Apostrophe"] border pixel 3 +for_window [app_id="blueman-manager"] border pixel 3 +for_window [app_id="chromium"] border pixel 3 +for_window [app_id="gcr-viewer"] border pixel 3 +for_window [app_id="gcr-prompter"] border pixel 3 +for_window [app_id="com.mitchellh.ghostty.*"] border pixel 3 +for_window [app_id="gtk-pipe-viewer"] border pixel 3 +for_window [app_id="gimp"] border pixel 3 +for_window [app_id="imv"] border pixel 3 +for_window [app_id="marker"] border pixel 3 +for_window [app_id="org.gnome.Nautilus"] border pixel 3 +for_window [app_id="nm-connection-editor"] border pixel 3 +for_window [app_id="nwg-look"] border pixel 3 +for_window [app_id="org.pulseaudio.pavucontrol"] border pixel 3 +for_window [app_id="org.gnome.seahorse.Application"] border pixel 3 +for_window [app_id="org.gnome.SimpleScan"] border pixel 3 +for_window [app_id="com.transmissionbt.transmission.*"] border pixel 3 +for_window [app_id="transmission-gtk"] border pixel 3 +for_window [app_id="waypaper"] border pixel 3 +for_window [app_id="org.wezfurlong.wezterm.*"] border pixel 3 +for_window [app_id="xdg-desktop-portal-gtk"] border pixel 3 +for_window [app_id="yad"] border pixel 3 +for_window [app_id="yad-settings"] border pixel 3 +for_window [app_id="org.pwmt.zathura"] border pixel 3 + +# Key mappings +#------------------------------------------------------------------------------- + +include $config_dir/sway/keymaps.conf + +# Include system config +#------------------------------------------------------------------------------- + +include /etc/sway/config.d/* diff --git a/config/sway/environment.sh b/config/sway/environment.sh new file mode 100755 index 0000000..4bc68c2 --- /dev/null +++ b/config/sway/environment.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +#------------------------------------------------------------------------------- +# Sway environment +#------------------------------------------------------------------------------- + +# Set cursor theme path. +export XCURSOR_PATH="/usr/share/icons" + +# QT performance flag. +export QT_QPA_PLATFORM=wayland +export QT_SCALE_FACTOR_ROUNDING_POLICY=round + +# XDG desktop portal integration. +export XDG_CURRENT_DESKTOP=sway diff --git a/config/sway/init b/config/sway/init new file mode 100755 index 0000000..5b257c6 --- /dev/null +++ b/config/sway/init @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +exec sway-run diff --git a/config/sway/init~sway b/config/sway/init~sway new file mode 100755 index 0000000..5b257c6 --- /dev/null +++ b/config/sway/init~sway @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +exec sway-run diff --git a/config/sway/keymaps.conf b/config/sway/keymaps.conf new file mode 100644 index 0000000..250d57b --- /dev/null +++ b/config/sway/keymaps.conf @@ -0,0 +1,153 @@ +#------------------------------------------------------------------------------- +# Sway key mappings +# +# See sway-bindsym(5) for keysym documentation +#------------------------------------------------------------------------------- + +# Mod key +#------------------------------------------------------------------------------- + +set $mod Mod4 + +# System mappings +#------------------------------------------------------------------------------- + +# Lock sway +bindsym $mod+Shift+z exec hyprlock + +# Exit sway +bindsym $mod+Shift+w exit + +# Reload sway configuration +bindsym $mod+Shift+r exec $config_dir/sway/refresh.sh + +# Shortcut mappings +#------------------------------------------------------------------------------- + +# Run menu +bindsym $mod+Return exec $LAUNCHER + +# New terminal +bindsym $mod+t exec spawn-terminal.sh + +# New floating terminal +bindsym $mod+g exec spawn-terminal.sh --floating + +# New terminal in a directory +bindsym $mod+Shift+t exec open-terminal-cwd.sh + +# Browser +bindsym $mod+b exec $BROWSER + +# Browser session +bindsym $mod+Shift+b exec open-qutebrowser-session.sh + +# Process manager +bindsym $mod+m exec spawn-terminal.sh --command btop + +# Toggle waybar +bindsym $mod+r exec toggle-waybar.sh + +# Dismiss all notifications +bindsym $mod+y exec makoctl dismiss -a + +# Take screenshot of a selected rectangle +bindsym $mod+p exec screenshot-rectangle.sh +bindsym $mod+Shift+p exec screenshot-rectangle.sh --upload + +# Window mappings +#------------------------------------------------------------------------------- + +# Drag windows with mouse +floating_modifier $mod normal + +# Toggle window float +bindsym $mod+Space floating toggle + +# Center floating window +bindsym $mod+c move position center + +# Toggle window fullscreen +bindsym $mod+f fullscreen toggle + +# Close window +bindsym $mod+w kill + +# Change focus +bindsym $mod+j focus down +bindsym $mod+k focus up +bindsym $mod+h focus left +bindsym $mod+l focus right + +# Move the focused window up/down +bindsym $mod+Control+j move down +bindsym $mod+Control+k move up + +# Move the focused window left/right +bindsym $mod+Control+h move left +bindsym $mod+Control+l move right + +# Close window with middle mouse button +bindsym --whole-window $mod+button2 kill + +# Resize (floating) window +bindsym $mod+Shift+d resize shrink height 100px +bindsym $mod+Shift+f resize grow height 100px +bindsym $mod+Shift+g resize grow width 200px +bindsym $mod+Shift+s resize shrink width 200px + +# Move (floating) window +bindsym $mod+Control+d move up 100px +bindsym $mod+Control+f move down 100px +bindsym $mod+Control+g move right 200px +bindsym $mod+Control+s move left 200px + +# Workspace mappings +#------------------------------------------------------------------------------- + +# Cycle focused workspaces +bindsym $mod+Shift+h exec sway-workspace prev-on-output +bindsym $mod+Shift+l exec sway-workspace next-on-output + +# Focus workspaces numerically (display-aware) +bindsym $mod+1 exec $config_dir/sway/sws.sh focus 1 +bindsym $mod+2 exec $config_dir/sway/sws.sh focus 2 +bindsym $mod+3 exec $config_dir/sway/sws.sh focus 3 +bindsym $mod+4 exec $config_dir/sway/sws.sh focus 4 +bindsym $mod+5 exec $config_dir/sway/sws.sh focus 5 +bindsym $mod+6 exec $config_dir/sway/sws.sh focus 6 +bindsym $mod+7 exec $config_dir/sway/sws.sh focus 7 +bindsym $mod+8 exec $config_dir/sway/sws.sh focus 8 +bindsym $mod+9 exec $config_dir/sway/sws.sh focus 9 +bindsym $mod+0 exec $config_dir/sway/sws.sh focus 10 + +# Focus special workspaces +bindsym $mod+F1 exec $config_dir/sway/sws.sh focus home +bindsym $mod+F2 exec $config_dir/sway/sws.sh focus work +bindsym $mod+F3 exec $config_dir/sway/sws.sh focus todo +bindsym $mod+F4 exec $config_dir/sway/sws.sh focus spotify + +# Send window to workspace (display-aware) +bindsym $mod+Control+1 exec $config_dir/sway/sws.sh move 1 +bindsym $mod+Control+2 exec $config_dir/sway/sws.sh move 2 +bindsym $mod+Control+3 exec $config_dir/sway/sws.sh move 3 +bindsym $mod+Control+4 exec $config_dir/sway/sws.sh move 4 +bindsym $mod+Control+5 exec $config_dir/sway/sws.sh move 5 +bindsym $mod+Control+6 exec $config_dir/sway/sws.sh move 6 +bindsym $mod+Control+7 exec $config_dir/sway/sws.sh move 7 +bindsym $mod+Control+8 exec $config_dir/sway/sws.sh move 8 +bindsym $mod+Control+9 exec $config_dir/sway/sws.sh move 9 +bindsym $mod+Control+0 exec $config_dir/sway/sws.sh move 10 + +# Send to special workspaces +bindsym $mod+Control+F1 exec $config_dir/sway/sws.sh move home +bindsym $mod+Control+F2 exec $config_dir/sway/sws.sh move work +bindsym $mod+Control+F3 exec $config_dir/sway/sws.sh move todo +bindsym $mod+Control+F4 exec $config_dir/sway/sws.sh move spotify + +# Layout mappings +#------------------------------------------------------------------------------- + +# Adjust split ratio (resize focused container) +bindsym $mod+Shift+equal resize grow width 5 ppt +bindsym $mod+minus resize shrink width 5 ppt diff --git a/config/sway/outputs.conf~home-dual b/config/sway/outputs.conf~home-dual new file mode 100644 index 0000000..22d7527 --- /dev/null +++ b/config/sway/outputs.conf~home-dual @@ -0,0 +1,11 @@ +#------------------------------------------------------------------------------- +# Sway output configuration - Dual monitor setup +# +# Based on way-displays configuration: +# - DP-2: Left monitor, rotated 90° clockwise +# - DP-1: Right monitor, normal orientation +#------------------------------------------------------------------------------- + +output DP-2 pos 0 0 transform 270 + +output DP-1 pos 1200 0 diff --git a/config/sway/outputs.conf~home-triple b/config/sway/outputs.conf~home-triple new file mode 100644 index 0000000..6661e30 --- /dev/null +++ b/config/sway/outputs.conf~home-triple @@ -0,0 +1,14 @@ +#------------------------------------------------------------------------------- +# Sway output configuration - Triple monitor setup (supertubes/cyxwel) +# +# Based on way-displays configuration: +# - HDMI-A-6: Left monitor, rotated 90° clockwise +# - DP-3: Center monitor, 2560x1440@240Hz, scaled 1.125 +# - DP-4: Right monitor, rotated 90° clockwise +#------------------------------------------------------------------------------- + +output HDMI-A-6 pos 0 0 transform 270 + +output DP-3 pos 1200 0 scale 1.125 mode 2560x1440@240Hz + +output DP-4 pos 3475 0 transform 270 diff --git a/config/sway/outputs.conf~intelic b/config/sway/outputs.conf~intelic new file mode 100644 index 0000000..361dfdf --- /dev/null +++ b/config/sway/outputs.conf~intelic @@ -0,0 +1,11 @@ +#------------------------------------------------------------------------------- +# Sway output configuration - Intelic laptop setup (vortex) +# +# Based on way-displays configuration: +# - LG ULTRAWIDE: External monitor, 3440x1440@60Hz +# - eDP-1: Laptop display, 2560x1600@120Hz, scaled 1.5 +#------------------------------------------------------------------------------- + +output "LG Electronics LG ULTRAWIDE 405NTPC4A128" pos 0 0 mode 3440x1440@60Hz + +output eDP-1 pos 3440 0 scale 1.5 mode 2560x1600@120Hz diff --git a/config/sway/refresh.sh b/config/sway/refresh.sh new file mode 100755 index 0000000..bcde208 --- /dev/null +++ b/config/sway/refresh.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +#------------------------------------------------------------------------------- +# Refresh the usual suspects +#------------------------------------------------------------------------------- + +swaymsg reload + +notify-send "Reloaded sway config." diff --git a/config/sway/sway-run.sh b/config/sway/sway-run.sh new file mode 100755 index 0000000..bd4eb78 --- /dev/null +++ b/config/sway/sway-run.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +#------------------------------------------------------------------------------- +# Run sway with custom environment and logging. +#------------------------------------------------------------------------------- + +set -euo pipefail + +# Load sway environment. +#------------------------------------------------------------------------------- + +# shellcheck disable=SC1091 +source "$XDG_CONFIG_HOME/sway/environment.sh" + +# Run sway with logging. +#------------------------------------------------------------------------------- + +# Ensure state directory exists. +if [[ ! -d "$XDG_STATE_HOME/sway" ]]; then + mkdir -p "$XDG_STATE_HOME/sway" +fi + +# Run sway and save session log file. +sway 2> "$XDG_STATE_HOME/sway/session-log-$(date -Iseconds)" diff --git a/config/sway/sws.sh b/config/sway/sws.sh new file mode 100755 index 0000000..1e731e7 --- /dev/null +++ b/config/sway/sws.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +#------------------------------------------------------------------------------- +# Sway workspace switcher +# +# TODO: don't hardcode outputs +#------------------------------------------------------------------------------- + +set -euo pipefail + +if [[ $# -lt 2 ]]; then + echo "Usage: $0 " + echo " action: 'focus' or 'move'" + echo " workspace_number: 1-10" + exit 1 +fi + +action="$1" +workspace_num="$2" + +focused_output=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused) | .name') + + +case "$focused_output" in + "DP-3"|"LG Electronics LG ULTRAWIDE 405NTPC4A128") + workspace_name="${workspace_num}" + ;; + "HDMI-A-6 | eDP-1") + workspace_name="1${workspace_num}" + ;; + "DP-4") + workspace_name="2${workspace_num}" + ;; + + *) + workspace_name="${workspace_num}" + ;; +esac + +case "$action" in + "focus") + swaymsg workspace "$workspace_name" + ;; + "move") + swaymsg move container to workspace "$workspace_name" + ;; + *) + echo "Invalid action: $action" + exit 1 + ;; +esac diff --git a/config/sway/theme.conf~esh b/config/sway/theme.conf~esh new file mode 100644 index 0000000..8f3a6b3 --- /dev/null +++ b/config/sway/theme.conf~esh @@ -0,0 +1,15 @@ +<%! declare opt_dir=${XDG_OPT_HOME:-$HOME/.local/opt} %> +<%! source "$opt_dir/theme/theme.sh" %> +#------------------------------------------------------------------------------- +# Sway theme configuration (auto-generated) +#------------------------------------------------------------------------------- + +# Cursor theme +seat * xcursor_theme "<%= ${cursor_theme} %>" <%= ${cursor_size} %> + +# Color scheme +# class border bg text hint child +client.focused <%= $(color_hash "${primary_8}") %> <%= $(color_hash "${system_bg}") %> <%= $(color_hash "${primary_8}") %> <%= $(color_hash "${primary_8}") %> <%= $(color_hash "${primary_8}") %> +client.focused_inactive <%= $(color_hash "${primary_3}") %> <%= $(color_hash "${system_bg}") %> <%= $(color_hash "${primary_3}") %> <%= $(color_hash "${primary_3}") %> <%= $(color_hash "${primary_3}") %> +client.unfocused <%= $(color_hash "${primary_3}") %> <%= $(color_hash "${system_bg}") %> <%= $(color_hash "${primary_3}") %> <%= $(color_hash "${primary_3}") %> <%= $(color_hash "${primary_3}") %> +client.urgent <%= $(color_hash "${primary_3}") %> <%= $(color_hash "${system_bg}") %> <%= $(color_hash "${primary_3}") %> <%= $(color_hash "${primary_3}") %> <%= $(color_hash "${primary_3}") %> diff --git a/config/sway/workspace.conf~home-triple b/config/sway/workspace.conf~home-triple new file mode 100644 index 0000000..5f96a73 --- /dev/null +++ b/config/sway/workspace.conf~home-triple @@ -0,0 +1,46 @@ +#------------------------------------------------------------------------------- +# Workspace configuration at home +#------------------------------------------------------------------------------- + +set $primary "DP-3" +set $left "HDMI-A-6" +set $right "DP-4" + +workspace 1 output $primary +workspace 2:2 output $primary +workspace 3:3 output $primary +workspace 4:4 output $primary +workspace 5:5 output $primary +workspace 6:6 output $primary +workspace 7:7 output $primary +workspace 8:8 output $primary +workspace 9:9 output $primary +workspace 10:10 output $primary +workspace home output $primary +workspace work output $primary +workspace todo output $primary +workspace spotify output $primary + +# left +workspace 11:11 output $left +workspace 12:12 output $left +workspace 13:13 output $left +workspace 14:14 output $left +workspace 15:15 output $left +workspace 16:16 output $left +workspace 17:17 output $left +workspace 18:18 output $left +workspace 19:19 output $left +workspace 20:20 output $left + +# right +workspace 21:21 output $right +workspace 22:22 output $right +workspace 23:23 output $right +workspace 24:24 output $right +workspace 25:25 output $right +workspace 26:26 output $right +workspace 27:27 output $right +workspace 28:28 output $right +workspace 29:29 output $right +workspace 30:30 output $right diff --git a/config/sway/workspace.conf~intelic b/config/sway/workspace.conf~intelic new file mode 100644 index 0000000..47e561b --- /dev/null +++ b/config/sway/workspace.conf~intelic @@ -0,0 +1,33 @@ +#------------------------------------------------------------------------------- +# Workspace configuration at Intelic +#------------------------------------------------------------------------------- + +set $primary "LG Electronics LG ULTRAWIDE 405NTPC4A128" +set $laptop "eDP-1" + +workspace 1 output $primary +workspace 2:2 output $primary +workspace 3:3 output $primary +workspace 4:4 output $primary +workspace 5:5 output $primary +workspace 6:6 output $primary +workspace 7:7 output $primary +workspace 8:8 output $primary +workspace 9:9 output $primary +workspace 10:10 output $primary +workspace home output $primary +workspace work output $primary +workspace todo output $primary +workspace spotify output $primary + +# laptop +workspace 11:11 output $laptop +workspace 12:12 output $laptop +workspace 13:13 output $laptop +workspace 14:14 output $laptop +workspace 15:15 output $laptop +workspace 16:16 output $laptop +workspace 17:17 output $laptop +workspace 18:18 output $laptop +workspace 19:19 output $laptop +workspace 20:20 output $laptop diff --git a/config/waybar/sway-config b/config/waybar/sway-config new file mode 100644 index 0000000..4afdf2e --- /dev/null +++ b/config/waybar/sway-config @@ -0,0 +1,138 @@ +{ + /* General + --------------------------------------------------------------------------*/ + "layer": "top", + "position": "top", + "height": 32, + "margin-top": -2, + "mode": "dock", + + /* Module layout + --------------------------------------------------------------------------*/ + "modules-left": [ + "sway/window" + ], + "modules-center": [ + "sway/workspaces" + ], + "modules-right": [ + "custom/tailscale", + "network", + "bluetooth", + "wireplumber", + "battery", + "cpu", + "memory", + "clock#calendar", + "clock" + ], + + /* Sway modules + --------------------------------------------------------------------------*/ + "sway/workspaces": { + "all-outputs": false, + "format": "{name}", + "disable-scroll": true, + "persistent-workspaces": [ + "home" + ] + }, + "sway/window": { + "max-length": 160, + "tooltip": false + }, + + /* Common modules + --------------------------------------------------------------------------*/ + "clock": { + "format": "󰥔 {:%H:%M}", + "tooltip": true, + "tooltip-format": "{:%A, %B %d, %Y %H:%M:%S (%Z)}" + }, + "clock#calendar": { + "format": "󰸘 {:%Y-%m-%d}", + "tooltip-format": "{calendar}", + "calendar": { + "mode" : "month", + "mode-mon-col" : 3, + "weeks-pos" : "right", + "on-scroll" : 1, + "format": { + /* TODO: templating for theme vars */ + "months": "{}", + "days": "{}", + "weeks": "W{}", + "weekdays": "{}", + "today": "{}" + } + }, + "actions": { + "on-click-right": "mode", + "on-scroll-up": "shift_down", + "on-scroll-down": "shift_up" + } + }, + "custom/tailscale": { + "exec": "${XDG_CONFIG_HOME}/waybar/tailscale.sh", + "format": "{}", + "interval": 5 + }, + "network": { + "format-ethernet": "󰲝 {ifname}", + "format-wifi": "󰖩 {essid}", + "format-disconnected": "󰲜 no network", + "tooltip": true, + "tooltip-format": "󰩟 {gwaddr} ↑{bandwidthUpBytes} ↓{bandwidthDownBytes}", + "tooltip-format-wifi": "󰤨 {signalStrength}% ↑{bandwidthUpBytes} ↓{bandwidthDownBytes}", + "tooltip-format-disconnected": "Disconnected" + }, + "bluetooth": { + "format": " {status}", + "tooltip": true, + "tooltip-format": "{device_address} · {device_alias}", + "tooltip-format-disabled": "controller disabled", + "tooltip-format-off": "controller off" + }, + "wireplumber": { + "format": "{icon} {volume}%", + "format-muted": "󰝟 {volume}%", + "format-icons": ["󰕿", "󰖀", "󰕾"], + "on-click": "pavucontrol", + "on-click-right": "wpctl set-mute 167 toggle" + }, + "cpu": { + "format": "cpu {usage}%", + "states": { + "medium": 50, + "heavy": 70, + "critical": 90 + } + }, + "memory": { + "interval": 30, + "format": "mem {percentage}%", + "states": { + "medium": 50, + "heavy": 70, + "critical": 90 + } + }, + + /* Laptop modules + --------------------------------------------------------------------------*/ + "battery": { + "format": "{icon} {capacity}%", + "format-icons": ["", "", "", "", ""], + "format-charging": " {icon} {capacity}%", + "format-plugged": " {icon} {capacity}%", + "format-full": "{icon} {capacity}%", + "interval": 5, + "states": { + "full": 100, + "normal": 99, + "warning": 30, + "critical": 15 + }, + "tooltip": true + } +} diff --git a/config/waybar/sway-style.css~esh b/config/waybar/sway-style.css~esh new file mode 100644 index 0000000..e2e599a --- /dev/null +++ b/config/waybar/sway-style.css~esh @@ -0,0 +1,141 @@ +<% source $XDG_OPT_HOME/theme/theme.sh -%> +* { + /* `otf-font-awesome` is required to be installed for icons */ + font-family: 'sans-serif'; + font-size: <%= $font_size_medium %>px; + font-weight: bold; +} + +window#waybar { + background: <% color_hash $primary_0 %>; + color: <% color_hash $system_text %>; + transition-property: background-color; + transition-duration: .5s; +} + +button { + /* Use box-shadow instead of border so the text isn't offset */ + box-shadow: inset 0 9px transparent; + /* Avoid rounded borders under each button name */ + border: none; + border-radius: 0; +} + +/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */ +button:hover { + background: inherit; + box-shadow: inset 0 9px <% color_css_rgba $primary_12 0.45 %>; +} + +tooltip { + font-size: <%= $font_size_msmall %>px; + background: <% color_hash $primary_0 %>; + border: 1px solid <% color_hash $primary_8 %>; +} + +tooltip label { + color: <% color_hash $system_text %>; + padding: 0px 2px; +} + +/* All modules +*-----------------------------------------------------------------------------*/ +box > * > * { + padding-left: 10px; + padding-right: 10px; +} + +.modules-left > widget:first-child { + padding-left: 6px; +} + +.modules-right > widget:last-child { + padding-right: 6px; +} + +/* Sway workspaces +*-----------------------------------------------------------------------------*/ +#workspaces button { + padding: 2px 5px; + /* NOTE: Necessary to override a default transition effect. */ + background-color: transparent; + color: <% color_hash $system_text %>; +} + +#workspaces button.visible { + background-color: <% color_css_rgba $primary_3 0.85 %>; +} + +#workspaces button.focused { + background-color: <% color_hash $primary_8 %>; +} + +#workspaces button.urgent { + background-color: <% color_hash $primary_3 %>; +} + +/* Network +*-----------------------------------------------------------------------------*/ + +#network { + color: <% color_hash $system_text %>; +} +#network.disabled { + color: <% color_hash $text_8 %>; +} +#network.disconnected { + color: <% color_hash $red_6 %>; +} + +/* Battery +*-----------------------------------------------------------------------------*/ +#battery.charging, #battery.plugged { + color: <% color_hash $green_5 %>; +} +#battery.full { + color: <% color_hash $primary_15 %>; +} +#battery.normal:not(.charging) { + color: <% color_hash $system_text %>; +} +#battery.warning:not(.charging) { + color: <% color_hash $orange_6 %>; +} +@keyframes blink { + to { + color: <% color_hash $red_2 %>; + } +} +#battery.critical:not(.charging) { + color: <% color_hash $red_6 %>; + animation-name: blink; + animation-duration: 0.5s; + /* NOTE: Using steps() instead of linear as a timing function to limit cpu usage */ + animation-timing-function: steps(12); + animation-iteration-count: infinite; + animation-direction: alternate; +} + +/* CPU +*-----------------------------------------------------------------------------*/ +#cpu.medium { + color: <% color_hash $yellow_7 %>; +} +#cpu.heavy { + color: <% color_hash $orange_6 %>; +} +#cpu.critical { + color: <% color_hash $red_6 %>; +} + +/* Memory +*-----------------------------------------------------------------------------*/ +#memory.medium { + color: <% color_hash $yellow_7 %>; +} +#memory.heavy { + color: <% color_hash $orange_6 %>; +} +#memory.critical { + color: <% color_hash $red_6 %>; +} diff --git a/deploy/deploy-desktop.sh b/deploy/deploy-desktop.sh index 44bb866..82cafb9 100755 --- a/deploy/deploy-desktop.sh +++ b/deploy/deploy-desktop.sh @@ -24,7 +24,7 @@ export XDG_SCRIPTS_HOME="$HOME/.local/scripts" export XDG_TEMPLATES_DIR="$HOME/.local/share/templates" export DEPLOY_PROFILE="desktop" export DEPLOY_DISTRO="$(get_distro_id)" -export DEPLOY_WM="river" +export DEPLOY_WM="sway" # Determine which shell the template engine executes export ESH_SHELL=/usr/bin/bash @@ -82,6 +82,7 @@ source "$base_dir/deploy/modules/scripts-markdown.sh" source "$base_dir/deploy/modules/scripts-misc.sh" source "$base_dir/deploy/modules/scripts-system-utils.sh" source "$base_dir/deploy/modules/ssh.sh" +source "$base_dir/deploy/modules/sway.sh" source "$base_dir/deploy/modules/syncthing.sh" source "$base_dir/deploy/modules/spotify.sh" source "$base_dir/deploy/modules/udiskie.sh" @@ -138,6 +139,7 @@ discord::install draw.io::install firefox::install fontconfig::install +fuzzel::install ghostty::install imv::install mako::install @@ -170,6 +172,10 @@ elif [[ $DEPLOY_WM == "river" ]]; then river::install hyprlock::install +elif [[ $DEPLOY_WM == "sway" ]]; then + sway::install + hyprlock::install + fi echo "Deploying desktop user services..." diff --git a/deploy/modules/sway.sh b/deploy/modules/sway.sh new file mode 100755 index 0000000..a4ec978 --- /dev/null +++ b/deploy/modules/sway.sh @@ -0,0 +1,61 @@ +#------------------------------------------------------------------------------- +# Deploy sway configuration +#------------------------------------------------------------------------------- + + +script_dir=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd) +base_dir=$(realpath "$script_dir/../..") +host=$(uname -n) + +source "$base_dir/config/lib-shell-utils/fs.sh" + + +sway::install () { + echo "└> Installing sway configuration." + + ensure_directory "$XDG_CONFIG_HOME/sway" + force_link "$base_dir/config/sway/config" "$XDG_CONFIG_HOME/sway/config" + force_link "$base_dir/config/sway/environment.sh" "$XDG_CONFIG_HOME/sway/environment.sh" + force_link "$base_dir/config/sway/keymaps.conf" "$XDG_CONFIG_HOME/sway/keymaps.conf" + force_link "$base_dir/config/sway/refresh.sh" "$XDG_CONFIG_HOME/sway/refresh.sh" + force_link "$base_dir/config/sway/sws.sh" "$XDG_CONFIG_HOME/sway/sws.sh" + + if [[ $host == "supertubes" ]] || [[ $host == "cyxwel" ]]; then + force_link "$base_dir/config/sway/outputs.conf~home-triple" "$XDG_CONFIG_HOME/sway/outputs.conf" + force_link "$base_dir/config/sway/workspace.conf~home-triple" "$XDG_CONFIG_HOME/sway/workspace.conf" + + elif [[ $host == "vortex" ]]; then + force_link "$base_dir/config/sway/outputs.conf~intelic" "$XDG_CONFIG_HOME/sway/outputs.conf" + force_link "$base_dir/config/sway/workspace.conf~intelic" "$XDG_CONFIG_HOME/sway/workspace.conf" + + else + echo "└> Warning: No outputs.conf configuration for host '$host'." + fi + + esh -o "$XDG_CONFIG_HOME/sway/theme.conf" "$base_dir/config/sway/theme.conf~esh" + + echo "└> Installing sway shortcuts." + + ensure_directory "$XDG_BIN_HOME" + force_link "$base_dir/config/sway/sway-run.sh" "$XDG_BIN_HOME/sway-run" + + if [[ $DEPLOY_WM == "sway" ]]; then + echo "└> Autorun sway on login." + + force_link "$base_dir/config/sway/init~sway" "$XDG_BIN_HOME/init" + fi +} + +sway::uninstall () { + echo "└> Uninstalling sway configuration." + + rm -r "$XDG_CONFIG_HOME/sway" + + echo "└> Uninstalling sway shortcuts." + + rm "$XDG_BIN_HOME/sway-run" + + if same_file "$XDG_BIN_HOME/init" "$base_dir/config/sway/init~sway"; then + rm "$XDG_BIN_HOME/init" + fi +} diff --git a/deploy/modules/waybar.sh b/deploy/modules/waybar.sh index d5fa195..581edfd 100755 --- a/deploy/modules/waybar.sh +++ b/deploy/modules/waybar.sh @@ -26,6 +26,10 @@ waybar::install () { force_link "$base_dir/config/waybar/river-config" "$XDG_CONFIG_HOME/waybar/config" esh "$base_dir/config/waybar/river-style.css~esh" > "$XDG_CONFIG_HOME/waybar/style.css" + elif [[ $DEPLOY_WM == "sway" ]]; then + force_link "$base_dir/config/waybar/sway-config" "$XDG_CONFIG_HOME/waybar/config" + esh "$base_dir/config/waybar/sway-style.css~esh" > "$XDG_CONFIG_HOME/waybar/style.css" + elif [[ -z $DEPLOY_WM ]]; then echo "[$(basename "$0")] ERROR: \$DEPLOY_WM not set." exit 2 diff --git a/install/ubuntu.sh b/install/ubuntu.sh index 537c70c..207ac2d 100755 --- a/install/ubuntu.sh +++ b/install/ubuntu.sh @@ -496,6 +496,303 @@ install_gtk_theme() { log_success "GTK theme installed" } +install_sdbus_cpp() { + if dpkg -l | grep -q "^ii libsdbus-c++-dev"; then + log_info "Removing conflicting old libsdbus-c++-dev package..." + sudo apt remove -y libsdbus-c++-dev libsdbus-c++1 + fi + + local current_version + current_version=$(pkg-config --modversion sdbus-c++ 2>/dev/null || echo "0.0.0") + + if [[ "$(printf '%s\n' "2.0.0" "$current_version" | sort -V | head -n1)" == "2.0.0" ]]; then + log_success "sdbus-c++ >= 2.0.0 is already installed (version $current_version)" + return + fi + + log_info "Installing sdbus-c++ >= 2.0.0..." + + install_apt_packages libsystemd-dev libexpat1-dev + + pushd /tmp >/dev/null + + local tag="v2.0.0" + local build_dir="sdbus-cpp-build-$$" + + if git clone --depth 1 -b $tag https://github.com/Kistler-Group/sdbus-cpp.git "$build_dir"; then + pushd "$build_dir" >/dev/null + + mkdir build + cd build + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local .. + make -j$(nproc 2>/dev/null || getconf _NPROCESSORS_CONF) + sudo make install + + popd >/dev/null + rm -rf "$build_dir" + + if [[ ! -f /etc/ld.so.conf.d/usr-local.conf ]]; then + echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/usr-local.conf > /dev/null + echo "/usr/local/lib/x86_64-linux-gnu" | sudo tee -a /etc/ld.so.conf.d/usr-local.conf > /dev/null + fi + + sudo ldconfig + log_success "sdbus-c++ installed" + else + log_error "Download failed for sdbus-c++" + fi + + popd >/dev/null +} + +install_hyprutils() { + if pkg-config --exists hyprutils; then + log_success "hyprutils is already installed" + return + fi + + log_info "Installing hyprutils..." + pushd /tmp >/dev/null + + local tag="v0.8.2" + local build_dir="hyprutils-build-$$" + + if git clone -b $tag https://github.com/hyprwm/hyprutils.git "$build_dir"; then + pushd "$build_dir" >/dev/null + + cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr/local -S . -B ./build + cmake --build ./build --config Release --target hyprutils -j$(nproc 2>/dev/null || getconf _NPROCESSORS_CONF) + sudo cmake --install build + + popd >/dev/null + rm -rf "$build_dir" + log_success "hyprutils installed" + else + log_error "Download failed for hyprutils" + fi + + popd >/dev/null +} + +install_hyprlang() { + if pkg-config --exists hyprlang; then + log_success "hyprlang is already installed" + return + fi + + log_info "Installing hyprlang..." + install_apt_packages gcc-14 g++-14 + + pushd /tmp >/dev/null + + local tag="v0.6.4" + local build_dir="hyprlang-build-$$" + + if git clone --recursive -b $tag https://github.com/hyprwm/hyprlang.git "$build_dir"; then + pushd "$build_dir" >/dev/null + + export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:/usr/local/lib/x86_64-linux-gnu/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" + + cmake --no-warn-unused-cli \ + -DCMAKE_BUILD_TYPE:STRING=Release \ + -DCMAKE_INSTALL_PREFIX:PATH=/usr/local \ + -DCMAKE_C_COMPILER=/usr/bin/gcc-14 \ + -DCMAKE_CXX_COMPILER=/usr/bin/g++-14 \ + -S . -B ./build + cmake --build ./build --config Release --target hyprlang -j$(nproc 2>/dev/null || getconf _NPROCESSORS_CONF) + sudo cmake --install ./build + + popd >/dev/null + rm -rf "$build_dir" + log_success "hyprlang installed" + else + log_error "Download failed for hyprlang" + fi + + popd >/dev/null +} + +install_hyprwayland_scanner() { + if command_exists hyprwayland-scanner; then + log_success "hyprwayland-scanner is already installed" + return + fi + + log_info "Installing hyprwayland-scanner..." + install_apt_packages libpugixml-dev + + pushd /tmp >/dev/null + + local tag="v0.4.5" + local build_dir="hyprwayland-scanner-build-$$" + + if git clone --recursive -b $tag https://github.com/hyprwm/hyprwayland-scanner.git "$build_dir"; then + pushd "$build_dir" >/dev/null + + cmake -DCMAKE_INSTALL_PREFIX=/usr -B build + cmake --build build -j$(nproc 2>/dev/null || getconf _NPROCESSORS_CONF) + sudo cmake --install build + + popd >/dev/null + rm -rf "$build_dir" + log_success "hyprwayland-scanner installed" + else + log_error "Download failed for hyprwayland-scanner" + fi + + popd >/dev/null +} + +install_hyprgraphics() { + if pkg-config --exists hyprgraphics; then + log_success "hyprgraphics is already installed" + return + fi + + log_info "Installing hyprgraphics..." + install_apt_packages libjpeg-dev libwebp-dev libpng-dev + + pushd /tmp >/dev/null + + local tag="v0.1.5" + local build_dir="hyprgraphics-build-$$" + + if git clone --recursive -b $tag https://github.com/hyprwm/hyprgraphics.git "$build_dir"; then + pushd "$build_dir" >/dev/null + + cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build + cmake --build ./build --config Release --target hyprgraphics -j$(nproc 2>/dev/null || getconf _NPROCESSORS_CONF) + sudo cmake --install ./build + + popd >/dev/null + rm -rf "$build_dir" + log_success "hyprgraphics installed" + else + log_error "Download failed for hyprgraphics" + fi + + popd >/dev/null +} + +install_hyprlock() { + if command_exists hyprlock; then + log_success "hyprlock is already installed" + return + fi + + log_info "Installing hyprlock dependencies..." + install_apt_packages \ + libpam0g-dev libgbm-dev libdrm-dev libmagic-dev libaudit-dev \ + libgl1-mesa-dev \ + libwayland-dev libcairo2-dev libpango1.0-dev libxkbcommon-dev + + install_sdbus_cpp + install_hyprutils + install_hyprlang + install_hyprwayland_scanner + install_hyprgraphics + + if [[ ! -f /etc/ld.so.conf.d/usr-local.conf ]]; then + echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/usr-local.conf > /dev/null + echo "/usr/local/lib/x86_64-linux-gnu" | sudo tee -a /etc/ld.so.conf.d/usr-local.conf > /dev/null + fi + + sudo ldconfig + + log_info "Building hyprlock..." + + local old_sdbus_moved=false + if [[ -f /lib/x86_64-linux-gnu/libsdbus-c++.so.1 ]]; then + log_info "Temporarily moving conflicting libsdbus-c++.so.1..." + sudo mv /lib/x86_64-linux-gnu/libsdbus-c++.so.1 /lib/x86_64-linux-gnu/libsdbus-c++.so.1.backup 2>/dev/null && old_sdbus_moved=true + sudo mv /lib/x86_64-linux-gnu/libsdbus-c++.so /lib/x86_64-linux-gnu/libsdbus-c++.so.backup 2>/dev/null + sudo ldconfig + fi + + pushd /tmp >/dev/null + + local tag="v0.9.1" + local build_dir="hyprlock-build-$$" + + if git clone --recursive -b $tag https://github.com/hyprwm/hyprlock.git "$build_dir"; then + pushd "$build_dir" >/dev/null + + rm -f src/auth/Fingerprint.cpp src/auth/Fingerprint.hpp + sed -i '/#include.*Fingerprint.hpp/d' src/auth/Auth.cpp + sed -i '/#include.*Fingerprint.hpp/d' src/core/hyprlock.cpp + sed -i '1i#include ' src/auth/Auth.cpp + sed -i '/ENABLEFINGERPRINT/,/makeShared()/d' src/auth/Auth.cpp + sed -i 's/std::ranges::any_of/std::any_of/g' src/auth/Auth.cpp + sed -i 's|return std::any_of.*|return std::any_of(m_vImpls.begin(), m_vImpls.end(), [](const auto\& i) { return i->checkWaiting(); });|' src/auth/Auth.cpp + sed -i '/fingerprintAuth.*g_pAuth->getImpl/d' src/core/hyprlock.cpp + sed -i '/dbusConn.*CFingerprint/d' src/core/hyprlock.cpp + sed -i 's/fdcount = dbusConn ? 2 : 1/fdcount = 1/g' src/core/hyprlock.cpp + sed -i '/if (dbusConn) {/,/^ }/d' src/core/hyprlock.cpp + sed -i '/if (pollfds\[1\]\.revents.*dbus/,/^ }/d' src/core/hyprlock.cpp + + export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:/usr/local/lib/x86_64-linux-gnu/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" + export LD_LIBRARY_PATH="/usr/local/lib:/usr/local/lib/x86_64-linux-gnu${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" + export LDFLAGS="-L/usr/local/lib -Wl,-rpath,/usr/local/lib" + + cmake --no-warn-unused-cli \ + -DCMAKE_BUILD_TYPE:STRING=Release \ + -DCMAKE_INSTALL_PREFIX="$HOME/.local" \ + -DCMAKE_C_COMPILER=/usr/bin/gcc-14 \ + -DCMAKE_CXX_COMPILER=/usr/bin/g++-14 \ + -DCMAKE_PREFIX_PATH=/usr/local \ + -DCMAKE_EXE_LINKER_FLAGS="-L/usr/local/lib -Wl,-rpath,/usr/local/lib" \ + -S . -B ./build + cmake --build ./build --config Release --target hyprlock -j$(nproc 2>/dev/null || getconf _NPROCESSORS_CONF) + cmake --install build + + popd >/dev/null + rm -rf "$build_dir" + log_success "hyprlock installed" + else + log_error "Download failed for hyprlock" + fi + + if [[ "$old_sdbus_moved" == "true" ]]; then + log_info "Restoring old libsdbus-c++ libraries..." + sudo mv /lib/x86_64-linux-gnu/libsdbus-c++.so.1.backup /lib/x86_64-linux-gnu/libsdbus-c++.so.1 2>/dev/null + sudo mv /lib/x86_64-linux-gnu/libsdbus-c++.so.backup /lib/x86_64-linux-gnu/libsdbus-c++.so 2>/dev/null + sudo ldconfig + fi + + popd >/dev/null +} + +install_simp1e_cursor_theme() { + local theme_dir="/usr/share/icons/Simp1e" + + if [[ -d "$theme_dir" ]]; then + log_success "Simp1e cursor theme is already installed" + return + fi + + log_info "Installing Simp1e cursor theme..." + pushd /tmp >/dev/null + + local files + files=$(curl -Lfs https://www.pling.com/p/1932768/loadFiles) + local raw_url + raw_url=$(echo $files | jq -r '.files[] | select(.name == "Simp1e.tar.xz") | .url') + local decoded_url + decoded_url=$(echo $raw_url | perl -pe 's/\%(\w\w)/chr hex $1/ge') + + download_file "$decoded_url" "Simp1e.tar.xz" + + local extract_dir="simp1e-cursor-$$" + mkdir -p "$extract_dir" + tar -xf Simp1e.tar.xz -C "$extract_dir" + + sudo mv "$extract_dir/Simp1e" /usr/share/icons/ + + rm -rf "$extract_dir" Simp1e.tar.xz + popd >/dev/null + log_success "Simp1e cursor theme installed" +} + install_sway() { if command_exists sway; then log_success "sway is already installed" @@ -504,7 +801,7 @@ install_sway() { log_info "Installing sway..." install_apt_packages \ - sway waybar hyprlock fuzzel mako-notifier + sway waybar fuzzel mako-notifier cargo install sway-workspace pipx install autotiling @@ -648,6 +945,8 @@ main() { log_info "Installing desktop environment packages..." install_ghostty install_gtk_theme + install_hyprlock + install_simp1e_cursor_theme install_sway install_waypaper