422 lines
14 KiB
Diff
422 lines
14 KiB
Diff
|
From a518c9f57e5fe9c6b5ece5c6cb0534a83f0b2f2d Mon Sep 17 00:00:00 2001
|
||
|
From: Ray Strode <rstrode@redhat.com>
|
||
|
Date: Mon, 15 Jul 2019 13:52:58 -0400
|
||
|
Subject: [PATCH 1/8] appDisplay: Don't leak duplicate items in AppView
|
||
|
|
||
|
If an icon already exists in an app view with the same id, the
|
||
|
duplicate is not added on a call to addItem. Unfortunately,
|
||
|
since it's not added, the icon actor gets orphaned and leaked.
|
||
|
|
||
|
This commit address the problem by introducing a new hasItem
|
||
|
method and disallowing callers to call addItem with a duplicate
|
||
|
in the first place.
|
||
|
|
||
|
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/628
|
||
|
---
|
||
|
js/ui/appDisplay.js | 15 ++++++++++++---
|
||
|
1 file changed, 12 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
|
||
|
index a07db6573..fa22f47e0 100644
|
||
|
--- a/js/ui/appDisplay.js
|
||
|
+++ b/js/ui/appDisplay.js
|
||
|
@@ -143,10 +143,14 @@ class BaseAppView {
|
||
|
return this._allItems;
|
||
|
}
|
||
|
|
||
|
+ hasItem(id) {
|
||
|
+ return this._items[id] !== undefined;
|
||
|
+ }
|
||
|
+
|
||
|
addItem(icon) {
|
||
|
let id = icon.id;
|
||
|
- if (this._items[id] !== undefined)
|
||
|
- return;
|
||
|
+ if (this.hasItem(id))
|
||
|
+ throw new Error(`icon with id ${id} already added to view`)
|
||
|
|
||
|
this._allItems.push(icon);
|
||
|
this._items[id] = icon;
|
||
|
@@ -386,6 +390,8 @@ var AllView = class AllView extends BaseAppView {
|
||
|
|
||
|
let folders = this._folderSettings.get_strv('folder-children');
|
||
|
folders.forEach(id => {
|
||
|
+ if (this.hasItem(id))
|
||
|
+ return;
|
||
|
let path = this._folderSettings.path + 'folders/' + id + '/';
|
||
|
let icon = new FolderIcon(id, path, this);
|
||
|
icon.connect('name-changed', this._itemNameChanged.bind(this));
|
||
|
@@ -1165,7 +1171,10 @@ var FolderIcon = class FolderIcon {
|
||
|
let excludedApps = this._folder.get_strv('excluded-apps');
|
||
|
let appSys = Shell.AppSystem.get_default();
|
||
|
let addAppId = appId => {
|
||
|
- if (excludedApps.indexOf(appId) >= 0)
|
||
|
+ if (this.view.hasItem(appId))
|
||
|
+ return;
|
||
|
+
|
||
|
+ if (excludedApps.includes(appId))
|
||
|
return;
|
||
|
|
||
|
let app = appSys.lookup_app(appId);
|
||
|
--
|
||
|
2.23.0
|
||
|
|
||
|
|
||
|
From 2b6aa9aed98c4854c2ad015879ddcb8d2bf91e9e Mon Sep 17 00:00:00 2001
|
||
|
From: Ray Strode <rstrode@redhat.com>
|
||
|
Date: Mon, 22 Jul 2019 11:06:30 -0400
|
||
|
Subject: [PATCH 2/8] iconGrid: Clear meta_later callback on destruction
|
||
|
|
||
|
The IconGrid code sometimes sets up a callback to be invoked
|
||
|
later right before being destroyed.
|
||
|
|
||
|
This commit adds a destroy handler to cancel the callback.
|
||
|
|
||
|
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/628
|
||
|
---
|
||
|
js/ui/iconGrid.js | 16 ++++++++++++++--
|
||
|
1 file changed, 14 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
|
||
|
index d51a443e8..1f05e67f3 100644
|
||
|
--- a/js/ui/iconGrid.js
|
||
|
+++ b/js/ui/iconGrid.js
|
||
|
@@ -210,6 +210,8 @@ var IconGrid = GObject.registerClass({
|
||
|
this.rightPadding = 0;
|
||
|
this.leftPadding = 0;
|
||
|
|
||
|
+ this._updateIconSizesLaterId = 0;
|
||
|
+
|
||
|
this._items = [];
|
||
|
this._clonesAnimating = [];
|
||
|
// Pulled from CSS, but hardcode some defaults here
|
||
|
@@ -227,6 +229,14 @@ var IconGrid = GObject.registerClass({
|
||
|
|
||
|
this.connect('actor-added', this._childAdded.bind(this));
|
||
|
this.connect('actor-removed', this._childRemoved.bind(this));
|
||
|
+ this.connect('destroy', this._onDestroy.bind(this));
|
||
|
+ }
|
||
|
+
|
||
|
+ _onDestroy() {
|
||
|
+ if (this._updateIconSizesLaterId) {
|
||
|
+ Meta.later_remove (this._updateIconSizesLaterId);
|
||
|
+ this._updateIconSizesLaterId = 0;
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
_keyFocusIn(actor) {
|
||
|
@@ -757,12 +767,14 @@ var IconGrid = GObject.registerClass({
|
||
|
|
||
|
this._updateSpacingForSize(availWidth, availHeight);
|
||
|
}
|
||
|
- Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
|
||
|
- this._updateIconSizes.bind(this));
|
||
|
+ if (!this._updateIconSizesLaterId)
|
||
|
+ this._updateIconSizesLaterId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
|
||
|
+ this._updateIconSizes.bind(this));
|
||
|
}
|
||
|
|
||
|
// Note that this is ICON_SIZE as used by BaseIcon, not elsewhere in IconGrid; it's a bit messed up
|
||
|
_updateIconSizes() {
|
||
|
+ this._updateIconSizesLaterId = 0;
|
||
|
let scale = Math.min(this._fixedHItemSize, this._fixedVItemSize) / Math.max(this._hItemSize, this._vItemSize);
|
||
|
let newIconSize = Math.floor(ICON_SIZE * scale);
|
||
|
for (let i in this._items) {
|
||
|
--
|
||
|
2.23.0
|
||
|
|
||
|
|
||
|
From 14a2650548a5104d6a3ec7a1174a23264d79030a Mon Sep 17 00:00:00 2001
|
||
|
From: Ray Strode <rstrode@redhat.com>
|
||
|
Date: Mon, 22 Jul 2019 11:02:10 -0400
|
||
|
Subject: [PATCH 3/8] appDisplay: Add AppFolderPopup destroy handler
|
||
|
|
||
|
At the moment AppFolderPopup calls popdown on destruction,
|
||
|
which leads to open-state-changed getting emitted after
|
||
|
the actor associated with the popup is destroyed.
|
||
|
|
||
|
This commit handles ungrabbing and closing from an
|
||
|
actor destroy handler to side-step the open-state-changed
|
||
|
signal.
|
||
|
|
||
|
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/628
|
||
|
---
|
||
|
js/ui/appDisplay.js | 9 +++++++++
|
||
|
1 file changed, 9 insertions(+)
|
||
|
|
||
|
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
|
||
|
index fa22f47e0..b75d095d5 100644
|
||
|
--- a/js/ui/appDisplay.js
|
||
|
+++ b/js/ui/appDisplay.js
|
||
|
@@ -1329,6 +1329,15 @@ var AppFolderPopup = class AppFolderPopup {
|
||
|
});
|
||
|
this._grabHelper.addActor(Main.layoutManager.overviewGroup);
|
||
|
this.actor.connect('key-press-event', this._onKeyPress.bind(this));
|
||
|
+ this.actor.connect('destroy', this._onDestroy.bind(this));
|
||
|
+ }
|
||
|
+
|
||
|
+ _onDestroy() {
|
||
|
+ if (this._isOpen) {
|
||
|
+ this._isOpen = false;
|
||
|
+ this._grabHelper.ungrab({ actor: this.actor });
|
||
|
+ this._grabHelper = null;
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
_onKeyPress(actor, event) {
|
||
|
--
|
||
|
2.23.0
|
||
|
|
||
|
|
||
|
From c9fcb2d23141694ffa2182df20ba75687b01dacc Mon Sep 17 00:00:00 2001
|
||
|
From: Ray Strode <rstrode@redhat.com>
|
||
|
Date: Thu, 18 Jul 2019 10:06:38 -0400
|
||
|
Subject: [PATCH 4/8] appDisplay: Clear AllView reference to current popup when
|
||
|
destroyed
|
||
|
|
||
|
AllView contains a reference to the current popup that lingers after
|
||
|
the popup is destroyed.
|
||
|
|
||
|
This commit fixes that, by explicitly nullifying when appropriate.
|
||
|
|
||
|
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/628
|
||
|
---
|
||
|
js/ui/appDisplay.js | 18 +++++++++++++++++-
|
||
|
1 file changed, 17 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
|
||
|
index b75d095d5..dabf63bfd 100644
|
||
|
--- a/js/ui/appDisplay.js
|
||
|
+++ b/js/ui/appDisplay.js
|
||
|
@@ -300,6 +300,7 @@ var AllView = class AllView extends BaseAppView {
|
||
|
this._eventBlocker.add_action(this._clickAction);
|
||
|
|
||
|
this._displayingPopup = false;
|
||
|
+ this._currentPopupDestroyId = 0;
|
||
|
|
||
|
this._availWidth = 0;
|
||
|
this._availHeight = 0;
|
||
|
@@ -589,7 +590,22 @@ var AllView = class AllView extends BaseAppView {
|
||
|
this._stack.add_actor(popup.actor);
|
||
|
popup.connect('open-state-changed', (popup, isOpen) => {
|
||
|
this._eventBlocker.reactive = isOpen;
|
||
|
- this._currentPopup = isOpen ? popup : null;
|
||
|
+
|
||
|
+ if (this._currentPopup) {
|
||
|
+ this._currentPopup.actor.disconnect(this._currentPopupDestroyId);
|
||
|
+ this._currentPopupDestroyId = 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ this._currentPopup = null;
|
||
|
+
|
||
|
+ if (isOpen) {
|
||
|
+ this._currentPopup = popup;
|
||
|
+ this._currentPopupDestroyId = popup.actor.connect('destroy', () => {
|
||
|
+ this._currentPopup = null;
|
||
|
+ this._currentPopupDestroyId = 0;
|
||
|
+ this._eventBlocker.reactive = false;
|
||
|
+ });
|
||
|
+ }
|
||
|
this._updateIconOpacities(isOpen);
|
||
|
if(!isOpen)
|
||
|
this._closeSpaceForPopup();
|
||
|
--
|
||
|
2.23.0
|
||
|
|
||
|
|
||
|
From b7a3fd7fa4527ba9411dcd18debe6ccf88c34dc0 Mon Sep 17 00:00:00 2001
|
||
|
From: Ray Strode <rstrode@redhat.com>
|
||
|
Date: Mon, 22 Jul 2019 10:57:57 -0400
|
||
|
Subject: [PATCH 5/8] appDisplay: Add destroy handler for FolderIcon
|
||
|
|
||
|
It is important that the FolderView of a FolderIcon always
|
||
|
gets destroyed before the AppFolderPopup, since the view
|
||
|
may or may not be in the popup, and the view should
|
||
|
get cleaned up exactly once in either case.
|
||
|
|
||
|
This commit adds a destroy handler on FolderIcon to ensure
|
||
|
things get taken down in the right order, and to make sure
|
||
|
the view isn't leaked if it's not yet part of the popup.
|
||
|
|
||
|
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/628
|
||
|
---
|
||
|
js/ui/appDisplay.js | 8 ++++++++
|
||
|
1 file changed, 8 insertions(+)
|
||
|
|
||
|
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
|
||
|
index dabf63bfd..5a8f4f1bf 100644
|
||
|
--- a/js/ui/appDisplay.js
|
||
|
+++ b/js/ui/appDisplay.js
|
||
|
@@ -1156,6 +1156,7 @@ var FolderIcon = class FolderIcon {
|
||
|
this.view.actor.vscroll.adjustment.value = 0;
|
||
|
this._openSpaceForPopup();
|
||
|
});
|
||
|
+ this.actor.connect('destroy', this.onDestroy.bind(this));
|
||
|
this.actor.connect('notify::mapped', () => {
|
||
|
if (!this.actor.mapped && this._popup)
|
||
|
this._popup.popdown();
|
||
|
@@ -1165,6 +1166,13 @@ var FolderIcon = class FolderIcon {
|
||
|
this._redisplay();
|
||
|
}
|
||
|
|
||
|
+ onDestroy() {
|
||
|
+ this.view.actor.destroy();
|
||
|
+
|
||
|
+ if (this._popup)
|
||
|
+ this._popup.actor.destroy();
|
||
|
+ }
|
||
|
+
|
||
|
getAppIds() {
|
||
|
return this.view.getAllItems().map(item => item.id);
|
||
|
}
|
||
|
--
|
||
|
2.23.0
|
||
|
|
||
|
|
||
|
From a90d7a97d21ffa596747cc8ecd0e3f500cb8a77c Mon Sep 17 00:00:00 2001
|
||
|
From: Ray Strode <rstrode@redhat.com>
|
||
|
Date: Thu, 18 Jul 2019 14:49:30 -0400
|
||
|
Subject: [PATCH 6/8] appDisplay: Stop watching FolderIcon parent view when
|
||
|
destroyed
|
||
|
|
||
|
When a FolderIcon is opened, it asks the parent view to allocate
|
||
|
space for it, which takes time. Eventually, the space-ready
|
||
|
signal is emitted on the view and the icon can make use of the new
|
||
|
space with its popup. If the icon gets destroyed in the
|
||
|
interim, though, space-ready signal handler still fires.
|
||
|
|
||
|
This commit disconnects the signal handler so it doesn't get called
|
||
|
on a destroyed icon.
|
||
|
|
||
|
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/628
|
||
|
---
|
||
|
js/ui/appDisplay.js | 10 ++++++++--
|
||
|
1 file changed, 8 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
|
||
|
index 5a8f4f1bf..062ff222c 100644
|
||
|
--- a/js/ui/appDisplay.js
|
||
|
+++ b/js/ui/appDisplay.js
|
||
|
@@ -1169,6 +1169,11 @@ var FolderIcon = class FolderIcon {
|
||
|
onDestroy() {
|
||
|
this.view.actor.destroy();
|
||
|
|
||
|
+ if (this._spaceReadySignalId) {
|
||
|
+ this._parentView.disconnect(this._spaceReadySignalId);
|
||
|
+ this._spaceReadySignalId = 0;
|
||
|
+ }
|
||
|
+
|
||
|
if (this._popup)
|
||
|
this._popup.actor.destroy();
|
||
|
}
|
||
|
@@ -1240,8 +1245,9 @@ var FolderIcon = class FolderIcon {
|
||
|
}
|
||
|
|
||
|
_openSpaceForPopup() {
|
||
|
- let id = this._parentView.connect('space-ready', () => {
|
||
|
- this._parentView.disconnect(id);
|
||
|
+ this._spaceReadySignalId = this._parentView.connect('space-ready', () => {
|
||
|
+ this._parentView.disconnect(this._spaceReadySignalId);
|
||
|
+ this._spaceReadySignalId = 0;
|
||
|
this._popup.popup();
|
||
|
this._updatePopupPosition();
|
||
|
});
|
||
|
--
|
||
|
2.23.0
|
||
|
|
||
|
|
||
|
From b57ab33dadf0f31c5bf2c800806593e94784050c Mon Sep 17 00:00:00 2001
|
||
|
From: Ray Strode <rstrode@redhat.com>
|
||
|
Date: Thu, 18 Jul 2019 10:19:13 -0400
|
||
|
Subject: [PATCH 7/8] appDisplay: Add open method to FolderIcon
|
||
|
|
||
|
At the moment the only way to open a folder icon is to click on it;
|
||
|
there's no API to open the icon programmatically.
|
||
|
|
||
|
This commits adds an open method and makes the click handler use
|
||
|
it.
|
||
|
|
||
|
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/628
|
||
|
---
|
||
|
js/ui/appDisplay.js | 12 +++++++-----
|
||
|
1 file changed, 7 insertions(+), 5 deletions(-)
|
||
|
|
||
|
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
|
||
|
index 062ff222c..c0c6e3663 100644
|
||
|
--- a/js/ui/appDisplay.js
|
||
|
+++ b/js/ui/appDisplay.js
|
||
|
@@ -1151,11 +1151,7 @@ var FolderIcon = class FolderIcon {
|
||
|
|
||
|
this.view = new FolderView();
|
||
|
|
||
|
- this.actor.connect('clicked', () => {
|
||
|
- this._ensurePopup();
|
||
|
- this.view.actor.vscroll.adjustment.value = 0;
|
||
|
- this._openSpaceForPopup();
|
||
|
- });
|
||
|
+ this.actor.connect('clicked', this.open.bind(this));
|
||
|
this.actor.connect('destroy', this.onDestroy.bind(this));
|
||
|
this.actor.connect('notify::mapped', () => {
|
||
|
if (!this.actor.mapped && this._popup)
|
||
|
@@ -1178,6 +1174,12 @@ var FolderIcon = class FolderIcon {
|
||
|
this._popup.actor.destroy();
|
||
|
}
|
||
|
|
||
|
+ open() {
|
||
|
+ this._ensurePopup();
|
||
|
+ this.view.actor.vscroll.adjustment.value = 0;
|
||
|
+ this._openSpaceForPopup();
|
||
|
+ }
|
||
|
+
|
||
|
getAppIds() {
|
||
|
return this.view.getAllItems().map(item => item.id);
|
||
|
}
|
||
|
--
|
||
|
2.23.0
|
||
|
|
||
|
|
||
|
From baacab7922a56957d041aa59944c419b82e7a7e1 Mon Sep 17 00:00:00 2001
|
||
|
From: Ray Strode <rstrode@redhat.com>
|
||
|
Date: Thu, 18 Jul 2019 11:13:27 -0400
|
||
|
Subject: [PATCH 8/8] appDisplay: Keep popup open on refresh
|
||
|
|
||
|
If the list of applications is refreshed we currently close
|
||
|
the open app folder.
|
||
|
|
||
|
This commit adds logic to reopen the app folder on reload.
|
||
|
|
||
|
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/628
|
||
|
---
|
||
|
js/ui/appDisplay.js | 15 +++++++++++++++
|
||
|
1 file changed, 15 insertions(+)
|
||
|
|
||
|
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
|
||
|
index c0c6e3663..7fad02cd0 100644
|
||
|
--- a/js/ui/appDisplay.js
|
||
|
+++ b/js/ui/appDisplay.js
|
||
|
@@ -345,6 +345,21 @@ var AllView = class AllView extends BaseAppView {
|
||
|
super.removeAll();
|
||
|
}
|
||
|
|
||
|
+ _redisplay() {
|
||
|
+ let openFolderId = null;
|
||
|
+ if (this._displayingPopup && this._currentPopup)
|
||
|
+ openFolderId = this._currentPopup._source.id;
|
||
|
+
|
||
|
+ super._redisplay();
|
||
|
+
|
||
|
+ if (openFolderId) {
|
||
|
+ let [folderToReopen] = this.folderIcons.filter(folder => folder.id == openFolderId);
|
||
|
+
|
||
|
+ if (folderToReopen)
|
||
|
+ folderToReopen.open();
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
_itemNameChanged(item) {
|
||
|
// If an item's name changed, we can pluck it out of where it's
|
||
|
// supposed to be and reinsert it where it's sorted.
|
||
|
--
|
||
|
2.23.0
|
||
|
|