Added indictaor for hyprscroll

This commit is contained in:
2026-02-26 14:32:39 +01:00
parent f324231ba8
commit 03d4263033
3 changed files with 125 additions and 40 deletions
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
set -euo pipefail
# Estimate how many "columns" fit on the focused monitor:
# max_visible_cols ≈ floor(1 / column_width)
# Then compare with number of windows in the active workspace on that monitor.
#
# Notes:
# - This is an approximation (hyprscrolling can have edge cases), but works well in practice.
# - If you use different column_width per monitor, you can extend this by detecting monitor + mapping widths.
COLUMN_WIDTH="${COLUMN_WIDTH:-0.5}" # match your hyprscrolling config
ICON="${ICON:-󰓒}" # pick any nerd-font icon you like
active_ws="$(hyprctl -j activeworkspace | jq -r '.id')"
focused_mon="$(hyprctl -j monitors | jq -r '.[] | select(.focused==true) | .name')"
# Count windows on the active workspace (and on the focused monitor).
# (Many people keep workspaces per-monitor; this keeps the widget “per your current screen”.)
win_count="$(hyprctl -j clients \
| jq --argjson ws "$active_ws" --arg mon "$focused_mon" '
[ .[]
| select(.workspace.id == $ws)
| select(.monitor == $mon)
| select(.mapped == true)
] | length
')"
# floor(1 / COLUMN_WIDTH) using awk (portable)
max_visible="$(awk -v w="$COLUMN_WIDTH" 'BEGIN{ if (w<=0) {print 1} else {print int(1.0/w)} }')"
if [ "$max_visible" -lt 1 ]; then max_visible=1; fi
overflow=$(( win_count - max_visible ))
if [ "$overflow" -gt 0 ]; then
# Waybar expects JSON for custom modules
printf '{"text":"%s +%d","tooltip":"%d windows on this workspace, approx %d fit on-screen (column_width=%s)","class":"overflow"}\n' \
"$ICON" "$overflow" "$win_count" "$max_visible" "$COLUMN_WIDTH"
else
# empty output hides it if you use "return-type: json" + "format": "{}"
printf '{"text":"","tooltip":"%d windows, approx %d fit on-screen","class":"ok"}\n' \
"$win_count" "$max_visible"
fi
@@ -1,7 +1,9 @@
{ {
"layer": "top", "layer": "top",
"height": 34, "height": 34,
"modules-left": ["hyprland/workspaces", "hyprland/window"], "modules-left": ["hyprland/workspaces", "hyprland/window"],
"modules-right": [ "modules-right": [
"idle_inhibitor", "idle_inhibitor",
"pulseaudio", "pulseaudio",
@@ -10,13 +12,24 @@
"memory", "memory",
"temperature", "temperature",
"battery", "battery",
"custom/hyprscroll_overflow",
"tray", "tray",
"clock" "clock",
], ],
"custom/hyprscroll_overflow": {
"exec": "COLUMN_WIDTH=0.5 ~/.config/hypr/scripts/hyprscroll-overflow.sh",
"return-type": "json",
"interval": 1,
"format": "{}",
},
"idle_inhibitor": { "idle_inhibitor": {
"format": "{icon}", "format": "{icon}",
"format-icons": { "activated": "  ", "deactivated": " 󰒲 " } "format-icons": {
"activated": "  ",
"deactivated": " 󰒲 ",
},
}, },
"pulseaudio": { "pulseaudio": {
@@ -27,10 +40,10 @@
"headphones": "", "headphones": "",
"headset": "", "headset": "",
"phone": "", "phone": "",
"portab le": "", "portable": "",
"default": ["", ""] "default": ["", ""],
}, },
"on-click": "pavucontrol" "on-click": "pavucontrol",
}, },
"network": { "network": {
@@ -39,24 +52,43 @@
"format-disconnected": "Disconnected ⚠", "format-disconnected": "Disconnected ⚠",
"tooltip-format-wifi": "{essid} ({signalStrength}%)", "tooltip-format-wifi": "{essid} ({signalStrength}%)",
"tooltip-format-ethernet": "{ifname}: {ipaddr}/{cidr}", "tooltip-format-ethernet": "{ifname}: {ipaddr}/{cidr}",
"on-click": "impala" "on-click": "impala",
}, },
"cpu": { "format": "{usage}%  ", "tooltip": false }, "cpu": {
"memory": { "format": "{percentage}% " }, "format": "{usage}% ",
"tooltip": false,
},
"temperature": { "format": "{temperatureC}°C ", "tooltip": false }, "memory": {
"format": "{percentage}%  ",
},
"tray": { "spacing": 10, "icon-size": 14 }, "temperature": {
"format": "{temperatureC}°C ",
"tooltip": false,
},
"clock": { "format": "{:%a, %d %b %Y - %H:%M}", "tooltip": false }, "tray": {
"spacing": 10,
"icon-size": 14,
},
"clock": {
"format": "{:%a, %d %b %Y - %H:%M}",
"tooltip": false,
},
"battery": { "battery": {
"bat": "BAT0", "bat": "BAT0",
"states": { "good": 95, "warning": 30, "critical": 15 }, "states": {
"good": 95,
"warning": 30,
"critical": 15,
},
"format": "{capacity}% {icon}", "format": "{capacity}% {icon}",
"format-charging": "{capacity}% 󰂄", "format-charging": "{capacity}% 󰂄",
"format-plugged": "{capacity}%  ", "format-plugged": "{capacity}%  ",
"format-icons": ["󰁺", "󰁼", "󰁾", "󰂀", "󱈏 "] "format-icons": ["󰁺", "󰁼", "󰁾", "󰂀", "󱈏 "],
} },
} }
@@ -1,6 +1,12 @@
* { * {
font-family: Aporetic Sans Mono, Iosevka Nerd Font, Roboto, Helvetica, Arial, sans-serif; font-family:
font-size: 13px; Aporetic Sans Mono,
Iosevka Nerd Font,
Roboto,
Helvetica,
Arial,
sans-serif;
font-size: 13px;
} }
window#waybar { window#waybar {
@@ -8,26 +14,26 @@ window#waybar {
color: @text; color: @text;
transition-property: background-color; transition-property: background-color;
border-bottom: 0px solid rgba(0, 0, 0, 0); border-bottom: 0px solid rgba(0, 0, 0, 0);
transition-duration: .5s; transition-duration: 0.5s;
} }
#workspaces button { #workspaces button {
padding: 0 5px; padding: 0 5px;
background-color: transparent; background-color: transparent;
border: none; border: none;
border-radius: 0; border-radius: 0;
color: @text; color: @text;
} }
#workspaces button:hover { #workspaces button:hover {
background: @surface1; background: @surface1;
color: @text; color: @text;
} }
#workspaces button.active { #workspaces button.active {
background-color: @green; background-color: @green;
color: @base; color: @base;
box-shadow: inset 0 -3px @subtext1; box-shadow: inset 0 -3px @subtext1;
} }
#clock, #clock,
@@ -39,16 +45,16 @@ box-shadow: inset 0 -3px @subtext1;
#network, #network,
#pulseaudio, #pulseaudio,
#tray { #tray {
margin: 0 5px; margin: 0 5px;
padding: 0 2px; padding: 0 2px;
} }
#idle_inhibitor.activated { #idle_inhibitor.activated {
background-color: @green; background-color: @green;
} }
#battery.charging { #battery.charging {
color: @green; color: @green;
} }
@keyframes blink { @keyframes blink {
@@ -59,17 +65,17 @@ color: @green;
} }
#battery.warning:not(.charging) { #battery.warning:not(.charging) {
color: white; color: white;
animation-name: blink; animation-name: blink;
animation-duration: 0.5s; animation-duration: 0.5s;
animation-timing-function: linear; animation-timing-function: linear;
animation-iteration-count: infinite; animation-iteration-count: infinite;
animation-direction: alternate; animation-direction: alternate;
} }
#window, #window,
#workspaces { #workspaces {
margin: 0 4px; margin: 0 4px;
} }
.modules-left > widget:first-child > #workspaces { .modules-left > widget:first-child > #workspaces {
@@ -81,9 +87,13 @@ margin: 0 4px;
} }
#network.disconnected { #network.disconnected {
background-color: @red; background-color: @red;
} }
#temperature.critical { #temperature.critical {
background-color: @red; background-color: @red;
}
#custom-hyprscroll_overflow.overflow {
font-weight: bold;
} }