[gnome-shell/T27795: 60/138] workspaceMonitor: Add a monitor to track when there are visible windows on the desktop.
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/T27795: 60/138] workspaceMonitor: Add a monitor to track when there are visible windows on the desktop.
- Date: Tue, 1 Oct 2019 23:34:22 +0000 (UTC)
commit 3f6ba6ce6c8a23e9967e3f0d28ecbfa227ede06c
Author: Mario Sanchez Prada <mario endlessm com>
Date: Sat May 27 04:38:26 2017 +0100
workspaceMonitor: Add a monitor to track when there are 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 | 96 +++++++++++++++++++++++++++++++++++++++++++
src/shell-wm.c | 20 +++++++++
4 files changed, 122 insertions(+)
---
diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml
index 80fe22fcd8..8213970de6 100644
--- a/js/js-resources.gresource.xml
+++ b/js/js-resources.gresource.xml
@@ -154,5 +154,6 @@
<file>ui/status/orientation.js</file>
<file>ui/userMenu.js</file>
<file>ui/watermark.js</file>
+ <file>ui/workspaceMonitor.js</file>
</gresource>
</gresources>
diff --git a/js/ui/main.js b/js/ui/main.js
index 6a109bf6a3..8c67e17000 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -48,6 +48,7 @@ const KbdA11yDialog = imports.ui.kbdA11yDialog;
const LocatePointer = imports.ui.locatePointer;
const PointerA11yTimeout = imports.ui.pointerA11yTimeout;
const Watermark = imports.ui.watermark;
+const WorkspaceMonitor = imports.ui.workspaceMonitor;
const A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard';
const STICKY_KEYS_ENABLE = 'stickykeys-enable';
@@ -90,6 +91,7 @@ var inputMethod = null;
var introspectService = null;
var locatePointer = null;
var trayArea = null;
+var workspaceMonitor = null;
let _startDate;
let _defaultCssStylesheet = null;
let _cssStylesheet = null;
@@ -210,6 +212,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..8fa667fe40
--- /dev/null
+++ b/js/ui/workspaceMonitor.js
@@ -0,0 +1,96 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+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(shellwm, actor) {
+ 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(function(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]