[gnome-shell] Sync clone stacking order with MetaStackTracker
- From: Colin Walters <walters src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-shell] Sync clone stacking order with MetaStackTracker
- Date: Thu, 1 Oct 2009 19:58:47 +0000 (UTC)
commit 20b29ff48fa992c83228cb25cb01842123558749
Author: Colin Walters <walters verbum org>
Date: Mon Sep 28 19:48:03 2009 -0400
Sync clone stacking order with MetaStackTracker
Previously, we initialized actor stacking order from the return
value of global.get_windows() once, which is defined to be in
stack order. However it was not updated later. Furthermore,
the way stackAbove was called from onAnimationComplete in
WindowClone was highly dubious, since there are lots of animations
which apply to the clones, and we want the stacking to be right
all of the time, not when some animation completes.
Fix this by connecting to 'restacked' on the screen and syncing
the clones.
I also snuck in another bugfix here; we weren't disconnecting
from the 'showing' signal handler, which had various bad
consequences.
https://bugzilla.gnome.org/show_bug.cgi?id=596263
js/ui/workspaces.js | 123 +++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 99 insertions(+), 24 deletions(-)
---
diff --git a/js/ui/workspaces.js b/js/ui/workspaces.js
index def2fd1..3f461d8 100644
--- a/js/ui/workspaces.js
+++ b/js/ui/workspaces.js
@@ -111,6 +111,8 @@ WindowClone.prototype = {
this.origX = realWindow.x;
this.origY = realWindow.y;
+ this._stackAbove = null;
+
this._title = null;
this.actor.connect('button-release-event',
@@ -129,6 +131,8 @@ WindowClone.prototype = {
this._draggable.connect('drag-begin', Lang.bind(this, this._onDragBegin));
this._draggable.connect('drag-end', Lang.bind(this, this._onDragEnd));
this._inDrag = false;
+
+ this._zooming = false;
},
setVisibleWithChrome: function(visible) {
@@ -143,6 +147,14 @@ WindowClone.prototype = {
}
},
+ setStackAbove: function (actor) {
+ this._stackAbove = actor;
+ if (this._inDrag || this._zooming)
+ // We'll fix up the stack after the drag/zooming
+ return;
+ this.actor.raise(this._stackAbove);
+ },
+
destroy: function () {
this.actor.destroy();
if (this._title)
@@ -157,7 +169,6 @@ WindowClone.prototype = {
this._havePointer = true;
- actor.raise_top();
this._updateTitle();
},
@@ -206,6 +217,8 @@ WindowClone.prototype = {
},
_zoomStart : function () {
+ this._zooming = true;
+
this._zoomLightbox = new Lightbox.Lightbox(global.stage);
this._zoomLocalOrig = new ScaledPoint(this.actor.x, this.actor.y, this.actor.scale_x, this.actor.scale_y);
@@ -232,7 +245,10 @@ WindowClone.prototype = {
},
_zoomEnd : function () {
+ this._zooming = false;
+
this.actor.reparent(this._origParent);
+ this.actor.raise(this._stackAbove);
[this.actor.x, this.actor.y] = this._zoomLocalOrig.getPosition();
[this.actor.scale_x, this.actor.scale_y] = this._zoomLocalOrig.getScale();
@@ -272,6 +288,12 @@ WindowClone.prototype = {
// mysteriously present
this._havePointer = false;
+ // We may not have a parent if DnD completed successfully, in
+ // which case our clone will shortly be destroyed and replaced
+ // with a new one on the target workspace.
+ if (this.actor.get_parent() != null)
+ this.actor.raise(this._stackAbove);
+
this.emit('drag-end');
},
@@ -283,7 +305,6 @@ WindowClone.prototype = {
// Called by Tweener
onAnimationComplete : function () {
this._updateTitle();
- this.actor.raise(this.stackAbove);
},
_createTitle : function () {
@@ -618,12 +639,43 @@ Workspace.prototype = {
this._desktop.actor.height + 2 * FRAME_SIZE / this.actor.scale_y);
},
+ _isCloneVisible: function(clone) {
+ return this._showOnlyWindows == null || (clone.metaWindow in this._showOnlyWindows);
+ },
+
+ /**
+ * _getVisibleClones:
+ *
+ * Returns a list WindowClone objects where the clone isn't filtered
+ * out by any application filter. The clone for the desktop is excluded.
+ * The returned array will always be newly allocated; it is not in any
+ * defined order, and thus it's convenient to call .sort() with your
+ * choice of sorting function.
+ */
+ _getVisibleClones: function() {
+ let visible = [];
+
+ for (let i = 1; i < this._windows.length; i++) {
+ let clone = this._windows[i];
+
+ if (!this._isCloneVisible(clone))
+ continue;
+
+ visible.push(clone);
+ }
+ return visible;
+ },
+
+ _getVisibleWindows: function() {
+ return this._getVisibleClones().map(function (clone) { return clone.metaWindow; });
+ },
+
_resetCloneVisibility: function () {
for (let i = 1; i < this._windows.length; i++) {
let clone = this._windows[i];
let icon = this._windowIcons[i];
- if (this._showOnlyWindows != null && !(clone.metaWindow in this._showOnlyWindows)) {
+ if (!this._isCloneVisible(clone)) {
clone.setVisibleWithChrome(false);
icon.hide();
} else {
@@ -853,21 +905,12 @@ Workspace.prototype = {
positionWindows : function(workspaceZooming) {
let totalVisible = 0;
- let visibleWindows = [];
-
- for (let i = 1; i < this._windows.length; i++) {
- let clone = this._windows[i];
-
- if (this._showOnlyWindows != null && !(clone.metaWindow in this._showOnlyWindows))
- continue;
-
- visibleWindows.push(clone.metaWindow);
- }
+ let visibleWindows = this._getVisibleWindows();
+ // Start the animations
let slots = this._computeAllWindowSlots(visibleWindows.length);
visibleWindows = this._orderWindowsByMotionAndStartup(visibleWindows, slots);
- let previousWindow = this._windows[0];
for (let i = 0; i < visibleWindows.length; i++) {
let slot = slots[i];
let metaWindow = visibleWindows[i];
@@ -875,9 +918,6 @@ Workspace.prototype = {
let clone = metaWindow._delegate;
let icon = this._windowIcons[mainIndex];
- clone.stackAbove = previousWindow.actor;
- previousWindow = clone;
-
let [x, y, scale] = this._computeWindowRelativeLayout(metaWindow, slot);
icon.hide();
@@ -896,6 +936,24 @@ Workspace.prototype = {
}
},
+ syncStacking: function(stackIndices) {
+ let desktopClone = this._windows[0];
+
+ let visibleClones = this._getVisibleClones();
+ visibleClones.sort(function (a, b) { return stackIndices[a.metaWindow.get_stable_sequence()] - stackIndices[b.metaWindow.get_stable_sequence()]; });
+
+ for (let i = 0; i < visibleClones.length; i++) {
+ let clone = visibleClones[i];
+ let metaWindow = clone.metaWindow;
+ if (i == 0) {
+ clone.setStackAbove(desktopClone.actor);
+ } else {
+ let previousClone = visibleClones[i - 1];
+ clone.setStackAbove(previousClone.actor);
+ }
+ }
+ },
+
_fadeInWindowIcon: function (clone, icon) {
icon.opacity = 0;
icon.show();
@@ -1320,10 +1378,12 @@ Workspaces.prototype = {
// workspaces have been created. This cannot be done first because
// window movement depends on the Workspaces object being accessible
// as an Overview member.
- Main.overview.connect('showing',
- Lang.bind(this, function() {
- for (let w = 0; w < this._workspaces.length; w++)
- this._workspaces[w].zoomToOverview();
+ this._overviewShowingId =
+ Main.overview.connect('showing',
+ Lang.bind(this, function() {
+ this._onRestacked();
+ for (let w = 0; w < this._workspaces.length; w++)
+ this._workspaces[w].zoomToOverview();
}));
// Track changes to the number of workspaces
@@ -1333,6 +1393,9 @@ Workspaces.prototype = {
this._switchWorkspaceNotifyId =
global.window_manager.connect('switch-workspace',
Lang.bind(this, this._activeWorkspaceChanged));
+ this._restackedNotifyId =
+ global.screen.connect('restacked',
+ Lang.bind(this, this._onRestacked));
},
_lookupWorkspaceForMetaWindow: function (metaWindow) {
@@ -1422,9 +1485,6 @@ Workspaces.prototype = {
this._clearApplicationWindowSelection(false);
}
- let clone = this._lookupCloneForMetaWindow (metaWindow);
- clone.actor.raise_top();
-
Main.activateWindow(metaWindow, time);
Main.overview.hide();
},
@@ -1448,8 +1508,10 @@ Workspaces.prototype = {
this.actor.destroy();
this.actor = null;
+ Main.overview.disconnect(this._overviewShowingId);
global.screen.disconnect(this._nWorkspacesNotifyId);
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
+ global.screen.disconnect(this._restackedNotifyId);
},
getScale : function() {
@@ -1595,6 +1657,19 @@ Workspaces.prototype = {
this.actor.add_actor(workspace.actor);
},
+ _onRestacked: function() {
+ let stack = global.get_windows();
+ let stackIndices = {};
+
+ for (let i = 0; i < stack.length; i++) {
+ // Use the stable sequence for an integer to use as a hash key
+ stackIndices[stack[i].get_meta_window().get_stable_sequence()] = i;
+ }
+
+ for (let i = 0; i < this._workspaces.length; i++)
+ this._workspaces[i].syncStacking(stackIndices);
+ },
+
// Handles a drop onto the (+) button; assumes the new workspace
// has already been added
acceptNewWorkspaceDrop : function(source, dropActor, x, y, time) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]