diff --git a/config/sway/autostart b/config/sway/autostart new file mode 100644 index 0000000..fe0da45 --- /dev/null +++ b/config/sway/autostart @@ -0,0 +1,39 @@ +# units + +set $initialize_foot_server '[ -x "$(command -v foot)" ] && foot --server' +# set $initialize_swayr_daemon '[ -x "$(command -v swayrd)" ] && systemctl --now --user enable swayrd' +set $initialize_waybar '[ -x "$(command -v waybar)" ] && (pkill -U $USER waybar || exit 0) && $HOME/.local/share/sway/scripts/waybar.sh)' +set $initialize_workspace_icons '[ -x "$(command -v sworkstyle)" ] && sworkstyle' +set $initialize_poweralert_daemon '[ -x "$(command -v poweralertd)" ] && systemctl --now --user enable poweralertd' +set $initialize_idlehack_daemon '[ -x "$(command -v idlehack)" ] && systemctl --now --user enable idlehack' +set $initialize_idle_daemon '[ -x "$(command -v swayidle-conf)" ] && systemctl --now --user enable swayidle' +set $initialize_mounting_daemon '[ -x "$(command -v pcmanfm-qt)" ] || [ -x "$(command -v pcmanfm)" ] && systemctl --now --user enable pcmanfm' +set $initialize_way_displays '[ -x "$(command -v way-displays)" ] && systemctl --now --user enable way-displays' +set $initialize_flashfocus 'systemctl --now --user enable flashfocus' + +# autostarts + +set $autostart_dex '[ -x "$(command -v dex)" ] && gdbus wait --session org.kde.StatusNotifierWatcher && dex -a -e SWAY' +set $wlsunset '[ -x "$(command -v wlsunset)" ] && $HOME/.local/share/sway/scripts/sunset.sh "on"' +set $autotiling '[ -x "$(command -v autotiling)" ] && autotiling || [ -x "$(command -v autotiling-rs)" ] && autotiling-rs' +set $help_menu '[ -x "$(command -v nwg-wrapper)" ] && [ -f $HOME/.config/nwg-wrapper/help.sh ] && $HOME/.local/share/sway/scripts/help.sh' +set $kanshi '[ -x "$(command -v kanshi)" ] && pkill -U $USER -x kanshi; exec kanshi' +set $xdg-dirs '[ -x "$(command -v xdg-user-dirs-update)" ] && exec xdg-user-dirs-update' + +## apply the keyboard layout from localectl if no keyboard layout has been set via config.d +set $auto_xdg_keyboard 'grep -q xkb_layout ~/.config/sway/config.d/*.conf || $HOME/.local/share/sway/scripts/keyboard.sh' +set $enable_noisetorch '[ -x "$(command -v noisetorch)" ] && noisetorch -u && noisetorch -i' +set $disable_nm_applet_autostart '[ -x "$(command -v nm-applet)" ] && [ ! -f $HOME/.config/autostart/nm-applet.desktop ] && cp /etc/xdg/autostart/nm-applet.desktop $HOME/.config/autostart/nm-applet.desktop && echo "Hidden=true" >> $HOME/.config/autostart/nm-applet.desktop' +set $apply_background swaymsg 'output * bg $background fill' + +## daemons + +set $mako '[ -x "$(command -v mako)" ] && pkill -U $USER -x mako; $HOME/.local/share/sway/scripts/mako.sh' +# set $mako '[ -x "$(command -v mako)" ] && pkill -U $USER -x mako; $HOME/.local/share/sway/scripts/mako.sh --font "$term-font" --text-color "$text-color" --border-color "$accent-color" --background-color "$background-color" --border-size 3 --width 400 --height 200 --padding 20 --margin 20 --default-timeout 15000' +set $swappy_notify '[ -x "$(command -v swappy)" ] && $HOME/.local/share/sway/scripts/screenshot-notify.sh' +set $cliphist_watch '[ -x "$(command -v wl-paste)" ] && [ -x "$(command -v cliphist)" ] && wl-paste --watch waybar-signal clipboard' +set $cliphist_store '[ -x "$(command -v wl-paste)" ] && [ -x "$(command -v cliphist)" ] && wl-paste --watch cliphist store' +set $clip-persist '[ -x "$(command -v wl-clip-persist)" ] && pkill -U $USER -x wl-clip-persist; wl-clip-persist --clipboard regular --all-mime-type-regex \'(?i)^(?!image/x-inkscape-svg).+\'' +set $calendar_daemon 'calcurse --daemon' +set $nm_applet '[ -x "$(command -v nm-applet)" ] && pkill -U $USER -x nm-applet && dbus-launch nm-applet' +set $watch_playerctl '[ -x "$(command -v playerctl)" ] && pkill -U $USER -x playerctl; playerctl -a metadata --format \"{{status}} {{title}}\" --follow | while read line; do waybar-signal playerctl; waybar-signal idle; done' diff --git a/config/sway/config b/config/sway/config new file mode 100644 index 0000000..724e133 --- /dev/null +++ b/config/sway/config @@ -0,0 +1,166 @@ +# Default config for sway +# +# Copy this to ~/.config/sway/config and edit it to your liking. +# +# Read `man 5 sway` for a complete reference. + +# styles - set the folder for your theme definition file +set $theme $HOME/.local/share/sway/themes/my-gruvbox + +# theme variables +include $theme/theme.conf + +# global variables +include $HOME/.config/sway/definitions + +include $HOME/.config/sway/inputs/* + +# enable modes +include $HOME/.config/sway/modes/* + +include $HOME/.config/sway/autostart + +include $HOME/.config/sway/config.d/* + +gaps inner 6 +smart_gaps on + +default_border pixel 1 +default_floating_border pixel 1 +hide_edge_borders smart +focus_follows_mouse no +mouse_warping container + +workspace_auto_back_and_forth no +workspace_layout default + +# only enable this if every app you use is compatible with wayland +# xwayland disable + +# Default config for sway +# +# Copy this to ~/.config/sway/config and edit it to your liking. +# +# Read `man 5 sway` for a complete reference. + +### Variables +# +# Logo key. Use Mod1 for Alt. +set $mod Mod4 +# Home row direction keys, like vim +set $left h +set $down j +set $up k +set $right l +# Your preferred application launcher + +### Output configuration +# +# Default wallpaper (more resolutions are available in /usr/share/backgrounds/sway/) +# output * bg $HOME/.local/share/wallpapers/20250607_192951_D4E78119.jpg fill +# output DP-1 pos 0 0 +# output eDP-1 pos 3840 2160 +# output HDMI-A-1 pos 0 2160 +# focus output DP-1 +# bindswitch lid:on output eDP-1 disable +# bindswitch lid:off output eDP-1 enable + +# +# Example configuration: +# +# output HDMI-A-1 resolution 1920x1080 position 1920,0 +# +# You can get the names of your outputs by running: swaymsg -t get_outputs + +### Idle configuration +# +# Example configuration: +# +# exec swayidle -w \ +# timeout 300 'swaylock -f -c 000000' \ +# timeout 600 'swaymsg "output * power off"' resume 'swaymsg "output * power on"' \ +# before-sleep 'swaylock -f -c 000000' +# +# This will lock your screen after 300 seconds of inactivity, then turn off +# your displays after another 300 seconds, and turn your screens back on when +# resumed. It will also lock your screen before your computer goes to sleep. + +exec swayidle -w \ + timeout 300 $locking \ + timeout 600 'swaymsg "output * dpms off"' resume 'swaymsg "output * dpms on"' \ + before-sleep $locking + + +for_window [class="(?i)firefox"] move container to workspace $ws1 +for_window [title="(?i)Picture-in-Picture"] floating enable border none +for_window [class="(?i)telegram"] move container to workspace $ws2 +for_window [class="mpv"] floating enable border none +for_window [class="(?i)zooout"] floating enable +for_window [class="(?i)netsurf"] floating enable +for_window [class="(?i)proton-bridge"] move container to workspace $ws9 floating enable border none +for_window [class="(?i)easyeffects"] move container to workspace $ws10 +# for_window [class="(?i)xterm-256color"] border none + +# for_window [class="(?i)cadence"] move container to workspace $ws7 floating enable +# for_window [class="(?i)catia"] move container to workspace $ws7 floating enable +# for_window [class="(?i)reaper"] move container to workspace $ws7 +# for_window [class="(?i)renoise"] move container to workspace $ws7 +for_window [class="(?i)uvi"] floating enable +for_window [class="(?i)arturia"] floating enable +for_window [class="(?i)ilok"] floating enable + +for_window [class="Space"] floating enable + + +####################### +#### sway appearance #### +####################### +font pango:DejaVu Sans Condensed Bold 8 + +# +# Utilities: +# + # Special keys to adjust volume via PulseAudio + bindsym --locked XF86AudioMute exec pactl set-sink-mute \@DEFAULT_SINK@ toggle + bindsym --locked XF86AudioLowerVolume exec pactl set-sink-volume \@DEFAULT_SINK@ -5% + bindsym --locked XF86AudioRaiseVolume exec pactl set-sink-volume \@DEFAULT_SINK@ +5% + bindsym --locked XF86AudioMicMute exec pactl set-source-mute \@DEFAULT_SOURCE@ toggle + # Special keys to adjust brightness via brightnessctl + bindsym --locked XF86MonBrightnessDown exec brightnessctl set 5%- + bindsym --locked XF86MonBrightnessUp exec brightnessctl set 5%+ + # Special key to take a screenshot with grim + # bindsym Print exec grim + +# +# Status Bar: +# +# Read `man 5 sway-bar` for more information about this section. +bar { + # Execute Waybar; Waybar restarts when Sway reloads. + status_command $HOME/.local/share/sway/scripts/waybar.sh + + # Hide Sway's builtin status bar. + mode invisible +} + +bindsym $mod+z exec $locking +# bindsym $mod+x exec "taskwarrior_stop" +# bindsym $mod+Shift+z exec "suspend-and-lock" + +bindsym XF86MonBrightnessUp exec --no-startup-id /usr/bin/light -A 5 +bindsym XF86MonBrightnessDown exec --no-startup-id /usr/bin/light -U 5 + +bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +3% +bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -3% +bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle + +# bindsym $mod+Shift+o exec "display_switch" + +bindsym $mod+minus exec "makoctl dismiss" +bindsym $mod+equal exec "makoctl restore" + +bindsym $mod+F4 exec "$term edit_project" +bindsym $mod+v exec "passmenu" +bindsym $mod+Shift+v exec "passotpmenu" + +exec --no-startup-id xautorun diff --git a/config/sway/config.d/98-application-defaults.conf b/config/sway/config.d/98-application-defaults.conf new file mode 100644 index 0000000..503c2f8 --- /dev/null +++ b/config/sway/config.d/98-application-defaults.conf @@ -0,0 +1,35 @@ +# don't show gaps if there's only one window on the desktop +smart_gaps on + +# set floating mode for generated windows +for_window [title="(?:Open|Save) (?:File|Folder|As)"] floating enable +for_window [title="(?:Open|Save) (?:File|Folder|As)"] resize set 800 600 +for_window [window_role="pop-up"] floating enable +for_window [window_role="bubble"] floating enable +for_window [window_role="task_dialog"] floating enable +for_window [window_role="Preferences"] floating enable +for_window [window_type="dialog"] floating enable +for_window [window_type="menu"] floating enable + +# set floating mode for specific applications +for_window [instance="lxappearance"] floating enable +for_window [app_id="pamac-manager"] floating enable +for_window [app_id="blueberry.py"] floating enable +for_window [app_id="dragon-drop"] floating enable, sticky enable +for_window [app_id="firefox" title="^Library$"] floating enable, border pixel 1, sticky enable +for_window [app_id="thunderbird" title=".*Reminder"] floating enable +for_window [app_id="floating_shell"] floating enable, border pixel 1, sticky enable +for_window [app_id="Manjaro.manjaro-settings-manager"] floating enable +for_window [app_id="" title="Picture in picture"] floating enable, sticky enable +for_window [app_id="" title="Picture-in-Picture"] floating enable, sticky enable +for_window [instance="around"] floating enable, sticky enable +for_window [app_id="xsensors"] floating enable +for_window [title="Save File"] floating enable +for_window [title="Firefox .*— Sharing Indicator"] floating enable, sticky enable, move to scratchpad +for_window [app_id="" title=".* is sharing your screen."] floating enable +for_window [title="^wlay$"] floating enable + +# Don't allow applications to inhibit shortcuts, i.e. grab total control of the +# keyboard. Chrome currently abuses this by enabling it for all "--app=..." +# shortcuts. +seat * shortcuts_inhibitor disable diff --git a/config/sway/config.d/99-autostart-applications.conf b/config/sway/config.d/99-autostart-applications.conf new file mode 100644 index 0000000..6702ffa --- /dev/null +++ b/config/sway/config.d/99-autostart-applications.conf @@ -0,0 +1,41 @@ +# autostart background applications +# FIXME: exec /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 + +# autostarts +exec { + # $initialize_way_displays + $initialize_foot_server + # $initialize_mounting_daemon + # $initialize_poweralert_daemon + # $initialize_idlehack_daemon + $initialize_workspace_icons + # $initialize_swayr_daemon + # $initialize_idle_daemon + # $initialize_flashfocus + + $xdg-dirs + # $swappy_notify + # $autostart_dex + # $wlsunset + # $autotiling + # $cliphist_store + # $cliphist_watch +} + +# commands that "reload" something +exec_always { + $initialize_waybar + + $apply_background + $help_menu + $kanshi + # $clip-persist + $mako + # $auto_xdg_keyboard + $watch_playerctl + # $calendar_daemon + # $enable_noisetorch + $onscreen_bar --refresh + $disable_nm_applet_autostart + $nm_applet +} diff --git a/config/sway/definitions b/config/sway/definitions new file mode 100644 index 0000000..5fb0274 --- /dev/null +++ b/config/sway/definitions @@ -0,0 +1,107 @@ +# shellcheck disable=SC2148,SC2086,SC2154,SC2046,SC2016 +### Variables +# +# Logo key. Use Mod1 for Alt and Mod4 for Super. +set $mod Mod4 +set $alt_mod Alt + +# Alternative direction keys +set $left h +set $down j +set $up k +set $right l + +# Default generated background +set $background $HOME/.local/share/wallpapers/20250607_192951_D4E78119.jpg + +# Add --to-code to bindsym, support for non-latin layouts +set $bindsym bindsym --to-code + +# For user's convenience, the same for unbindsym +set $unbindsym unbindsym --to-code + +# Script paths +set $script_path $HOME/.local/share/sway/scripts + +# Terminal emulator +set $term footclient +set $term_cwd $term -D "$(swaycwd 2>/dev/null || echo $HOME)" +set $term_float footclient --app-id floating_shell --window-size-chars 82x25 + +# Task manager +set $task_manager $script_path/once.sh $term_float btop + +# Onscreen bar +set $onscreen_bar $script_path/wob.sh "$accent-color" "$background-color" + +# Brightness control +set $brightness $script_path/brightness.sh +set $brightness_up $brightness up | $onscreen_bar +set $brightness_down $brightness down | $onscreen_bar + +# Scaling +set $scale_up $script_path/scale.sh up +set $scale_down $script_path/scale.sh down +set $scale_default $script_path/scale.sh default + +# Audio control +set $sink_volume pactl get-sink-volume @DEFAULT_SINK@ | grep '^Volume:' | cut -d / -f 2 | tr -d ' ' | sed 's/%//' +set $source_volume pactl get-source-volume @DEFAULT_SOURCE@ | grep '^Volume:' | cut -d / -f 2 | tr -d ' ' | sed 's/%//' +set $volume_down $onscreen_bar $(pactl set-sink-volume @DEFAULT_SINK@ -5% && $sink_volume) +set $volume_up $onscreen_bar $(pactl set-sink-volume @DEFAULT_SINK@ +5% && $sink_volume) +set $volume_mute $onscreen_bar $(pactl set-sink-mute @DEFAULT_SINK@ toggle && pactl get-sink-mute @DEFAULT_SINK@ | sed -En "/no/ s/.*/$($sink_volume)/p; /yes/ s/.*/0/p") +set $mic_mute $onscreen_bar $(pactl set-source-mute @DEFAULT_SOURCE@ toggle && pactl get-source-mute @DEFAULT_SOURCE@ | sed -En "/no/ s/.*/$($source_volume)/p; /yes/ s/.*/0/p") + +# Clipboard history +set $clipboard cliphist list | rofi -dmenu -p "Select item to copy" -lines 10 | cliphist decode | wl-copy +set $clipboard-del cliphist list | rofi -dmenu -p "Select item to delete" -lines 10 | cliphist delete + +# Application launcher +set $menu rofi -show combi -combi-modi "drun,run" -terminal "$term" -ssh-command "{terminal} {ssh-client} {host} [-p {port}]" -run-shell-command "{terminal} {cmd}" -show-icons -lines 10 + +# Lockscreen configuration +set $locking $script_path/lock.sh + +# Bluetooth menu +set $bluetooth $script_path/once.sh $term_float bluetuith + +# Hide cursor after 5 seconds of inactivty +seat seat0 hide_cursor 5000 + +# Pulseaudio command +set $pulseaudio $script_path/once.sh $term_float pulsemixer + +# Help command +set $help $script_path/help.sh --toggle + +# Calendar application +set $calendar $script_path/once.sh $term_float ikhal + +# Workspace names +set $ws1 number 1 +set $ws2 number 2 +set $ws3 number 3 +set $ws4 number 4 +set $ws5 number 5 +set $ws6 number 6 +set $ws7 number 7 +set $ws8 number 8 +set $ws9 number 9 +set $ws10 number 10 + +# Screenshot commands +set $grimshot grimshot +set $pipe_output $grimshot save output - +set $pipe_selection $grimshot save area - +set $notify_paste [[ $(wl-paste -l) == "image/png" ]] && notify-send "Screenshot copied to clipboard" +set $swappy swappy -f - +set $upload_pipe curl -s -F "file=@-;filename=.png" https://x0.at/ | tee >(wl-copy) >(xargs notify-send) + +set $screenshot_screen $pipe_output | $swappy && $notify_paste +set $screenshot_screen_upload $pipe_output | $upload_pipe + +set $screenshot_selection $pipe_selection | $swappy && $notify_paste +set $screenshot_selection_upload $pipe_selection | $upload_pipe + +# Emoji picker +set $emoji_picker emoji-picker diff --git a/config/sway/idle.yaml b/config/sway/idle.yaml new file mode 100644 index 0000000..af1862a --- /dev/null +++ b/config/sway/idle.yaml @@ -0,0 +1,33 @@ +--- +debug: true +wait: false +timeouts: + # idle_timeout + - timeout: 240 + command: brightnessctl -s && brightnessctl set 10 + resume: brightnessctl -r + # locking_timeout + - timeout: 300 + command: swaymsg exec \$locking + # keyboard_timeout + - timeout: 600 + command: /usr/share/sway/scripts/keyboard-backlight-switch.sh off + resume: /usr/share/sway/scripts/keyboard-backlight-switch.sh on + # screen_timeout + - timeout: 600 + command: swaymsg "output * power off" + resume: swaymsg "output * power on" + # dpms_timeout + - timeout: 600 + command: swaymsg "output * dpms off" + resume: swaymsg "output * dpms on" + # sleep_timeout_bat + - timeout: 900 + command: acpi --ac-adapter | grep -v 'on-line' && systemctl sleep + # sleep_timeout_ac + - timeout: 3600 + command: acpi --ac-adapter | grep 'on-line' && systemctl sleep +before-sleep: swaymsg exec \$locking +after-resume: swaymsg "output * dpms on" && brightnessctl -r +lock: swaymsg exec \$locking +idlehint: '240' diff --git a/config/sway/inputs/default-keyboard b/config/sway/inputs/default-keyboard new file mode 100644 index 0000000..2280c15 --- /dev/null +++ b/config/sway/inputs/default-keyboard @@ -0,0 +1,13 @@ +### Input configuration +# +# Example configuration: + +# input type:keyboard { +# xkb_layout "eu" +# } + +input type:keyboard { + xkb_layout "us,ru" + xkb_variant "colemak,winkeys" + xkb_options "grp:shifts_toggle,grp_led:caps" +} diff --git a/config/sway/inputs/default-touchpad b/config/sway/inputs/default-touchpad new file mode 100644 index 0000000..b81060e --- /dev/null +++ b/config/sway/inputs/default-touchpad @@ -0,0 +1,12 @@ +### Input configuration +# +# You can get the names of your inputs by running: swaymsg -t get_inputs +# Read `man 5 sway-input` for more information about this section. + +input type:touchpad { + dwt enabled + tap enabled + natural_scroll false + middle_emulation enabled + pointer_accel 0.5 +} diff --git a/config/sway/modes/default b/config/sway/modes/default new file mode 100644 index 0000000..6468e5d --- /dev/null +++ b/config/sway/modes/default @@ -0,0 +1,162 @@ +### Key bindings +# +# Basics: +# +## Launch // Terminal ## +$bindsym $mod+Return exec $term + +## Action // Kill focused window ## +$bindsym $mod+Shift+c kill + +## Launch // Open launcher ## +$bindsym $alt_mod+space exec $menu +$bindsym $mod+F2 exec $menu + +## Launch // Open clipboard ## +$bindsym $mod+Shift+p exec $clipboard + +# Drag floating windows by holding down $mod and left mouse button. +# Resize them with right mouse button + $mod. +# Despite the name, also works for non-floating windows. +# Change normal to inverse to use left mouse button for resizing and right +# mouse button for dragging. +floating_modifier $mod normal + +## Action // Reload Sway Configuration ## +$bindsym $mod+Shift+r reload +$bindsym $mod+F12 restart + +## Action // Toggle Waybar ## +$bindsym $mod+Shift+b exec pkill -U $USER -x -SIGUSR1 waybar + +# --locked flags allow the buttons to be used whilst the screen is locked. +$bindsym --locked XF86AudioRaiseVolume exec $volume_up + +$bindsym --locked XF86AudioLowerVolume exec $volume_down + +$bindsym --locked XF86AudioMute exec $volume_mute + +$bindsym XF86AudioMicMute exec $mic_mute + +$bindsym --locked XF86MonBrightnessUp exec $brightness_up + +$bindsym --locked XF86MonBrightnessDown exec $brightness_down + +$bindsym --locked XF86AudioPlay exec playerctl play-pause + +$bindsym XF86AudioNext exec playerctl next + +$bindsym XF86AudioPrev exec playerctl previous + +$bindsym XF86PowerOff exec $shutdown + +$bindsym XF86TouchpadToggle input type:touchpad events toggle enabled disabled + +# Moving around: +# +# Move your focus around +## Navigation // Move focus // $mod + ↑ ↓ ← → ## +$bindsym $mod+$left focus left +$bindsym $mod+$down focus down +$bindsym $mod+$up focus up +$bindsym $mod+$right focus right + +## Navigation // Move focused window // $mod + Shift + ↑ ↓ ← → ## +$bindsym $mod+Shift+$left move left +$bindsym $mod+Shift+$down move down +$bindsym $mod+Shift+$up move up +$bindsym $mod+Shift+$right move right + +## Navigation // Move focused workspace // $mod + Alt + ↑ ↓ ← → ## +$bindsym $mod+$alt_mod+$right move workspace to output right +$bindsym $mod+$alt_mod+$left move workspace to output left +$bindsym $mod+$alt_mod+$down move workspace to output down +$bindsym $mod+$alt_mod+$up move workspace to output up + +## Navigation // List all open windows in last-recently-used order ## +$bindsym $mod+p exec env RUST_BACKTRACE=1 swayr switch-window &>> /tmp/swayr.log + +## Navigation // Switch to the last recently used window ## +$bindsym $alt_mod+Tab exec env RUST_BACKTRACE=1 swayr switch-to-urgent-or-lru-window &>> /tmp/swayr.log + +## Navigation // Switch to the last recently used workspace ## +$bindsym $mod+Tab workspace back_and_forth + +# +# Workspaces: +# +## Navigation // Switch workspace // $mod + [number] ## +$bindsym $mod+1 workspace $ws1 +$bindsym $mod+2 workspace $ws2 +$bindsym $mod+3 workspace $ws3 +$bindsym $mod+4 workspace $ws4 +$bindsym $mod+5 workspace $ws5 +$bindsym $mod+6 workspace $ws6 +$bindsym $mod+7 workspace $ws7 +$bindsym $mod+8 workspace $ws8 +$bindsym $mod+9 workspace $ws9 +$bindsym $mod+0 workspace $ws10 + +set $focus_ws [ "$focus_after_move" == 'true' ] && swaymsg workspace + +## Action // Move focused window to workspace // $mod + Shift + [number] ## +$bindsym $mod+Shift+1 move container to workspace $ws1, exec $focus_ws $ws1 +$bindsym $mod+Shift+2 move container to workspace $ws2, exec $focus_ws $ws2 +$bindsym $mod+Shift+3 move container to workspace $ws3, exec $focus_ws $ws3 +$bindsym $mod+Shift+4 move container to workspace $ws4, exec $focus_ws $ws4 +$bindsym $mod+Shift+5 move container to workspace $ws5, exec $focus_ws $ws5 +$bindsym $mod+Shift+6 move container to workspace $ws6, exec $focus_ws $ws6 +$bindsym $mod+Shift+7 move container to workspace $ws7, exec $focus_ws $ws7 +$bindsym $mod+Shift+8 move container to workspace $ws8, exec $focus_ws $ws8 +$bindsym $mod+Shift+9 move container to workspace $ws9, exec $focus_ws $ws9 +$bindsym $mod+Shift+0 move container to workspace $ws10, exec $focus_ws $ws10 + +# +# Layout stuff: +# +# change container layout (stacked, tabbed, toggle split) +$bindsym $mod+Shift+q layout stacking +$bindsym $mod+Shift+t layout tabbed +$bindsym $mod+Shift+w layout toggle split + +# enter fullscreen mode for the focused container +$bindsym $mod+f fullscreen toggle +## Action // Toggle global fullscreen ## +$bindsym $mod+Shift+f fullscreen global + +## Action // Scale up  ## +$bindsym $alt_mod+plus exec $scale_up + +## Action // Scale down  ## +$bindsym $alt_mod+minus exec $scale_down + +## Action // Scale default  ## +$bindsym $alt_mod+equal exec $scale_default + +## Action // Toggle floating ## +$bindsym $mod+Shift+space floating toggle +$bindsym $mod+Shift+equal sticky toggle + +## Navigation // Toggle focus between tiling and floating ## +# $bindsym $mod+space focus mode_toggle + +## Navigation // Swap focus to the parent window ## +$bindsym $mod+a focus parent + +## Launch // Toggle Help ## +$bindsym $mod+question exec $help + +## Launch // Inhibit Idle ## +$bindsym $mod+Shift+i exec inhibit-idle interactive + +default_border pixel 1 +hide_edge_borders smart + +# allow to kill focused floating shell windows using Esc +$bindsym --release Escape [app_id="floating_shell" con_id=__focused__] kill + +## Launch // Task Manager ## +$bindsym Ctrl+$alt_mod+Delete exec $task_manager + +## Launch // Emoji Picker ## +$bindsym $alt_mod+Shift+e exec $emoji_picker diff --git a/config/sway/modes/recording b/config/sway/modes/recording new file mode 100644 index 0000000..2fef203 --- /dev/null +++ b/config/sway/modes/recording @@ -0,0 +1,19 @@ +# set $mode_recording " \ +# Record (r) \ +# + [Shift for 󰍮]" +# +# set $recorder /usr/share/sway/scripts/recorder.sh +# +# mode --pango_markup $mode_recording { +# $bindsym r exec $recorder, mode "default" +# $bindsym Shift+r exec $recorder -a, mode "default" +# +# # Return to default mode. +# $bindsym Escape mode "default" +# } +# +## Launch // Recording Mode ## +# $bindsym $mod+Shift+r mode $mode_recording +# +## Launch // Stop Recording Mode ## +# $bindsym $mod+Escape exec killall -s SIGINT wf-recorder diff --git a/config/sway/modes/resize b/config/sway/modes/resize new file mode 100644 index 0000000..d805f35 --- /dev/null +++ b/config/sway/modes/resize @@ -0,0 +1,25 @@ +set $mode_resize "󰉸 \ +Resize (↑ ↓ ← →) \ +Increase Gaps (+) \ +Decrease Gaps (-)" + +mode --pango_markup $mode_resize { + # left will shrink the containers width + # right will grow the containers width + # up will shrink the containers height + # down will grow the containers height + $bindsym $left resize shrink width 10px + $bindsym $down resize grow height 10px + $bindsym $up resize shrink height 10px + $bindsym $right resize grow width 10px + + ## Resize // Window Gaps // + - ## + $bindsym minus gaps inner current minus 5px + $bindsym plus gaps inner current plus 5px + + # Return to default mode + $bindsym Return mode "default" + $bindsym Escape mode "default" +} +## Launch // Resize Mode ## +$bindsym $mod+r mode $mode_resize diff --git a/config/sway/modes/scratchpad b/config/sway/modes/scratchpad new file mode 100644 index 0000000..ff7ee78 --- /dev/null +++ b/config/sway/modes/scratchpad @@ -0,0 +1,12 @@ +# +# Scratchpad: +# +# Sway has a "scratchpad", which is a bag of holding for windows. +# You can send windows there and get them back later. + +## Action // Move window to scratchpad ## +$bindsym $mod+Shift+minus move scratchpad, exec "waybar-signal scratchpad" + +# If there are multiple scratchpad windows, this command cycles through them. +## Action // Toggle scratchpad ## +$bindsym $mod+space scratchpad show, exec "waybar-signal scratchpad" diff --git a/config/sway/modes/screenshot b/config/sway/modes/screenshot new file mode 100644 index 0000000..1cb1c90 --- /dev/null +++ b/config/sway/modes/screenshot @@ -0,0 +1,20 @@ +set $mode_screenshot "󰄄 \ +Pick (p) \ +Output (o) \ ++ Shift for " + +mode --pango_markup $mode_screenshot { + # output = currently active output + $bindsym o mode "default", exec $screenshot_screen + $bindsym Shift+o mode "default", exec $screenshot_screen_upload + + # pick the region to screenshot + $bindsym p mode "default", exec $screenshot_selection + $bindsym Shift+p mode "default", exec $screenshot_selection_upload + + # Return to default mode. + $bindsym Escape mode "default" +} + +## Launch // Screenshot Mode ## +$bindsym Print mode $mode_screenshot diff --git a/config/sway/modes/shutdown b/config/sway/modes/shutdown new file mode 100644 index 0000000..b513d76 --- /dev/null +++ b/config/sway/modes/shutdown @@ -0,0 +1,30 @@ +set $mode_shutdown "\ + \ + \ +(l)lock \ +(e)logout \ +(r)reboot \ +(s)shutdown \ +" + +set $purge_cliphist [ $purge_cliphist_logout == 'true' ] && rm -f $HOME/.cache/cliphist/db || exit 0 + +mode --pango_markup $mode_shutdown { + # lock + $bindsym l mode "default", exec $locking + + # logout + $bindsym e exec $purge_cliphist; exec swaymsg exit + + # shutdown + $bindsym s exec $purge_cliphist; exec sudo /sbin/poweroff + + # reboot + $bindsym r exec $purge_cliphist; exec sudo /sbin/reboot + + # Return to default mode. + $bindsym Escape mode "default" +} + +## Launch // Exit Menu ## +$bindsym $mod+Shift+e mode $mode_shutdown diff --git a/config/sway/modes/split b/config/sway/modes/split new file mode 100644 index 0000000..b5c21c2 --- /dev/null +++ b/config/sway/modes/split @@ -0,0 +1,15 @@ +set $mode_split "󰉸 \ +Horizontal (h) \ +Vertical (v)" + +mode --pango_markup $mode_split { + $bindsym h splith, mode "default" + $bindsym $mod+h splith, mode "default" + $bindsym v splitv, mode "default" + $bindsym $mod+v splitv, mode "default" + + $bindsym Escape mode "default" + $bindsym Return mode "default" +} +## Launch // Resize Mode ## +$bindsym $mod+s mode $mode_split diff --git a/config/sway/themes/my-gruvbox/theme.conf b/config/sway/themes/my-gruvbox/theme.conf new file mode 100644 index 0000000..618fea8 --- /dev/null +++ b/config/sway/themes/my-gruvbox/theme.conf @@ -0,0 +1,31 @@ +# dracula + +# some global theme specific variables +# set $gtk-theme Dracula +# set $icon-theme Dracula-icons +# set $cursor-theme Dracula-cursors +set $gui-font Iosevka Custom 12 +set $term-font Iosevka Custom 12 +set $gtk-color-scheme prefer-dark +# set $kvantum-theme Dracula-purple-solid + +############################### +#### Gruvbox Material Dark #### +############################### +set $bg #282828 +set $fg #d4be98 +set $red #ea6962 +set $orange #e78a4e +set $green #a9b665 +set $blue #7daea3 +set $purple #d3869b +set $aqua #89b482 +set $darkgray #282828 + +# Gruvbox Theme brdr bg text indictr chld_brdr +client.focused $orange $orange $bg $green $orange +client.focused_inactive $blue $blue $bg $blue $blue +client.unfocused $bg $bg $bg $bg $bg +client.urgent $red $red $bg $red $red +client.placeholder $bg $bg $bg $bg $bg +client.background $bg diff --git a/local/share/sway/scripts/brightness.sh b/local/share/sway/scripts/brightness.sh new file mode 100755 index 0000000..281918e --- /dev/null +++ b/local/share/sway/scripts/brightness.sh @@ -0,0 +1,25 @@ +#!/bin/sh +current_abs=$(brightnessctl get) +current_rel() { + echo "$(brightnessctl get) * 100 / $(brightnessctl max)" | bc +} +max=$(brightnessctl max) +factor=3 +brightness_step=$((max * factor / 100 < 1 ? 1 : max * factor / 100)) + +case $1'' in +'') ;; +'down') + # if current value <= 3% and absolute value != 1, set brightness to absolute 1 + if [ "$(current_rel)" -le "$factor" ] && [ "$current_abs" -ge 0 ]; then + brightnessctl --quiet set 1 + else + brightnessctl --quiet set "${brightness_step}-" + fi + ;; +'up') + brightnessctl --quiet set "${brightness_step}+" + ;; +esac + +current_rel diff --git a/local/share/sway/scripts/checkupdates.sh b/local/share/sway/scripts/checkupdates.sh new file mode 100755 index 0000000..61613ea --- /dev/null +++ b/local/share/sway/scripts/checkupdates.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +case $1'' in +'status') + printf '{\"text\":\"%s\",\"tooltip\":\"%s\"}' "$(pamac checkupdates -q | wc -l)" "$(pamac checkupdates -q | awk 1 ORS='\\n' | sed 's/\\n$//')" + ;; +'check') + [ $(pamac checkupdates -q | wc -l) -gt 0 ] + exit $? + ;; +'upgrade') + if [ -x "$(command -v pacseek)" ]; then + xdg-terminal-exec pacseek -u + elif [ -x "$(command -v topgrade)" ]; then + xdg-terminal-exec topgrade + elif [ -x "$(command -v pamac-manager)" ]; then + pamac-manager --updates + else + xdg-terminal-exec pacman -Syu + fi + ;; +esac diff --git a/local/share/sway/scripts/dnd.sh b/local/share/sway/scripts/dnd.sh new file mode 100755 index 0000000..a9a41af --- /dev/null +++ b/local/share/sway/scripts/dnd.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +case $1'' in +'status') + printf '{\"alt\":\"%s\",\"tooltip\":\"mode: %s\"}' $(makoctl mode | grep -q 'do-not-disturb' && echo dnd || echo default) $(makoctl mode | tail -1) + ;; +'restore') + makoctl restore + ;; +'toggle') + makoctl mode | grep 'do-not-disturb' && makoctl mode -r do-not-disturb || makoctl mode -a do-not-disturb + ;; +esac diff --git a/local/share/sway/scripts/enable-gtk-theme.sh b/local/share/sway/scripts/enable-gtk-theme.sh new file mode 100755 index 0000000..b950c1f --- /dev/null +++ b/local/share/sway/scripts/enable-gtk-theme.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -xu + +THEME=$1 + +gsettings set org.gnome.desktop.interface gtk-theme $THEME + +mkdir -p "$HOME"/.config/gtk-4.0 + +THEME_DIR="/usr/share/themes/${THEME}/gtk-4.0" + +[ -d "$THEME_DIR/assets" ] && /usr/bin/cp -rf --backup "/usr/share/themes/${THEME}/gtk-4.0/assets" "$HOME"/.config/gtk-4.0/ +[ -f "$THEME_DIR/gtk.css" ] && /usr/bin/cp -rf --backup "/usr/share/themes/${THEME}/gtk-4.0/gtk.css" "$HOME"/.config/gtk-4.0/ + +[ -f "$THEME_DIR/gtk-dark.css" ] && /usr/bin/cp -rf --backup "/usr/share/themes/${THEME}/gtk-4.0/gtk-dark.css" "$HOME"/.config/gtk-4.0/ +[ ! -f "$THEME_DIR/gtk-dark.css" ] && rm -rf "$HOME"/.config/gtk-4.0/gtk-dark.css + +[ -d "$THEME_DIR/icons" ] && /usr/bin/cp -rf --backup "/usr/share/themes/${THEME}/gtk-4.0/icons" "$HOME"/.config/gtk-4.0/ diff --git a/local/share/sway/scripts/first-empty-workspace.py b/local/share/sway/scripts/first-empty-workspace.py new file mode 100755 index 0000000..704c42b --- /dev/null +++ b/local/share/sway/scripts/first-empty-workspace.py @@ -0,0 +1,51 @@ +#!/usr/bin/python3 + +import i3ipc +from argparse import ArgumentParser +from time import sleep + +# Assumption: it exists 10 workspaces (otherwise, change this value) +NUM_WORKSPACES = 10 + +if __name__ == "__main__": + + arguments_parser = ArgumentParser() + arguments_parser.add_argument('-s', + '--switch', + action='store_true', + help='switch to the first empty workspace' + ) + arguments_parser.add_argument('-m', + '--move', + action='store_true', + help='move the currently focused container to the first empty workspace' + ) + arguments = arguments_parser.parse_args() + assert(arguments.switch or arguments.move) # at least one of the flags must be specificated + + ipc = i3ipc.Connection() + tree = ipc.get_tree() + current_workspace = tree.find_focused().workspace() + workspaces = tree.workspaces() # includes current_workspace + + workspace_numbers = [workspace.num for workspace in workspaces] + empty_workspace_numbers = set([number for number in range(1,NUM_WORKSPACES+1)]) - set(workspace_numbers) + # Take into consideration that the current workspace exists but might be empty + if len(current_workspace.nodes) == 0: empty_workspace_numbers.add(current_workspace.num) + + # Get the minor empty workspace's number (or set it as the current workspace's number if all are busy) + first_empty_workspace_number = current_workspace.num + if empty_workspace_numbers: + first_empty_workspace_number = min(empty_workspace_numbers) + + # Use the value of first_empty_workspace_number to make the requested actions + if arguments.move and arguments.switch: + # Avoid wallpaper flickering when moving and switching by specifying both actions in the same Sway's command + reply = ipc.command("move container to workspace number {}, workspace number {}".format(first_empty_workspace_number, first_empty_workspace_number)) + assert(reply[0].success) # exit with non-zero status if the assertion fails + elif arguments.switch: + reply = ipc.command("workspace number {}".format(first_empty_workspace_number)) + assert(reply[0].success) # exit with non-zero status if the assertion fails + elif arguments.move: + reply = ipc.command("move container to workspace number {}".format(first_empty_workspace_number)) + assert(reply[0].success) # exit with non-zero status if the assertion fails diff --git a/local/share/sway/scripts/fontconfig.sh b/local/share/sway/scripts/fontconfig.sh new file mode 100755 index 0000000..984ca74 --- /dev/null +++ b/local/share/sway/scripts/fontconfig.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env sh +set -xu + +export CATEGORY=${1:-"monospace"} +export FONT=${2:-"JetBrainsMono NF"} + +FONTCONFIG_DIR=$HOME/.config/fontconfig/conf.d + +mkdir -p $FONTCONFIG_DIR + +cat /usr/share/sway/templates/fontconfig.conf | envsubst > $FONTCONFIG_DIR/51-${CATEGORY}.conf diff --git a/local/share/sway/scripts/foot.sh b/local/share/sway/scripts/foot.sh new file mode 100755 index 0000000..01ebed5 --- /dev/null +++ b/local/share/sway/scripts/foot.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env sh +# wrapper script for foot + +USER_CONFIG_PATH="${HOME}/.config/foot/foot.ini" +USER_THEME_CONFIG_PATH="${HOME}/.config/foot/foot-theme.ini" + +if [ -f "$USER_THEME_CONFIG_PATH" ]; then + USER_CONFIG=$USER_THEME_CONFIG_PATH +fi + +if [ -f "$USER_CONFIG_PATH" ]; then + USER_CONFIG=$USER_CONFIG_PATH +fi + +foot -c "${USER_CONFIG:-"/usr/share/sway/templates/foot.ini"}" $@ diff --git a/local/share/sway/scripts/generate-bg.sh b/local/share/sway/scripts/generate-bg.sh new file mode 100755 index 0000000..cc728bc --- /dev/null +++ b/local/share/sway/scripts/generate-bg.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh +set -xu + +export CROWN=$1 +export ROOT=$2 +export BACKGROUND=$3 + +# shellcheck disable=SC2002 +cat /usr/share/sway/templates/manjarosway-scalable.svg | envsubst > "$HOME/.config/sway/generated_background.svg" diff --git a/local/share/sway/scripts/geoip.sh b/local/share/sway/scripts/geoip.sh new file mode 100755 index 0000000..1b04018 --- /dev/null +++ b/local/share/sway/scripts/geoip.sh @@ -0,0 +1,11 @@ +#!/bin/sh +set -u + +cache_file="$HOME/.cache/geoip" +cache_time=$(date -r "$cache_file" +%s) +yesterday_time=$(date -d 'now - 6 hour' +%s) +start_of_day=$(date -d '00:00' +%s) +if [ ! -f "$cache_file" ] || [ $cache_time -lt $yesterday_time ] || [ $cache_time -lt $start_of_day ]; then + curl -sL https://manjaro-sway.download/geoip >"$cache_file" +fi +cat "$cache_file" diff --git a/local/share/sway/scripts/help.sh b/local/share/sway/scripts/help.sh new file mode 100755 index 0000000..6806720 --- /dev/null +++ b/local/share/sway/scripts/help.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env sh +set -x +# toggles the help wrapper state + +VISIBILITY_SIGNAL=30 +QUIT_SIGNAL=31 +LOCKFILE="$HOME/.local/help_disabled" + +if [ "$1" = "--toggle" ]; then + if [ -f "$LOCKFILE" ]; then + rm "$LOCKFILE" + else + touch "$LOCKFILE" + fi + # toggles the visibility + pkill -U $USER -f -${VISIBILITY_SIGNAL} 'nwg-wrapper.*-s help.sh' + +else + # makes sure no "old" wrappers are mounted (on start and reload) + pkill -U $USER -f -${QUIT_SIGNAL} 'nwg-wrapper.*-s help.sh' + # mounts the wrapper to all outputs + for output in $(swaymsg -t get_outputs --raw | jq -r '.[].name'); do + # sets the initial visibility + if [ -f "$LOCKFILE" ]; then + VISIBILITY="--invisible" + else + VISIBILITY="--no-invisible" + fi + nwg-wrapper ${VISIBILITY} -o "$output" -sv ${VISIBILITY_SIGNAL} -sq ${QUIT_SIGNAL} -s help.sh -p left -a end & + done +fi diff --git a/local/share/sway/scripts/keyboard-backlight-switch.sh b/local/share/sway/scripts/keyboard-backlight-switch.sh new file mode 100755 index 0000000..ba8a636 --- /dev/null +++ b/local/share/sway/scripts/keyboard-backlight-switch.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env sh +set -x + +case $1'' in +'on') + for device in $DEVICES; do + brightnessctl -r -d "*kbd_backlight" + done + ;; +'off') + for device in $DEVICES; do + brightnessctl -s -d "*kbd_backlight" && brightnessctl -d "*kbd_backlight" set 0 + done + ;; +esac diff --git a/local/share/sway/scripts/keyboard.sh b/local/share/sway/scripts/keyboard.sh new file mode 100755 index 0000000..1d263fd --- /dev/null +++ b/local/share/sway/scripts/keyboard.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env sh +# script that sets the locale from current locale settings +swaymsg input type:keyboard xkb_layout "$(localectl status | grep "X11 Layout" | sed -e "s/^.*X11 Layout://")" + +if localectl status | grep "X11 Variant" ; then + swaymsg input type:keyboard xkb_variant "$(localectl status | grep "X11 Variant" | sed -e "s/^.*X11 Variant://")" +fi diff --git a/local/share/sway/scripts/lock.sh b/local/share/sway/scripts/lock.sh new file mode 100755 index 0000000..c18965e --- /dev/null +++ b/local/share/sway/scripts/lock.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +swaylock --daemonize --show-failed-attempts -K \ + --color 282828 \ + --inside-color 282828 diff --git a/local/share/sway/scripts/mako.sh b/local/share/sway/scripts/mako.sh new file mode 100755 index 0000000..7ad43f8 --- /dev/null +++ b/local/share/sway/scripts/mako.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env sh +# wrapper script for mako +USER_CONFIG_PATH="${HOME}/.config/mako/config" + +if [ -f "$USER_CONFIG_PATH" ]; then + USER_CONFIG=$USER_CONFIG_PATH +fi + +# mako -c "${USER_CONFIG}" "$@" +mako "$@" diff --git a/local/share/sway/scripts/once.sh b/local/share/sway/scripts/once.sh new file mode 100755 index 0000000..51b90f9 --- /dev/null +++ b/local/share/sway/scripts/once.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +mkdir -p "$HOME/.local/state" +LOCKFILE="$HOME/.local/state/once.lock" + +# Kills the process if it's already running +lsof -Fp "$LOCKFILE" | sed 's/^p//' | xargs -r kill + +flock --verbose -n "$LOCKFILE" "$@" diff --git a/local/share/sway/scripts/recorder.sh b/local/share/sway/scripts/recorder.sh new file mode 100755 index 0000000..d04b1dd --- /dev/null +++ b/local/share/sway/scripts/recorder.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env sh +set -x + +pgrep wf-recorder +status=$? + +countdown() { + notify "Recording in 3 seconds" -t 1000 + sleep 1 + notify "Recording in 2 seconds" -t 1000 + sleep 1 + notify "Recording in 1 seconds" -t 1000 + sleep 1 +} + +notify() { + line=$1 + shift + notify-send "Recording" "${line}" -i /usr/share/icons/Papirus-Dark/32x32/devices/camera-video.svg $* +} + +if [ $status != 0 ]; then + target_path=$(xdg-user-dir VIDEOS) + timestamp=$(date +'recording_%Y%m%d-%H%M%S') + + notify "Select a region to record" -t 1000 + area=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp) + + countdown + (sleep 0.5 && waybar-signal recorder) & + + if [ "$1" = "-a" ]; then + file="$target_path/$timestamp.mp4" + wf-recorder --audio -g "$area" --file="$file" + else + file="$target_path/$timestamp.webm" + wf-recorder -g "$area" -c libvpx --codec-param="qmin=0" --codec-param="qmax=25" --codec-param="crf=4" --codec-param="b:v=1M" --file="$file" + fi + + waybar-signal recorder && notify "Finished recording ${file}" +else + pkill -U $USER -x --signal SIGINT wf-recorder + waybar-signal recorder +fi diff --git a/local/share/sway/scripts/sbdp.py b/local/share/sway/scripts/sbdp.py new file mode 100755 index 0000000..902f321 --- /dev/null +++ b/local/share/sway/scripts/sbdp.py @@ -0,0 +1,138 @@ +#!/usr/bin/python +import sys +import glob +import re +import os +from typing import Text +import json + +if len(sys.argv) >= 2: + rootPath = sys.argv[1] +else: + rootPath = '/etc/sway/config' + + +def readFile(filePath): + try: + paths = glob.glob(filePath) + except: + print("couldn't resolve glob:", filePath) + paths = [] + + allLines: list[str] = [] + for path in paths: + allLines = allLines + open(path, "r").readlines() + + finalLines: list[str] = [] + for line in allLines: + if re.search(r'^include\s+(.+?)$', line): + nextPath = re.findall(r'^include\s+(.+?)$', line)[0] + nextPath = os.path.expandvars(nextPath) + finalLines = finalLines + readFile(nextPath) + else: + finalLines = finalLines + [line] + + return finalLines + + +lines = readFile(rootPath) + + +def findKeybindingForLine(lineNumber: int, lines: list[str]): + return lines[lineNumber+1].split(' ')[1] + + +class DocsConfig: + category: Text + action: Text + keybinding: Text + + +def getDocsConfig(lines: list[str]): + docsLineRegex = r"^## (?P.+?) // (?P.+?)\s+(// (?P.+?))*##" + docsConfig: list[DocsConfig] = [] + for index, line in enumerate(lines): + match = re.match(docsLineRegex, line) + if (match): + config = DocsConfig() + config.category = match.group('category') + config.action = match.group('action') + config.keybinding = match.group('keybinding') + if (config.keybinding == None): + config.keybinding = findKeybindingForLine(index, lines) + docsConfig = docsConfig + [config] + return docsConfig + + +def getSymbolDict(lines: list[str]): + setRegex = r"^set\s+(?P\$.+?)\s(?P.+)?" + dictionary = {} + for line in lines: + match = re.match(setRegex, line) + if (match): + if (match.group('variable')): + dictionary[match.group('variable')] = match.group('value') + return dict(dictionary) + + +translations = { + 'Mod1': "Alt", + 'Mod2': "", + 'Mod3': "󰘲", + 'Mod4': "", + 'Mod5': "Scroll", + 'question': "?", + 'space': "␣", + 'minus': "-", + 'plus': '+', + 'Return': "󰌑", + 'XF86AudioRaiseVolume': "󰝝", + 'XF86AudioLowerVolume': "󰝞", + 'XF86AudioMute': "󰝟", + 'XF86AudioMicMute': '󰍭', + 'XF86MonBrightnessUp': "󰃠", + 'XF86MonBrightnessDown': "󰃞", + 'XF86PowerOff': "󰐥", + 'XF86TouchpadToggle': "Toggle Touchpad" +} + + +def translate(word: Text, dictionary: dict): + try: + return dictionary[word.strip()] + except: + return word.strip() + + +def replaceBindingFromMap(binding: Text, dictionary: dict): + elements = binding.split('+') + resultElements = [] + for el in elements: + translation = translate(translate(el, dictionary), translations) + resultElements = resultElements + [translation] + + return " + ".join(resultElements) + + +def sanitize(configs: list[DocsConfig], symbolDict: dict): + for index, config in enumerate(configs): + config.keybinding = replaceBindingFromMap( + config.keybinding, symbolDict) + configs[index] = config + return configs + + +def getDocsList(lines: list[str]): + docsConfig = getDocsConfig(lines) + symbolDict = getSymbolDict(lines) + sanitizedConfig = sanitize(docsConfig, symbolDict) + return sanitizedConfig + + +docsList = getDocsList(lines) + +result = [] +for config in docsList: + result = result + [{'category': config.category, + 'action': config.action, 'keybinding': config.keybinding}] +print(json.dumps(result)) diff --git a/local/share/sway/scripts/scale.sh b/local/share/sway/scripts/scale.sh new file mode 100755 index 0000000..22e140b --- /dev/null +++ b/local/share/sway/scripts/scale.sh @@ -0,0 +1,36 @@ +#!/bin/sh +make=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused==true) | .make') +model=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused==true) | .model') +name=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused==true) | .name') +current_screen="$make $model ($name" + +increment=0.25 + +current_scale() { + swaymsg -t get_outputs | jq -r '.[] | select(.focused==true) | .scale' +} + +next_scale=$(current_scale) + +scale() { + [ -x "$(command -v way-displays)" ] && way-displays -s SCALE "$current_screen" $next_scale && way-displays -w || swaymsg output "\"$name\"" scale "$next_scale" +} + +case $1'' in +'') + current_scale +;; +'up') + next_scale=$(echo "$(current_scale) + $increment" | bc) + scale + ;; +'down') + next_scale=$(echo "$(current_scale) - $increment" | bc) + scale + ;; +'default') + next_scale=1 + scale + ;; +esac + diff --git a/local/share/sway/scripts/scratchpad.sh b/local/share/sway/scripts/scratchpad.sh new file mode 100755 index 0000000..50d8546 --- /dev/null +++ b/local/share/sway/scripts/scratchpad.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env sh +tooltip=$(swaymsg -r -t get_tree | jq -r 'recurse(.nodes[]) | first(select(.name=="__i3_scratch")) | .floating_nodes | .[] | "\(.app_id) | \(.name)"') +count=$(printf "%s" "$tooltip" | grep -c '^') + +if [ "$count" -eq 0 ]; then + exit 1 +elif [ "$count" -eq 1 ]; then + class="one" +elif [ "$count" -gt 1 ]; then + class="many" +else + class="unknown" +fi + +printf '{"text":"%s", "class":"%s", "alt":"%s", "tooltip":"%s"}\n' "$count" "$class" "$class" "$(echo "${tooltip}" | sed -z 's/\n/\\n/g')" diff --git a/local/share/sway/scripts/screenshot-notify.sh b/local/share/sway/scripts/screenshot-notify.sh new file mode 100755 index 0000000..d5a8562 --- /dev/null +++ b/local/share/sway/scripts/screenshot-notify.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env sh + +set -e +DIR=${XDG_SCREENSHOTS_DIR:-$HOME/Screenshots} + +while true; do + mkdir -p "$DIR" && inotifywait -q -e create "$DIR" --format '%w%f' | xargs notify-send "Screenshot saved" +done diff --git a/local/share/sway/scripts/sunset.sh b/local/share/sway/scripts/sunset.sh new file mode 100755 index 0000000..2db6b0f --- /dev/null +++ b/local/share/sway/scripts/sunset.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env sh + +config="$HOME/.config/wlsunset/config" + +#Startup function +start() { + [ -f "$config" ] && . "$config" + temp_low=${temp_low:-"4000"} + temp_high=${temp_high:-"6500"} + duration=${duration:-"900"} + sunrise=${sunrise:-"07:00"} + sunset=${sunset:-"19:00"} + location=${location:-"on"} + fallback_longitude=${fallback_longitude:-"8.7"} + fallback_latitude=${fallback_latitude:-"50.1"} + + if [ "${location}" = "on" ]; then + if [ -z ${longitude+x} ] || [ -z ${latitude+x} ]; then + GEO_CONTENT=$(sh /usr/share/sway/scripts/geoip.sh) + fi + longitude=${longitude:-$(echo "$GEO_CONTENT" | jq -r '.longitude // empty')} + longitude=${longitude:-$fallback_longitude} + latitude=${latitude:-$(echo "$GEO_CONTENT" | jq -r '.latitude // empty')} + latitude=${latitude:-$fallback_latitude} + + echo longitude: "$longitude" latitude: "$latitude" + + wlsunset -l "$latitude" -L "$longitude" -t "$temp_low" -T "$temp_high" -d "$duration" & + else + wlsunset -t "$temp_low" -T "$temp_high" -d "$duration" -S "$sunrise" -s "$sunset" & + fi +} + +#Accepts managing parameter +case $1'' in +'off') + pkill -U $USER -x wlsunset + waybar-signal sunset + ;; +'on') + start + waybar-signal sunset + ;; +'toggle') + if pkill -U $USER -x -0 wlsunset; then + pkill -U $USER -x wlsunset + else + start + fi + waybar-signal sunset + ;; +'check') + command -v wlsunset + exit $? + ;; +esac + +#Returns a string for Waybar +if pkill -U $USER -x -0 wlsunset; then + class="on" + text="location-based gamma correction" +else + class="off" + text="no gamma correction" +fi + +printf '{"alt":"%s","tooltip":"%s"}\n' "$class" "$text" diff --git a/local/share/sway/scripts/theme-toggle.sh b/local/share/sway/scripts/theme-toggle.sh new file mode 100755 index 0000000..c9d153d --- /dev/null +++ b/local/share/sway/scripts/theme-toggle.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +set -u + +LOCKFILE="$HOME/.local/auto-theme-toggle" +DARK_SWAY_THEME="$HOME/.config/sway/definitions.d/theme.dark.conf_" +LIGHT_SWAY_THEME="$HOME/.config/sway/definitions.d/theme.light.conf_" + +CURRENT_PRIMARY_THEME="dark" +CURRENT_SECONDARY_THEME="light" +NEXT_PRIMARY_THEME="dark" +NEXT_SECONDARY_THEME="light" + +if [ -f "$DARK_SWAY_THEME" ]; then + CURRENT_PRIMARY_THEME="light" + CURRENT_SECONDARY_THEME="dark" + NEXT_PRIMARY_THEME="light" + NEXT_SECONDARY_THEME="dark" +fi + +current_unix=$(date +%s) +__geo_content=$(sh /usr/share/sway/scripts/geoip.sh) + +sunrise_unix() { + sunrise_string=$(echo "$__geo_content" | jq -r '.sunrise // empty') + sunrise_unix=$(date -d "$sunrise_string" +%s) + echo "$sunrise_unix" +} + +sunset_unix() { + sunset_string=$(echo "$__geo_content" | jq -r '.sunset // empty') + sunset_unix=$(date -d "$sunset_string" +%s) + echo "$sunset_unix" +} + +tomorrow_sunrise_unix() { + sunrise_string=$(echo "$__geo_content" | jq -r '.sunrise_tomorrow // empty') + sunrise_unix=$(date -d "$sunrise_string" +%s) + echo "$sunrise_unix" +} + +tomorrow_sunset_unix() { + sunset_string=$(echo "$__geo_content" | jq -r '.sunset_tomorrow // empty') + sunset_unix=$(date -d "$sunset_string" +%s) + echo "$sunset_unix" +} + +if [ -f "$LOCKFILE" ]; then + if [ $current_unix -ge $(sunrise_unix) ] && [ $current_unix -lt $(sunset_unix) ]; then + NEXT_PRIMARY_THEME="light" + NEXT_SECONDARY_THEME="dark" + else + NEXT_PRIMARY_THEME="dark" + NEXT_SECONDARY_THEME="light" + fi +fi + +ensure_theme() { + if [ "$CURRENT_PRIMARY_THEME" != "$1" ]; then + PRIMARY_SWAY_THEME="$HOME/.config/sway/definitions.d/theme.conf" + PRIMARY_FOOT_THEME="$HOME/.config/foot/foot-theme.ini" + /usr/bin/mv --backup -v $PRIMARY_SWAY_THEME "$HOME/.config/sway/definitions.d/theme.$2.conf_" + /usr/bin/mv --backup -v $PRIMARY_FOOT_THEME "$HOME/.config/foot/foot-theme.$2.ini_" + /usr/bin/mv --backup -v "$HOME/.config/sway/definitions.d/theme.$1.conf_" $PRIMARY_SWAY_THEME + /usr/bin/mv --backup -v "$HOME/.config/foot/foot-theme.$1.ini_" $PRIMARY_FOOT_THEME + + swaymsg reload + fi +} + +#Accepts managing parameter +case $1'' in +'toggle') + if [ -f "$LOCKFILE" ]; then + NEXT_PRIMARY_THEME="$CURRENT_PRIMARY_THEME" + NEXT_SECONDARY_THEME="$CURRENT_SECONDARY_THEME" + else + NEXT_PRIMARY_THEME="$CURRENT_SECONDARY_THEME" + NEXT_SECONDARY_THEME="$CURRENT_PRIMARY_THEME" + fi + + ensure_theme $NEXT_PRIMARY_THEME $NEXT_SECONDARY_THEME + exit 0 + ;; +'auto-toggle') + if [ -f "$LOCKFILE" ]; then + rm "$LOCKFILE" + else + touch "$LOCKFILE" + fi + + waybar-signal theme + exit 0 + ;; +'check') + [ -f "$DARK_SWAY_THEME" ] || [ -f "$LIGHT_SWAY_THEME" ] + exit $? + ;; +'status') + #Returns a string for Waybar + text="switch to ${CURRENT_SECONDARY_THEME} theme\r(Right click to switch automatically)" + alt=$CURRENT_PRIMARY_THEME + if [ -f "$LOCKFILE" ]; then + next_switch_unix=$(sunrise_unix) + if [ $current_unix -ge $next_switch_unix ]; then + next_switch_unix=$(sunset_unix) + fi + if [ $current_unix -ge $next_switch_unix ]; then + next_switch_unix=$(tomorrow_sunrise_unix) + fi + hours=$((($next_switch_unix - $current_unix) / (60 * 60))) + minutes=$((($next_switch_unix - $current_unix) / 60 % 60)) + text="switching to ${CURRENT_SECONDARY_THEME} theme in ${hours}h ${minutes}m\r(Right click to disable)" + alt="auto_${CURRENT_PRIMARY_THEME}" + + ensure_theme $NEXT_PRIMARY_THEME $NEXT_SECONDARY_THEME + fi + + printf '{"alt":"%s","tooltip":"%s"}\n' "$alt" "$text" + + exit 0 + ;; +esac diff --git a/local/share/sway/scripts/type-to-app.sh b/local/share/sway/scripts/type-to-app.sh new file mode 100755 index 0000000..f92b046 --- /dev/null +++ b/local/share/sway/scripts/type-to-app.sh @@ -0,0 +1,15 @@ +#!/bin/sh +set -x + +PID=$(swaymsg -t get_tree | jq '.. | select(.type?) | select(.focused==true) | .pid') + +matcher=$1 +shift +type=$@ + +swaymsg [$matcher] focus + if [ "$?" = "0" ] +then + wtype $type + swaymsg "[pid=$PID] focus" +fi diff --git a/local/share/sway/scripts/valent.py b/local/share/sway/scripts/valent.py new file mode 100755 index 0000000..3058a2d --- /dev/null +++ b/local/share/sway/scripts/valent.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +import dbus +import json +import logging, sys +import os +import math + +level = logging.DEBUG if os.environ.get("DEBUG") == "true" else logging.INFO + +logging.basicConfig(stream=sys.stderr, level=level) + +CONNECTIVITY_STRENGTH_SYMBOL = ["󰞃", "󰢼", "󰢽", "󰢾", "󰢾"] + +BATTERY_PERCENTAGE_SYMBOL = ["󱃍", "󰁺", "󰁼", "󰁽", "󰁾", "󰁿", "󰂀", "󰂁", "󰂂", "󰁹"] + +bus = dbus.SessionBus() +valent_object = bus.get_object("ca.andyholmes.Valent", "/ca/andyholmes/Valent") +valent_interface = dbus.Interface(valent_object, "org.freedesktop.DBus.ObjectManager") +managed_objects = valent_interface.GetManagedObjects() + +dangerously_empty = False +connected = False +no_connectivity = False + +devices = [] + +for path in managed_objects: + device = {} + device["state"] = ( + "connected" + if managed_objects[path].get("ca.andyholmes.Valent.Device", {}).get("State", 0) + == 3 + else "disconnected" + ) + device["id"] = ( + managed_objects[path].get("ca.andyholmes.Valent.Device", {}).get("Id", 0) + ) + device["name"] = ( + managed_objects[path].get("ca.andyholmes.Valent.Device", {}).get("Name", 0) + ) + + device_obj = bus.get_object("ca.andyholmes.Valent", path) + device_action_interface = dbus.Interface(device_obj, "org.gtk.Actions") + + battery_state = device_action_interface.Describe("battery.state")[2][0] + device["battery_percentage"] = battery_state["percentage"] + device["battery_status"] = ( + "discharging" if battery_state["charging"] == 0 else "charging" + ) + + connectivity_state = device_action_interface.Describe("connectivity_report.state")[ + 2 + ][0]["signal-strengths"]["1"] + device["connectivity_strength"] = connectivity_state["signal-strength"] + + if device["state"] == "connected": + connected = True + + if device["connectivity_strength"] <= 1: + no_connectivity = True + + if device["battery_percentage"] <= 15 and device["battery_status"] == "discharging": + dangerously_empty = True + + devices.append(device) + +data = {} +data["alt"] = ( + "no-devices" + if len(devices) == 0 + else "dangerously-empty" + if dangerously_empty + else "no-signal" + if no_connectivity + else "connected" + if connected + else "disconnected" +) +data["class"] = data["alt"] +data["tooltip"] = "" + +logging.debug(devices) + +tooltip = [] + +for device in devices: + battery_symbol = math.ceil(round(device["battery_percentage"] / 10, 0)) + details = ( + f"\t{CONNECTIVITY_STRENGTH_SYMBOL[device['connectivity_strength']]} {BATTERY_PERCENTAGE_SYMBOL[battery_symbol]} {device['battery_percentage']}% ({device['battery_status']})" + if device["state"] == "connected" + else "" + ) + tooltip.append(f"{device['name']} ({device['state']}){details}") + +data["tooltip"] = "\n".join(tooltip) + +print(json.dumps(data)) diff --git a/local/share/sway/scripts/waybar.sh b/local/share/sway/scripts/waybar.sh new file mode 100755 index 0000000..527c5b3 --- /dev/null +++ b/local/share/sway/scripts/waybar.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# wrapper script for waybar with args, see https://github.com/swaywm/sway/issues/5724 + +USER_CONFIG_PATH=$HOME/.config/waybar/config.jsonc +USER_STYLE_PATH=$HOME/.config/waybar/style.css + +pkill -U $USER -x waybar + +if [ -f "$USER_CONFIG_PATH" ]; then + USER_CONFIG=$USER_CONFIG_PATH +fi + +if [ -f "$USER_STYLE_PATH" ]; then + USER_STYLE=$USER_STYLE_PATH +fi + +waybar -c "${USER_CONFIG}" -s "${USER_STYLE}" > $(mktemp -t XXXX.waybar.log) diff --git a/local/share/sway/scripts/weather.py b/local/share/sway/scripts/weather.py new file mode 100755 index 0000000..1eac13e --- /dev/null +++ b/local/share/sway/scripts/weather.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +"""Script for the Waybar weather module.""" + +import getopt +import json +import locale +import sys +import urllib.parse +from datetime import datetime +import requests +import configparser +from os import path, environ + +config_path = path.join( + environ.get('APPDATA') or + environ.get('XDG_CONFIG_HOME') or + path.join(environ['HOME'], '.config'), + "weather.cfg" +) + +config = configparser.ConfigParser() +config.read(config_path) + +# see https://docs.python.org/3/library/locale.html#background-details-hints-tips-and-caveats +locale.setlocale(locale.LC_ALL, "") +current_locale, _ = locale.getlocale(locale.LC_NUMERIC) +city = config.get('DEFAULT', 'city', fallback='auto') +temperature = config.get('DEFAULT', 'temperature', fallback='C') +distance = config.get('DEFAULT', 'distance', fallback='km') +lng = config.get('DEFAULT', 'locale', fallback=locale.getlocale()[0] or current_locale) + +if current_locale == "en_US": + temperature = temperature or "F" + distance = distance or "miles" + +argument_list = sys.argv[1:] +options = "t:c:d:" +long_options = ["temperature=", "city=", "distance="] + +try: + args, values = getopt.getopt(argument_list, options, long_options) + + for current_argument, current_value in args: + if current_argument in ("-t", "--temperature"): + temperature = current_value[0].upper() + if temperature not in ("C", "F"): + msg = "temperature unit is neither (C)elsius, nor (F)ahrenheit" + raise RuntimeError( + msg, + temperature, + ) + + elif current_argument in ("-d", "--distance"): + distance = current_value.lower() + if distance not in ("km", "miles"): + msg = "distance unit is neither km, nor miles", distance + raise RuntimeError(msg) + + else: + city = urllib.parse.quote(current_value) + +except getopt.error as err: + print(str(err)) + sys.exit(1) + +if temperature == "F": + temperature_unit = "fahrenheit" + +if temperature == "C": + temperature_unit = "celsius" + +if distance == "miles": + wind_speed_unit = "mph" + +if distance == "km": + wind_speed_unit = "kmh" + +try: + headers = {"Accept-Language": f"{lng.replace("_", "-")},{lng.split("_")[0]};q=0.5"} + weather = requests.get(f"https://manjaro-sway.download/weather/{city}?temperature_unit={temperature_unit}&wind_speed_unit={wind_speed_unit}", timeout=10, headers=headers).json() +except ( + requests.exceptions.HTTPError, + requests.exceptions.ConnectionError, + requests.exceptions.Timeout, +) as err: + print(str(err)) + sys.exit(1) + +print(json.dumps(weather)) diff --git a/local/share/sway/scripts/wluma.sh b/local/share/sway/scripts/wluma.sh new file mode 100755 index 0000000..23567c5 --- /dev/null +++ b/local/share/sway/scripts/wluma.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env sh + +status() { + systemctl --user is-active wluma >/dev/null 2>&1 +} + +#Accepts managing parameter +case $1'' in +'toggle') + status && systemctl --user stop wluma || systemctl --user --now enable wluma + waybar-signal adaptive_brightness + ;; +'check') + [ -x "$(command -v wluma)" ] && [ $(ls -A /sys/class/backlight/ | wc -l) -gt 0 ] + exit $? + ;; +esac + +#Returns data for Waybar +if status; then + class="on" + text="adaptive brightness" +else + class="off" + text="static brightness" +fi + +printf '{"alt":"%s","tooltip":"%s"}\n' "$class" "$text" diff --git a/local/share/sway/scripts/wob.sh b/local/share/sway/scripts/wob.sh new file mode 100755 index 0000000..955b2ee --- /dev/null +++ b/local/share/sway/scripts/wob.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env sh +# https://github.com/francma/wob/wiki/wob-wrapper-script +#$1 - accent color. $2 - background color. $3 - new value +# returns 0 (success) if $1 is running and is attached to this sway session; else 1 +is_running_on_this_screen() { + pkill -U $USER -x -0 "wob" || return 1 + for pid in $(pgrep "wob"); do + WOB_SWAYSOCK="$(tr '\0' '\n' >$ini +} + +if [ ! -f "$ini" ] || [ "$3" = "--refresh" ]; then + refresh "$1" "$2" +fi + +# wob does not appear in $(swaymsg -t get_msg), so: +is_running_on_this_screen || { + tail -f "$wob_pipe" | wob -c $ini & +} + +if [ "$3" = "--refresh" ]; then + exit 0; +elif [ -n "$3" ]; then + echo "$3" >"$wob_pipe" +else + cat >"$wob_pipe" +fi diff --git a/local/share/sway/templates/fontconfig.conf b/local/share/sway/templates/fontconfig.conf new file mode 100644 index 0000000..d9a7dc2 --- /dev/null +++ b/local/share/sway/templates/fontconfig.conf @@ -0,0 +1,10 @@ + + + + ${CATEGORY} + + + ${FONT} + + + diff --git a/local/share/sway/templates/foot.ini b/local/share/sway/templates/foot.ini new file mode 100644 index 0000000..257d447 --- /dev/null +++ b/local/share/sway/templates/foot.ini @@ -0,0 +1,149 @@ +# -*- conf -*- + +# shell=$SHELL (if set, otherwise user's default shell from /etc/passwd) +term=foot-extra #(or xterm-256color if built with -Dterminfo=disabled) +# login-shell=no + +# font=JetBrainsMono NF:size=8 +# font-bold= +# font-italic= +# font-bold-italic= +# line-height= +# letter-spacing=0 +# horizontal-letter-offset=0 +# vertical-letter-offset=0 +# underline-offset= +# box-drawings-uses-font-glyphs=no +# dpi-aware=yes + +# initial-window-size-pixels=700x500 # Or, +# initial-window-size-chars= +# initial-window-mode=windowed +# pad=2x2 # optionally append 'center' +resize-delay-ms=50 + +# notify=notify-send -a ${app-id} -i ${app-id} ${title} ${body} + +# bold-text-in-bright=no +# bell=none +# word-delimiters=,│`|:"'()[]{}<> +# selection-target=primary +# workers= + +[bell] +# urgent=no +# notify=no +# command= +# command-focused=no + +[scrollback] +lines=10000 +# multiplier=3.0 +# indicator-position=relative +# indicator-format= + +[url] +# launch=xdg-open ${url} +# label-letters=sadfjklewcmpgh +# osc8-underline=url-mode +# protocols = http, https, ftp, ftps, file, gemini, gopher + +[cursor] +# style=block +# blink=no +# beam-thickness=1.5 +# underline-thickness= + +[mouse] +# hide-when-typing=no +# alternate-scroll-mode=yes + +[csd] +# preferred=server +# size=26 +# color= +# button-width=26 +# button-color= +# button-minimize-color= +# button-maximize-color= +# button-close-color= + +[key-bindings] +# scrollback-up-page=Shift+Page_Up +# scrollback-up-half-page=none +# scrollback-up-line=none +# scrollback-down-page=Shift+Page_Down +# scrollback-down-half-page=none +# scrollback-down-line=none +# clipboard-copy=Control+Shift+c +# clipboard-paste=Control+Shift+v +# primary-paste=Shift+Insert +# search-start=Control+Shift+r +# font-increase=Control+plus Control+equal Control+KP_Add +# font-decrease=Control+minus Control+KP_Subtract +# font-reset=Control+0 Control+KP_0 +# spawn-terminal=Control+Shift+n +# minimize=none +# maximize=none +# fullscreen=none +# pipe-visible=[sh -c "xurls | fuzzel | xargs -r firefox"] none +# pipe-scrollback=[sh -c "xurls | fuzzel | xargs -r firefox"] none +# pipe-selected=[xargs -r firefox] none +# show-urls-launch=Control+Shift+u +# show-urls-copy=none + +[search-bindings] +# cancel=Control+g Escape +# commit=Return +# find-prev=Control+r +# find-next=Control+s +# cursor-left=Left Control+b +# cursor-left-word=Control+Left Mod1+b +# cursor-right=Right Control+f +# cursor-right-word=Control+Right Mod1+f +# cursor-home=Home Control+a +# cursor-end=End Control+e +# delete-prev=BackSpace +# delete-prev-word=Mod1+BackSpace Control+BackSpace +# delete-next=Delete +# delete-next-word=Mod1+d Control+Delete +# extend-to-word-boundary=Control+w +# extend-to-next-whitespace=Control+Shift+w +# clipboard-paste=Control+v Control+y +# primary-paste=Shift+Insert + +[url-bindings] +# cancel=Control+g Control+d Escape +# toggle-url-visible=t + +[mouse-bindings] +# primary-paste=BTN_MIDDLE +# select-begin=BTN_LEFT +# select-begin-block=Control+BTN_LEFT +# select-extend=BTN_RIGHT +# select-extend-character-wise=Control+BTN_RIGHT +# select-word=BTN_LEFT-2 +# select-word-whitespace=Control+BTN_LEFT-2 +# select-row=BTN_LEFT-3 + +[colors] +alpha=0.9 +foreground=eeeeee +background=141a1b +cursor=141a1b eeeeee +regular0=141a1B # black +regular1=cd3f45 # red +regular2=9fca56 # green +regular3=e6cd69 # yellow +regular4=16a085 # blue +regular5=a074c4 # magenta +regular6=55b5db # cyan +regular7=d6d6d6 # white +bright0=41535B # bright black +bright1=cd3f45 # red +bright2=9fca56 # green +bright3=e6cd69 # yellow +bright4=16a085 # blue +bright5=a074c4 # magenta +bright6=55b5db # cyan +bright7=ffffff # bright white diff --git a/local/share/sway/templates/mako b/local/share/sway/templates/mako new file mode 100644 index 0000000..9e53de7 --- /dev/null +++ b/local/share/sway/templates/mako @@ -0,0 +1,2 @@ +[mode=do-not-disturb] +invisible=1 diff --git a/local/share/sway/templates/manjarosway-scalable.svg b/local/share/sway/templates/manjarosway-scalable.svg new file mode 100644 index 0000000..85ebe68 --- /dev/null +++ b/local/share/sway/templates/manjarosway-scalable.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/local/share/sway/templates/rofi/config.rasi b/local/share/sway/templates/rofi/config.rasi new file mode 100644 index 0000000..b7a241f --- /dev/null +++ b/local/share/sway/templates/rofi/config.rasi @@ -0,0 +1 @@ +@import "Manjaro" diff --git a/local/share/sway/templates/waybar/config.jsonc b/local/share/sway/templates/waybar/config.jsonc new file mode 100644 index 0000000..5e58102 --- /dev/null +++ b/local/share/sway/templates/waybar/config.jsonc @@ -0,0 +1,377 @@ +// ============================================================================= +// +// Waybar configuration +// +// Configuration reference: https://github.com/Alexays/Waybar/wiki/Configuration +// +// ============================================================================= +{ + // ------------------------------------------------------------------------- + // Global configuration + // ------------------------------------------------------------------------- + "layer": "top", + // If height property would be not present, it'd be calculated dynamically + "height": 30, + "position": "top", + "modules-left": [ + "custom/menu", + "sway/workspaces", + "custom/scratchpad" + ], + "modules-center": [ + "custom/wf-recorder", + "sway/mode", + "custom/weather" + ], + "modules-right": [ + // informational + "sway/language", + "custom/github", + "custom/clipboard", + "custom/zeit", + "cpu", + // "temperature", + // "memory", + "battery", + // connecting + "network", + "bluetooth", + "custom/valent", + // media + "custom/playerctl", + "custom/idle_inhibitor", + "custom/dnd", + "pulseaudio", + "backlight", + // system + "custom/theme", + "custom/adaptive-light", + "custom/sunset", + "custom/pacman", + "tray", + "clock" + ], + // ------------------------------------------------------------------------- + // Modules + // ------------------------------------------------------------------------- + "battery": { + "interval": 30, + "states": { + "warning": 30, + "critical": 15 + }, + "format-charging": "󰂄 {capacity}%", + "format": "{icon} {capacity}%", + "format-icons": [ + "󱃍", + "󰁺", + "󰁼", + "󰁽", + "󰁾", + "󰁿", + "󰂀", + "󰂁", + "󰂂", + "󰁹" + ], + "tooltip": true + }, + "clock": { + "interval": 60, + "format": "{:%e %b %Y %H:%M}", + "tooltip": true, + "tooltip-format": "{:%B %Y}\n{calendar}", + "on-click": "swaymsg exec \\$calendar" + }, + "cpu": { + "interval": 10, + "format": "󰘚", + "states": { + "warning": 70, + "critical": 90 + }, + "on-click": "swaymsg exec \\$task_manager", + "tooltip": true + }, + "memory": { + "interval": 10, + "format": "󰍛", + "states": { + "warning": 70, + "critical": 90 + }, + "on-click": "swaymsg exec \\$task_manager", + "tooltip": true + }, + "network": { + "interval": 5, + "format-wifi": "{icon}", + "format-ethernet": "󰈀", + "format-disconnected": "󰖪", + "format-disabled": "󰀝", + "format-icons": [ + "󰤯", + "󰤟", + "󰤢", + "󰤥", + "󰤨" + ], + "tooltip-format": "{icon} {ifname}: {ipaddr}", + "tooltip-format-ethernet": "{icon} {ifname}: {ipaddr}", + "tooltip-format-wifi": "{icon} {ifname} ({essid}): {ipaddr}", + "tooltip-format-disconnected": "{icon} disconnected", + "tooltip-format-disabled": "{icon} disabled", + "on-click": "swaymsg exec \\$once \\$term_float nmtui connect" + }, + "sway/mode": { + "format": "{}", + "tooltip": false + }, + "backlight": { + "format": "{icon} {percent}%", + "format-icons": [ + "󰃞", + "󰃟", + "󰃠" + ], + "on-scroll-up": "swaymsg exec \\$brightness_up", + "on-scroll-down": "swaymsg exec \\$brightness_down" + }, + "pulseaudio": { + "scroll-step": 5, + "format": "{icon} {volume}%{format_source}", + "format-muted": "󰖁 {format_source}", + "format-source": "", + "format-source-muted": " 󰍭", + "format-icons": { + "headphone": "󰋋", + "headset": "󰋎", + "default": [ + "󰕿", + "󰖀", + "󰕾" + ] + }, + "tooltip-format": "{icon}  {volume}% {format_source}", + "on-click": "swaymsg exec \\$pulseaudio", + "on-click-middle": "swaymsg exec \\$volume_mute", + "on-scroll-up": "swaymsg exec \\$volume_up", + "on-scroll-down": "swaymsg exec \\$volume_down" + }, + "temperature": { + "critical-threshold": 90, + "interval": 5, + "format": "{icon}", + "tooltip-format": "{temperatureC}°C", + "format-icons": [ + "", + "", + "" + ], + "tooltip": true, + "on-click": "swaymsg exec \"\\$once \\$term_float watch sensors\"" + }, + "tray": { + "icon-size": 21, + "spacing": 5 + }, + "custom/pacman": { + "format": "󰀼 {}", + "interval": 3600, + "return-type": "json", + "exec-if": "/usr/share/sway/scripts/checkupdates.sh check", + "exec": "/usr/share/sway/scripts/checkupdates.sh status", + "on-click": "/usr/share/sway/scripts/checkupdates.sh check && swaymsg exec \\$update_manager", + "on-click-middle": "waybar-signal pacman", + "signal": 14 + }, + "custom/menu": { + "format": "", + "on-click": "swaymsg exec \\$menu", + "tooltip": false + }, + "bluetooth": { + "format": "󰂯", + "format-disabled": "󰂲", + "on-click": "swaymsg exec \\$bluetooth", + "on-click-right": "rfkill toggle bluetooth", + "tooltip-format": "{}" + }, + "sway/language": { + "format": " {}", + "min-length": 5, + "tooltip": false, + "on-click": "swaymsg input type:keyboard xkb_switch_layout next" + }, + "custom/scratchpad": { + "interval": "once", + "return-type": "json", + "format": "{icon}", + "format-icons": { + "one": "󰖯", + "many": "󰖲" + }, + "exec": "/bin/sh /usr/share/sway/scripts/scratchpad.sh", + "on-click": "swaymsg 'scratchpad show'", + "signal": 7 + }, + "custom/sunset": { + "interval": "once", + "tooltip": true, + "return-type": "json", + "format": "{icon}", + "format-icons": { + "on": "󰌵", + "off": "󰌶" + }, + "exec": "fallback_latitude=50.1 fallback_longitude=8.7 latitude= longitude= /usr/share/sway/scripts/sunset.sh", + "on-click": "/usr/share/sway/scripts/sunset.sh toggle", + "exec-if": "/usr/share/sway/scripts/sunset.sh check", + "signal": 6 + }, + "custom/theme": { + "format": "{icon}", + "interval": 300, + "tooltip": true, + "format-icons": { + "light": "", + "dark": "", + "auto_light": "󱩷", + "auto_dark": "󱩸" + }, + "return-type": "json", + "exec-if": "/usr/share/sway/scripts/theme-toggle.sh check", + "exec": "/usr/share/sway/scripts/theme-toggle.sh status", + "on-click": "/usr/share/sway/scripts/theme-toggle.sh toggle", + "on-click-right": "/usr/share/sway/scripts/theme-toggle.sh auto-toggle", + "signal": 17 + }, + "custom/wf-recorder": { + "interval": "once", + "return-type": "json", + "format": "{}", + "exec": "echo '{\"class\": \"recording\",\"text\":\"󰑊\",\"tooltip\":\"press $mod+Esc to stop recording\"}'", + "exec-if": "pgrep wf-recorder", + "on-click": "waybar-signal recorder", + "signal": 8 + }, + "custom/github": { + "interval": 300, + "tooltip": false, + "return-type": "json", + "format": " {}", + "exec": "gh api '/notifications' -q '{ text: length }' | cat -", + "exec-if": "[ -x \"$(command -v gh)\" ] && gh auth status 2>&1 | grep -q -m 1 'Logged in' && test $(gh api '/notifications' -q 'length') -ne 0", + "on-click": "test $(gh api '/notifications' -q 'length') -ne 0 && xdg-open https://github.com/notifications && sleep 30 && waybar-signal github", + "signal": 4 + }, + "custom/playerctl": { + "interval": "once", + "tooltip": true, + "return-type": "json", + "format": "{icon}", + "format-icons": { + "Playing": "󰏦", + "Paused": "󰐍" + }, + "exec": "playerctl metadata --format '{\"alt\": \"{{status}}\", \"tooltip\": \"{{playerName}}: {{markup_escape(title)}} - {{markup_escape(artist)}}\" }'", + "on-click": "playerctl play-pause", + "on-click-right": "playerctl next", + "on-scroll-up": "playerctl position 10+", + "on-scroll-down": "playerctl position 10-", + "signal": 5 + }, + "custom/clipboard": { + "format": "󰨸", + "interval": "once", + "return-type": "json", + "on-click": "swaymsg -q exec '$clipboard'; waybar-signal clipboard", + "on-click-right": "swaymsg -q exec '$clipboard-del'; waybar-signal clipboard", + "on-click-middle": "rm -f ~/.cache/cliphist/db; waybar-signal clipboard", + "exec": "printf '{\"tooltip\":\"%s\"}' $(cliphist list | wc -l)' item(s) in the clipboard\r(Mid click to clear)'", + "exec-if": "[ -x \"$(command -v cliphist)\" ] && [ $(cliphist list | wc -l) -gt 0 ]", + "signal": 9 + }, + "custom/weather": { + "format": "{}", + "tooltip": true, + "interval": 3600, + // accepts -c/--city -t/--temperature -d/--distance + "exec": "/usr/share/sway/scripts/weather.py", + "return-type": "json", + "on-click": "xdg-open \"https://wttr.in/$(curl -s https://manjaro-sway.download/geoip | jq -r '.city')\"", + "on-click-right": "waybar-signal weather", + "signal": 16 + }, + "custom/zeit": { + "return-type": "json", + "interval": "once", + "format": "{icon}", + "format-icons": { + "tracking": "󰖷", + "stopped": "󰋣" + }, + "exec": "/usr/share/sway/scripts/zeit.sh status", + "on-click": "/usr/share/sway/scripts/zeit.sh click; waybar-signal zeit", + "exec-if": "[ -x \"$(command -v zeit)\" ]", + "signal": 10 + }, + "custom/dnd": { + "interval": "once", + "return-type": "json", + "format": "{}{icon}", + "format-icons": { + "default": "󰚢", + "dnd": "󰚣" + }, + "on-click": "/usr/share/sway/scripts/dnd.sh toggle; waybar-signal dnd", + "on-click-right": "/usr/share/sway/scripts/dnd.sh restore", + "exec": "/usr/share/sway/scripts/dnd.sh status", + "signal": 11 + }, + "custom/adaptive-light": { + "interval": "once", + "tooltip": true, + "return-type": "json", + "format": "{icon}", + "format-icons": { + "on": "󰃡", + "off": "󰃠" + }, + "exec": "/usr/share/sway/scripts/wluma.sh", + "on-click": "/usr/share/sway/scripts/wluma.sh toggle", + "exec-if": "/usr/share/sway/scripts/wluma.sh check", + "signal": 12 + }, + "custom/valent": { + "format": "{icon}", + "tooltip": true, + "interval": 60, + "exec": "/usr/share/sway/scripts/valent.py", + "exec-if": "[ -x \"$(command -v valent)\" ]", + "return-type": "json", + "format-icons": { + "no-devices": "", + "dangerously-empty": "󰂃", + "no-signal": "󰞃", + "connected": "", + "disconnected": "" + }, + "on-click": "valent", + "on-click-middle": "waybar-signal valent", + "signal": 13 + }, + "custom/idle_inhibitor": { + "interval": 60, + "return-type": "json", + "format": "{icon}", + "format-icons": { + "on": "󰒳", + "off": "󰒲" + }, + "exec": "inhibit-idle", + "on-click": "inhibit-idle off; inhibit-idle interactive", + "on-click-middle": "inhibit-idle off", + "signal": 15 + } +} diff --git a/local/share/sway/templates/waybar/style.css b/local/share/sway/templates/waybar/style.css new file mode 100644 index 0000000..ec198e4 --- /dev/null +++ b/local/share/sway/templates/waybar/style.css @@ -0,0 +1,216 @@ +/* ============================================================================= + * + * Waybar configuration + * + * Configuration reference: https://github.com/Alexays/Waybar/wiki/Configuration + * + * =========================================================================== */ + +/* import css definitions for current theme */ + +/* ----------------------------------------------------------------------------- + * Keyframes + * -------------------------------------------------------------------------- */ + +@keyframes blink-warning { + 70% { + color: @wm_icon_bg; + } + + to { + color: @wm_icon_bg; + background-color: @warning_color; + } +} + +@keyframes blink-critical { + 70% { + color: @wm_icon_bg; + } + + to { + color: @wm_icon_bg; + background-color: @error_color; + } +} + +/* ----------------------------------------------------------------------------- + * Base styles + * -------------------------------------------------------------------------- */ + +/* Reset all styles */ +* { + border: none; + border-radius: 0; + min-height: 0; + margin: 0; + padding: 0; + font-family: "JetBrainsMono NF", "Roboto Mono", sans-serif; +} + +/* The whole bar */ +window#waybar { + background: @theme_base_color; + color: @theme_text_color; + font-size: 14px; +} + +/* Each module */ +#custom-pacman, +#custom-menu, +#custom-help, +#custom-scratchpad, +#custom-github, +#custom-clipboard, +#custom-zeit, +#custom-dnd, +#custom-valent, +#custom-idle_inhibitor, +#bluetooth, +#battery, +#clock, +#cpu, +#memory, +#mode, +#network, +#pulseaudio, +#temperature, +#backlight, +#language, +#custom-adaptive-light, +#custom-sunset, +#custom-playerctl, +#custom-weather, +#custom-theme, +#tray { + padding-left: 8px; + padding-right: 8px; +} + +/* ----------------------------------------------------------------------------- + * Module styles + * -------------------------------------------------------------------------- */ + +#custom-scratchpad, +#custom-menu, +#workspaces button.focused, +#clock { + color: @theme_bg_color; + background-color: @theme_selected_bg_color; +} + +#custom-zeit.tracking { + background-color: @warning_color; +} + +#battery { + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-direction: alternate; +} + +#battery.warning { + color: @warning_color; +} + +#battery.critical { + color: @error_color; +} + +#battery.warning.discharging { + animation-name: blink-warning; + animation-duration: 3s; +} + +#battery.critical.discharging { + animation-name: blink-critical; + animation-duration: 2s; +} + +#clock { + font-weight: bold; +} + +#cpu.warning { + color: @warning_color; +} + +#cpu.critical { + color: @error_color; +} + +#custom-menu { + padding-left: 8px; + padding-right: 13px; +} + +#memory { + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-direction: alternate; +} + +#memory.warning { + color: @warning_color; +} + +#memory.critical { + color: @error_color; + animation-name: blink-critical; + animation-duration: 2s; +} + +#mode { + background: @background_color; +} + +#network.disconnected { + color: @warning_color; +} + +#pulseaudio.muted { + color: @warning_color; +} + +#temperature.critical { + color: @error_color; +} + +#workspaces button { + border-top: 2px solid transparent; + /* To compensate for the top border and still have vertical centering */ + padding-bottom: 2px; + padding-left: 10px; + padding-right: 10px; + color: @theme_selected_bg_color; +} + +#workspaces button.focused { + border-color: @theme_selected_bg_color; +} + +#workspaces button.urgent { + border-color: @error_color; + color: @error_color; +} + +#workspaces button:hover { + color: @theme_bg_color; +} + +#custom-pacman { + color: @warning_color; +} + +#bluetooth.disabled { + color: @warning_color; +} + +#custom-wf-recorder { + color: @error_color; + padding-right: 10px; +} + +#custom-valent.dangerously-empty { + color: @warning_color; +}