grabHelper: Ignore key focus changes when ungrabbing

Calling onUngrab() may change key focus, either directly or
indirectly (e.g. hiding the actor). Such key focus changes
would cause an extra actor to be ungrabbed, so make sure to
ignore such focus changes while we're ungrabbing.

https://bugzilla.gnome.org/show_bug.cgi?id=693975
This commit is contained in:
Jasper St. Pierre 2013-02-16 13:19:44 -05:00
parent 180000a531
commit 3628c81885

View File

@ -35,6 +35,7 @@ const GrabHelper = new Lang.Class({
this._keyFocusNotifyId = 0; this._keyFocusNotifyId = 0;
this._focusWindowChangedId = 0; this._focusWindowChangedId = 0;
this._ignoreRelease = false; this._ignoreRelease = false;
this._isUngrabbingCount = 0;
this._modalCount = 0; this._modalCount = 0;
this._grabFocusCount = 0; this._grabFocusCount = 0;
@ -275,6 +276,14 @@ const GrabHelper = new Lang.Class({
if (grabStackIndex < 0) if (grabStackIndex < 0)
return; return;
// We may get key focus changes when calling onUngrab, which
// would cause an extra ungrab() on the next actor in the
// stack, which is wrong. Ignore key focus changes during the
// ungrab, and restore the saved key focus ourselves afterwards.
// We use a count as ungrab() may be re-entrant, as onUngrab()
// may ungrab additional actors.
this._isUngrabbingCount++;
let focus = global.stage.key_focus; let focus = global.stage.key_focus;
let hadFocus = focus && this._isWithinGrabbedActor(focus); let hadFocus = focus && this._isWithinGrabbedActor(focus);
@ -306,6 +315,8 @@ const GrabHelper = new Lang.Class({
if (poppedGrab.savedFocus) if (poppedGrab.savedFocus)
poppedGrab.savedFocus.grab_key_focus(); poppedGrab.savedFocus.grab_key_focus();
} }
this._isUngrabbingCount--;
}, },
_onCapturedEvent: function(actor, event) { _onCapturedEvent: function(actor, event) {
@ -348,6 +359,9 @@ const GrabHelper = new Lang.Class({
}, },
_onKeyFocusChanged: function() { _onKeyFocusChanged: function() {
if (this._isUngrabbingCount > 0)
return;
let focus = global.stage.key_focus; let focus = global.stage.key_focus;
if (!focus || !this._isWithinGrabbedActor(focus)) if (!focus || !this._isWithinGrabbedActor(focus))
this.ungrab({ isUser: true }); this.ungrab({ isUser: true });