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
This commit is contained in:
parent
c41175af45
commit
b3045cb964
@ -28,7 +28,10 @@ var CloseDialog = new Lang.Class({
|
|||||||
this.parent();
|
this.parent();
|
||||||
this._window = window;
|
this._window = window;
|
||||||
this._dialog = null;
|
this._dialog = null;
|
||||||
|
this._tracked = undefined;
|
||||||
this._timeoutId = 0;
|
this._timeoutId = 0;
|
||||||
|
this._windowFocusChangedId = 0;
|
||||||
|
this._keyFocusChangedId = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
get window() {
|
get window() {
|
||||||
@ -96,6 +99,37 @@ var CloseDialog = new Lang.Class({
|
|||||||
this.response(Meta.CloseDialogResponse.FORCE_CLOSE);
|
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() {
|
vfunc_show() {
|
||||||
if (this._dialog != null)
|
if (this._dialog != null)
|
||||||
return;
|
return;
|
||||||
@ -108,6 +142,14 @@ var CloseDialog = new Lang.Class({
|
|||||||
return GLib.SOURCE_CONTINUE;
|
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._addWindowEffect();
|
||||||
this._initDialog();
|
this._initDialog();
|
||||||
|
|
||||||
@ -118,9 +160,7 @@ var CloseDialog = new Lang.Class({
|
|||||||
{ scale_y: 1,
|
{ scale_y: 1,
|
||||||
transition: 'linear',
|
transition: 'linear',
|
||||||
time: DIALOG_TRANSITION_TIME,
|
time: DIALOG_TRANSITION_TIME,
|
||||||
onComplete: () => {
|
onComplete: this._onFocusChanged.bind(this)
|
||||||
Main.layoutManager.trackChrome(this._dialog, { affectsInputRegion: true });
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -133,6 +173,12 @@ var CloseDialog = new Lang.Class({
|
|||||||
GLib.source_remove(this._timeoutId);
|
GLib.source_remove(this._timeoutId);
|
||||||
this._timeoutId = 0;
|
this._timeoutId = 0;
|
||||||
|
|
||||||
|
global.display.disconnect(this._windowFocusChangedId)
|
||||||
|
this._windowFocusChangedId = 0;
|
||||||
|
|
||||||
|
global.stage.disconnect(this._keyFocusChangedId);
|
||||||
|
this._keyFocusChangedId = 0;
|
||||||
|
|
||||||
let dialog = this._dialog;
|
let dialog = this._dialog;
|
||||||
this._dialog = null;
|
this._dialog = null;
|
||||||
this._removeWindowEffect();
|
this._removeWindowEffect();
|
||||||
|
Loading…
Reference in New Issue
Block a user