Add a facility to show the stage without grabbing
When the user is doing a drag-and-drop, we want to temporarily show the stage to allow them to drag to a different window. But we're not "really" in the overview, and getting a grab would conflict with the X client doing the drag and drop. So add a showTemporarily()/hideTemporarily() pair of methods that show the overview without grabbing. This adds a lot more possibilities for asynchronous race conditions, so rework the code to be more robust against multiple calls to show*() and hide*(). The interpretation is now that all calls to show*() and hide*() affect the state, but if we have conflicting calls to show and hide we wait until the current animation is finished before correcting to the right visual state. https://bugzilla.gnome.org/show_bug.cgi?id=601731
This commit is contained in:
parent
7beb7e0f65
commit
62507c9759
@ -6,6 +6,7 @@ const Mainloop = imports.mainloop;
|
|||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
const Gettext = imports.gettext.domain('gnome-shell');
|
const Gettext = imports.gettext.domain('gnome-shell');
|
||||||
const _ = Gettext.gettext;
|
const _ = Gettext.gettext;
|
||||||
|
|
||||||
@ -135,7 +136,10 @@ Overview.prototype = {
|
|||||||
|
|
||||||
this._workspacesDisplay = null;
|
this._workspacesDisplay = null;
|
||||||
|
|
||||||
this.visible = false;
|
this.visible = false; // animating to overview, in overview, animating out
|
||||||
|
this._shown = false; // show() and not hide()
|
||||||
|
this._shownTemporarily = false; // showTemporarily() and not hideTemporarily()
|
||||||
|
this._modal = false; // have a modal grab
|
||||||
this.animationInProgress = false;
|
this.animationInProgress = false;
|
||||||
this._hideInProgress = false;
|
this._hideInProgress = false;
|
||||||
|
|
||||||
@ -267,11 +271,23 @@ Overview.prototype = {
|
|||||||
return [this.workspaces.actor.x, this.workspaces.actor.y];
|
return [this.workspaces.actor.x, this.workspaces.actor.y];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// show:
|
||||||
|
//
|
||||||
|
// Animates the overview visible and grabs mouse and keyboard input
|
||||||
show : function() {
|
show : function() {
|
||||||
if (this.visible)
|
if (this._shown)
|
||||||
return;
|
return;
|
||||||
|
// Do this manually instead of using _syncInputMode, to handle failure
|
||||||
if (!Main.pushModal(this.viewSelector.actor))
|
if (!Main.pushModal(this.viewSelector.actor))
|
||||||
return;
|
return;
|
||||||
|
this._modal = true;
|
||||||
|
this._animateVisible();
|
||||||
|
this._shown = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
_animateVisible: function() {
|
||||||
|
if (this.visible || this.animationInProgress)
|
||||||
|
return;
|
||||||
|
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
this.animationInProgress = true;
|
this.animationInProgress = true;
|
||||||
@ -337,8 +353,102 @@ Overview.prototype = {
|
|||||||
this.emit('showing');
|
this.emit('showing');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// showTemporarily:
|
||||||
|
//
|
||||||
|
// Animates the overview visible without grabbing mouse and keyboard input;
|
||||||
|
// if show() has already been called, this has no immediate effect, but
|
||||||
|
// will result in the overview not being hidden until hideTemporarily() is
|
||||||
|
// called.
|
||||||
|
showTemporarily: function() {
|
||||||
|
if (this._shownTemporarily)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._syncInputMode();
|
||||||
|
this._animateVisible();
|
||||||
|
this._shownTemporarily = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
// hide:
|
||||||
|
//
|
||||||
|
// Reverses the effect of show()
|
||||||
hide: function() {
|
hide: function() {
|
||||||
if (!this.visible || this._hideInProgress)
|
if (!this._shown)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!this._shownTemporarily)
|
||||||
|
this._animateNotVisible();
|
||||||
|
|
||||||
|
this._shown = false;
|
||||||
|
this._syncInputMode();
|
||||||
|
},
|
||||||
|
|
||||||
|
// hideTemporarily:
|
||||||
|
//
|
||||||
|
// Reverses the effect of showTemporarily()
|
||||||
|
hideTemporarily: function() {
|
||||||
|
if (!this._shownTemporarily)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!this._shown)
|
||||||
|
this._animateNotVisible();
|
||||||
|
|
||||||
|
this._shownTemporarily = false;
|
||||||
|
this._syncInputMode();
|
||||||
|
},
|
||||||
|
|
||||||
|
toggle: function() {
|
||||||
|
if (this._shown)
|
||||||
|
this.hide();
|
||||||
|
else
|
||||||
|
this.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getWorkspacesForWindow:
|
||||||
|
* @metaWindow: A #MetaWindow
|
||||||
|
*
|
||||||
|
* Returns the Workspaces object associated with the given window.
|
||||||
|
* This method is not be accessible if the overview is not open
|
||||||
|
* and will return %null.
|
||||||
|
*/
|
||||||
|
getWorkspacesForWindow: function(metaWindow) {
|
||||||
|
return this.workspaces;
|
||||||
|
},
|
||||||
|
|
||||||
|
//// Private methods ////
|
||||||
|
|
||||||
|
_syncInputMode: function() {
|
||||||
|
// We delay input mode changes during animation so that when removing the
|
||||||
|
// overview we don't have a problem with the release of a press/release
|
||||||
|
// going to an application.
|
||||||
|
if (this.animationInProgress)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this._shown) {
|
||||||
|
if (!this._modal) {
|
||||||
|
if (Main.pushModal(this._dash.actor))
|
||||||
|
this._modal = true;
|
||||||
|
else
|
||||||
|
this.hide();
|
||||||
|
}
|
||||||
|
} else if (this._shownTemporarily) {
|
||||||
|
if (this._modal) {
|
||||||
|
Main.popModal(this._dash.actor);
|
||||||
|
this._modal = false;
|
||||||
|
}
|
||||||
|
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
|
||||||
|
} else {
|
||||||
|
if (this._modal) {
|
||||||
|
Main.popModal(this._dash.actor);
|
||||||
|
this._modal = false;
|
||||||
|
}
|
||||||
|
else if (global.stage_input_mode == Shell.StageInputMode.FULLSCREEN)
|
||||||
|
global.stage_input_mode = Shell.StageInputMode.NORMAL;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_animateNotVisible: function() {
|
||||||
|
if (!this.visible || this.animationInProgress)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.animationInProgress = true;
|
this.animationInProgress = true;
|
||||||
@ -382,36 +492,17 @@ Overview.prototype = {
|
|||||||
this.emit('hiding');
|
this.emit('hiding');
|
||||||
},
|
},
|
||||||
|
|
||||||
toggle: function() {
|
|
||||||
if (this.visible)
|
|
||||||
this.hide();
|
|
||||||
else
|
|
||||||
this.show();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getWorkspacesForWindow:
|
|
||||||
* @metaWindow: A #MetaWindow
|
|
||||||
*
|
|
||||||
* Returns the Workspaces object associated with the given window.
|
|
||||||
* This method is not be accessible if the overview is not open
|
|
||||||
* and will return %null.
|
|
||||||
*/
|
|
||||||
getWorkspacesForWindow: function(metaWindow) {
|
|
||||||
return this.workspaces;
|
|
||||||
},
|
|
||||||
|
|
||||||
//// Private methods ////
|
|
||||||
|
|
||||||
_showDone: function() {
|
_showDone: function() {
|
||||||
if (this._hideInProgress)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.animationInProgress = false;
|
this.animationInProgress = false;
|
||||||
this._desktopFade.hide();
|
this._desktopFade.hide();
|
||||||
this._coverPane.lower_bottom();
|
this._coverPane.lower_bottom();
|
||||||
|
|
||||||
this.emit('shown');
|
this.emit('shown');
|
||||||
|
// Handle any calls to hide* while we were showing
|
||||||
|
if (!this._shown && !this._shownTemporarily)
|
||||||
|
this._animateNotVisible();
|
||||||
|
|
||||||
|
this._syncInputMode();
|
||||||
},
|
},
|
||||||
|
|
||||||
_hideDone: function() {
|
_hideDone: function() {
|
||||||
@ -434,8 +525,12 @@ Overview.prototype = {
|
|||||||
|
|
||||||
this._coverPane.lower_bottom();
|
this._coverPane.lower_bottom();
|
||||||
|
|
||||||
Main.popModal(this.viewSelector.actor);
|
|
||||||
this.emit('hidden');
|
this.emit('hidden');
|
||||||
|
// Handle any calls to show* while we were hiding
|
||||||
|
if (this._shown || this._shownTemporarily)
|
||||||
|
this._animateVisible();
|
||||||
|
|
||||||
|
this._syncInputMode();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Signals.addSignalMethods(Overview.prototype);
|
Signals.addSignalMethods(Overview.prototype);
|
||||||
|
Loading…
Reference in New Issue
Block a user