Panes do not all close the same way, and none close on Escape #15
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Escape closes nothing. Only the notification centre listens for
it, because it is the one surface that takes keyboard focus.
Behind that, the same pane exists in three shapes:
it (network, audio, bluetooth, vpn, microphone, clock).
own grab rather than using PanelSurface.
The bookkeeping is copied too. PanelToggle watches its surface
to call Panels.noteClosed(), and BatteryIndicator repeats that
same Connections block by hand because PowerPanel is not wired
through PanelToggle. ClockDisplay skips Panels altogether: a raw
MouseArea flips dropdown.visible, so opening the clock leaves
another pane open beside it.
The shape to land on, one class and many instances:
visible flag scattered across surfaces: toggle(name),
show(name), close(). Opening one pane closing another falls
out of that instead of being arranged.
Panels, owns the grab, and answers Escape. Every pane is a
PanelSurface, PowerPanel, the tray menu and the clock
included.
Escape needs deciding: a PopupWindow takes no keyboard focus, so
whether the focus grab delivers the key at all has to be tested
before choosing between handling it in the surface and having
the compositor tell the shell.
Implemented in
7176158.Panels holds one name for what is open. A surface binds its own
visibility to it, so one pane closing another is the state
rather than an arrangement between neighbours. PowerPanel, the
tray menu and the clock are all PanelSurface now, and
PanelToggle is down to reporting a click. BatteryIndicator's
hand-copied Connections block is gone.
Escape arrives through PaneKeys: one layer surface, no size,
nothing drawn, alive only while a pane is open, holding the
keyboard because a PopupWindow is never given it. PopoverGrab
counts it as part of the pane, or taking the keyboard would read
as focus leaving and close the pane on the way in.
Verified: the state machine through the IPC (opening one pane
replaces another, toggling the same one closes it), the key
surface appearing and disappearing with the pane in hyprctl
layers, the pane surviving that surface taking the keyboard, and
the power pane rendering correctly through the shared frame.
Not verified: the tray menu, which changed shape most. Nothing
is registered in the tray at the moment, so RegisteredStatus
NotifierItems is empty and there was no menu to open.
Two findings, one of them the actual bug.
Clicking away never worked, before my changes or after. The grab
was armed in the same pass that made the surface visible, so the
compositor refused a grab for a surface it had not mapped yet,
and a refused grab is silent: it never reports a click landing
elsewhere. Fixed in
6cb15e4by arming a beat later, with thegrab's state readable through 'panels grabbed' so the difference
between refused and quiet is one question away.
PaneKeys was worse than the problem. Holding the keyboard
exclusively pinned focus to it, so the compositor never saw
focus leave, the grab never cleared, and a pane could not be
dismissed by any means. Removed.
Escape is therefore still open, and wants a route that does not
touch focus: most likely a non-consuming Hyprland bind added
while a pane is open and removed when it closes, so Escape still
reaches applications the rest of the time.
Confirmed working. Clicking anywhere else closes a pane, and
every pane is one class with instances now.
Escape is not done and is not part of this any more: split out
so closing this does not lose it.