fix menu height

This commit is contained in:
Damocles 2026-04-12 12:29:28 +02:00
parent 5ad933c03b
commit 73443a78b1
3 changed files with 102 additions and 45 deletions

60
PLAN-traymenu-fix.md Normal file
View file

@ -0,0 +1,60 @@
# Plan: fix tray menu grey bar
## Root cause
`Column` (a QML positioner) lays out children using their `height` property.
`implicitHeight` is advisory — layouts like `ColumnLayout` use it, but plain
`Column` does not. The delegate `Item`s in `TrayMenu.qml` set `implicitHeight`
but leave `height` at its default of 0, so every row collapses. The only
visible pixels are the Column's `topPadding + bottomPadding = 8 px` — the grey
bar.
The same mistake applies to `implicitWidth` on the delegate items and the back
button; the width happens to work because the children use `anchors` relative to
`parent` which already has `width: 220` from the Column, but it is still wrong
and should be fixed for clarity.
## Fix — TrayMenu.qml only, two places
### 1. Back button Item (line ~108)
```qml
// before
implicitWidth: page.implicitWidth
implicitHeight: 28
// after
width: page.width
height: 28
```
### 2. Repeater delegate Item (line ~142)
```qml
// before
implicitWidth: page.implicitWidth
implicitHeight: modelData.isSeparator ? 9 : 28
// after
width: page.width
height: modelData.isSeparator ? 9 : 28
```
## Also check: StackView height binding
The StackView currently binds:
```qml
height: currentItem ? currentItem.implicitHeight : 0
```
`Column.implicitHeight` is computed from children's `implicitHeight` (not
`height`), so it should be correct in principle — but once the delegate items
have a real `height`, `Column.implicitHeight` will equal `Column.height`
anyway. Worth verifying that `currentItem.implicitHeight` and
`currentItem.height` agree after the fix; if not, switch to `currentItem.height`.
## Expected result
Each menu row is 28 px tall (9 px for separators). The panel Rectangle sizes
correctly. The dismiss MouseArea still works. No other files need changing.

View file

@ -11,33 +11,18 @@ exactly when you should be most suspicious.
## "Features" ## "Features"
- Bar with workspaces, clock, tray, and a pile of widgets the AI insisted on adding - Bar with workspaces, clock, tray, and a pile of widgets the AI insisted on adding
- Home Manager module (probably works) - Home Manager module (probably works, has not been tested in a controlled environment)
- treefmt + nixfmt for formatting, because even AI slop deserves consistent indentation - treefmt + nixfmt for formatting, because even AI slop deserves consistent indentation
- Checks via `nix flake check` (the irony of testing AI garbage is not lost on anyone) - Checks via `nix flake check` (the irony of testing AI garbage is not lost on anyone)
- Context menus for tray icons, implemented in a separate window per icon because the
shared flyout window was "suspected of being less responsive" — a diplomatic way of
saying it was bad
## Installation ## Installation
Add the flake input and use the Home Manager module. Good luck — the robot Add the flake input and import the Home Manager module. The robot did not test
didn't test any of this on real hardware. any of this on real hardware, but it was extremely confident while writing it,
which is the next best thing.
```nix
inputs.nova-shell.url = "github:yourname/nova-shell";
```
Then in your Home Manager config:
```nix
imports = [ inputs.nova-shell.homeModules.default ];
programs.nova-shell.enable = true;
```
## Configuration
Surprisingly, the robot managed to wire up a Home Manager module that mostly works.
Here is how to make it do things.
### Flake setup
```nix ```nix
# flake.nix # flake.nix
@ -52,6 +37,8 @@ inputs = {
imports = [ inputs.nova-shell.homeModules.default ]; imports = [ inputs.nova-shell.homeModules.default ];
``` ```
## Configuration
### Turning it on ### Turning it on
```nix ```nix
@ -61,23 +48,29 @@ programs.nova-shell.enable = true;
This installs the bar, the Symbols Nerd Font, and a systemd user service that This installs the bar, the Symbols Nerd Font, and a systemd user service that
starts with `graphical-session.target`. If you use starts with `graphical-session.target`. If you use
[stylix](https://github.com/danth/stylix), colors and fonts are populated [stylix](https://github.com/danth/stylix), colors and fonts are populated
automatically — one fewer thing for the AI to have gotten wrong. automatically — one fewer thing for the AI to have gotten wrong. If you do not
use stylix, you get Catppuccin Mocha, because the robot has taste and it is
purple.
### Disabling modules ### Disabling modules
All modules are on by default because the robot was optimistic. Set any to All modules are enabled by default, because the robot was optimistic about
`false` to get rid of them. Disabling `weather` also skips pulling in what hardware you own and what software you run. Set any to `false` to make
`wttrbar`, which is the one genuinely useful thing the module system does. them go away permanently, which will feel better than you expect.
Disabling `weather` also removes `wttrbar` from your packages, which is the
one piece of genuine dependency management in this entire project and
frankly more than it deserves.
```nix ```nix
programs.nova-shell.modules = { programs.nova-shell.modules = {
weather = false; # also removes the wttrbar dependency weather = false; # also evicts wttrbar from your system
bluetooth = false; # unless you enjoy a ghost icon on your desktop bluetooth = false; # for people whose computers have ethernet ports and opinions
backlight = false; # desktops don't have screens that dim, allegedly backlight = false; # your desktop monitor does not have a backlight slider, probably
battery = false; # see above battery = false; # see above, but for power
temperature = false; # ignorance is thermally efficient temperature = false; # what you don't measure can't alarm you
disk = false; disk = false; # the number will only make you anxious
wlogout = false; # if you enjoy living dangerously without a logout button wlogout = false; # living on the edge
}; };
``` ```
@ -88,9 +81,11 @@ Full list of things you can disable: `tray`, `windowTitle`, `clock`,
### Theme ### Theme
Theme keys merge on top of whatever stylix provides, so you only need to Theme keys are merged on top of whatever stylix provides. You only need to
specify what you want to override. The AI picked Catppuccin Mocha as the specify what you want to override. Values are written to
fallback, because of course it did. `~/.config/nova-shell/theme.json`, which the bar watches for changes at
runtime, so you can iterate on colors without restarting anything — a level
of polish that frankly raises uncomfortable questions about the rest of it.
```nix ```nix
programs.nova-shell.theme = { programs.nova-shell.theme = {
@ -102,7 +97,7 @@ programs.nova-shell.theme = {
fontSize = 13; fontSize = 13;
fontFamily = "JetBrains Mono"; fontFamily = "JetBrains Mono";
# override individual palette entries if stylix's choices offend you # override individual palette entries if stylix's choices personally offend you
colors.base00 = "#1a1a2e"; colors.base00 = "#1a1a2e";
colors.base05 = "#e0e0f0"; colors.base05 = "#e0e0f0";
}; };
@ -125,8 +120,9 @@ Full list of theme keys and their defaults:
### Systemd service ### Systemd service
Enabled by default. To attach it to a different target or disable it entirely Enabled by default, bound to `graphical-session.target`. To attach it to
because you have opinions about service management: something more specific, or to disable it entirely because you have strong
feelings about how your session starts:
```nix ```nix
programs.nova-shell.systemd = { programs.nova-shell.systemd = {
@ -137,7 +133,8 @@ programs.nova-shell.systemd = {
## Contributing ## Contributing
Sure, why not. It can't get much worse. Sure, why not. It can't get much worse, and the GPL requires you to share
your improvements anyway, so you might as well.
## License ## License

View file

@ -70,7 +70,7 @@ PanelWindow {
id: menuStack id: menuStack
width: currentItem ? currentItem.width : 0 width: currentItem ? currentItem.width : 0
height: currentItem ? currentItem.implicitHeight : 0 height: currentItem ? currentItem.height : 0
// Push the root page once the stack is ready // Push the root page once the stack is ready
Component.onCompleted: { Component.onCompleted: {
@ -107,8 +107,8 @@ PanelWindow {
// Back button (shown only in submenus) // Back button (shown only in submenus)
Item { Item {
visible: !page.isRoot visible: !page.isRoot
implicitWidth: page.implicitWidth width: page.width
implicitHeight: 28 height: 28
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
@ -144,8 +144,8 @@ PanelWindow {
required property QsMenuEntry modelData required property QsMenuEntry modelData
implicitWidth: page.implicitWidth width: page.width
implicitHeight: modelData.isSeparator ? 9 : 28 height: modelData.isSeparator ? 9 : 28
// Separator line // Separator line
Rectangle { Rectangle {