Add experimental options to style the 15505+ main menu popover to match stock Nickel (caret, separators, position, width)#233
Open
fyoosh wants to merge 4 commits into
Open
Conversation
The from-scratch main menu on FW 4.23.15505+ renders as a plain
rectangle, unlike every stock Nickel popover, which draws a caret
pointing at its anchor. NickelTouchMenu has the full decoration API;
it just needs three things NickelMenu never did:
- a parent widget: drawDecoration() returns immediately when the
menu has no QObject parent, so the caret can never render on the
stock nullptr-parent construction (this is why the menu has always
been flat). Parent to the tab button's top-level window, whose
coordinate space the anchor mapping expects. The nullptr parent is
kept when the caret is not requested.
- showDecoration(true): paintEvent() gates drawDecoration() on this
flag.
- setDecorationPositionOffset(): the global anchor point the caret
aims at (the painter adds half the target rect's width itself, so
pass the target's top-left).
All new behavior is opt-in via experimental options and defaults to
the existing appearance:
- menu_main_15505_caret draw the native caret (default off)
- menu_main_15505_decoration caret edge: 0=top 1=right 2=left
3=bottom 5=none (default 3)
- menu_main_15505_caret_dx/_dy nudge the caret anchor (px)
- menu_main_15505_offset_x/_y nudge the popup position (px)
The four NickelTouchMenu symbols are resolved optionally, so firmware
without them degrades to the current flat menu.
Verified on a Libra Colour, FW 4.45.23697, NickelMenu v0.6.0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fitting The stock popup point (derived from the tab button's geometry) lands far off-screen right, so QMenu::popup()'s screen-fit clamping repositions the menu every time — and silently swallows any offset added to the popup point itself. Apply menu_main_15505_offset_x/_y via move() after popup() instead: the offsets become relative to the position the menu actually landed at, which also makes them device-geometry independent. Verified on a Libra Colour, FW 4.45.23697: offset_x -30 / offset_y -16 inset the popover from the screen edge and bottom bar like the stock toolbar popovers, with the caret staying anchored to the tab button. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
menu_main_15505_width sets a fixed popover width in pixels; unset/0 keeps the stock auto-size-to-widest-item behaviour. Auto-sizing tracks the longest configured label, so menus with short labels render narrower than the stock Nickel popovers; a fixed width lets the menu match the surrounding UI's proportions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
menu_main_15505_flush_separators draws the popover's row dividers with Nickel's native separator action (the same LightMenuSeparator the pre-15505 main menu items use) and stretches them toward the popover edges after popup() assigns geometry, since the menu lays out every action inset from the edges. menu_main_15505_separator_inset tunes how far the dividers stay from the edges so they can be lined up with the painted border (the widget's true edge sits outside the frame). menu_main_15505_italic 0 renders item labels upright. The MenuTextItem constructor's italic flag is not sufficient on its own because setText() re-applies the item's italics; the explicit MenuTextItem::setTextItalics(false) after setText() is what sticks (this mirrors the stock battery popover, which mixes upright labels with italic tap actions via the same setter). Both options default to the existing stock-NickelMenu appearance. Also tones down the debug logging added with the caret work. Verified on a Libra Colour, FW 4.45.23697. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On firmware 4.23.15505+, where the original main menu was removed, NickelMenu builds its menu from scratch as a bare
NickelTouchMenu. Stock Nickel popovers (e.g. the brightness and battery popovers) draw a pointer caret aimed at their anchor, sit inset from the screen edge, and use full-width dividers — the from-scratch menu has none of that. This adds a handful of opt-inexperimental:options to bring it closer to the native look.Everything here defaults to the current behaviour, so an unset config renders exactly as before (the left screenshot above is this branch with no options set).
Options added
All under the existing
menu_main_15505_*experimental namespace:caretdecoration0top,3bottom;1/2the side edges,5none)caret_dx/caret_dyoffset_x/offset_ywidthflush_separatorsseparator_insetitalic0renders item labels uprightNotes on the implementation
A few things were needed beyond what the existing code does, in case they're useful context for review:
drawDecorationreturns earlyotherwise),
showDecoration(true)is set (gated inpaintEvent), and a targetrect is given — so the menu is now parented to the tab button's window when the
caret is requested.
offset_x/_yare applied withmove()afterpopup(), becausepopup()'sscreen-fit clamping otherwise swallows them.
flush_separatorsadds aLightMenuSeparatorand widens it after layout,since the menu insets every action.
italic 0callsMenuTextItem::setTextItalics(false)aftersetText()(the constructor flag alone doesn't stick, as
setTextre-applies italics).The four new
NickelTouchMenu/MenuTextItemsymbols are resolved optionally, sofirmware without them just falls back to the current appearance.
Testing
Built with
nickeltc:1.0and verified on a Kobo Libra Colour, FW 4.45.23697.Symbol tags follow the existing entries (
4.23.15505 *); CI will confirm acrossversions.
A question on defaults
I've kept everything opt-in here to stay conservative — but I wanted to raise one idea:
The pointer/caret and full-width dividers are arguably less "a styling option" and more "the native Kobo look this menu is currently missing".
NickelMenu's menus look native because they are native widgets, and the 15505+ popover is the one element that doesn't (flat box, inset dividers, no caret/pointer) only because it's built from scratch rather than reused.
So — would you want the caret, full-width dividers, and a small edge margin on by default for the 15505+ menu, with width / italic staying opt-in? The caret anchor is derived from the tab button's own geometry, so it's device-independent, and the margin is just a small fixed inset; width and italic are the user-taste parts, which I'd suggest stay opt-in regardless.
No presumption either way — happy to leave it fully opt-in as in this PR, flip those to default, or whatever fits your appetite for a behaviour change. The "match native" angle just felt worth raising.
Thanks for your work on NickelMenu so far :)