diff --git a/hyprland/hooks/networkmanager.sh b/hyprland/hooks/networkmanager.sh index e217670..1e30627 100755 --- a/hyprland/hooks/networkmanager.sh +++ b/hyprland/hooks/networkmanager.sh @@ -24,7 +24,7 @@ network_print() { signal=$(nmcli -t -f in-use,signal device wifi list ifname "$device" | grep "\*" | cut -d ':' -f 2) if [ "$signal" -lt 40 ]; then - description="$description - %{F#f9cc18}$signal%%{F-}" + description="$description - $signal" fi elif [ "$type" = "802-3-ethernet" ]; then icon="" @@ -53,9 +53,9 @@ network_print() { fi if [ $counter -gt 0 ]; then - printf " %s %s" "$icon" "$description" + printf "%s %s" "$icon" "$description" else - printf "%s %s" "$icon" "$description" + printf "%s %s" "$icon" "$description" fi counter=$((counter + 1)) diff --git a/hyprland/hyprland.conf b/hyprland/hyprland.conf index 4143a56..6becb34 100644 --- a/hyprland/hyprland.conf +++ b/hyprland/hyprland.conf @@ -14,19 +14,23 @@ exec-once = dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CUR # Execute your favorite apps at launch # exec-once = waybar & hyprpaper & firefox +exec-once = battery_status & exec-once = swayidle & exec-once = xiccd & exec-once = dunst & exec-once = ibus-daemon -drxR & exec-once = sleep 3 && kanshi & -exec-once = bash ~/.config/hypr/scripts/launch_waybar.sh +exec-once = bash ~/.config/hypr/scripts/launch_waybar.sh & exec-once = easyeffects --gapplication-service & exec-once = lxqt-policykit-agent & exec-once = thunar --daemon & +exec-once = copyq --start-server -exec-once = env QT_QPA_PLATFORM=xcb /usr/lib/kdeconnectd -exec-once = env QT_QPA_PLATFORM=xcb kdeconnect-indicator +exec-once = env QT_QPA_PLATFORM=xcb /usr/lib/kdeconnectd & +exec-once = env QT_QPA_PLATFORM=xcb kdeconnect-indicator & + +monitor = eDP-1,pref,auto,auto # On reload: exec = pkill -1 kanshi @@ -114,7 +118,7 @@ device:epic-mouse-v1 { sensitivity = -0.5 } -misc { +misc { focus_on_activate = true } @@ -124,6 +128,12 @@ misc { # windowrulev2 = float,class:^(kitty)$,title:^(kitty)$ # See https://wiki.hyprland.org/Configuring/Window-Rules/ for more +windowrulev2 = float,class:^(thunderbird)$,title:.*Reminders? + +windowrulev2 = workspace, 4,title:^(Spotify)$ +windowrulev2 = workspace, 4,class:^(org.keepassxc.KeepassXC)$ +windowrulev2 = workspace, 5,title:^(Discord).*$ +windowrulev2 = workspace, 8,class:^(thunderbird)$ # See https://wiki.hyprland.org/Configuring/Keywords/ for more $mainMod = SUPER @@ -132,6 +142,7 @@ $mainMod = SUPER # bind = $mainMod, Q, exec, kitty bind = $mainMod SHIFT, Q, killactive, bind = $mainMod, RETURN, exec, alacritty +bind = $mainMod, E, exec, thunar bind = $mainMod CONTROL, L, exec, loginctl lock-session self bindr = $mainMod, D, exec, dunstctl context bind = $mainMod, F, fullscreen @@ -141,7 +152,7 @@ binde = , XF86AudioRaiseVolume, exec, pactl set-sink-volume @DEFAULT_SINK@ +100 binde = , XF86AudioLowerVolume, exec, pactl set-sink-volume @DEFAULT_SINK@ -100 binde = SHIFT, XF86AudioRaiseVolume, exec, pactl set-sink-volume @DEFAULT_SINK@ +1000 binde = SHIFT, XF86AudioLowerVolume, exec, pactl set-sink-volume @DEFAULT_SINK@ -1000 -bind = , XF86AudioMute, exec, pactl set-sink-mute @DEFAULT_SINK@ toggle +bindr = , XF86AudioMute, exec, pactl set-sink-mute @DEFAULT_SINK@ toggle # Microphone control bind = , XF86AudioMicMute, exec, pactl set-source-mute @DEFAULT_SOURCE@ toggle @@ -152,7 +163,6 @@ binde = , XF86MonBrightnessUp, exec, brightnessctl s +2% binde = , XF86MonBrightnessDown, exec, brightnessctl s 2%- binde = SHIFT , XF86MonBrightnessUp, exec, brightnessctl s +10% binde = SHIFT , XF86MonBrightnessDown, exec, brightnessctl s 10%- -bind = , XF86AudioMute, exec, pactl set-sink-mute @DEFAULT_SINK@ toggle # Flameshot bindr = CONTROL SHIFT, Print, exec, ~/.config/hypr/scripts/screenshot.sh @@ -170,7 +180,7 @@ bind = ALT, SPACE, exec, rofi -show drun bind = $mainMod, TAB, exec, rofi -show window bind = $mainMod SHIFT, N, exec, networkmanager_dmenu --rofi -i bind = $mainMod SHIFT, B, exec, rofi-bluetooth -bind = $mainMod , E, exec, rofimoji --typer wtype +bind = $mainMod SHIFT , E, exec, rofimoji --typer wtype bind = $mainMod CONTROL, SPACE, togglefloating, bind = $mainMod, SPACE, layoutmsg, orientationnext @@ -214,8 +224,8 @@ bind = $mainMod SHIFT, 9, movetoworkspace, 9 bind = $mainMod SHIFT, 0, movetoworkspace, 10 # Scroll through existing workspaces with mainMod + scroll -bind = $mainMod, mouse_down, workspace, e+1 -bind = $mainMod, mouse_up, workspace, e-1 +bind = $mainMod, mouse_down, workspace, m+1 +bind = $mainMod, mouse_up, workspace, m-1 # Move/resize windows with mainMod + LMB/RMB and dragging bindm = $mainMod, mouse:272, movewindow diff --git a/hyprland/scripts/launch_waybar.sh b/hyprland/scripts/launch_waybar.sh index 9b8b984..6a30636 100755 --- a/hyprland/scripts/launch_waybar.sh +++ b/hyprland/scripts/launch_waybar.sh @@ -3,9 +3,16 @@ getDisplay () { local DESK + # DOCK DESK="$(~/.config/hypr/scripts/displaybyname.sh Samsung Electric Company S34J55x H4LT100404)" - [[ -n "$DESK" ]] && echo $DESK && return + # FSI + DESK="$(~/.config/hypr/scripts/displaybyname.sh LG Electronics 24EB23 609NTFAF4483)" + [[ -n "$DESK" ]] && echo $DESK && return + # Technofabrik + DESK="$(~/.config/hypr/scripts/displaybyname.sh Dell Inc. DELL U2713HM GK0KD27S476L)" + [[ -n "$DESK" ]] && echo $DESK && return + # Fallback echo "eDP-1" } @@ -17,4 +24,4 @@ export PRIMARY_DISPLAY envsubst < ~/.config/waybar/config > /tmp/waybar pkill waybar -waybar -c /tmp/waybar &! +waybar -c /tmp/waybar $@ &! diff --git a/hyprland/scripts/workspaces.sh b/hyprland/scripts/workspaces.sh new file mode 100755 index 0000000..b81572e --- /dev/null +++ b/hyprland/scripts/workspaces.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +mapfile -t MONITORS < <(hyprctl monitors -j | yq -r '. | sort_by(.x) | .[].name') +mapfile -t WORKSPACES < <(hyprctl workspaces -j | yq -r '.[].name') + +function docked() { + + if [ ! ${#MONITORS[@]} -eq 3 ]; then + echo "Not the right amount of displays" + exit 1 + fi + + echo "Assume Docked at home." + for i in "${!WORKSPACES[@]}"; do + # Move the workspace to the correct monitor + w=${WORKSPACES[$i]} + case $w in + 4|8|9) + hyprctl dispatch moveworkspacetomonitor "${w} ${MONITORS[0]}" + ;; + 5|6) + hyprctl dispatch moveworkspacetomonitor "${w} ${MONITORS[2]}" + ;; + *) + hyprctl dispatch moveworkspacetomonitor "${w} ${MONITORS[1]}" + ;; + esac + done +} + +if [ "$1" = "docked" ]; then + docked +fi diff --git a/kanshi/config.d/10-dock b/kanshi/config.d/10-dock index 8f2d56e..c69b2a0 100644 --- a/kanshi/config.d/10-dock +++ b/kanshi/config.d/10-dock @@ -8,4 +8,17 @@ profile Dock { exec systemctl --user start gammastep.service exec rfkill block wifi exec bash ~/.config/hypr/scripts/launch_waybar.sh + exec bash ~/.config/hypr/scripts/workspaces.sh docked +} + +profile Dock-Fallback { + output "BNQ BenQ GL2450H ACB00126019" enable mode 1920x1080 position 0,0 transform 270 scale 1 + output "BNQ BenQ GL2450H X4F00171019" enable mode 1920x1080 position 4520,0 transform normal scale 1 + output "Samsung Electric Company S34J55x H4LT100404" enable mode 3440x1440 position 1080,0 transform normal scale 1 + exec ~/.config/hypr/scripts/transformbyname.sh "BNQ BenQ GL2450H ACB00126019" 1 + exec ~/.config/hypr/scripts/transformbyname.sh "BNQ BenQ GL2450H X4F00171019" 3 + exec systemctl --user start gammastep.service + exec rfkill block wifi + exec bash ~/.config/hypr/scripts/launch_waybar.sh + exec bash ~/.config/hypr/scripts/workspaces.sh docked } diff --git a/waybar/config b/waybar/config index b8fd361..4b6a5c3 100644 --- a/waybar/config +++ b/waybar/config @@ -7,11 +7,13 @@ "spacing": 4, // Gaps between modules (4px) "output": "${PRIMARY_DISPLAY}", // Choose the order of the modules - "modules-left": ["wlr/workspaces", "hyprland/window"], + "modules-left": ["hyprland/workspaces", "hyprland/window"], "modules-center": ["custom/inhibit", "idle_inhibitor", "custom/dunst"], "modules-right": ["hyprland/submap", "custom/wifionice", "custom/spotify", "pulseaudio", "custom/network", "cpu", "memory", "temperature", "backlight", "battery", "clock", "tray"], // Modules configuration - "wlr/workspaces": { + "hyprland/workspaces": { + "format-alt": "{name}", + "format-alt-click": "click-middle", "disable-scroll": false, "sort-by-number": true, "all-outputs": true, @@ -28,24 +30,24 @@ "default": "" } }, - "keyboard-state": { - "numlock": true, - "capslock": true, - "format": "{name} {icon}", - "format-icons": { - "locked": "", - "unlocked": "" - } - }, "custom/spotify": { + "format-alt": "{status_icon} {title}", + "format-alt-click": "click-middle", "exec": "/usr/bin/python3 ~/.config/waybar/scripts/mediaplayer.py --player spotify", - "format": "{} ", + "format": "{status_icon} {artist} - {title}", "return-type": "json", "escape": true, "on-click": "playerctl play-pause", "on-scroll-up": "playerctl next", "on-scroll-down": "playerctl previous" }, + "custom/debug": { + "format": "{}", + "exec": "~/test.sh", + "return-type": "json", + "escape": true, + "interval": 3 + }, "custom/inhibit": { "format": "☕", "on-click": "systemd-inhibit --what=handle-lid-switch --who=waybar --why='Inhibiting suspend' --mode=block sleep 120 & notify-send 'Inhibiting suspend' 'Waybar will prevent the system from suspending for 2 minutes'" @@ -59,6 +61,8 @@ "restart-interval": 1 }, "custom/wifionice": { + "format-alt": "{:.2}", // only show train :D + "format-alt-click": "click-middle", "exec": "~/.config/waybar/scripts/wifionice.sh", "escape": true }, @@ -112,9 +116,6 @@ // "format-full": "", "format-icons": ["", "", "", "", ""] }, - "battery#bat2": { - "bat": "BAT2" - }, "custom/network": { "format": "{}", "max-length": 40, @@ -127,30 +128,19 @@ "format-bluetooth": "{volume}% {icon} {format_source}", "format-bluetooth-muted": " {icon} {format_source}", "format-muted": " {format_source}", - "format-source": "{volume}% ", + "format-source": "", "format-source-muted": "", + "ignored-sinks": [ "Easy Effects Sink" ], "format-icons": { "headphone": "", "hands-free": "", - "headset": "", + "headset": "", "phone": "", "portable": "", "car": "", "default": ["", "", ""] }, "on-click": "pavucontrol" - }, - "custom/media": { - "format": "{icon} {}", - "return-type": "json", - "max-length": 40, - "format-icons": { - "spotify": "", - "default": "🎜" - }, - "escape": true, - "exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder - // "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name } } diff --git a/waybar/scripts/dunst.sh b/waybar/scripts/dunst.sh index d2ce884..804f04d 100755 --- a/waybar/scripts/dunst.sh +++ b/waybar/scripts/dunst.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -euo pipefail -readonly ENABLED=' ' -readonly DISABLED=' ' +readonly ENABLED='' +readonly DISABLED='\uf1f6' # nf-fa-bell_slash dbus-monitor path='/org/freedesktop/Notifications',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged' --profile | while read -r _; do PAUSED="$(dunstctl is-paused)" diff --git a/waybar/scripts/mediaplayer.py b/waybar/scripts/mediaplayer.py index 51a4837..b21afd2 100644 --- a/waybar/scripts/mediaplayer.py +++ b/waybar/scripts/mediaplayer.py @@ -61,16 +61,6 @@ class PlayerManager: def get_players(self) -> List[Player]: return self.manager.props.players - def write_output(self, text, player): - logger.debug(f"Writing output: {text}") - - output = {"text": text, - "class": "custom-" + player.props.player_name, - "alt": player.props.player_name} - - sys.stdout.write(json.dumps(output) + "\n") - sys.stdout.flush() - def clear_output(self): sys.stdout.write("\n") sys.stdout.flush() @@ -102,32 +92,29 @@ class PlayerManager: current_player = self.get_first_playing_player() if current_player is not None: self.on_metadata_changed(current_player, current_player.props.metadata) - else: + else: self.clear_output() def on_metadata_changed(self, player, metadata, _=None): logger.debug(f"Metadata changed for player {player.props.player_name}") - player_name = player.props.player_name - artist = player.get_artist() - title = player.get_title() - - track_info = "" - if player_name == "spotify" and "mpris:trackid" in metadata.keys() and ":ad:" in player.props.metadata["mpris:trackid"]: - track_info = "Advertisement" - elif artist is not None and title is not None: - track_info = f"{artist} - {title}" - else: - track_info = title - - if track_info: - if player.props.status == "Playing": - track_info = " " + track_info - else: - track_info = " " + track_info + data = { + "player_name": player.props.player_name, + "player_icon": "" if player.props.player_name == "spotify" else "", + "artist": player.get_artist(), + "title": player.get_title(), + "status": player.props.status, + "status_icon": "" if player.props.status == "Paused" else "", + "class": [ + player.props.player_name.lower(), + player.props.status.lower() + ], + "text": f"{player.get_artist()} - {player.get_title()}", + } # only print output if no other player is playing current_playing = self.get_first_playing_player() if current_playing is None or current_playing.props.player_name == player.props.player_name: - self.write_output(track_info, player) + sys.stdout.write(json.dumps(data) + "\n") + sys.stdout.flush() else: logger.debug(f"Other player {current_playing.props.player_name} is playing, skipping") diff --git a/waybar/style.css b/waybar/style.css index ad1e295..2020ebb 100644 --- a/waybar/style.css +++ b/waybar/style.css @@ -19,15 +19,6 @@ window#waybar.hidden { opacity: 0.2; } -/* -window#waybar.empty { - background-color: transparent; -} -window#waybar.solo { - background-color: #FFFFFF; -} -*/ - window#waybar.termite { background-color: #3F3F3F; } @@ -54,19 +45,16 @@ button:hover { #workspaces button { padding: 0 5px; background-color: transparent; - color: #ffffff; + color: @text; } #submap { padding: 0 10px; margin: 0 4px; background-color: @peach; - color: black; + color: @base; } -#dunst { - -} #workspaces button:hover { background: alpha(@overlay0, 0.2); @@ -107,7 +95,7 @@ button:hover { #scratchpad, #mpd { padding: 0 10px; - color: #ffffff; + color: @text; border-bottom: 3px solid alpha(@crust, 0.5); } #window, @@ -125,30 +113,39 @@ button:hover { margin-right: 0; } -#clock { - background-color: #64727D; +.modules-center { + background-color: @surface0; +} + +#memory, +#clock, +#memory, +#disk, +#idle_inhibitor.activated { + background-color: @lavender; + color: @base; } #battery { background-color: @yellow; - color: black; + color: @base; } #battery.charging, #battery.plugged { - color: black; + color: @base; background-color: @green; } @keyframes blink { to { background-color: @yellow; - color: black; + color: @base; } } #battery.critical:not(.charging) { background-color: @red; - color: black; + color: @base; animation-name: blink; animation-duration: 0.5s; animation-timing-function: linear; @@ -158,25 +155,18 @@ button:hover { #custom-wifionice { background-color: @red; - color: black; + color: @base; } label:focus { - background-color: black; + background-color: @base; } #cpu { background-color: @green; - color: black; + color: @base; } -#memory { - background-color: @lavender; -} - -#disk { - background-color: @lavender; -} #backlight { background-color: @overlay1; @@ -184,7 +174,7 @@ label:focus { #custom-network { background-color: @sky; - color: black; + color: @base; } #network.disconnected { @@ -193,12 +183,13 @@ label:focus { #pulseaudio { background-color: @yellow; - color: black; + color: @base; } -#pulseaudio.muted { - background-color: @overlay2; - color: @text; +#custom-dunst.disabled, +#pulseaudio.source-muted { + background-color: @red; + color: @base; } #custom-media { @@ -208,15 +199,13 @@ label:focus { } #custom-spotify { - padding: 0 10px; - margin: 0 4px; background-color: @green; - color: black; + color: @base; } #temperature { background-color: @peach; - color: black; + color: @base; } #temperature.critical { @@ -235,12 +224,3 @@ label:focus { -gtk-icon-effect: highlight; background-color: @red; } - -#idle_inhibitor { - background-color: @base; -} - -#idle_inhibitor.activated { - background-color: @lavender; - color: #2d3436; -}