|
|
efe155 |
From 65f96732fba480f1d6e0ce760d8666cbbf5abfd3 Mon Sep 17 00:00:00 2001
|
|
|
efe155 |
From: Ray Strode <rstrode@redhat.com>
|
|
|
efe155 |
Date: Mon, 22 Jul 2019 10:57:57 -0400
|
|
|
efe155 |
Subject: [PATCH 05/13] appDisplay: Add destroy handler for FolderIcon
|
|
|
efe155 |
|
|
|
efe155 |
It is important that the FolderView of a FolderIcon always
|
|
|
efe155 |
gets destroyed before the AppFolderPopup, since the view
|
|
|
efe155 |
may or may not be in the popup, and the view should
|
|
|
efe155 |
get cleaned up exactly once in either case.
|
|
|
efe155 |
|
|
|
efe155 |
This commit adds a destroy handler on FolderIcon to ensure
|
|
|
efe155 |
things get taken down in the right order, and to make sure
|
|
|
efe155 |
the view isn't leaked if it's not yet part of the popup.
|
|
|
efe155 |
|
|
|
efe155 |
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/628
|
|
|
efe155 |
---
|
|
|
efe155 |
js/ui/appDisplay.js | 9 ++++++++-
|
|
|
efe155 |
1 file changed, 8 insertions(+), 1 deletion(-)
|
|
|
efe155 |
|
|
|
efe155 |
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
|
|
|
efe155 |
index 756e8ae44..2392281a2 100644
|
|
|
efe155 |
--- a/js/ui/appDisplay.js
|
|
|
efe155 |
+++ b/js/ui/appDisplay.js
|
|
|
efe155 |
@@ -1275,69 +1275,77 @@ var FolderIcon = new Lang.Class({
|
|
|
efe155 |
Name: 'FolderIcon',
|
|
|
efe155 |
|
|
|
efe155 |
_init(id, path, parentView) {
|
|
|
efe155 |
this.id = id;
|
|
|
efe155 |
this.name = '';
|
|
|
efe155 |
this._parentView = parentView;
|
|
|
efe155 |
|
|
|
efe155 |
this._folder = new Gio.Settings({ schema_id: 'org.gnome.desktop.app-folders.folder',
|
|
|
efe155 |
path: path });
|
|
|
efe155 |
this.actor = new St.Button({ style_class: 'app-well-app app-folder',
|
|
|
efe155 |
button_mask: St.ButtonMask.ONE,
|
|
|
efe155 |
toggle_mode: true,
|
|
|
efe155 |
can_focus: true,
|
|
|
efe155 |
x_fill: true,
|
|
|
efe155 |
y_fill: true });
|
|
|
efe155 |
this.actor._delegate = this;
|
|
|
efe155 |
// whether we need to update arrow side, position etc.
|
|
|
efe155 |
this._popupInvalidated = false;
|
|
|
efe155 |
|
|
|
efe155 |
this.icon = new IconGrid.BaseIcon('', { createIcon: this._createIcon.bind(this), setSizeManually: true });
|
|
|
efe155 |
this.actor.set_child(this.icon.actor);
|
|
|
efe155 |
this.actor.label_actor = this.icon.label;
|
|
|
efe155 |
|
|
|
efe155 |
this.view = new FolderView();
|
|
|
efe155 |
|
|
|
efe155 |
this.actor.connect('clicked', () => {
|
|
|
efe155 |
this._ensurePopup();
|
|
|
efe155 |
this.view.actor.vscroll.adjustment.value = 0;
|
|
|
efe155 |
this._openSpaceForPopup();
|
|
|
efe155 |
});
|
|
|
efe155 |
+ this.actor.connect('destroy', this.onDestroy.bind(this));
|
|
|
efe155 |
this.actor.connect('notify::mapped', () => {
|
|
|
efe155 |
if (!this.actor.mapped && this._popup)
|
|
|
efe155 |
this._popup.popdown();
|
|
|
efe155 |
});
|
|
|
efe155 |
|
|
|
efe155 |
this._folder.connect('changed', this._redisplay.bind(this));
|
|
|
efe155 |
this._redisplay();
|
|
|
efe155 |
},
|
|
|
efe155 |
|
|
|
efe155 |
+ onDestroy() {
|
|
|
efe155 |
+ this.view.actor.destroy();
|
|
|
efe155 |
+
|
|
|
efe155 |
+ if (this._popup)
|
|
|
efe155 |
+ this._popup.actor.destroy();
|
|
|
efe155 |
+ },
|
|
|
efe155 |
+
|
|
|
efe155 |
getAppIds() {
|
|
|
efe155 |
return this.view.getAllItems().map(item => item.id);
|
|
|
efe155 |
},
|
|
|
efe155 |
|
|
|
efe155 |
_updateName() {
|
|
|
efe155 |
let name = _getFolderName(this._folder);
|
|
|
efe155 |
if (this.name == name)
|
|
|
efe155 |
return;
|
|
|
efe155 |
|
|
|
efe155 |
this.name = name;
|
|
|
efe155 |
this.icon.label.text = this.name;
|
|
|
efe155 |
this.emit('name-changed');
|
|
|
efe155 |
},
|
|
|
efe155 |
|
|
|
efe155 |
_redisplay() {
|
|
|
efe155 |
this._updateName();
|
|
|
efe155 |
|
|
|
efe155 |
this.view.removeAll();
|
|
|
efe155 |
|
|
|
efe155 |
let excludedApps = this._folder.get_strv('excluded-apps');
|
|
|
efe155 |
let appSys = Shell.AppSystem.get_default();
|
|
|
efe155 |
let addAppId = appId => {
|
|
|
efe155 |
if (this.view.hasItem(appId))
|
|
|
efe155 |
return;
|
|
|
efe155 |
|
|
|
efe155 |
if (excludedApps.indexOf(appId) >= 0)
|
|
|
efe155 |
return;
|
|
|
efe155 |
|
|
|
efe155 |
let app = appSys.lookup_app(appId);
|
|
|
efe155 |
if (!app)
|
|
|
efe155 |
@@ -1460,61 +1468,60 @@ var AppFolderPopup = new Lang.Class({
|
|
|
efe155 |
// We don't want to expand really, but look
|
|
|
efe155 |
// at the layout manager of our parent...
|
|
|
efe155 |
//
|
|
|
efe155 |
// DOUBLE HACK: if you set one, you automatically
|
|
|
efe155 |
// get the effect for the other direction too, so
|
|
|
efe155 |
// we need to set the y_align
|
|
|
efe155 |
x_expand: true,
|
|
|
efe155 |
y_expand: true,
|
|
|
efe155 |
x_align: Clutter.ActorAlign.CENTER,
|
|
|
efe155 |
y_align: Clutter.ActorAlign.START });
|
|
|
efe155 |
this._boxPointer = new BoxPointer.BoxPointer(this._arrowSide,
|
|
|
efe155 |
{ style_class: 'app-folder-popup-bin',
|
|
|
efe155 |
x_fill: true,
|
|
|
efe155 |
y_fill: true,
|
|
|
efe155 |
x_expand: true,
|
|
|
efe155 |
x_align: St.Align.START });
|
|
|
efe155 |
|
|
|
efe155 |
this._boxPointer.actor.style_class = 'app-folder-popup';
|
|
|
efe155 |
this.actor.add_actor(this._boxPointer.actor);
|
|
|
efe155 |
this._boxPointer.bin.set_child(this._view.actor);
|
|
|
efe155 |
|
|
|
efe155 |
this.closeButton = Util.makeCloseButton(this._boxPointer);
|
|
|
efe155 |
this.closeButton.connect('clicked', this.popdown.bind(this));
|
|
|
efe155 |
this.actor.add_actor(this.closeButton);
|
|
|
efe155 |
|
|
|
efe155 |
this._boxPointer.actor.bind_property('opacity', this.closeButton, 'opacity',
|
|
|
efe155 |
GObject.BindingFlags.SYNC_CREATE);
|
|
|
efe155 |
|
|
|
efe155 |
global.focus_manager.add_group(this.actor);
|
|
|
efe155 |
|
|
|
efe155 |
- source.actor.connect('destroy', () => { this.actor.destroy(); });
|
|
|
efe155 |
this._grabHelper = new GrabHelper.GrabHelper(this.actor);
|
|
|
efe155 |
this._grabHelper.addActor(Main.layoutManager.overviewGroup);
|
|
|
efe155 |
this.actor.connect('key-press-event', this._onKeyPress.bind(this));
|
|
|
efe155 |
this.actor.connect('destroy', this._onDestroy.bind(this));
|
|
|
efe155 |
},
|
|
|
efe155 |
|
|
|
efe155 |
_onDestroy() {
|
|
|
efe155 |
if (this._isOpen) {
|
|
|
efe155 |
this._isOpen = false;
|
|
|
efe155 |
this._grabHelper.ungrab({ actor: this.actor });
|
|
|
efe155 |
this._grabHelper = null;
|
|
|
efe155 |
}
|
|
|
efe155 |
},
|
|
|
efe155 |
|
|
|
efe155 |
_onKeyPress(actor, event) {
|
|
|
efe155 |
if (global.stage.get_key_focus() != actor)
|
|
|
efe155 |
return Clutter.EVENT_PROPAGATE;
|
|
|
efe155 |
|
|
|
efe155 |
// Since we need to only grab focus on one item child when the user
|
|
|
efe155 |
// actually press a key we don't use navigate_focus when opening
|
|
|
efe155 |
// the popup.
|
|
|
efe155 |
// Instead of that, grab the focus on the AppFolderPopup actor
|
|
|
efe155 |
// and actually moves the focus to a child only when the user
|
|
|
efe155 |
// actually press a key.
|
|
|
efe155 |
// It should work with just grab_key_focus on the AppFolderPopup
|
|
|
efe155 |
// actor, but since the arrow keys are not wrapping_around the focus
|
|
|
efe155 |
// is not grabbed by a child when the widget that has the current focus
|
|
|
efe155 |
// is the same that is requesting focus, so to make it works with arrow
|
|
|
efe155 |
// keys we need to connect to the key-press-event and navigate_focus
|
|
|
efe155 |
// when that happens using TAB_FORWARD or TAB_BACKWARD instead of arrow
|
|
|
efe155 |
--
|
|
|
efe155 |
2.25.1
|
|
|
efe155 |
|