diff --git a/SOURCES/0001-desktop-icons-Fix-stuck-grab-issue-with-rubber-bandi.patch b/SOURCES/0001-desktop-icons-Fix-stuck-grab-issue-with-rubber-bandi.patch new file mode 100644 index 0000000..73b8f24 --- /dev/null +++ b/SOURCES/0001-desktop-icons-Fix-stuck-grab-issue-with-rubber-bandi.patch @@ -0,0 +1,179 @@ +From b334c8c248f849be996963cdafb1b0b69476bdf1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Tue, 2 Nov 2021 09:20:11 +0100 +Subject: [PATCH] desktop-icons: Fix stuck grab issue with rubber banding + +The desktop icons extension can get into a state where the desktop no longer +takes mouse input. + +This happens if a user starts a rubber banding operation and then drags +the mouse to somewhere on screen that has a pop up menu, and then pops +the menu up. + +This commit addresses the bug by limiting the grab actor to the +backgrounds, and by explicitly ending the rubber banding operation +when one of the icons own menus is shown. + +One side effect of limiting the grab actor to the backgrounds, is the +rubber banding code never gets to see motion outside of the backgrounds +anymore. In order to keep drag operations feeling fluid when the user moves +toward the edge of the screen, this commit also overrides the +grab helpers captured-event handler so those motion events keep coming. + +We also start to end the rubber band if for any reason the grab it had +was released. +--- + extensions/desktop-icons/desktopGrid.js | 1 + + extensions/desktop-icons/desktopManager.js | 75 ++++++++++++++-------- + extensions/desktop-icons/fileItem.js | 1 + + 3 files changed, 49 insertions(+), 28 deletions(-) + +diff --git a/extensions/desktop-icons/desktopGrid.js b/extensions/desktop-icons/desktopGrid.js +index 602fa7f..bd27e2a 100644 +--- a/extensions/desktop-icons/desktopGrid.js ++++ b/extensions/desktop-icons/desktopGrid.js +@@ -365,6 +365,7 @@ var DesktopGrid = class { + } + + _openMenu(x, y) { ++ Extension.desktopManager.endRubberBand(); + Main.layoutManager.setDummyCursorGeometry(x, y, 0, 0); + this.actor._desktopBackgroundMenu.open(BoxPointer.PopupAnimation.NONE); + /* Since the handler is in the press event it needs to ignore the release event +diff --git a/extensions/desktop-icons/desktopManager.js b/extensions/desktop-icons/desktopManager.js +index a70cd98..c37e1e7 100644 +--- a/extensions/desktop-icons/desktopManager.js ++++ b/extensions/desktop-icons/desktopManager.js +@@ -79,6 +79,7 @@ var DesktopManager = GObject.registerClass({ + this._queryFileInfoCancellable = null; + this._unixMode = null; + this._writableByOthers = null; ++ this._rubberBandActive = false; + + this._monitorsChangedId = Main.layoutManager.connect('monitors-changed', () => this._recreateDesktopIcons()); + this._rubberBand = new St.Widget({ style_class: 'rubber-band' }); +@@ -86,6 +87,20 @@ var DesktopManager = GObject.registerClass({ + Main.layoutManager._backgroundGroup.add_child(this._rubberBand); + this._grabHelper = new GrabHelper.GrabHelper(global.stage); + ++ let origCapturedEvent = this._grabHelper.onCapturedEvent; ++ this._grabHelper.onCapturedEvent = (event) => { ++ if (event.type() === Clutter.EventType.MOTION) { ++ /* We handle motion events from a captured event handler so we ++ * we can see motion over actors that are on other parts of the ++ * stage. ++ */ ++ this._handleMotion(event); ++ return Clutter.EVENT_STOP; ++ } ++ ++ return origCapturedEvent.bind(this._grabHelper)(event); ++ }; ++ + this._addDesktopIcons(); + this._monitorDesktopFolder(); + +@@ -108,30 +123,15 @@ var DesktopManager = GObject.registerClass({ + this._initRubberBandColor(); + this._updateRubberBand(x, y); + this._rubberBand.show(); +- this._grabHelper.grab({ actor: global.stage }); ++ this._rubberBandActive = true; ++ this._grabHelper.grab({ ++ actor: Main.layoutManager._backgroundGroup, ++ onUngrab: () => this.endRubberBand(false), ++ }); + Extension.lockActivitiesButton = true; + this._stageReleaseEventId = global.stage.connect('button-release-event', (actor, event) => { + this.endRubberBand(); + }); +- this._rubberBandId = global.stage.connect('motion-event', (actor, event) => { +- /* In some cases, when the user starts a rubberband selection and ends it +- * (by releasing the left button) over a window instead of doing it over +- * the desktop, the stage doesn't receive the "button-release" event. +- * This happens currently with, at least, Dash to Dock extension, but +- * it probably also happens with other applications or extensions. +- * To fix this, we also end the rubberband selection if we detect mouse +- * motion in the stage without the left button pressed during a +- * rubberband selection. +- * */ +- let button = event.get_state(); +- if (!(button & Clutter.ModifierType.BUTTON1_MASK)) { +- this.endRubberBand(); +- return; +- } +- [x, y] = event.get_coords(); +- this._updateRubberBand(x, y); +- this._updateSelection(x, y); +- }); + this._rubberBandTouchId = global.stage.connect('touch-event', (actor, event) => { + // Let x11 pointer emulation do the job on X11 + if (!Meta.is_wayland_compositor()) +@@ -175,14 +175,37 @@ var DesktopManager = GObject.registerClass({ + } + } + +- endRubberBand() { ++ _handleMotion(event) { ++ /* In some cases, when the user starts a rubberband selection and ends it ++ * (by releasing the left button) over a window instead of doing it over ++ * the desktop, the stage doesn't receive the "button-release" event. ++ * This happens currently with, at least, Dash to Dock extension, but ++ * it probably also happens with other applications or extensions. ++ * To fix this, we also end the rubberband selection if we detect mouse ++ * motion in the stage without the left button pressed during a ++ * rubberband selection. ++ * */ ++ let button = event.get_state(); ++ if (!(button & Clutter.ModifierType.BUTTON1_MASK)) { ++ this.endRubberBand(); ++ return; ++ } ++ let [x, y] = event.get_coords(); ++ this._updateRubberBand(x, y); ++ this._updateSelection(x, y); ++ } ++ ++ endRubberBand(ungrab=true) { ++ if (!this._rubberBandActive) ++ return; ++ ++ this._rubberBandActive = false; + this._rubberBand.hide(); + Extension.lockActivitiesButton = false; +- this._grabHelper.ungrab(); +- global.stage.disconnect(this._rubberBandId); ++ if (ungrab) ++ this._grabHelper.ungrab(); + global.stage.disconnect(this._rubberBandTouchId); + global.stage.disconnect(this._stageReleaseEventId); +- this._rubberBandId = 0; + this._rubberBandTouchId = 0; + this._stageReleaseEventId = 0; + +@@ -760,10 +783,6 @@ var DesktopManager = GObject.registerClass({ + global.stage.disconnect(this._stageReleaseEventId); + this._stageReleaseEventId = 0; + +- if (this._rubberBandId) +- global.stage.disconnect(this._rubberBandId); +- this._rubberBandId = 0; +- + if (this._rubberBandTouchId) + global.stage.disconnect(this._rubberBandTouchId); + this._rubberBandTouchId = 0; +diff --git a/extensions/desktop-icons/fileItem.js b/extensions/desktop-icons/fileItem.js +index 1cb47e8..90f326d 100644 +--- a/extensions/desktop-icons/fileItem.js ++++ b/extensions/desktop-icons/fileItem.js +@@ -676,6 +676,7 @@ var FileItem = class { + } + + _onPressButton(actor, event) { ++ Extension.desktopManager.endRubberBand(); + this._updateClickState(event); + let button = this._eventButton(event); + if (button == 3) { +-- +2.31.1 + diff --git a/SOURCES/0001-gesture-inhibitor-Put-a-foot-down-with-self-enabling.patch b/SOURCES/0001-gesture-inhibitor-Put-a-foot-down-with-self-enabling.patch new file mode 100644 index 0000000..af7d0e7 --- /dev/null +++ b/SOURCES/0001-gesture-inhibitor-Put-a-foot-down-with-self-enabling.patch @@ -0,0 +1,41 @@ +From dfdd10b46d670674d5e0e38f7adcd007f5884822 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Wed, 29 Sep 2021 14:33:25 +0200 +Subject: [PATCH] gesture-inhibitor: Put a foot down with self-enabling + gestures + +If a gesture (unfullscreen, I'm looking at you) controls its 'enabled' +property, it will bypass the will of this extension. Make it sure that +gestures are forced-off if the extension says so. +--- + extensions/gesture-inhibitor/extension.js | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/extensions/gesture-inhibitor/extension.js b/extensions/gesture-inhibitor/extension.js +index e74ede2..66c706e 100644 +--- a/extensions/gesture-inhibitor/extension.js ++++ b/extensions/gesture-inhibitor/extension.js +@@ -59,13 +59,19 @@ class Extension { + enable() { + this._map.forEach(m => { + this._settings.bind(m.setting, m.action, 'enabled', +- Gio.SettingsBindFlags.DEFAULT); ++ Gio.SettingsBindFlags.GET); ++ m.handler = m.action.connect('notify::enabled', () => { ++ if (m.action.enabled && !this._settings.get_boolean(m.setting)) ++ m.action.enabled = this._settings.get_boolean(m.setting); ++ }); + }); + } + + disable() { + this._map.forEach(m => { + m.action.enabled = true; ++ if (m.handler > 0) ++ m.action.disconnect(m.handler); + }); + } + } +-- +2.31.1 + diff --git a/SPECS/gnome-shell-extensions.spec b/SPECS/gnome-shell-extensions.spec index 6eddfa3..b3539f0 100644 --- a/SPECS/gnome-shell-extensions.spec +++ b/SPECS/gnome-shell-extensions.spec @@ -6,7 +6,7 @@ Name: gnome-shell-extensions Version: 3.32.1 -Release: 20%{?dist}.1 +Release: 22%{?dist} Summary: Modify and extend GNOME Shell functionality and behavior Group: User Interface/Desktops @@ -46,6 +46,8 @@ Patch0017: desktop-icons-touch-support.patch Patch0018: 0001-Add-gesture-inhibitor-extension.patch Patch0019: 0001-top-icons-Don-t-use-wm_class-as-role.patch Patch0020: 0001-heads-up-display-Add-extension-for-showing-persisten.patch +Patch0021: 0001-desktop-icons-Fix-stuck-grab-issue-with-rubber-bandi.patch +Patch0022: 0001-gesture-inhibitor-Put-a-foot-down-with-self-enabling.patch %description GNOME Shell Extensions is a collection of extensions providing additional and @@ -512,6 +514,14 @@ cp $RPM_SOURCE_DIR/gnome-classic.desktop $RPM_BUILD_ROOT%{_datadir}/xsessions %changelog +* Thu Nov 04 2021 Carlos Garnacho - 3.32.1-22 +- Fix gesture inhibitor extension with unfullscreen gesture + Resolves: #2009192 + +* Tue Nov 02 2021 Jonas Ã…dahl - 3.32.1-21 +- Fix stuck grab on desktop-icons + Resolves: #2019405 + * Wed Oct 27 2021 Tomas Pelka - 3.32.1-20.1 - Moving new extension from buildroot to AppStream Related: #2014404