Skip to content

Overview gesture hangs / shell freezes after a preceding 3-finger gesture on GNOME 49/50 (SwipeTracker enabled=false → _interrupt → invalid overview transition) #1165

@woongzeyi

Description

@woongzeyi

Describe the bug

On GNOME 49/50, doing a 3-finger horizontal scroll and then immediately a 3-finger swipe up to the overview hangs the overview mid-animation. Pressing Super at that point freezes the shell completely.

The shell logs a burst of overview state-machine errors when it happens:

JS ERROR: Error: Invalid overview shown transition from HIDDEN to HIDING
JS ERROR: Error: Invalid overview shown transition from SHOWING to SHOWING
JS ERROR: Error: Invalid overview shown transition from HIDING to HIDING

Environment

  • PaperWM 50.0.1 (v148)
  • GNOME Shell 50.2, Wayland
  • Fedora Silverblue 44

To Reproduce

  1. Have a couple of windows tiled in a space.
  2. 3-finger swipe left/right to scroll windows.
  3. Immediately 3-finger swipe up to the overview.
  4. Overview sticks part-way; pressing Super then hangs the shell.

Root cause

GNOME 49 rewrote SwipeTracker (js/ui/swipeTracker.js). The touchpad path is now a TouchpadSwipeGesture connected via actor.connectObject('event::touchpad', …) plus a Clutter.PanGesture action, and the enabled setter does this:

set enabled(enabled) {
    if (this._enabled === enabled)
        return;
    this._enabled = enabled;
    if (!enabled && this._state === State.SCROLLING)
        this._interrupt();   // emits a synthetic 'end' with cancelProgress
    this.notify('enabled');
}

_interrupt() {
    this.emit('end', 0, this._cancelProgress);
    this._panGesture.cancel();
    this._reset();
}

So on GNOME 49+, calling swipeTrackersEnable(false) while the overview tracker is mid-gesture (State.SCROLLING) no longer just flips a flag — it fires a synthetic end, which drives the overview into an illegal state transition (HIDDEN→HIDING, SHOWING→SHOWING, …). The animation never completes and the shell wedges.

PaperWM disables trackers from several places that can fire while an overview hand-off gesture is live. The one that triggers it on every up-swipe is the Main.overview 'hidden' handler in gestures.js, which runs during the hand-off and disables the still-scrolling tracker. The 300 ms pillSwipeTimer in patches.js can do the same when a previous gesture's timer lands inside the next gesture.

Evidence

Instrumenting the disable sites confirmed the overview 'hidden' handler fires during the hand-off (inGesture=true) on every reproduction. Deferring/guarding those mid-gesture disables eliminates the Invalid overview … errors entirely and the hang no longer occurs.

Proposed fix

Never disable a swipe tracker while a PaperWM gesture is in progress:

  • Track an inGesture flag (BEGIN → END/CANCEL).
  • Defer the overview 'hidden' disable to idle and skip it if a gesture is still active.
  • Skip the pillSwipeTimer disable while a gesture is active.

This keeps the follow-finger overview hand-off intact. PR follows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions