Skip to content

System tray context menu has a larger gap from a vertical bar than widget menus (goth corners) #2818

Description

@MoriVotum

Compositor

Niri

Distribution

Arch Linux

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

DMS Doctor Report

System

  • [ok] Operating System: Arch Linux
    • ID: arch, Version: rolling, Arch: amd64
  • [ok] Architecture: amd64
  • [ok] Display Server: Wayland
    • WAYLAND_DISPLAY=wayland-1

Versions

  • [ok] DMS CLI: dms v1.5.0
    • /usr/bin/dms
  • [ok] Quickshell: Quickshell 0.3.0 (revision , distributed by Arch Linux)
    • /usr/bin/qs
  • [ok] DMS Shell: v1.5.0
    • /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] niri: 26.04
    • /usr/bin/niri
  • [info] Active: niri
  • [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
  • [info] I2C/DDC: No monitors 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: kitty
  • [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
  • [ok] fprintd: Installed
    • Fingerprint auth

Config Files

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

Services

  • [ok] dms.service: enabled, active
  • [ok] greetd: enabled

Environment

  • [info] QT_QPA_PLATFORMTHEME: gtk3
  • [info] QS_ICON_THEME: Not set

Fonts

  • [warn] Normal Font: 'Inter Variable' not found
    • Font is not registered. Try running 'fc-cache -fv' or install the font.
  • [warn] Monospace Font: 'Fira Code' not found
    • Font is not registered. Try running 'fc-cache -fv' or install the font.

Summary: 0 error(s), 2 warning(s), 33 ok

Description

System tray context menu has a larger gap from a vertical bar than widget menus (goth corners)

Environment

  • Compositor: niri
  • Distro: Arch Linux
  • DMS: latest (reproduces on current main / v1.5.0)
  • Bar: vertical (position: 2 / left), gothCornersEnabled: true, cornerRadius: 12, spacing: 0, popupGapsAuto: true

Summary

On a vertical bar with goth corners enabled, the context menu of a system‑tray (SNI) icon (Steam, Telegram, etc.) opens noticeably further from the bar than the context menus of bar widgets (e.g. the clipboard button). The two used to line up. Every tray icon is affected equally; widget menus are not.

Measured on my setup: widget context menu sits ~6 px from the bar, tray context menu ~30 px — a ~24 px difference (≈18 px logical at ~1.3× scale).

Root cause

The tray menus and the widget menus compute their distance from the bar differently, and only the tray path folds in the goth‑corner wing.

Tray context menuModules/DankBar/Widgets/SystemTrayBar.qml (the menuWindow / trayMenuContainer x: binding):

const left = menuWindow.maskX + 10;
...
if (edge === "left") {
    const targetX = menuWindow.anchorPos.x;
    return Math.max(left, Math.min(right, targetX));   // clamped up to maskX + 10
}

menuWindow.maskX comes from DismissZoneSettingsData.getBarBounds(screen, barThickness + barSpacing, ...). For a vertical bar, getBarBounds returns width: barThickness + wingSize, and wingSize = gothCornersEnabled ? cornerRadius : 0 (Common/SettingsData.qml). So:

maskX      = barThickness + barSpacing + wingSize
left       = barThickness + barSpacing + wingSize + 10
menu.x     = max(left, anchorPos.x) = barThickness + barSpacing + wingSize + 10

whereas anchorPos.x itself is only barThickness + barSpacing + popupDistance.

Widget context menuModules/DankBar/Widgets/ClipboardButton.qml:

const gap = Math.max(Theme.spacingXS, root.barSpacing ?? Theme.spacingXS);
anchorX = root.barThickness + root.barSpacing + gap;   // no wingSize, no +10 mask clamp

So the widget menu lands at barThickness + barSpacing + max(4, barSpacing), while the tray menu is pushed out by an additional wingSize + 10 − popupDistance (≈ cornerRadius + 6 px). With cornerRadius: 12 that's ≈ 18 px logical extra — exactly the observed gap.

The same maskX + 10 clamp is also present in the tray overflow popup (the overflowMenu x: binding in the same file), so that popup is offset too.

Note: anchorPos.x already clears the bar and already equals the widget‑menu anchor, so the extra Math.max(maskX + 10, …) clamp is what over‑pushes the menu. The goth wing only exists at the swooping ends of the bar, not alongside the tray icons where the menu actually opens, so clamping the menu away by the full wing width is unnecessary.

Likely introduced by fix(SystemTrayBar): improve menu position boundaries (the maskX + 10 clamp) combined with wingSize being folded into getBarBounds in the multi‑bar / settings‑v2 refactor.

Expected Behavior

No response

Steps to Reproduce

Steps to reproduce

  1. Set the bar to a side (left/right) with gothCornersEnabled: true.
  2. Right‑click a system‑tray icon (Steam, Telegram, …).
  3. Right‑click a bar widget with a context menu (clipboard).
  4. Compare the horizontal gap between each menu and the bar.

Expected: tray menu sits at the same distance from the bar as widget menus.
Actual: tray menu (and tray overflow popup) sits ~cornerRadius+ px further out.

Error Messages/Logs

No response

Screenshots/Recordings

Suggested fix

For the vertical branches, clamp the tray menu to the screen edges instead of the wing‑inflated bar mask. anchorPos.x already provides the correct, widget‑consistent offset. Horizontal (top/bottom) bars and goth corners are unaffected.

Modules/DankBar/Widgets/SystemTrayBar.qml, both the menuWindow and overflowMenu x: bindings — replace the two vertical returns:

                             if (menuRoot.isVertical) {          // (or root.isVerticalOrientation for overflow)
                                 const edge = menuRoot.axis?.edge;
                                 if (edge === "left") {
                                     const targetX = menuWindow.anchorPos.x;
-                                    return Math.max(left, Math.min(right, targetX));
+                                    return Math.max(10, Math.min(menuWindow.width - alignedWidth - 10, targetX));
                                 } else {
                                     const targetX = menuWindow.anchorPos.x - alignedWidth;
-                                    return Math.max(left, Math.min(right, targetX));
+                                    return Math.max(10, Math.min(menuWindow.width - alignedWidth - 10, targetX));
                                 }
                             } else {
                                 const want = menuWindow.anchorPos.x - alignedWidth / 2;
                                 return Math.max(left, Math.min(right, want));   // unchanged
                             }

(Use overflowMenu.width in the overflow block. The horizontal want branch is intentionally left as‑is.)

Alternatively, exclude wingSize from the bounds used specifically for tray‑menu positioning, or route tray menus through the same anchoring path that widget context menus use, so both stay consistent by construction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions