PerKey dialog: size window from measured natural size

The dialog used hardcoded offsets to compute its target size from the
canvas's size_request:

    target_w = canvas_w + 32  # 8 wrapper border * 2 + ~16 scrollbar slack
    target_h = canvas_h + 80  # 8 wrapper border * 2 + 50 toolbar + slack

Two problems with that:

1. The "+32" only covered the canvas's width plus borders, not the
   toolbar's width. Small layouts (e.g. an 8-LED mouse: canvas ~172px)
   produced a window narrower than the toolbar wanted (~261px with
   the icon buttons + palette + color picker + unset toggle), causing
   toolbar overflow / clipping.

2. The "+80" assumed a fixed toolbar height and scrollbar slack —
   wrong on themes with chunkier buttons or different scrollbar
   metrics, and brittle to any future toolbar additions.

Replace with `wrapper.get_preferred_size()`. GTK already aggregates
the canvas's size_request through ScrolledWindow + the editor VBox +
the wrapper's border into a natural size that accounts for every
contribution, including the toolbar's width. Drop the now-unused
`canvas_size()` shim from PerKeyEditor.
This commit is contained in:
Ken Sanislo 2026-05-11 00:56:15 -07:00 committed by Peter F. Patel-Schneider
parent dfa1cb7ca5
commit 6c99d2f9d1
2 changed files with 8 additions and 15 deletions

View File

@ -69,15 +69,14 @@ class PerKeyEditorDialog:
self._wrapper.pack_start(self._editor, True, True, 0) self._wrapper.pack_start(self._editor, True, True, 0)
self._wrapper.show_all() self._wrapper.show_all()
self._window.set_title(_("Per-key Lighting") + "" + sink.title) self._window.set_title(_("Per-key Lighting") + "" + sink.title)
# Resize to fit canvas + toolbar. ScrolledWindow's *minimum* is tiny # Ask GTK what the wrapper actually wants to be — the canvas's
# (one row's worth) regardless of propagate_natural_size, so we have # size_request propagates up through ScrolledWindow + editor VBox
# to compute the target ourselves from the canvas's size_request. # (toolbar + scrolled canvas) + the wrapper's border, so the
canvas_w, canvas_h = self._editor.canvas_size() # natural size already accounts for every layout contribution
if canvas_w > 0 and canvas_h > 0: # rather than hardcoding "toolbar ~50, border 8 each side".
# Toolbar ~50px, wrapper border 8px each side, scrollbar slack ~4. _min, nat = self._wrapper.get_preferred_size()
target_w = canvas_w + 32 if nat.width > 0 and nat.height > 0:
target_h = canvas_h + 80 self._window.resize(nat.width, nat.height)
self._window.resize(target_w, target_h)
self._window.present() self._window.present()

View File

@ -156,12 +156,6 @@ class PerKeyEditor(Gtk.Box):
except Exception as e: except Exception as e:
logger.debug("palette shutdown failed: %s", e) logger.debug("palette shutdown failed: %s", e)
def canvas_size(self) -> tuple[int, int]:
"""Return the canvas's pixel size_request — what the dialog should
size its content area to so the layout fits without scrollbars.
"""
return self._canvas.get_size_request()
def _refresh_layout(self) -> None: def _refresh_layout(self) -> None:
if self._layout is None: if self._layout is None:
# No registered layout: lay out all reported zones as a flat strip. # No registered layout: lay out all reported zones as a flat strip.