gnome-shell/SOURCES/fix-close-dialog-annoyances...

232 lines
7.4 KiB
Diff

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