├── README.md ├── environment.d ├── ssh.conf └── wayland.conf ├── i3status-rust └── config.toml ├── sway-service.desktop ├── sway-service.sh ├── sway.png ├── sway ├── apps ├── bar ├── bindings ├── config ├── input ├── keyboard-layout-per-window.py └── output ├── swayidle └── config ├── swaylock └── config ├── systemd └── user │ ├── communi.service │ ├── firefox.service │ ├── mako.service │ ├── nm-applet.service │ ├── org.kde.kdeconnect.service │ ├── soulseekqt.service │ ├── ssh-agent.service │ ├── sway-session.target │ ├── sway.service │ ├── swayidle.service │ ├── swaykbdd.service │ ├── swaylock.service │ └── wayland-session.target └── waybar ├── config └── style.css /README.md: -------------------------------------------------------------------------------- 1 | # My Sway setup 2 | 3 | ![sway screenshot](./sway.png) 4 | 5 | [Sway](https://swaywm.org/) is a modern tilling wayland compositor, that emulates i3. 6 | Based on wlroots, it's one of the most featureful wayland compositors. 7 | 8 | Still, a lot of things wont work in Wayland. 9 | 10 | # [sway systemd integration](https://github.com/swaywm/sway/wiki/Systemd-integration) 11 | 12 | I'm running sway as a user systemd service, started by sddm (the login manager). 13 | 14 | * `/usr/share/wayland-sessions/sway-service.desktop` is added for a custom wayland session 15 | * when I choose that session in sddm `/usr/local/bin/sway-service.sh` is started, which: 16 | * loads the sddm/pam environment into the user systemd service manager 17 | * then starts the sway.service 18 | * systemd/user/sway.service loads additional environment variables from `~/.config/sway/env` 19 | * waits for the service to finish, which signals the end of the session 20 | * next, sway initializes and starts running: 21 | * at the end sway calls `exec "systemctl --user import-environment ; systemctl --user start sway-session.target"` 22 | * which imports the additional sway env vars back into systemd 23 | * only then `sway-session.target` is getting started: 24 | * it has `Wants=graphical-session-pre.target` so any desktop non-gui services starts first 25 | * then it has `BindsTo=graphical-session.target wayland-session.target`, and any enabled 26 | gui/wayland and sway applets/services start from there 27 | * examples are `swayidle.service` which has `WantedBy=sway-session.target` (or `wayland-session.target`) 28 | * same with swaybar/waybar, mako, and similar. 29 | 30 | ## Where do environment variables go? 31 | 32 | Read `man environment.d`, environment variables set there will be read by the 33 | --user systemd, and since everything is started in its hierarchy variables will 34 | properly propagate. 35 | 36 | ## Wayland tools 37 | - https://github.com/gdamjan/swaylock (fork: implements a grace period before a password is required) 38 | - https://gist.github.com/gdamjan/1415d93b83a38f64cffea0ff4c54fc4b (nm-applet with --indicator support) 39 | - https://github.com/kennylevinsen/wldash (runner / dashboard) 40 | - https://github.com/Hummer12007/brightnessctl/ 41 | - https://github.com/misterdanb/avizo (notification daemon for volume/backlight) 42 | - https://github.com/cyclopsian/wdisplays (GUI display configurator for wlroots compositors) 43 | - https://github.com/bugaevc/wl-clipboard (Command-line copy/paste utilities for Wayland) 44 | - https://github.com/Alexays/Waybar/pull/85#issuecomment-525223382 (sway-layout script for waybar) 45 | 46 | … and [more](https://github.com/topics/sway). 47 | 48 | # An unordered list of wayland bugs and issues 49 | 50 | - all firefox issues https://bugzilla.mozilla.org/show_bug.cgi?id=635134 51 | - ~copy by select / paste with middle click in QT/KDE apps~ 52 | (need to implement [gtk_primary_selection_device_manager](https://bugreports.qt.io/browse/QTBUG-66008)) (qt-5.14) 53 | - ~ctrl-Ц/В doesn't copy/paste in QT/KDE~ https://bugreports.qt.io/browse/QTBUG-65503 (fixed qt-5.13) 54 | - ~utf-8 paste~ https://bugreports.qt.io/browse/QTBUG-54786 (fixed qt-5.13) 55 | - per window/app keyboard layout 56 | https://github.com/swaywm/sway/pull/3155 (see https://github.com/swaywm/sway/pull/4504/files) 57 | - keyboard layout applet ([waybar](https://github.com/Alexays/Waybar/issues/66), [protocol](https://github.com/swaywm/wlr-protocols/pull/31)) 58 | 59 | - ~mpv doesn't inhibit screensaver~ (fix is: --gpu-context=wayland) 60 | should be automatic in mpv > 0.29.1 61 | - ~mpv error: failed to resolve wl_drm_interface(): /usr/lib/libEGL_mesa.so.0: undefined symbol: wl_drm_interface 62 | libva-intel-driver > 2.3.0~ (fixed in arch packages) 63 | 64 | - xmag/zoom - double check font antialiasing 65 | - ~networkmanager applet~ (recompiled `nm-applet --indicator`) 66 | - ~pulseaudio applet~ (waybar kind of) 67 | - bluetooth applet 68 | - kdeconnect applet (and functionality: clipboard, remote control) 69 | - ~KDE/Qt apps style~ (works fine with XDG_CURRENT_DESKTOP=KDE) 70 | - systemd --user support in sway https://github.com/swaywm/sway/pull/3486 71 | - generic screen/window capture (chromecasting, webrtc screensharing, screencasting) - pipewire integration in firefox/chrome 72 | 73 | # ps: `systemd-cgls -u user.slice` 74 | 75 | ``` 76 | Unit user.slice (/user.slice): 77 | └─user-1000.slice 78 | ├─user@1000.service 79 | │ ├─dbus-broker.service 80 | │ │ ├─1043 /usr/bin/dbus-broker-launch --scope user 81 | │ │ └─1044 dbus-broker --log 4 --controller 10 --machine-id dcf0d2b9b08f4fcf8… 82 | │ ├─run-r142215d057bf43d3bceb5cd0158dd792.service 83 | │ │ ├─2290 /usr/bin/alacritty 84 | │ │ └─2310 /bin/bash 85 | │ ├─run-r93568e2d57e14e339b1b7f25e38b521c.service 86 | │ │ ├─2131 /usr/bin/alacritty 87 | │ │ ├─2151 /bin/bash 88 | │ │ └─6512 systemd-cgls -u user.slice 89 | │ ├─swaykbdd.service 90 | │ │ └─1115 /usr/bin/swaykbdd 91 | │ ├─run-r8d99f10d5f2e4bf58089b02b0a7791e8.service 92 | │ │ ├─2184 /usr/bin/alacritty 93 | │ │ └─2204 /bin/bash 94 | │ ├─mako.service 95 | │ │ └─1116 /usr/bin/mako 96 | │ ├─firefox.service 97 | │ │ ├─1109 /opt/firefox/firefox 98 | │ │ ├─1329 /opt/firefox/firefox-bin -contentproc -parentBuildID 2020110616042… 99 | │ │ ├─1365 /opt/firefox/firefox-bin -contentproc -childID 1 -isForBrowser -pr… 100 | │ │ ├─1446 /opt/firefox/firefox-bin -contentproc -childID 2 -isForBrowser -pr… 101 | │ │ ├─1529 /opt/firefox/firefox-bin -contentproc -childID 3 -isForBrowser -pr… 102 | │ │ ├─1549 /opt/firefox/firefox-bin -contentproc -childID 5 -isForBrowser -pr… 103 | │ │ ├─1901 /opt/firefox/firefox-bin -contentproc -childID 6 -isForBrowser -pr… 104 | │ │ └─1980 /opt/firefox/firefox-bin -contentproc -childID 7 -isForBrowser -pr… 105 | │ ├─pulseaudio.service 106 | │ │ ├─1004 /usr/bin/pulseaudio --daemonize=no --log-target=journal 107 | │ │ └─1039 /usr/lib/pulse/gsettings-helper 108 | │ ├─swayidle.service 109 | │ │ └─1113 /usr/bin/swayidle -w -l 110 | │ ├─init.scope 111 | │ │ ├─878 /usr/lib/systemd/systemd --user 112 | │ │ └─883 (sd-pam) 113 | │ ├─run-r68c60c3012ca412e81cc474fbc32b2ad.service 114 | │ │ ├─2237 /usr/bin/alacritty 115 | │ │ └─2257 /bin/bash 116 | │ ├─sway.service 117 | │ │ ├─1045 /usr/bin/sway 118 | │ │ ├─1098 swaybg -o * -i /usr/share/backgrounds/sway/Sway_Wallpaper_Blue_192… 119 | │ │ ├─1100 swaybar -b bar-0 120 | │ │ ├─1120 Xwayland :1 -rootless -terminate -listen 21 -listen 23 -wm 47 121 | │ │ └─1164 i3status-rs 122 | │ ├─org.kde.kdeconnect.service 123 | │ │ ├─1112 /usr/lib/kdeconnectd 124 | │ │ ├─2493 kdeinit5: Running... 125 | │ │ ├─2494 /usr/lib/kf5/klauncher --fd=8 126 | │ │ └─2496 tags.so [kdeinit5] tags local:/run/user/1000/klauncherRBMkrF.1.sla… 127 | │ └─run-r652066f058184006ae1d462739e93b52.service 128 | │ └─2062 /usr/bin/communi 129 | └─session-2.scope 130 | ├─1012 /usr/lib/sddm/sddm-helper --socket /tmp/sddm-authe3be91ee-741e-41f8-… 131 | ├─1019 /usr/bin/kwalletd5 --pam-login 7 3 132 | └─1021 systemctl --wait --user start sway.service 133 | ``` 134 | -------------------------------------------------------------------------------- /environment.d/ssh.conf: -------------------------------------------------------------------------------- 1 | # ~/.config/environment.d/ssh.conf 2 | SSH_AUTH_SOCK=${XDG_RUNTIME_DIR}/ssh-agent.socket 3 | SSH_ASKPASS=/usr/bin/ksshaskpass 4 | -------------------------------------------------------------------------------- /environment.d/wayland.conf: -------------------------------------------------------------------------------- 1 | XDG_CURRENT_DESKTOP=KDE 2 | MOZ_ENABLE_WAYLAND=1 3 | SDL_VIDEODRIVER=wayland 4 | FREETYPE_PROPERTIES="truetype:interpreter-version=35" 5 | _JAVA_AWT_WM_NONREPARENTING=1 6 | -------------------------------------------------------------------------------- /i3status-rust/config.toml: -------------------------------------------------------------------------------- 1 | # when using 3istsatus-rs with swaybar 2 | # https://github.com/greshake/i3status-rust 3 | # 4 | 5 | theme = "solarized-dark" 6 | icons = "awesome5" 7 | 8 | [[block]] 9 | block = "temperature" 10 | collapsed = false 11 | interval = 10 12 | format = "gpu {max}°" 13 | chip = "amdgpu-pci-*" 14 | 15 | [[block]] 16 | block = "temperature" 17 | collapsed = false 18 | interval = 10 19 | format = "cpu {max}°" 20 | chip = "k10temp-pci-*" 21 | 22 | [[block]] 23 | block = "temperature" 24 | collapsed = true 25 | interval = 10 26 | format = "nvme: {max}°" 27 | chip = "nvme-pci-*" 28 | 29 | [[block]] 30 | block = "temperature" 31 | collapsed = true 32 | interval = 10 33 | format = "wifi: {max}°" 34 | chip = "iwlwifi_1-*" 35 | 36 | [[block]] 37 | block = "net" 38 | device = "wlan0" 39 | format = "{ssid} {signal_strength} {ip} {speed_down} {graph_down}" 40 | interval = 5 41 | 42 | [[block]] 43 | block = "disk_space" 44 | path = "/" 45 | alias = "/" 46 | info_type = "available" 47 | unit = "GB" 48 | interval = 20 49 | warning = 20.0 50 | alert = 10.0 51 | 52 | [[block]] 53 | block = "memory" 54 | display_type = "memory" 55 | format_mem = "{Mup}%" 56 | format_swap = "{SUp}%" 57 | 58 | [[block]] 59 | block = "cpu" 60 | interval = 1 61 | 62 | [[block]] 63 | block = "load" 64 | interval = 1 65 | format = "{1m}" 66 | 67 | [[block]] 68 | block = "sound" 69 | 70 | [[block]] 71 | block = "keyboard_layout" 72 | driver = "sway" 73 | sway_kb_identifier = "6127:24585:Lite-On_Technology_Corp._ThinkPad_USB_Keyboard_with_TrackPoint" 74 | 75 | [[block]] 76 | block = "time" 77 | interval = 60 78 | format = "%a %d/%m %R" 79 | -------------------------------------------------------------------------------- /sway-service.desktop: -------------------------------------------------------------------------------- 1 | # /usr/share/wayland-sessions/sway-service.desktop 2 | [Desktop Entry] 3 | Name=Sway Service 4 | Comment=i3-compatible Wayland compositor as a systemd service 5 | Exec=sway-service.sh 6 | Type=Application 7 | -------------------------------------------------------------------------------- /sway-service.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # /usr/local/bin/sway-service.sh - needs to be 0755 3 | 4 | # first import environment variables from the login manager 5 | systemctl --user import-environment 6 | # then start the service 7 | exec systemctl --wait --user start sway.service -------------------------------------------------------------------------------- /sway.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gdamjan/sway-setup/eca5adf4d7be0c737f51ac4e89580c163a89a91c/sway.png -------------------------------------------------------------------------------- /sway/apps: -------------------------------------------------------------------------------- 1 | for_window [class="Firefox" window_role="browser"] { 2 | border normal 0 3 | move container to workspace 1:web 4 | } 5 | for_window [class="Firefox" window_role="^(?!browser$)"] { 6 | floating enable 7 | } 8 | for_window [app_id="firefox"] { 9 | border normal 0 10 | move container to workspace 1:web 11 | inhibit_idle fullscreen 12 | } 13 | for_window [app_id="firefox" title="^About Firefox Nightly$"] { 14 | border normal 1 15 | floating enable 16 | } 17 | for_window [app_id="firefox" title=" - Sharing Indicator$"] { 18 | floating enable 19 | inhibit_idle open 20 | } 21 | 22 | for_window [app_id="org.kde.konsole"] { 23 | move to scratchpad 24 | resize set width 1266 px 25 | } 26 | 27 | for_window [app_id="com.github.communi.communi"] { 28 | move container to workspace 3:irc 29 | } 30 | 31 | for_window [app_id="pinentry-qt"] { 32 | move position center 33 | floating enable 34 | } 35 | for_window [app_id="pavucontrol"] { 36 | floating enable 37 | } 38 | for_window [class="^Popcorn-Time$"] { 39 | inhibit_idle fullscreen 40 | } 41 | for_window [app_id="wdisplays"] { 42 | floating enable 43 | } 44 | for_window [app_id="org.kde.kruler"] { 45 | border normal 1 46 | floating enable 47 | } 48 | for_window [app_id="desktopclient.nextcloud.com.nextcloud"] { 49 | border normal 1 50 | floating enable 51 | } 52 | for_window [class="SoulseekQt"] { 53 | move container to workspace 5:media 54 | } 55 | for_window [app_id="Alacritty"] { 56 | move container to workspace 2:term 57 | } 58 | 59 | for_window [app_id="avizo-service"] border pixel 0 60 | for_window [app_id="avizo-service"] sticky toggle 61 | no_focus [app_id="avizo-service"] 62 | -------------------------------------------------------------------------------- /sway/bar: -------------------------------------------------------------------------------- 1 | # 2 | # Status Bar: 3 | # 4 | # Read `man 5 sway-bar` for more information about this section. 5 | bar { 6 | position bottom 7 | 8 | # When the status_command prints a new line to stdout, swaybar updates. 9 | # The default just shows the current date and time. 10 | status_command i3status-rs 11 | 12 | colors { 13 | statusline #ffffff 14 | background #323232 15 | inactive_workspace #32323200 #32323200 #5c5c5c 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /sway/bindings: -------------------------------------------------------------------------------- 1 | # lock screen 2 | bindsym $mod+l exec systemctl kill swayidle.service --user --signal USR1 --kill-who=main 3 | bindsym $mod+r exec $menu 4 | bindsym $mod+Shift+t sticky toggle 5 | bindsym $mod+Print exec grim screenshot-$(date --iso-8601=ns).png 6 | 7 | # Pulse Audio controls 8 | bindsym XF86AudioRaiseVolume exec pactl set-sink-volume 0 +5% #increase sound volume 9 | bindsym XF86AudioLowerVolume exec pactl set-sink-volume 0 -5% #decrease sound volume 10 | bindsym XF86AudioMute exec pactl set-sink-mute 0 toggle # mute sound 11 | bindsym XF86AudioMicMute exec pactl set-source-mute alsa_input.pci-0000_00_1b.0.analog-stereo toggle # mute mic 12 | 13 | # Sreen brightness controls 14 | bindsym XF86MonBrightnessUp exec brightnessctl -q s +10% 15 | bindsym XF86MonBrightnessDown exec brightnessctl -q s 10%- 16 | 17 | ### Key bindings 18 | # 19 | # Basics: 20 | # 21 | # start a terminal 22 | bindsym $mod+Return exec systemd-run --user $term 23 | 24 | # kill focused window 25 | bindsym $mod+Shift+q kill 26 | 27 | # start your launcher 28 | bindsym $mod+d exec $menu 29 | 30 | # Drag floating windows by holding down $mod and left mouse button. 31 | # Resize them with right mouse button + $mod. 32 | # Despite the name, also works for non-floating windows. 33 | # Change normal to inverse to use left mouse button for resizing and right 34 | # mouse button for dragging. 35 | floating_modifier $mod normal 36 | 37 | # reload the configuration file 38 | bindsym $mod+Shift+c reload 39 | 40 | # exit sway (logs you out of your Wayland session) 41 | bindsym $mod+Alt+Delete exec swaynag -t warning -m 'You pressed the mod4+alt+del. Do you really want to: ' \ 42 | -b 'Exit sway' 'swaymsg exit' \ 43 | -b 'Reboot' 'systemctl reboot' \ 44 | -b 'Shutdown' 'systemctl poweroff' 45 | # 46 | # Moving around: 47 | # 48 | # Move your focus around 49 | bindsym $mod+Left focus left 50 | bindsym $mod+Down focus down 51 | bindsym $mod+Up focus up 52 | bindsym $mod+Right focus right 53 | 54 | # _move_ the focused window with the same, but add Shift 55 | bindsym $mod+Shift+Left move left 56 | bindsym $mod+Shift+Down move down 57 | bindsym $mod+Shift+Up move up 58 | bindsym $mod+Shift+Right move right 59 | # 60 | # Workspaces: 61 | # 62 | # switch to workspace 63 | bindsym $mod+1 workspace 1:web 64 | bindsym $mod+2 workspace 2:term 65 | bindsym $mod+3 workspace 3:irc 66 | bindsym $mod+4 workspace 4:code 67 | bindsym $mod+5 workspace 5:media 68 | bindsym $mod+6 workspace 6 69 | bindsym $mod+7 workspace 7 70 | bindsym $mod+8 workspace 8 71 | bindsym $mod+9 workspace 9 72 | bindsym $mod+0 workspace 10 73 | # move focused container to workspace 74 | bindsym $mod+Shift+1 move container to workspace 1:web 75 | bindsym $mod+Shift+2 move container to workspace 2:term 76 | bindsym $mod+Shift+3 move container to workspace 3:irc 77 | bindsym $mod+Shift+4 move container to workspace 4:code 78 | bindsym $mod+Shift+5 move container to workspace 5:media 79 | bindsym $mod+Shift+6 move container to workspace 6 80 | bindsym $mod+Shift+7 move container to workspace 7 81 | bindsym $mod+Shift+8 move container to workspace 8 82 | bindsym $mod+Shift+9 move container to workspace 9 83 | bindsym $mod+Shift+0 move container to workspace 10 84 | # Note: workspaces can have any name you want, not just numbers. 85 | # We just use 1-10 as the default. 86 | # 87 | # Layout stuff: 88 | # 89 | # You can "split" the current object of your focus with 90 | # $mod+b or $mod+v, for horizontal and vertical splits 91 | # respectively. 92 | bindsym $mod+b splith 93 | bindsym $mod+v splitv 94 | 95 | # Switch the current container between different layout styles 96 | bindsym $mod+s layout stacking 97 | bindsym $mod+w layout tabbed 98 | bindsym $mod+e layout toggle split 99 | 100 | # Make the current focus fullscreen 101 | bindsym $mod+f fullscreen 102 | 103 | # Toggle the current focus between tiling and floating mode 104 | bindsym $mod+Shift+space floating toggle 105 | 106 | # Swap focus between the tiling area and the floating area 107 | bindsym $mod+space focus mode_toggle 108 | 109 | # move focus to the parent container 110 | bindsym $mod+a focus parent 111 | # 112 | # Scratchpad: 113 | # 114 | # Sway has a "scratchpad", which is a bag of holding for windows. 115 | # You can send windows there and get them back later. 116 | 117 | # Move the currently focused window to the scratchpad 118 | bindsym $mod+Shift+minus move scratchpad 119 | 120 | # Show the next scratchpad window or hide the focused scratchpad window. 121 | # If there are multiple scratchpad windows, this command cycles through them. 122 | bindsym Print scratchpad show 123 | # 124 | # Resizing containers: 125 | # 126 | mode "resize" { 127 | # left will shrink the containers width 128 | # right will grow the containers width 129 | # up will shrink the containers height 130 | # down will grow the containers height 131 | bindsym Left resize shrink width 10px 132 | bindsym Down resize grow height 10px 133 | bindsym Up resize shrink height 10px 134 | bindsym Right resize grow width 10px 135 | 136 | # return to default mode 137 | bindsym Return mode "default" 138 | bindsym Escape mode "default" 139 | } 140 | bindsym $mod+Shift+R mode "resize" 141 | 142 | -------------------------------------------------------------------------------- /sway/config: -------------------------------------------------------------------------------- 1 | # Read `man 5 sway` for a complete reference. 2 | 3 | ### Variables 4 | # 5 | # Logo key. Use Mod1 for Alt. 6 | set $mod Mod4 7 | 8 | # Your preferred terminal emulator 9 | set $term konsole 10 | 11 | # Your preferred application launcher 12 | # Note: it's recommended that you pass the final command to sway 13 | #set $menu dmenu_path | dmenu | xargs swaymsg exec 14 | #set $menu dmenu_path | dmenu | xargs systemd-run --user 15 | set $menu ~/src/wldash/target/release/wldash 16 | 17 | font DejaVu Sans 10 18 | workspace_layout tabbed 19 | focus_follows_mouse no 20 | 21 | include input 22 | include output 23 | include bindings 24 | include apps 25 | include /etc/sway/config.d/* 26 | 27 | exec "~/.config/sway/keyboard-layout-per-window.py" 28 | exec "systemctl --user import-environment ; systemctl --user start sway-session.target" 29 | -------------------------------------------------------------------------------- /sway/input: -------------------------------------------------------------------------------- 1 | input 1:1:AT_Translated_Set_2_keyboard { 2 | xkb_layout us,mk 3 | xkb_options grp:switch,grp:caps_toggle 4 | } 5 | -------------------------------------------------------------------------------- /sway/keyboard-layout-per-window.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # This script keeps track of active keyboard layouts per window. 4 | # 5 | # This script requires i3ipc-python package (install it from a system package 6 | # manager or pip). 7 | # 8 | # https://github.com/swaywm/sway/pull/4504/files 9 | import i3ipc 10 | 11 | sway = i3ipc.Connection() 12 | prev_focused = sway.get_tree().find_focused().id 13 | windows = {} 14 | 15 | def on_window_focus(ipc, event): 16 | global windows, prev_focused 17 | 18 | # Save current layouts 19 | layouts = {input.identifier: input.xkb_active_layout_index for input in sway.get_inputs()} 20 | windows[prev_focused] = layouts 21 | 22 | # Restore layout of the newly focused window 23 | if event.container.id in windows: 24 | for (input_id, layout_index) in windows[event.container.id].items(): 25 | if layout_index != layouts[input_id]: 26 | sway.command(f'input "{input_id}" xkb_switch_layout {layout_index}') 27 | 28 | prev_focused = event.container.id 29 | 30 | def on_window_close(ipc, event): 31 | global windows 32 | if event.container.id in windows: 33 | del(windows[event.container.id]) 34 | 35 | def on_window(ipc, event): 36 | if event.change == "focus": 37 | on_window_focus(ipc, event) 38 | elif event.change == "close": 39 | on_window_close(ipc, event) 40 | 41 | sway.on("window", on_window) 42 | sway.main() 43 | -------------------------------------------------------------------------------- /sway/output: -------------------------------------------------------------------------------- 1 | ### Output configuration 2 | # 3 | # Default wallpaper (more resolutions are available in /usr/share/backgrounds/sway/) 4 | output * bg /usr/share/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill 5 | # 6 | # Example configuration: 7 | # 8 | # output HDMI-A-1 resolution 1920x1080 position 1920,0 9 | # 10 | # You can get the names of your outputs by running: swaymsg -t get_outputs 11 | 12 | -------------------------------------------------------------------------------- /swayidle/config: -------------------------------------------------------------------------------- 1 | # ~/.config/swayidle/config 2 | before-sleep 'systemctl --user start swaylock' 3 | lock 'systemctl --user start swaylock' 4 | unlock 'swaymsg "output * dpms on"' 5 | after-resume 'swaymsg "output * dpms on"' 6 | timeout 300 'systemctl --user start swaylock' 7 | timeout 600 'swaymsg "output * dpms off"' 8 | resume 'swaymsg "output * dpms on"' 9 | -------------------------------------------------------------------------------- /swaylock/config: -------------------------------------------------------------------------------- 1 | color=222222 2 | -------------------------------------------------------------------------------- /systemd/user/communi.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=communi - modern irc client 3 | PartOf=graphical-session.target 4 | 5 | [Service] 6 | Type=exec 7 | ExecStart=/usr/bin/communi 8 | 9 | [Install] 10 | WantedBy=graphical-session.target 11 | -------------------------------------------------------------------------------- /systemd/user/firefox.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Firefox nightly 3 | PartOf=graphical-session.target 4 | 5 | [Service] 6 | Type=exec 7 | ExecStart=/opt/firefox/firefox 8 | 9 | [Install] 10 | WantedBy=graphical-session.target 11 | -------------------------------------------------------------------------------- /systemd/user/mako.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Lightweight Wayland notification daemon 3 | Documentation=man:mako(1) 4 | PartOf=sway-session.target 5 | After=sway-session.target 6 | 7 | [Service] 8 | Type=dbus 9 | BusName=org.freedesktop.Notifications 10 | ExecCondition=/bin/sh -c '[ -n "$WAYLAND_DISPLAY" ]' 11 | ExecStart=/usr/bin/mako 12 | ExecReload=/usr/bin/makoctl reload 13 | 14 | [Install] 15 | WantedBy=sway-session.target 16 | -------------------------------------------------------------------------------- /systemd/user/nm-applet.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=network monitor and control GUI applet 3 | Documentation=man:nm-applet(1) 4 | PartOf=wayland-session.target 5 | After=wayland-session.target 6 | 7 | # requires nm-applet compiled with -D appindicator=yes 8 | [Service] 9 | Type=dbus 10 | BusName=org.freedesktop.network-manager-applet 11 | ExecStart=/usr/bin/nm-applet --indicator 12 | 13 | [Install] 14 | WantedBy=wayland-session.target 15 | -------------------------------------------------------------------------------- /systemd/user/org.kde.kdeconnect.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Adds communication between KDE and your smartphone 3 | After=graphical-session.target 4 | PartOf=graphical-session.target 5 | 6 | [Service] 7 | Type=dbus 8 | BusName=org.kde.kdeconnect 9 | ExecStart=/usr/lib/kdeconnectd 10 | 11 | [Install] 12 | WantedBy=graphical-session.target 13 | -------------------------------------------------------------------------------- /systemd/user/soulseekqt.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=SoulseekQt 3 | PartOf=graphical-session.target 4 | 5 | [Service] 6 | Type=exec 7 | ExecStart=/usr/bin/soulseekqt 8 | 9 | [Install] 10 | WantedBy=graphical-session.target 11 | -------------------------------------------------------------------------------- /systemd/user/ssh-agent.service: -------------------------------------------------------------------------------- 1 | # ~/.config/systemd/user/ssh-agent.service 2 | [Unit] 3 | Description=SSH key agent 4 | 5 | [Service] 6 | Type=simple 7 | Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket 8 | ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK 9 | 10 | [Install] 11 | WantedBy=default.target 12 | -------------------------------------------------------------------------------- /systemd/user/sway-session.target: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=sway compositor session 3 | Documentation=man:systemd.special(7) 4 | BindsTo=graphical-session.target wayland-session.target 5 | Wants=graphical-session-pre.target 6 | After=graphical-session-pre.target 7 | -------------------------------------------------------------------------------- /systemd/user/sway.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=sway - i3-compatible Wayland compositor 3 | Documentation=man:sway(5) 4 | Before=graphical-session.service 5 | Wants=graphical-session-pre.service 6 | After=graphical-session-pre.service 7 | 8 | [Service] 9 | Type=simple 10 | EnvironmentFile=-%h/.config/sway/env 11 | ExecStart=/usr/bin/sway 12 | Restart=on-failure 13 | RestartSec=1 14 | TimeoutStopSec=10 15 | -------------------------------------------------------------------------------- /systemd/user/swayidle.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Idle manager for Wayland 3 | Documentation=man:swayidle(1) 4 | Documentation=https://github.com/gdamjan/swayidle - fork with sd-notify and autolock 5 | PartOf=graphical-session.target 6 | After=sway-session.target 7 | 8 | [Service] 9 | Type=notify 10 | ExecStart=/usr/bin/swayidle -w 11 | 12 | [Install] 13 | WantedBy=sway-session.target 14 | -------------------------------------------------------------------------------- /systemd/user/swaykbdd.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Keyboard layout per window 3 | PartOf=graphical-session.target 4 | After=sway-session.target 5 | 6 | [Service] 7 | Type=exec 8 | ExecStart=/usr/bin/swaykbdd 9 | 10 | [Install] 11 | WantedBy=sway-session.target 12 | -------------------------------------------------------------------------------- /systemd/user/swaylock.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=swaylock - Screen locker for Wayland 3 | Documentation=man:swaylock(1) 4 | 5 | [Service] 6 | Type=forking 7 | ExecStart=/usr/bin/swaylock -f 8 | Restart=on-failure 9 | 10 | [Install] 11 | WantedBy=sway-session.target 12 | -------------------------------------------------------------------------------- /systemd/user/wayland-session.target: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: LGPL-2.1+ 2 | # 3 | # This file is inspired from systemd's `graphical-session.target` 4 | # 5 | # systemd is free software; you can redistribute it and/or modify it 6 | # under the terms of the GNU Lesser General Public License as published by 7 | # the Free Software Foundation; either version 2.1 of the License, or 8 | # (at your option) any later version. 9 | 10 | [Unit] 11 | Description=Current wayland user session 12 | Documentation=man:systemd.special(7) 13 | Requires=basic.target 14 | RefuseManualStart=yes 15 | StopWhenUnneeded=yes 16 | BindsTo=graphical-session.target 17 | -------------------------------------------------------------------------------- /waybar/config: -------------------------------------------------------------------------------- 1 | { 2 | "layer": "top", 3 | "position": "bottom", 4 | "height": 24, 5 | "modules-left": ["sway/workspaces", "idle_inhibitor", "sway/mode"], 6 | "modules-center": ["sway/window"], 7 | "modules-right": [ "pulseaudio", "backlight", "network", "cpu", "memory", "battery#bat0", "battery#bat1", 8 | "tray", "sway/language", "clock" ], 9 | "sway/workspaces": { 10 | "disable-scroll": true, 11 | "all-outputs": true, 12 | "format": "{index} {name}" 13 | }, 14 | "sway/mode": { 15 | "format": "{}" 16 | }, 17 | "sway/language": { 18 | "format": "{}", 19 | "max-length": 50 20 | }, 21 | "tray": { 22 | // "icon-size": 21, 23 | "spacing": 10 24 | }, 25 | "clock": { 26 | "tooltip-format": "{:%A\n%d %B %Y\n%H:%M}", 27 | "format": "{:%a %d %b %H:%M}", 28 | "format-alt": "{:%H:%M}" 29 | }, 30 | "cpu": { 31 | "format": "{usage:2}% " 32 | }, 33 | "memory": { 34 | "format": "{}% " 35 | }, 36 | "battery#bat0": { 37 | "bat": "BAT0", 38 | "name": "BAT0", 39 | "states": { 40 | "warning": 20, 41 | "critical": 10 42 | }, 43 | "format": "{capacity}% {icon}", 44 | "format-icons": ["", "", "", "", ""] 45 | }, 46 | "battery#bat1": { 47 | "bat": "BAT1", 48 | "name": "BAT1", 49 | "states": { 50 | "warning": 20, 51 | "critical": 10 52 | }, 53 | "format": "{capacity}% {icon}", 54 | "format-icons": ["", "", "", "", ""] 55 | }, 56 | "network": { 57 | "interval": 1, 58 | "max-width": 50, 59 | // "interface": "wlp2s0", // (Optional) To force the use of this interface 60 | "format-wifi": "", 61 | "format-ethernet": "{bandwidthUpBits} {bandwidthDownBits} ", 62 | "format-disconnected": "⚠", 63 | "tooltip-format-wifi": " {essid}: {frequency}Mhz ({signalStrength}%)\n{bandwidthUpBits}\n{bandwidthDownBits}", 64 | "tooltip-format-ethernet": " {ifname}: {ipaddr}/{cidr}", 65 | "tooltip-format-disconnected": "⚠ Disconnected" 66 | }, 67 | "pulseaudio": { 68 | //"scroll-step": 1, 69 | "format": "{volume}% {icon}", 70 | "format-bluetooth": "{volume}% {icon}", 71 | "format-muted": "", 72 | "format-icons": { 73 | "headphones": "", 74 | "handsfree": "", 75 | "headset": "", 76 | "phone": "", 77 | "portable": "", 78 | "car": "", 79 | "default": ["", ""] 80 | }, 81 | "on-click": "pavucontrol" 82 | }, 83 | "backlight": { 84 | "device": "intel_backlight", 85 | "format": "{percent}% {icon}", 86 | "format-icons": ["", ""] 87 | }, 88 | "idle_inhibitor": { 89 | "format": "{icon}", 90 | "format-icons": { 91 | "activated": "", 92 | "deactivated": "" 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /waybar/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | border: none; 3 | border-radius: 0; 4 | font-family: Roboto, Helvetica, Arial, sans-serif; 5 | font-size: 13px; 6 | min-height: 0; 7 | } 8 | 9 | window#waybar { 10 | background-color: rgba(43, 48, 59, 0.5); 11 | border-bottom: 3px solid rgba(100, 114, 125, 0.5); 12 | color: #ffffff; 13 | transition-property: background-color; 14 | transition-duration: .5s; 15 | } 16 | 17 | window#waybar.hidden { 18 | opacity: 0.2; 19 | } 20 | 21 | /* 22 | window#waybar.empty { 23 | background-color: transparent; 24 | } 25 | window#waybar.solo { 26 | background-color: #FFFFFF; 27 | } 28 | */ 29 | 30 | window#waybar.termite { 31 | background-color: #3F3F3F; 32 | } 33 | 34 | window#waybar.chromium { 35 | background-color: #000000; 36 | border: none; 37 | } 38 | 39 | #workspaces button { 40 | padding: 0 5px; 41 | background-color: transparent; 42 | color: #ffffff; 43 | border-bottom: 3px solid transparent; 44 | } 45 | 46 | /* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */ 47 | #workspaces button:hover { 48 | background: rgba(0, 0, 0, 0.2); 49 | box-shadow: inherit; 50 | border-bottom: 3px solid #ffffff; 51 | } 52 | 53 | #workspaces button.focused { 54 | background-color: #64727D; 55 | border-bottom: 3px solid #ffffff; 56 | } 57 | 58 | #workspaces button.urgent { 59 | background-color: #eb4d4b; 60 | } 61 | 62 | #mode { 63 | background-color: #64727D; 64 | border-bottom: 3px solid #ffffff; 65 | } 66 | 67 | #cpu, 68 | #memory, 69 | #temperature, 70 | #backlight, 71 | #network, 72 | #pulseaudio, 73 | #custom-media, 74 | #tray, 75 | #mode, 76 | #idle_inhibitor { 77 | padding: 0 10px; 78 | margin: 0 4px; 79 | color: #ffffff; 80 | } 81 | 82 | #clock { 83 | padding: 0 10px; 84 | color: #ffffff; 85 | background-color: #64727D; 86 | } 87 | 88 | #battery .BAT0 { 89 | margin-left: 9px; 90 | } 91 | #battery .BAT1 { 92 | margin-right: 9px; 93 | } 94 | #battery { 95 | padding: 0 10px; 96 | background-color: #ffffff; 97 | color: #000000; 98 | } 99 | 100 | #battery.charging { 101 | color: #ffffff; 102 | background-color: #26A65B; 103 | } 104 | 105 | @keyframes blink { 106 | to { 107 | background-color: #ffffff; 108 | color: #000000; 109 | } 110 | } 111 | 112 | #battery.critical:not(.charging) { 113 | background-color: #f53c3c; 114 | color: #ffffff; 115 | animation-name: blink; 116 | animation-duration: 0.5s; 117 | animation-timing-function: linear; 118 | animation-iteration-count: infinite; 119 | animation-direction: alternate; 120 | } 121 | 122 | label:focus { 123 | background-color: #000000; 124 | } 125 | 126 | #cpu { 127 | background-color: #2ecc71; 128 | color: #000000; 129 | } 130 | 131 | #memory { 132 | background-color: #9b59b6; 133 | } 134 | 135 | #backlight { 136 | background-color: #90b1b1; 137 | } 138 | 139 | #network { 140 | background-color: #2980b9; 141 | } 142 | 143 | #network.disconnected { 144 | background-color: #f53c3c; 145 | } 146 | 147 | #pulseaudio { 148 | background-color: #f1c40f; 149 | color: #000000; 150 | } 151 | 152 | #pulseaudio.muted { 153 | background-color: #90b1b1; 154 | color: #2a5c45; 155 | } 156 | 157 | #custom-media { 158 | background-color: #66cc99; 159 | color: #2a5c45; 160 | min-width: 100px; 161 | } 162 | 163 | #custom-media.custom-spotify { 164 | background-color: #66cc99; 165 | } 166 | 167 | #custom-media.custom-vlc { 168 | background-color: #ffa000; 169 | } 170 | 171 | #temperature { 172 | background-color: #f0932b; 173 | } 174 | 175 | #temperature.critical { 176 | background-color: #eb4d4b; 177 | } 178 | 179 | #tray { 180 | background-color: #2980b9; 181 | } 182 | 183 | #idle_inhibitor { 184 | background-color: #2d3436; 185 | } 186 | 187 | #idle_inhibitor.activated { 188 | background-color: #ecf0f1; 189 | color: #2d3436; 190 | } 191 | 192 | #mpd { 193 | background-color: #66cc99; 194 | color: #2a5c45; 195 | } 196 | 197 | #mpd.disconnected { 198 | background-color: #f53c3c; 199 | } 200 | 201 | #mpd.stopped { 202 | background-color: #90b1b1; 203 | } 204 | 205 | #mpd.paused { 206 | background-color: #51a37a; 207 | } 208 | #custom-layout { 209 | background-color: #ecf0f1; 210 | color: #2d3436; 211 | min-width: 2em; 212 | } 213 | 214 | --------------------------------------------------------------------------------