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();