Fixa GTK-grab-låsningen: en popover åt gången, grab-fria fönsterlistor
All checks were successful
check / check (push) Successful in 1m35s

Rotorsak till att alla klick slutade fungera (även i settings):
grabbing-popovers i snabb följd + ikon-ombyggen som rev en öppen
popovers förälder gav 'Tried to map a grabbing popup with a non-top
most parent' i mängder och en fastnad pekar-grab på Wayland.

- refresh_items skjuts upp medan en popover är öppen (räknare i Ctx)
  och körs när den stängts — föräldern rivs aldrig under en öppen popup.
- Bara en popover åt gången; ny popup stänger den gamla först.
- Fönsterlistan grabbar aldrig (autohide av): stängs på pointer-leave
  (400 ms hover-läge / 700 ms klick-läge) + watchdog om pekaren aldrig
  når listan. Därmed kan man öppna nästa grupps lista direkt utan att
  första klicket bara stänger den förra.
- Listan öppnas riktad bort från dockans kant och radernas
  hover-effekter armeras efter 250 ms, så raden under pekaren vid
  öppning inte triggas av misstag.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-30 00:48:04 +02:00
parent 558c178ec4
commit 6be8c6fe27
3 changed files with 122 additions and 26 deletions

View File

@@ -41,6 +41,12 @@ pub struct Ctx {
pub urgent: RefCell<HashSet<String>>,
/// hot corner/edge-fönster (hotspots.rs äger innehållet)
pub hotspot_windows: RefCell<Vec<gtk::ApplicationWindow>>,
/// antal öppna popovers — medan > 0 skjuts ikon-ombyggen upp
/// (att riva en öppen popovers förälder låser GTK:s pekar-grab)
pub open_popovers: Cell<u32>,
pub refresh_pending: Cell<bool>,
/// den enda popover som får vara öppen åt gången
pub current_popover: RefCell<Option<gtk::Popover>>,
}
pub struct Dock {
@@ -544,7 +550,14 @@ fn build_items(ctx: &Ctx, connector: &str, snapshot: &[ToplevelInfo]) -> Vec<Ite
}
/// Uppdatera ikonraderna i alla dockor (körs vid varje fönsterhändelse).
/// Skjuts upp medan en popover är öppen — annars rivs popoverns förälder
/// och GTK:s grab fastnar (inga klick landar någonstans i appen).
pub fn refresh_items(ctx: &Rc<Ctx>) {
if ctx.open_popovers.get() > 0 {
ctx.refresh_pending.set(true);
return;
}
ctx.refresh_pending.set(false);
let snapshot = ctx
.service
.borrow()