[gnome-shell/eos3.8: 24/255] workspaceMonitor: Add a monitor to track visible windows on the desktop
- From: Matthew Leeds <mwleeds src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/eos3.8: 24/255] workspaceMonitor: Add a monitor to track visible windows on the desktop
- Date: Wed, 10 Jun 2020 18:59:57 +0000 (UTC)
commit b4e2277cf1430b7ea5957c5710daf762854dc7f2
Author: Mario Sanchez Prada <mario endlessm com>
Date: Sat May 27 04:38:26 2017 +0100
workspaceMonitor: Add a monitor to track visible windows on the desktop
This will be useful to implement the "Endless button" in the bottom panel (to
decide when we need to show the apps view or blink the search entry box) and
for any other actions that depend on not having any window opened in the desktop.
Starting in EOS 3.4 / GNOME Shell 3.26, this also fixes a corner case that has not
been contemplated before, because it normally happens when manipulating the status
icon in the tray area, which was fairly hidden in a sliding panel until now: when
you have an app hidden (not minimized) because of interacting with it via the tray
area icon (e.g. Telegram) and clicking on its icon again should make it visible again,
the previous code prevented that from happening unless some other windows wass already
visible, because nothing would hide the overview in this scenario, keeping the app hidden.
https://phabricator.endlessm.com/T17937
js/js-resources.gresource.xml | 1 +
js/ui/main.js | 5 +++
js/ui/workspaceMonitor.js | 97 +++++++++++++++++++++++++++++++++++++++++++
src/shell-wm.c | 20 +++++++++
4 files changed, 123 insertions(+)
---
diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml
index 03ff04d5aa..f0ed005e7c 100644
--- a/js/js-resources.gresource.xml
+++ b/js/js-resources.gresource.xml
@@ -144,5 +144,6 @@
<file>ui/appActivation.js</file>
<file>ui/appIconBar.js</file>
<file>ui/forceAppExitDialog.js</file>
+ <file>ui/workspaceMonitor.js</file>
</gresource>
</gresources>
diff --git a/js/ui/main.js b/js/ui/main.js
index fbfc8a058d..26c6defa0c 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -47,6 +47,7 @@ const XdndHandler = imports.ui.xdndHandler;
const KbdA11yDialog = imports.ui.kbdA11yDialog;
const LocatePointer = imports.ui.locatePointer;
const PointerA11yTimeout = imports.ui.pointerA11yTimeout;
+const WorkspaceMonitor = imports.ui.workspaceMonitor;
const A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard';
const STICKY_KEYS_ENABLE = 'stickykeys-enable';
@@ -87,6 +88,7 @@ var kbdA11yDialog = null;
var inputMethod = null;
var introspectService = null;
var locatePointer = null;
+var workspaceMonitor = null;
let _startDate;
let _defaultCssStylesheet = null;
let _cssStylesheet = null;
@@ -216,6 +218,9 @@ function _initializeUI() {
new PointerA11yTimeout.PointerA11yTimeout();
+ // WorkspaceMonitor expects layoutManager to be ready, initialize it here.
+ workspaceMonitor = new WorkspaceMonitor.WorkspaceMonitor();
+
_a11ySettings = new Gio.Settings({ schema_id: A11Y_SCHEMA });
global.display.connect('overlay-key', () => {
diff --git a/js/ui/workspaceMonitor.js b/js/ui/workspaceMonitor.js
new file mode 100644
index 0000000000..1935ffa4cb
--- /dev/null
+++ b/js/ui/workspaceMonitor.js
@@ -0,0 +1,97 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+/* exported WorkspaceMonitor */
+
+const { Shell } = imports.gi;
+
+const Main = imports.ui.main;
+const ViewSelector = imports.ui.viewSelector;
+
+var WorkspaceMonitor = class {
+ constructor() {
+ this._shellwm = global.window_manager;
+ this._shellwm.connect('minimize-completed', this._windowDisappeared.bind(this));
+ this._shellwm.connect('destroy-completed', this._windowDisappeared.bind(this));
+
+ this._windowTracker = Shell.WindowTracker.get_default();
+ this._windowTracker.connect('tracked-windows-changed', this._trackedWindowsChanged.bind(this));
+
+ global.display.connect('in-fullscreen-changed', this._fullscreenChanged.bind(this));
+
+ let primaryMonitor = Main.layoutManager.primaryMonitor;
+ this._inFullscreen = primaryMonitor && primaryMonitor.inFullscreen;
+
+ this._appSystem = Shell.AppSystem.get_default();
+ }
+
+ _fullscreenChanged() {
+ let primaryMonitor = Main.layoutManager.primaryMonitor;
+ let inFullscreen = primaryMonitor && primaryMonitor.inFullscreen;
+
+ if (this._inFullscreen !== inFullscreen) {
+ this._inFullscreen = inFullscreen;
+ this._updateOverview();
+ }
+ }
+
+ _updateOverview() {
+ let visibleApps = this._getVisibleApps();
+ if (visibleApps.length !== 0 && this._inFullscreen)
+ Main.overview.hide();
+ }
+
+ _windowDisappeared() {
+ this._updateOverview();
+ }
+
+ _trackedWindowsChanged() {
+ let visibleApps = this._getVisibleApps();
+ let isShowingAppsGrid = Main.overview.visible &&
+ Main.overview.getActivePage() === ViewSelector.ViewPage.APPS;
+
+ if (visibleApps.length > 0 && isShowingAppsGrid) {
+ // Make sure to hide the apps grid so that running apps whose
+ // windows are becoming visible are shown to the user.
+ Main.overview.hide();
+ } else {
+ // Fallback to the default logic used for dissapearing windows.
+ this._updateOverview();
+ }
+ }
+
+ _getVisibleApps() {
+ let runningApps = this._appSystem.get_running();
+ return runningApps.filter(app => {
+ let windows = app.get_windows();
+ for (let window of windows) {
+ // We do not count transient windows because of an issue with Audacity
+ // where a transient window was always being counted as visible even
+ // though it was minimized
+ if (window.get_transient_for())
+ continue;
+
+ if (!window.minimized)
+ return true;
+ }
+
+ return false;
+ });
+ }
+
+ get hasActiveWindows() {
+ // Count anything fullscreen as an extra window
+ if (this._inFullscreen)
+ return true;
+
+ let apps = this._appSystem.get_running();
+ return apps.length > 0;
+ }
+
+ get hasVisibleWindows() {
+ // Count anything fullscreen as an extra window
+ if (this._inFullscreen)
+ return true;
+
+ let visibleApps = this._getVisibleApps();
+ return visibleApps.length > 0;
+ }
+};
diff --git a/src/shell-wm.c b/src/shell-wm.c
index 1e579ad8c2..aa648591a6 100644
--- a/src/shell-wm.c
+++ b/src/shell-wm.c
@@ -20,11 +20,13 @@ struct _ShellWM {
enum
{
MINIMIZE,
+ MINIMIZE_COMPLETED,
UNMINIMIZE,
SIZE_CHANGED,
SIZE_CHANGE,
MAP,
DESTROY,
+ DESTROY_COMPLETED,
SWITCH_WORKSPACE,
KILL_SWITCH_WORKSPACE,
KILL_WINDOW_EFFECTS,
@@ -70,6 +72,14 @@ shell_wm_class_init (ShellWMClass *klass)
NULL, NULL, NULL,
G_TYPE_NONE, 1,
META_TYPE_WINDOW_ACTOR);
+ shell_wm_signals[MINIMIZE_COMPLETED] =
+ g_signal_new ("minimize-completed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 1,
+ META_TYPE_WINDOW_ACTOR);
shell_wm_signals[UNMINIMIZE] =
g_signal_new ("unminimize",
G_TYPE_FROM_CLASS (klass),
@@ -110,6 +120,14 @@ shell_wm_class_init (ShellWMClass *klass)
NULL, NULL, NULL,
G_TYPE_NONE, 1,
META_TYPE_WINDOW_ACTOR);
+ shell_wm_signals[DESTROY_COMPLETED] =
+ g_signal_new ("destroy-completed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 1,
+ META_TYPE_WINDOW_ACTOR);
shell_wm_signals[SWITCH_WORKSPACE] =
g_signal_new ("switch-workspace",
G_TYPE_FROM_CLASS (klass),
@@ -247,6 +265,7 @@ shell_wm_completed_minimize (ShellWM *wm,
MetaWindowActor *actor)
{
meta_plugin_minimize_completed (wm->plugin, actor);
+ g_signal_emit (wm, shell_wm_signals[MINIMIZE_COMPLETED], 0, actor);
}
/**
@@ -296,6 +315,7 @@ shell_wm_completed_destroy (ShellWM *wm,
MetaWindowActor *actor)
{
meta_plugin_destroy_completed (wm->plugin, actor);
+ g_signal_emit (wm, shell_wm_signals[DESTROY_COMPLETED], 0, actor);
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]