altTab: Don't return from _init() if there are no windows/apps

If a new SwitcherPopup is created and there are no windows or apps to
switch through found, instead of returning from _init(), still
initialize the SwitcherPopup and let the check in SwitcherPopup.show()
return false to terminate the popup.

In both cases, with or without the return statements,
WindowManager._startSwitcher() will call SwicherPopup.destroy(), which
will try to disconnect signal handlers, destroy actors etc. Now if the
constructor can't finish creating the popup, some of the functions
called from _onDestroy() will fail and throw errors.

One of those cases is when window-switcher is limited to the current
workspace, and a WindowCyclerPopup is initiated on an empty workspace.
Because this._highlight hasn't been created, _onDestroy() will fail when
trying to destroy the actor of this._highlight.

Also, the actor of this._switcherList will not get destroyed in case
show() returns because this._items is empty. For example, this will
happen when a new AppSwitcherPopup is initialized with at least 1
running app, but 0 windows on the active workspace.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/168
This commit is contained in:
Jonas Dreßler 2018-05-06 17:17:33 +02:00 committed by Florian Müllner
parent 79ccf1a0b5
commit 84250bbf88
2 changed files with 5 additions and 9 deletions

View File

@ -64,9 +64,6 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
let apps = Shell.AppSystem.get_default().get_running(); let apps = Shell.AppSystem.get_default().get_running();
if (apps.length == 0)
return;
this._switcherList = new AppSwitcher(apps, this); this._switcherList = new AppSwitcher(apps, this);
this._items = this._switcherList.icons; this._items = this._switcherList.icons;
} }
@ -481,9 +478,6 @@ var CyclerPopup = GObject.registerClass({
this._items = this._getWindows(); this._items = this._getWindows();
if (this._items.length == 0)
return;
this._highlight = new CyclerHighlight(); this._highlight = new CyclerHighlight();
global.window_group.add_actor(this._highlight); global.window_group.add_actor(this._highlight);
@ -559,9 +553,6 @@ class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup {
let windows = this._getWindowList(); let windows = this._getWindowList();
if (windows.length == 0)
return;
let mode = this._settings.get_enum('app-icon-mode'); let mode = this._settings.get_enum('app-icon-mode');
this._switcherList = new WindowSwitcher(windows, mode); this._switcherList = new WindowSwitcher(windows, mode);
this._items = this._switcherList.icons; this._items = this._switcherList.icons;

View File

@ -330,6 +330,11 @@ var SwitcherPopup = GObject.registerClass({
GLib.source_remove(this._initialDelayTimeoutId); GLib.source_remove(this._initialDelayTimeoutId);
if (this._noModsTimeoutId != 0) if (this._noModsTimeoutId != 0)
GLib.source_remove(this._noModsTimeoutId); GLib.source_remove(this._noModsTimeoutId);
// Make sure the SwitcherList is always destroyed, it may not be
// a child of the actor at this point.
if (this._switcherList)
this._switcherList.destroy();
} }
_select(num) { _select(num) {