AvengeMedia / AvengeMedia/DankMaterialShell

Bar widget blur regions lag one layout behind when the bar resizes

Open
#3,348 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
QML
Stars
8.1k
Forks
515
Avg merge
1d 8h
Merged PRs (30d)
102

Description

### Compositor

Hyprland

### Distribution

CachyOS

### If Other, please specify

_No response_

### Select your Installation Method

DankInstaller

### Was this your original Installation method?

Yes

### If no, specify

_No response_

### dms doctor -vC

Click to expand
## DMS Doctor Report

**System**
- [ok] Operating System: CachyOS
- ID: cachyos, Version: rolling, Arch: amd64
- [ok] Architecture: amd64
- [ok] Display Server: Wayland
- WAYLAND_DISPLAY=wayland-1

**Versions**
- [ok] DMS CLI: dms v1.5.3
- /usr/bin/dms
- [ok] Quickshell: Quickshell 0.3.1 (revision , distributed by Arch Linux)
- /usr/bin/qs
- [ok] DMS Shell: v1.5.3
- /usr/share/quickshell/dms

**Installation**
- [ok] DMS Configuration: Found
- /usr/share/quickshell/dms
- [ok] shell.qml: Present
- /usr/share/quickshell/dms/shell.qml
- [info] Install Type: System package
- /usr/share/quickshell/dms

**Compositor**
- [ok] Hyprland: 0.56.2
- /usr/bin/hyprland
- [info] Active: Hyprland
- [ok] Background Blur: Supported
- Compositor supports ext-background-effect-v1

**Quickshell Features**
- [ok] Polkit: Available
- Authentication prompts
- [ok] IdleMonitor: Available
- Idle detection
- [ok] IdleInhibitor: Available
- Prevent idle/sleep
- [ok] ShortcutInhibitor: Available
- Allow shortcut management (niri)
- [ok] BackgroundBlur: Available
- Background blur API support in Quickshell

**Optional Features**
- [ok] accountsservice: Available
- User accounts
- [ok] power-profiles-daemon: Available
- Power profile management
- [ok] logind: Available
- Session management
- [ok] cups-pk-helper: Available
- Printer management
- [ok] I2C/DDC: 2 monitor(s) detected
- External monitor brightness control
- [ok] qt6-imageformats: Installed (1 formats)
- Formats: GIF (/usr/lib/qt6/plugins/imageformats:/usr/lib64/qt6/plugins/imageformats)
- [ok] kimageformats: Installed (4 formats)
- Formats: AVIF, HEIF, JXL, EXR (/usr/lib/qt6/plugins/imageformats:/usr/lib64/qt6/plugins/imageformats)
- [ok] Terminal: ghostty, alacritty
- [ok] Network: NetworkManager
- NetworkManager present. Using NM API.
- [ok] matugen: Installed
- Dynamic theming
- [ok] dgop: Installed
- System monitoring
- [ok] cava: Installed
- Audio visualizer
- [info] khal: Not installed
- Calendar events
- [ok] danksearch: Installed
- File search
- [info] dankcalendar: Not installed
- Calendar app
- [info] fprintd: Not installed
- Fingerprint auth

**Config Files**
- [ok] settings.json: Present
- /home/mctaco/.config/DankMaterialShell/settings.json
- [info] clsettings.json: Not yet created
- /home/mctaco/.config/DankMaterialShell/clsettings.json
- [info] plugin_settings.json: Not yet created
- /home/mctaco/.config/DankMaterialShell/plugin_settings.json
- [ok] session.json: Present
- /home/mctaco/.local/state/DankMaterialShell/session.json
- [ok] dms-colors.json: Present
- /home/mctaco/.cache/DankMaterialShell/dms-colors.json

**Services**
- [ok] dms.service: enabled, active
- [ok] greetd: enabled

**Environment**
- [info] QT_QPA_PLATFORMTHEME: Not set
- [info] QS_ICON_THEME: Not set
- [warn] XDG_MENU_PREFIX: hyprland- (menu file not found)
- Dolphin 'Open with…' dialog may be empty. Ensure /etc/xdg/menus/hyprland-applications.menu exists.

**Fonts**
- [ok] Normal Font: Inter Variable
- Available
- [ok] Monospace Font: Fira Code
- Available

---
**Summary:** 0 error(s), 1 warning(s), 35 ok

### Description

With a transparent bar and translucent widgets, the blur region behind each
bar widget does not follow the widget when the bar re-lays out. Switching
window focus resizes the focused-window widget and the bar's length changes as
intended, but the blur patches stay where the widgets were *before* the change.
They only catch up on the next focus change, so the blur sits permanently one
layout behind rather than merely being late.

With `transparency: 0` the bar itself contributes no region (`barHasTransparency`
is false), so what is left is only the per-widget sub-regions — which is why
this reads as "the blur behind each widget" rather than the bar as a whole.

**Cause**

`BasePill` registers its `visualContent` item as a blur sub-region
(`Modules/Plugins/BasePill.qml:183`), and `Region { item: ... }` only re-reads
the item when *that item's own* x/y/width/height change. The sections never move
`visualContent` — they reposition its ancestors:

- `CenterSection.updateLayout()` places widgets imperatively
(`widget.x = currentPos`) from a 0ms `layoutTimer`. That timer is restarted by
the very width change that already fired `Region.changed()`, so the region is
rebuilt *before* the new positions are applied, using the old ones.
- `Left/RightSection` use `Row`/`Column`, which reposition children during the
polish pass — again after the fact. `RightSection`'s row is `anchors.right`,
so it slides as a whole when the bar resizes while no child's own x changes at
all.

Either way nothing emits `changed()` once the layout has settled, so the stale
region survives until the next resize triggers another, equally stale, rebuild.

`IslandSatelliteHost` already handles exactly this case: `kickBlur()` defers
`_blurRegion.changed()` by a tick and is wired to its container's
`onAlongPosChanged` / `onAlongSizeChanged`. The bar has no equivalent.

I hit this on 1.5.3, but the code path is unchanged on `master` (v1.7-beta) —
it just moved from `DankBarWindow.qml` into `DankBarBody.qml`.

### Expected Behavior

The blur region behind each widget should track that widget within the same
frame the bar resizes, the way it does while the bar is idle. Instead each patch
of blur renders at the position the widget held before the most recent layout,
so blurred rectangles visibly sit beside or partly outside the widgets they
belong to until the next focus change shifts them again.

### Steps to Reproduce

1. Compositor with blur support (Hyprland here, `ext-background-effect-v1`), and
`blurEnabled: true` in settings.
2. In the bar settings, set bar transparency to 0 and widget transparency to
something below 1 (I use 0.6), so the widget backgrounds are translucent and
the bar itself is not.
3. Put the `focusedWindow` widget in the centre section. Mine is
`weather, focusedWindow, clock` in the centre and
`music, systemTray, notificationButton, controlCenterButton, powerMenuButton`
on the right.
4. Open two windows whose titles differ a lot in length (e.g. a terminal and a
browser on a long page title).
5. Alt-tab between them, watching the widget backgrounds rather than the bar
outline.

The bar resizes correctly, but the blurred patches render at the widget
positions from before the switch. Alt-tab again and they move to where the
widgets were during the previous switch — always one step behind. Any bar
config where a widget changes width at runtime should show it; the
focused-window widget is just the easiest trigger.

Relevant bits of my config:

```json
"transparency": 0,
"widgetTransparency": 0.6,
"position": 0,
"spacing": 4,
"widgetPadding": 8
```

### Error Messages/Logs

None — nothing is logged. The region is rebuilt successfully every time, just
from stale geometry, so there is no warning or QML error to capture. Journal
output around a reproduction contains no `BarBlur` messages.

Source references, line numbers against `master` @ f3d9d73:

- `Modules/Plugins/BasePill.qml:183` — registers `visualContent` as the blur item
- `Modules/DankBar/DankBarBody.qml:150` — `registerBlurWidget()`
- `Modules/DankBar/DankBarBody.qml:193` — `blurSubRegionComp`, the
`Region { item: w }` that only tracks the widget's own geometry
- `Modules/DankBar/DankBarBody.qml:390,394,405` — the only `changed()` emitters
(bar slide x/y and the goth wing radius); nothing for widget layout
- `Modules/DankBar/CenterSection.qml:35` — `updateLayout()`, driven by the 0ms
`layoutTimer` at `:326`
- `Modules/DankBar/RightSection.qml:47` — the `anchors.right` row that slides as
a whole
- `Modules/DankIsland/IslandSatelliteHost.qml:272` — the existing `kickBlur()`
(master only; this file does not exist in 1.5.3)

I have a patch against `master` that fixes it (+63 across five files, no
behaviour change when blur is disabled): add `refreshBlurRegion()` to
`DankBarBody`, call it at the end of `CenterSection.updateLayout()` and from the
`Left/RightSection` positioner geometry handlers, plus a guarded settle pass in
`barBlur` for layout the sections don't hook; the island's `blurBarWindow` shim
forwards to the existing `kickBlur()` so the shared sections fix it there too.
I have been running the same change backported to 1.5.3 and the blur now tracks
the widgets as the bar resizes.

Caveats: only exercised on a horizontal top bar on Hyprland. The vertical
(`Column`) paths, the island satellite host and multi-bar / frame-chrome
configurations are unverified, and the 32ms settle interval is a guess at "after
the next frame" rather than a measured value. Happy to open it as a PR, or to
hook something more precise if you'd prefer a different approach.

### Screenshots/Recordings

_No response_

Contributor guide

Open the contributing guide

Research direction

Reproduce the resize with blur enabled, then read Modules/DankBar/DankBarBody.qml, CenterSection.qml, LeftSection.qml, and RightSection.qml alongside Modules/Plugins/BasePill.qml. Compare the existing IslandSatelliteHost.qml kickBlur() handling with the bar's changed() emitters; done means widget blur regions follow layout changes in the same frame across the affected bar layouts.

Written by the indexing model from the issue text.

Assessment

Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.