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",
"height": 34,
"modules-left": ["hyprland/workspaces", "hyprland/window"],
"modules-right": [
"idle_inhibitor",
"pulseaudio",
@@ -10,13 +12,24 @@
"memory",
"temperature",
"battery",
"custom/hyprscroll_overflow",
"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": {
"format": "{icon}",
"format-icons": { "activated": "  ", "deactivated": " 󰒲 " }
"format-icons": {
"activated": "  ",
"deactivated": " 󰒲 ",
},
},
"pulseaudio": {
@@ -27,10 +40,10 @@
"headphones": "",
"headset": "",
"phone": "",
"portab le": "",
"default": ["", ""]
"portable": "",
"default": ["", ""],
},
"on-click": "pavucontrol"
"on-click": "pavucontrol",
},
"network": {
@@ -39,24 +52,43 @@
"format-disconnected": "Disconnected ⚠",
"tooltip-format-wifi": "{essid} ({signalStrength}%)",
"tooltip-format-ethernet": "{ifname}: {ipaddr}/{cidr}",
"on-click": "impala"
"on-click": "impala",
},
"cpu": { "format": "{usage}%  ", "tooltip": false },
"memory": { "format": "{percentage}% " },
"cpu": {
"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": {
"bat": "BAT0",
"states": { "good": 95, "warning": 30, "critical": 15 },
"states": {
"good": 95,
"warning": 30,
"critical": 15,
},
"format": "{capacity}% {icon}",
"format-charging": "{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-size: 13px;
font-family:
Aporetic Sans Mono,
Iosevka Nerd Font,
Roboto,
Helvetica,
Arial,
sans-serif;
font-size: 13px;
}
window#waybar {
@@ -8,26 +14,26 @@ window#waybar {
color: @text;
transition-property: background-color;
border-bottom: 0px solid rgba(0, 0, 0, 0);
transition-duration: .5s;
transition-duration: 0.5s;
}
#workspaces button {
padding: 0 5px;
background-color: transparent;
border: none;
border-radius: 0;
color: @text;
padding: 0 5px;
background-color: transparent;
border: none;
border-radius: 0;
color: @text;
}
#workspaces button:hover {
background: @surface1;
color: @text;
background: @surface1;
color: @text;
}
#workspaces button.active {
background-color: @green;
color: @base;
box-shadow: inset 0 -3px @subtext1;
background-color: @green;
color: @base;
box-shadow: inset 0 -3px @subtext1;
}
#clock,
@@ -39,16 +45,16 @@ box-shadow: inset 0 -3px @subtext1;
#network,
#pulseaudio,
#tray {
margin: 0 5px;
padding: 0 2px;
margin: 0 5px;
padding: 0 2px;
}
#idle_inhibitor.activated {
background-color: @green;
background-color: @green;
}
#battery.charging {
color: @green;
color: @green;
}
@keyframes blink {
@@ -59,17 +65,17 @@ color: @green;
}
#battery.warning:not(.charging) {
color: white;
animation-name: blink;
animation-duration: 0.5s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-direction: alternate;
color: white;
animation-name: blink;
animation-duration: 0.5s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-direction: alternate;
}
#window,
#workspaces {
margin: 0 4px;
margin: 0 4px;
}
.modules-left > widget:first-child > #workspaces {
@@ -81,9 +87,13 @@ margin: 0 4px;
}
#network.disconnected {
background-color: @red;
background-color: @red;
}
#temperature.critical {
background-color: @red;
background-color: @red;
}
#custom-hyprscroll_overflow.overflow {
font-weight: bold;
}