Hyprland 0.54 replaced the text-based dispatch socket protocol with a
Lua-based one. Commands like "dispatch workspace 1" are now interpreted
as invalid Lua (return hl.dispatch(workspace 1)), breaking workspace
clicks and scroll navigation.
Add IPC::dispatch() that probes the running Hyprland on first call and
routes commands through the new hl.dsp Lua API when the Lua protocol is
detected, falling back to the old text format otherwise.
Only delete the corresponding address type (IPv4 or IPv6) when an event
about a specific type (AF_INET or AF_INET6) is received
This fixes situations where only one type of the address is deleted (and
possibly added again) but Waybar still thinks the interface is in
"linked" (no IP) state.
When netlink events (link/addr/route changes) fire between timer
intervals, dp.emit() triggers update() which consumes the byte delta
and resets bandwidth_down_total_. A subsequent timer update sees
near-zero delta, displaying very small bandwidth.
Cache the last computed bandwidth values and skip recalculation
when update() is called within half the interval. Event-driven
updates reuse the cached values instead.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This allows users to use #RRGGBBAA format in their style.css.
The client now detects 8-bit hex codes, transforms them into
GTK-compatible rgba() syntax, and loads the modified data
into the CSS provider.
- Added utility to detect 8-bit hex patterns.
- Added transformation logic to convert hex alpha to decimal.
- Intercepted CSS loading in Client::setupCss to handle the conversion.
When an interface is not specified for the network module, we parse the
routing table to look for default routes.
We have defined a default route to:
- have a gateway specified, and
- have no destination specified, or have an all-zero destination.
Previous versions of Waybar had the second condition inverted,
causing it to incorrectly pick interfaces are used to route a
subnet/single host.
For example, with the following routing table, we should pick `eth0` to
show information about, not `wg0`.
```
ip -4 route
default via 192.168.252.1 dev eth0 proto dhcp src 192.168.252.200 metric 100
192.168.252.0/24 dev eth0 proto kernel scope link src 192.168.252.200 metric 100
192.168.2.254 via 192.168.1.1 dev wg0 proto static metric 50
192.168.1.0/24 dev wg0 proto static scope link metric 50
192.168.1.0/24 dev wg0 proto kernel scope link src 192.168.1.254 metric 50
```
These Nerdfonts codepoints were removed in [3.0.0](https://www.nerdfonts.com/releases#v3.0.0):
> **Breaking 2: Material Design Icons Codepoints**
>
> The old Material Design Icon codepoints are finally dropped. Due to an historic mistake we placed them in between some asiatic glyphs, breaking that script. Since v2.3.0 the (updated and expanded) Material Design Icons have new codepoints in the 5 digit region.
>
> - Dropped codepoints `F500`… and class names `nf-mdi-*`
> - New codepoints `F0001`… and class names `nf-md-*`
> - The whole discussions are here: https://github.com/ryanoasis/nerd-fonts/issues/365
> - A translation table is available here: https://github.com/ryanoasis/nerd-fonts/issues/1059#issuecomment-1404891287
> - There are tools out there that probably can update your configuration.
For the majority of the removed symbols, it was as easy as finding the
replacement with the exact same name. For example, `f76b` (`nf-mdi-format_header_2`)
became `f026c` (`nf-md-format_header_2`).
There was one symbol that was completely removed (it was removed from
Material Design): `f5fc` (`nf-mdi-camcorder_box`). I have substituted it
with `f03d` (`nf-fa-video_camera`) which is not Material Design, but the
closest icon I could find.
Here's some example output from [nerdfix](https://github.com/loichyan/nerdfix)
```
╭─(ignormies)(~/g/fork-waybar) removed-nerdfonts-codepoints
╰──▪ nix-shell -p nerdfix --run "nerdfix check resources/config.jsonc"
INFO Check input from 'resources/config.jsonc'
☞ Found obsolete icon U+F76B
╭─[resources/config.jsonc:131:27]
130 │ "format": "{temperatureC}°C {icon}",
131 │ "format-icons": ["", "", ""]
· ┬
· ╰── Icon 'mdi-format_header_2' is marked as obsolete
132 │ },
╰────
help: You could replace it with:
1. U+F026C md-format_header_2
2. U+F026B md-format_header_1
3. U+F026D md-format_header_3
4. U+F026E md-format_header_4
☞ Found obsolete icon U+F769
╭─[resources/config.jsonc:131:41]
130 │ "format": "{temperatureC}°C {icon}",
131 │ "format-icons": ["", "", ""]
· ┬
· ╰── Icon 'mdi-format_float_right' is marked as obsolete
132 │ },
╰────
help: You could replace it with:
1. U+F026A md-format_float_right
2. U+F0268 md-format_float_left
3. U+F0269 md-format_float_none
4. U+F0263 md-format_align_right
☞ Found obsolete icon U+F5E7
╭─[resources/config.jsonc:146:41]
145 │ "format-full": "{capacity}% {icon}",
146 │ "format-charging": "{capacity}% ",
· ┬
· ╰── Icon 'mdi-cached' is marked as obsolete
147 │ "format-plugged": "{capacity}% ",
╰────
help: You could replace it with:
1. U+F00E8 md-cached
☞ Found obsolete icon U+F796
╭─[resources/config.jsonc:170:45]
169 │ "format-wifi": "{essid} ({signalStrength}%) ",
170 │ "format-ethernet": "{ipaddr}/{cidr} ",
· ┬
· ╰── Icon 'mdi-gamepad_variant' is marked as obsolete
171 │ "tooltip-format": "{ifname} via {gwaddr} ",
╰────
help: You could replace it with:
1. U+F0297 md-gamepad_variant
2. U+F0EB7 md-gamepad_variant_outline
3. U+F0462 md-road_variant
4. U+F025C md-food_variant
☞ Found obsolete icon U+F796
╭─[resources/config.jsonc:171:50]
170 │ "format-ethernet": "{ipaddr}/{cidr} ",
171 │ "tooltip-format": "{ifname} via {gwaddr} ",
· ┬
· ╰── Icon 'mdi-gamepad_variant' is marked as obsolete
172 │ "format-linked": "{ifname} (No IP) ",
╰────
help: You could replace it with:
1. U+F0297 md-gamepad_variant
2. U+F0EB7 md-gamepad_variant_outline
3. U+F0462 md-road_variant
4. U+F025C md-food_variant
☞ Found obsolete icon U+F796
╭─[resources/config.jsonc:172:44]
171 │ "tooltip-format": "{ifname} via {gwaddr} ",
172 │ "format-linked": "{ifname} (No IP) ",
· ┬
· ╰── Icon 'mdi-gamepad_variant' is marked as obsolete
173 │ "format-disconnected": "Disconnected ⚠",
╰────
help: You could replace it with:
1. U+F0297 md-gamepad_variant
2. U+F0EB7 md-gamepad_variant_outline
3. U+F0462 md-road_variant
4. U+F025C md-food_variant
☞ Found obsolete icon U+F6A9
╭─[resources/config.jsonc:180:36]
179 │ "format-bluetooth": "{volume}% {icon} {format_source}",
180 │ "format-bluetooth-muted": " {icon} {format_source}",
· ┬
· ╰── Icon 'mdi-cup' is marked as obsolete
181 │ "format-muted": " {format_source}",
╰────
help: You could replace it with:
1. U+F01AA md-cup
☞ Found obsolete icon U+F6A9
╭─[resources/config.jsonc:181:26]
180 │ "format-bluetooth-muted": " {icon} {format_source}",
181 │ "format-muted": " {format_source}",
· ┬
· ╰── Icon 'mdi-cup' is marked as obsolete
182 │ "format-source": "{volume}% ",
╰────
help: You could replace it with:
1. U+F01AA md-cup
☞ Found obsolete icon U+F590
╭─[resources/config.jsonc:186:28]
185 │ "headphone": "",
186 │ "hands-free": "",
· ┬
· ╰── Icon 'mdi-battery_unknown' is marked as obsolete
187 │ "headset": "",
╰────
help: You could replace it with:
1. U+F0091 md-battery_unknown
2. U+F094A md-battery_unknown_bluetooth
3. U+F17DE md-battery_arrow_down
4. U+F0750 md-microsoft_xbox_controller_battery_unknown
☞ Found obsolete icon U+F590
╭─[resources/config.jsonc:187:25]
186 │ "hands-free": "",
187 │ "headset": "",
· ┬
· ╰── Icon 'mdi-battery_unknown' is marked as obsolete
188 │ "phone": "",
╰────
help: You could replace it with:
1. U+F0091 md-battery_unknown
2. U+F094A md-battery_unknown_bluetooth
3. U+F17DE md-battery_arrow_down
4. U+F0750 md-microsoft_xbox_controller_battery_unknown
```
The window module registers itself with the Hyprland IPC singleton at
the start of its constructor, before calling update(). If update()
throws an exception (e.g. from an invalid format string), the object is
destroyed without the destructor running, leaving a dangling pointer in
the IPC callback list. When the IPC thread receives an event, it
attempts to call onEvent() on this invalid memory, causing a crash.
Moving the update() call before IPC registration ensures that any
initialization errors occur before the pointer is shared. If the
configuration is invalid, the module fails to construct and is
gracefully disabled by the factory without leaving a "landmine" in the
background IPC thread.
Fixes: #4923
Signed-off-by: Emir Baha Yıldırım <jayshozie@gmail.com>