layout: add chrome actors directly to uiGroup

Rather than having a single chrome layer and putting all of the chrome
into that, put the chrome actors directly into uiGroup, so that they
can be stacked independently of one another relative to other actors.

(This requires making uiGroup a ShellGenericContainer, so we can use
skip_paint to avoid painting non-visibleInFullscreen chrome when we're
in fullscreen.)

https://bugzilla.gnome.org/show_bug.cgi?id=657986
This commit is contained in:
Dan Winship 2011-09-01 10:20:52 -04:00
parent cbb3831c7b
commit e79c093d80
3 changed files with 40 additions and 31 deletions

View File

@ -309,11 +309,11 @@ LayoutManager.prototype = {
},
// addChrome:
// @actor: an actor to add to the chrome layer
// @actor: an actor to add to the chrome
// @params: (optional) additional params
//
// Adds @actor to the chrome layer and (unless %affectsInputRegion
// in @params is %false) extends the input region to include it.
// Adds @actor to the chrome, and (unless %affectsInputRegion in
// @params is %false) extends the input region to include it.
// Changes in @actor's size, position, and visibility will
// automatically result in appropriate changes to the input
// region.
@ -355,9 +355,9 @@ LayoutManager.prototype = {
},
// removeChrome:
// @actor: a child of the chrome layer
// @actor: a chrome actor
//
// Removes @actor from the chrome layer
// Removes @actor from the chrome
removeChrome: function(actor) {
this._chrome.removeActor(actor);
}
@ -556,11 +556,6 @@ Chrome.prototype = {
_init: function(layoutManager) {
this._layoutManager = layoutManager;
// The group itself has zero size so it doesn't interfere with DND
this.actor = new Shell.GenericContainer({ width: 0, height: 0 });
Main.uiGroup.add_actor(this.actor);
this.actor.connect('allocate', Lang.bind(this, this._allocated));
this._monitors = [];
this._inOverview = false;
this._updateRegionIdle = 0;
@ -577,6 +572,7 @@ Chrome.prototype = {
global.screen.connect('notify::n-workspaces',
Lang.bind(this, this._queueUpdateRegions));
this._screenSaverActive = false;
this._screenSaverProxy = new ScreenSaver.ScreenSaverProxy();
this._screenSaverProxy.connect('ActiveChanged', Lang.bind(this, this._onScreenSaverActiveChanged));
this._screenSaverProxy.GetActiveRemote(Lang.bind(this,
@ -595,14 +591,8 @@ Chrome.prototype = {
Lang.bind(this, this._overviewHidden));
},
_allocated: function(actor, box, flags) {
let children = this.actor.get_children();
for (let i = 0; i < children.length; i++)
children[i].allocate_preferred_size(flags);
},
addActor: function(actor, params) {
this.actor.add_actor(actor);
Main.uiGroup.add_actor(actor);
this._trackActor(actor, params);
},
@ -614,7 +604,7 @@ Chrome.prototype = {
index = this._findActor(ancestor);
}
if (!ancestor)
throw new Error('actor is not a descendent of the chrome layer');
throw new Error('actor is not a descendent of a chrome actor');
let ancestorData = this._trackedActors[index];
if (!params)
@ -634,7 +624,7 @@ Chrome.prototype = {
},
removeActor: function(actor) {
this.actor.remove_actor(actor);
Main.uiGroup.remove_actor(actor);
this._untrackActor(actor);
},
@ -653,6 +643,7 @@ Chrome.prototype = {
let actorData = Params.parse(params, defaultParams);
actorData.actor = actor;
actorData.isToplevel = actor.get_parent() == Main.uiGroup;
actorData.visibleId = actor.connect('notify::visible',
Lang.bind(this, this._queueUpdateRegions));
actorData.allocationId = actor.connect('notify::allocation',
@ -682,18 +673,29 @@ Chrome.prototype = {
},
_actorReparented: function(actor, oldParent) {
if (!this.actor.contains(actor))
let newParent = actor.get_parent();
if (!newParent)
this._untrackActor(actor);
else
actorData.isToplevel = (newParent == Main.uiGroup);
},
_updateVisibility: function() {
for (let i = 0; i < this._trackedActors.length; i++) {
let actorData = this._trackedActors[i];
if (!this._inOverview && !actorData.visibleInFullscreen &&
this._findMonitorForActor(actorData.actor).inFullscreen)
this.actor.set_skip_paint(actorData.actor, true);
let actorData = this._trackedActors[i], visible;
if (!actorData.isToplevel)
continue;
if (this._screenSaverActive)
visible = false;
else if (this._inOverview)
visible = true;
else if (!actorData.visibleInFullscreen &&
this._findMonitorForActor(actorData.actor).inFullscreen)
visible = false;
else
this.actor.set_skip_paint(actorData.actor, false);
visible = true;
Main.uiGroup.set_skip_paint(actorData.actor, !visible);
}
},
@ -719,7 +721,8 @@ Chrome.prototype = {
},
_onScreenSaverActiveChanged: function(proxy, screenSaverActive) {
this.actor.visible = !screenSaverActive;
this._screenSaverActive = screenSaverActive;
this._updateVisibility();
this._queueUpdateRegions();
},
@ -783,7 +786,7 @@ Chrome.prototype = {
for (let i = 0; i < this._monitors.length; i++)
this._monitors[i].inFullscreen = false;
// The chrome layer should be visible unless there is a window
// Ordinary chrome should be visible unless there is a window
// with layer FULLSCREEN, or a window with layer
// OVERRIDE_REDIRECT that covers the whole screen.
// ('override_redirect' is not actually a layer above all
@ -864,7 +867,7 @@ Chrome.prototype = {
if (actorData.affectsInputRegion &&
actorData.actor.get_paint_visibility() &&
!this.actor.get_skip_paint(actorData.actor))
!Main.uiGroup.get_skip_paint(actorData.actor))
rects.push(rect);
if (!actorData.affectsStruts)

View File

@ -974,7 +974,7 @@ LookingGlass.prototype = {
this._notebook.selectIndex(0);
this.actor.show();
this.actor.lower_bottom();
this.actor.lower(Main.layoutManager.panelBox);
this._open = true;
this._history.lastItem();
@ -1005,7 +1005,7 @@ LookingGlass.prototype = {
Main.popModal(this._entry);
this.actor.lower_bottom();
this.actor.lower(Main.layoutManager.panelBox);
Tweener.addTween(this.actor, { time: 0.5 / St.get_slow_down_factor(),
transition: 'easeOutQuad',
y: this._hiddenY,

View File

@ -193,7 +193,13 @@ function start() {
loadTheme();
// Set up stage hierarchy to group all UI actors under one container.
uiGroup = new Clutter.Group();
uiGroup = new Shell.GenericContainer({ name: 'uiGroup' });
uiGroup.connect('allocate',
function (actor, box, flags) {
let children = uiGroup.get_children();
for (let i = 0; i < children.length; i++)
children[i].allocate_preferred_size(flags);
});
St.set_ui_root(global.stage, uiGroup);
global.window_group.reparent(uiGroup);
global.overlay_group.reparent(uiGroup);