|
|
a528c3 |
From df0adb82dba725fa2734a8697ae33727201b2ee1 Mon Sep 17 00:00:00 2001
|
|
|
a528c3 |
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
|
|
a528c3 |
Date: Mon, 21 May 2018 21:21:05 +0200
|
|
|
a528c3 |
Subject: [PATCH 1/3] closeDialog: Disable unredirection while showing
|
|
|
a528c3 |
|
|
|
a528c3 |
The dialog won't be visible when unredirection is in place (for example
|
|
|
a528c3 |
while a fullscreen window is focused), so disable unredirection while
|
|
|
a528c3 |
the dialog is up.
|
|
|
a528c3 |
|
|
|
a528c3 |
https://gitlab.gnome.org/GNOME/gnome-shell/issues/298
|
|
|
a528c3 |
---
|
|
|
a528c3 |
js/ui/closeDialog.js | 4 ++++
|
|
|
a528c3 |
1 file changed, 4 insertions(+)
|
|
|
a528c3 |
|
|
|
a528c3 |
diff --git a/js/ui/closeDialog.js b/js/ui/closeDialog.js
|
|
|
a528c3 |
index aa0b5ceaf..821480a9c 100644
|
|
|
a528c3 |
--- a/js/ui/closeDialog.js
|
|
|
a528c3 |
+++ b/js/ui/closeDialog.js
|
|
|
a528c3 |
@@ -97,6 +97,8 @@ var CloseDialog = new Lang.Class({
|
|
|
a528c3 |
if (this._dialog != null)
|
|
|
a528c3 |
return;
|
|
|
a528c3 |
|
|
|
a528c3 |
+ Meta.disable_unredirect_for_screen(global.screen);
|
|
|
a528c3 |
+
|
|
|
a528c3 |
this._addWindowEffect();
|
|
|
a528c3 |
this._initDialog();
|
|
|
a528c3 |
|
|
|
a528c3 |
@@ -117,6 +119,8 @@ var CloseDialog = new Lang.Class({
|
|
|
a528c3 |
if (this._dialog == null)
|
|
|
a528c3 |
return;
|
|
|
a528c3 |
|
|
|
a528c3 |
+ Meta.enable_unredirect_for_screen(global.screen);
|
|
|
a528c3 |
+
|
|
|
a528c3 |
let dialog = this._dialog;
|
|
|
a528c3 |
this._dialog = null;
|
|
|
a528c3 |
this._removeWindowEffect();
|
|
|
a528c3 |
--
|
|
|
a528c3 |
2.21.0
|
|
|
a528c3 |
|
|
|
a528c3 |
|
|
|
a528c3 |
From eca06cb4dfdd8ca90e4add3e45420ab1d6cfb84a Mon Sep 17 00:00:00 2001
|
|
|
a528c3 |
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
|
|
a528c3 |
Date: Mon, 21 May 2018 23:12:35 +0200
|
|
|
a528c3 |
Subject: [PATCH 2/3] closeDialog: Periodically check for window to become
|
|
|
a528c3 |
responsive again
|
|
|
a528c3 |
|
|
|
a528c3 |
The close dialog for non-responding windows is closed automatically
|
|
|
a528c3 |
when we detect that the window is responding again. However as we
|
|
|
a528c3 |
currently only ping the window in response to certain user actions
|
|
|
a528c3 |
(like focusing the window or opening the window menu), this can
|
|
|
a528c3 |
easily go undetected.
|
|
|
a528c3 |
|
|
|
a528c3 |
Address this by periodically pinging the window while the close
|
|
|
a528c3 |
dialog is shown.
|
|
|
a528c3 |
|
|
|
a528c3 |
https://gitlab.gnome.org/GNOME/gnome-shell/issues/298
|
|
|
a528c3 |
---
|
|
|
a528c3 |
js/ui/closeDialog.js | 12 ++++++++++++
|
|
|
a528c3 |
1 file changed, 12 insertions(+)
|
|
|
a528c3 |
|
|
|
a528c3 |
diff --git a/js/ui/closeDialog.js b/js/ui/closeDialog.js
|
|
|
a528c3 |
index 821480a9c..7943880d8 100644
|
|
|
a528c3 |
--- a/js/ui/closeDialog.js
|
|
|
a528c3 |
+++ b/js/ui/closeDialog.js
|
|
|
a528c3 |
@@ -2,6 +2,7 @@
|
|
|
a528c3 |
|
|
|
a528c3 |
const Clutter = imports.gi.Clutter;
|
|
|
a528c3 |
const Gio = imports.gi.Gio;
|
|
|
a528c3 |
+const GLib = imports.gi.GLib;
|
|
|
a528c3 |
const GObject = imports.gi.GObject;
|
|
|
a528c3 |
const Lang = imports.lang;
|
|
|
a528c3 |
const Meta = imports.gi.Meta;
|
|
|
a528c3 |
@@ -13,6 +14,7 @@ const Tweener = imports.ui.tweener;
|
|
|
a528c3 |
|
|
|
a528c3 |
var FROZEN_WINDOW_BRIGHTNESS = -0.3
|
|
|
a528c3 |
var DIALOG_TRANSITION_TIME = 0.15
|
|
|
a528c3 |
+var ALIVE_TIMEOUT = 5000;
|
|
|
a528c3 |
|
|
|
a528c3 |
var CloseDialog = new Lang.Class({
|
|
|
a528c3 |
Name: 'CloseDialog',
|
|
|
a528c3 |
@@ -26,6 +28,7 @@ var CloseDialog = new Lang.Class({
|
|
|
a528c3 |
this.parent();
|
|
|
a528c3 |
this._window = window;
|
|
|
a528c3 |
this._dialog = null;
|
|
|
a528c3 |
+ this._timeoutId = 0;
|
|
|
a528c3 |
},
|
|
|
a528c3 |
|
|
|
a528c3 |
get window() {
|
|
|
a528c3 |
@@ -99,6 +102,12 @@ var CloseDialog = new Lang.Class({
|
|
|
a528c3 |
|
|
|
a528c3 |
Meta.disable_unredirect_for_screen(global.screen);
|
|
|
a528c3 |
|
|
|
a528c3 |
+ this._timeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, ALIVE_TIMEOUT,
|
|
|
a528c3 |
+ () => {
|
|
|
a528c3 |
+ this._window.check_alive(global.display.get_current_time_roundtrip());
|
|
|
a528c3 |
+ return GLib.SOURCE_CONTINUE;
|
|
|
a528c3 |
+ });
|
|
|
a528c3 |
+
|
|
|
a528c3 |
this._addWindowEffect();
|
|
|
a528c3 |
this._initDialog();
|
|
|
a528c3 |
|
|
|
a528c3 |
@@ -121,6 +130,9 @@ var CloseDialog = new Lang.Class({
|
|
|
a528c3 |
|
|
|
a528c3 |
Meta.enable_unredirect_for_screen(global.screen);
|
|
|
a528c3 |
|
|
|
a528c3 |
+ GLib.source_remove(this._timeoutId);
|
|
|
a528c3 |
+ this._timeoutId = 0;
|
|
|
a528c3 |
+
|
|
|
a528c3 |
let dialog = this._dialog;
|
|
|
a528c3 |
this._dialog = null;
|
|
|
a528c3 |
this._removeWindowEffect();
|
|
|
a528c3 |
--
|
|
|
a528c3 |
2.21.0
|
|
|
a528c3 |
|
|
|
a528c3 |
|
|
|
a528c3 |
From a33a32cd63f881411fd62aae1d56ceba3b971ff2 Mon Sep 17 00:00:00 2001
|
|
|
a528c3 |
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
|
|
a528c3 |
Date: Tue, 4 Sep 2018 13:53:24 +0200
|
|
|
a528c3 |
Subject: [PATCH 3/3] closeDialog: Untrack chrome when window loses focus
|
|
|
a528c3 |
|
|
|
a528c3 |
On X11, reactive chrome must be added to the input region in order
|
|
|
a528c3 |
to work as expected. However that region works independently from
|
|
|
a528c3 |
any window stacking, with the result that the unresponsive-app dialog
|
|
|
a528c3 |
currently blocks all input in the "covered" area, even in windows
|
|
|
a528c3 |
stacked above the unresponsive window.
|
|
|
a528c3 |
|
|
|
a528c3 |
The correct fix would be to track the unobscured parts of the dialog
|
|
|
a528c3 |
and set the input region from that, but that's quite cumbersome. So
|
|
|
a528c3 |
instead, only track chrome when the corresponding window is focused
|
|
|
a528c3 |
(or the dialog itself of course).
|
|
|
a528c3 |
|
|
|
a528c3 |
https://gitlab.gnome.org/GNOME/gnome-shell/issues/273
|
|
|
a528c3 |
---
|
|
|
a528c3 |
js/ui/closeDialog.js | 52 +++++++++++++++++++++++++++++++++++++++++---
|
|
|
a528c3 |
1 file changed, 49 insertions(+), 3 deletions(-)
|
|
|
a528c3 |
|
|
|
a528c3 |
diff --git a/js/ui/closeDialog.js b/js/ui/closeDialog.js
|
|
|
a528c3 |
index 7943880d8..c4b033230 100644
|
|
|
a528c3 |
--- a/js/ui/closeDialog.js
|
|
|
a528c3 |
+++ b/js/ui/closeDialog.js
|
|
|
a528c3 |
@@ -28,7 +28,10 @@ var CloseDialog = new Lang.Class({
|
|
|
a528c3 |
this.parent();
|
|
|
a528c3 |
this._window = window;
|
|
|
a528c3 |
this._dialog = null;
|
|
|
a528c3 |
+ this._tracked = undefined;
|
|
|
a528c3 |
this._timeoutId = 0;
|
|
|
a528c3 |
+ this._windowFocusChangedId = 0;
|
|
|
a528c3 |
+ this._keyFocusChangedId = 0;
|
|
|
a528c3 |
},
|
|
|
a528c3 |
|
|
|
a528c3 |
get window() {
|
|
|
a528c3 |
@@ -96,6 +99,37 @@ var CloseDialog = new Lang.Class({
|
|
|
a528c3 |
this.response(Meta.CloseDialogResponse.FORCE_CLOSE);
|
|
|
a528c3 |
},
|
|
|
a528c3 |
|
|
|
a528c3 |
+ _onFocusChanged() {
|
|
|
a528c3 |
+ if (Meta.is_wayland_compositor())
|
|
|
a528c3 |
+ return;
|
|
|
a528c3 |
+
|
|
|
a528c3 |
+ let focusWindow = global.display.focus_window;
|
|
|
a528c3 |
+ let keyFocus = global.stage.key_focus;
|
|
|
a528c3 |
+
|
|
|
a528c3 |
+ let shouldTrack;
|
|
|
a528c3 |
+ if (focusWindow != null)
|
|
|
a528c3 |
+ shouldTrack = focusWindow == this._window;
|
|
|
a528c3 |
+ else
|
|
|
a528c3 |
+ shouldTrack = keyFocus && this._dialog.contains(keyFocus);
|
|
|
a528c3 |
+
|
|
|
a528c3 |
+ if (this._tracked === shouldTrack)
|
|
|
a528c3 |
+ return;
|
|
|
a528c3 |
+
|
|
|
a528c3 |
+ if (shouldTrack)
|
|
|
a528c3 |
+ Main.layoutManager.trackChrome(this._dialog,
|
|
|
a528c3 |
+ { affectsInputRegion: true });
|
|
|
a528c3 |
+ else
|
|
|
a528c3 |
+ Main.layoutManager.untrackChrome(this._dialog);
|
|
|
a528c3 |
+
|
|
|
a528c3 |
+ // The buttons are broken when they aren't added to the input region,
|
|
|
a528c3 |
+ // so disable them properly in that case
|
|
|
a528c3 |
+ this._dialog.buttonLayout.get_children().forEach(b => {
|
|
|
a528c3 |
+ b.reactive = shouldTrack;
|
|
|
a528c3 |
+ });
|
|
|
a528c3 |
+
|
|
|
a528c3 |
+ this._tracked = shouldTrack;
|
|
|
a528c3 |
+ },
|
|
|
a528c3 |
+
|
|
|
a528c3 |
vfunc_show() {
|
|
|
a528c3 |
if (this._dialog != null)
|
|
|
a528c3 |
return;
|
|
|
a528c3 |
@@ -108,6 +142,14 @@ var CloseDialog = new Lang.Class({
|
|
|
a528c3 |
return GLib.SOURCE_CONTINUE;
|
|
|
a528c3 |
});
|
|
|
a528c3 |
|
|
|
a528c3 |
+ this._windowFocusChangedId =
|
|
|
a528c3 |
+ global.display.connect('notify::focus-window',
|
|
|
a528c3 |
+ this._onFocusChanged.bind(this));
|
|
|
a528c3 |
+
|
|
|
a528c3 |
+ this._keyFocusChangedId =
|
|
|
a528c3 |
+ global.stage.connect('notify::key-focus',
|
|
|
a528c3 |
+ this._onFocusChanged.bind(this));
|
|
|
a528c3 |
+
|
|
|
a528c3 |
this._addWindowEffect();
|
|
|
a528c3 |
this._initDialog();
|
|
|
a528c3 |
|
|
|
a528c3 |
@@ -118,9 +160,7 @@ var CloseDialog = new Lang.Class({
|
|
|
a528c3 |
{ scale_y: 1,
|
|
|
a528c3 |
transition: 'linear',
|
|
|
a528c3 |
time: DIALOG_TRANSITION_TIME,
|
|
|
a528c3 |
- onComplete: () => {
|
|
|
a528c3 |
- Main.layoutManager.trackChrome(this._dialog, { affectsInputRegion: true });
|
|
|
a528c3 |
- }
|
|
|
a528c3 |
+ onComplete: this._onFocusChanged.bind(this)
|
|
|
a528c3 |
});
|
|
|
a528c3 |
},
|
|
|
a528c3 |
|
|
|
a528c3 |
@@ -133,6 +173,12 @@ var CloseDialog = new Lang.Class({
|
|
|
a528c3 |
GLib.source_remove(this._timeoutId);
|
|
|
a528c3 |
this._timeoutId = 0;
|
|
|
a528c3 |
|
|
|
a528c3 |
+ global.display.disconnect(this._windowFocusChangedId)
|
|
|
a528c3 |
+ this._windowFocusChangedId = 0;
|
|
|
a528c3 |
+
|
|
|
a528c3 |
+ global.stage.disconnect(this._keyFocusChangedId);
|
|
|
a528c3 |
+ this._keyFocusChangedId = 0;
|
|
|
a528c3 |
+
|
|
|
a528c3 |
let dialog = this._dialog;
|
|
|
a528c3 |
this._dialog = null;
|
|
|
a528c3 |
this._removeWindowEffect();
|
|
|
a528c3 |
--
|
|
|
a528c3 |
2.21.0
|
|
|
a528c3 |
|