main: correct pushModal/popModal mechanism

1. disconnect destroy signals in popModal (actors can have great lifetime and then pushed again)
2. incorrect pushModal/popModal pair in overview
https://bugzilla.gnome.org/show_bug.cgi?id=64078
This commit is contained in:
Maxim Ermilov 2011-02-25 01:29:20 +03:00
parent 84889d6dea
commit 3a6b4f3eb5
2 changed files with 40 additions and 25 deletions

View File

@ -539,11 +539,9 @@ function _globalKeyPressHandler(actor, event) {
function _findModal(actor) { function _findModal(actor) {
for (let i = 0; i < modalActorFocusStack.length; i++) { for (let i = 0; i < modalActorFocusStack.length; i++) {
let [stackActor, stackFocus] = modalActorFocusStack[i]; if (modalActorFocusStack[i].actor == actor)
if (stackActor == actor) {
return i; return i;
} }
}
return -1; return -1;
} }
@ -568,7 +566,6 @@ function _findModal(actor) {
* Returns: true iff we successfully acquired a grab or already had one * Returns: true iff we successfully acquired a grab or already had one
*/ */
function pushModal(actor, timestamp) { function pushModal(actor, timestamp) {
if (timestamp == undefined) if (timestamp == undefined)
timestamp = global.get_current_time(); timestamp = global.get_current_time();
@ -582,20 +579,24 @@ function pushModal(actor, timestamp) {
global.set_stage_input_mode(Shell.StageInputMode.FULLSCREEN); global.set_stage_input_mode(Shell.StageInputMode.FULLSCREEN);
modalCount += 1; modalCount += 1;
actor.connect('destroy', function() { let actorDestroyId = actor.connect('destroy', function() {
let index = _findModal(actor); let index = _findModal(actor);
if (index >= 0) if (index >= 0)
modalActorFocusStack.splice(index, 1); modalActorFocusStack.splice(index, 1);
}); });
let curFocus = global.stage.get_key_focus(); let curFocus = global.stage.get_key_focus();
let curFocusDestroyId;
if (curFocus != null) { if (curFocus != null) {
curFocus.connect('destroy', function() { curFocusDestroyId = curFocus.connect('destroy', function() {
let index = _findModal(actor); let index = _findModal(actor);
if (index >= 0) if (index >= 0)
modalActorFocusStack[index][1] = null; modalActorFocusStack[index].actor = null;
}); });
} }
modalActorFocusStack.push([actor, curFocus]); modalActorFocusStack.push({ actor: actor,
focus: curFocus,
destroyId: actorDestroyId,
focusDestroyId: curFocusDestroyId });
global.stage.set_key_focus(actor); global.stage.set_key_focus(actor);
return true; return true;
@ -615,28 +616,42 @@ function pushModal(actor, timestamp) {
* global.get_current_time() is assumed. * global.get_current_time() is assumed.
*/ */
function popModal(actor, timestamp) { function popModal(actor, timestamp) {
if (timestamp == undefined) if (timestamp == undefined)
timestamp = global.get_current_time(); timestamp = global.get_current_time();
modalCount -= 1;
let focusIndex = _findModal(actor); let focusIndex = _findModal(actor);
if (focusIndex >= 0) { if (focusIndex < 0) {
global.stage.set_key_focus(null);
global.end_modal(timestamp);
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
throw new Error('incorrect pop');
}
modalCount -= 1;
let record = modalActorFocusStack[focusIndex];
record.actor.disconnect(record.destroyId);
if (focusIndex == modalActorFocusStack.length - 1) { if (focusIndex == modalActorFocusStack.length - 1) {
let [stackActor, stackFocus] = modalActorFocusStack[focusIndex]; if (record.focus)
global.stage.set_key_focus(stackFocus); record.focus.disconnect(record.focusDestroyId);
global.stage.set_key_focus(record.focus);
} else { } else {
let t = modalActorFocusStack[modalActorFocusStack.length - 1];
if (t.focus)
t.focus.disconnect(t.focusDestroyId);
// Remove from the middle, shift the focus chain up // Remove from the middle, shift the focus chain up
for (let i = focusIndex; i < modalActorFocusStack.length - 1; i++) { for (let i = modalActorFocusStack.length - 1; i > focusIndex; i--) {
modalActorFocusStack[i + 1][1] = modalActorFocusStack[i][1]; modalActorFocusStack[i].focus = modalActorFocusStack[i - 1].focus;
modalActorFocusStack[i].focusDestroyId = modalActorFocusStack[i - 1].focusDestroyId;
} }
} }
modalActorFocusStack.splice(focusIndex, 1); modalActorFocusStack.splice(focusIndex, 1);
}
if (modalCount > 0) if (modalCount > 0)
return; return;
global.stage.set_key_focus(null);
global.end_modal(timestamp); global.end_modal(timestamp);
global.set_stage_input_mode(Shell.StageInputMode.NORMAL); global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
} }

View File

@ -655,20 +655,20 @@ Overview.prototype = {
if (this._shown) { if (this._shown) {
if (!this._modal) { if (!this._modal) {
if (Main.pushModal(this.dash.actor)) if (Main.pushModal(this._group))
this._modal = true; this._modal = true;
else else
this.hide(); this.hide();
} }
} else if (this._shownTemporarily) { } else if (this._shownTemporarily) {
if (this._modal) { if (this._modal) {
Main.popModal(this.dash.actor); Main.popModal(this._group);
this._modal = false; this._modal = false;
} }
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN; global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
} else { } else {
if (this._modal) { if (this._modal) {
Main.popModal(this.dash.actor); Main.popModal(this._group);
this._modal = false; this._modal = false;
} }
else if (global.stage_input_mode == Shell.StageInputMode.FULLSCREEN) else if (global.stage_input_mode == Shell.StageInputMode.FULLSCREEN)