layout: Merge Chrome and LayoutManager
The two classes have been gaining each other's functionality for a little while, adding the new code wherever it was more convenient. Rather than have a clear delineation between "This Manages Shell Chrome" and "This Manages Shell Layout", I think it's better off if we just accept that the responsibilities are pretty much the same. https://bugzilla.gnome.org/show_bug.cgi?id=692677
This commit is contained in:
parent
72405cd43f
commit
8e231cb2ec
231
js/ui/layout.js
231
js/ui/layout.js
@ -95,6 +95,12 @@ const MonitorConstraint = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const defaultParams = {
|
||||
trackFullscreen: false,
|
||||
affectsStruts: false,
|
||||
affectsInputRegion: true
|
||||
};
|
||||
|
||||
const LayoutManager = new Lang.Class({
|
||||
Name: 'LayoutManager',
|
||||
|
||||
@ -110,7 +116,10 @@ const LayoutManager = new Lang.Class({
|
||||
this._rightPanelBarrier = 0;
|
||||
this._trayBarrier = 0;
|
||||
|
||||
this._chrome = new Chrome(this);
|
||||
this._inOverview = false;
|
||||
this._updateRegionIdle = 0;
|
||||
|
||||
this._trackedActors = [];
|
||||
|
||||
this.screenShieldGroup = new St.Widget({ name: 'screenShieldGroup',
|
||||
visible: false,
|
||||
@ -136,22 +145,40 @@ const LayoutManager = new Lang.Class({
|
||||
this.addChrome(this.keyboardBox);
|
||||
this._keyboardHeightNotifyId = 0;
|
||||
|
||||
// Need to update struts on new workspaces when they are added
|
||||
global.screen.connect('notify::n-workspaces',
|
||||
Lang.bind(this, this._queueUpdateRegions));
|
||||
global.screen.connect('restacked',
|
||||
Lang.bind(this, this._windowsRestacked));
|
||||
global.screen.connect('monitors-changed',
|
||||
Lang.bind(this, this._monitorsChanged));
|
||||
this._monitorsChanged();
|
||||
|
||||
this._chrome.connect('primary-fullscreen-changed', Lang.bind(this, function(chrome, state) {
|
||||
this.emit('primary-fullscreen-changed', state);
|
||||
}));
|
||||
},
|
||||
|
||||
// This is called by Main after everything else is constructed;
|
||||
// Chrome.init() needs access to Main.overview, which didn't exist
|
||||
// it needs access to Main.overview, which didn't exist
|
||||
// yet when the LayoutManager was constructed.
|
||||
init: function() {
|
||||
this._chrome.init();
|
||||
Main.overview.connect('showing', Lang.bind(this, this._overviewShowing));
|
||||
Main.overview.connect('hidden', Lang.bind(this, this._overviewHidden));
|
||||
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
|
||||
},
|
||||
|
||||
this._startupAnimation();
|
||||
_overviewShowing: function() {
|
||||
this._inOverview = true;
|
||||
this._updateVisibility();
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
_overviewHidden: function() {
|
||||
this._inOverview = false;
|
||||
this._updateVisibility();
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
_sessionUpdated: function() {
|
||||
this._updateVisibility();
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
_updateMonitors: function() {
|
||||
@ -230,7 +257,7 @@ const LayoutManager = new Lang.Class({
|
||||
let corner = new HotCorner();
|
||||
this._hotCorners.push(corner);
|
||||
corner.actor.set_position(cornerX, cornerY);
|
||||
this._chrome.addActor(corner.actor);
|
||||
this.addChrome(corner.actor);
|
||||
}
|
||||
},
|
||||
|
||||
@ -287,6 +314,9 @@ const LayoutManager = new Lang.Class({
|
||||
this._updateMonitors();
|
||||
this._updateBoxes();
|
||||
this._updateHotCorners();
|
||||
this._updateFullscreen();
|
||||
this._updateVisibility();
|
||||
this._queueUpdateRegions();
|
||||
|
||||
this.emit('monitors-changed');
|
||||
},
|
||||
@ -321,11 +351,11 @@ const LayoutManager = new Lang.Class({
|
||||
global.stage_input_mode == Shell.StageInputMode.FULLSCREEN) {
|
||||
let focusActor = global.stage.key_focus;
|
||||
if (focusActor)
|
||||
i = this._chrome.findIndexForActor(focusActor);
|
||||
i = this.findIndexForActor(focusActor);
|
||||
} else {
|
||||
let focusWindow = global.display.focus_window;
|
||||
if (focusWindow)
|
||||
i = this._chrome.findIndexForWindow(focusWindow);
|
||||
i = this.findIndexForWindow(focusWindow);
|
||||
}
|
||||
|
||||
return i;
|
||||
@ -374,8 +404,7 @@ const LayoutManager = new Lang.Class({
|
||||
},
|
||||
|
||||
_fadeBackgroundComplete: function() {
|
||||
// Don't animate the strut
|
||||
this._chrome.freezeUpdateRegions();
|
||||
this._freezeUpdateRegions();
|
||||
|
||||
if (this._background != null) {
|
||||
this._background.destroy();
|
||||
@ -393,7 +422,7 @@ const LayoutManager = new Lang.Class({
|
||||
|
||||
_startupAnimationComplete: function() {
|
||||
this.emit('panel-box-changed');
|
||||
this._chrome.thawUpdateRegions();
|
||||
this._thawUpdateRegions();
|
||||
},
|
||||
|
||||
showKeyboard: function () {
|
||||
@ -420,7 +449,7 @@ const LayoutManager = new Lang.Class({
|
||||
_showKeyboardComplete: function() {
|
||||
// Poke Chrome to update the input shape; it doesn't notice
|
||||
// anchor point changes
|
||||
this._chrome.updateRegions();
|
||||
this._updateRegions();
|
||||
|
||||
this._keyboardHeightNotifyId = this.keyboardBox.connect('notify::height', Lang.bind(this, function () {
|
||||
this.keyboardBox.anchor_y = this.keyboardBox.height;
|
||||
@ -454,7 +483,7 @@ const LayoutManager = new Lang.Class({
|
||||
},
|
||||
|
||||
_hideKeyboardComplete: function() {
|
||||
this._chrome.updateRegions();
|
||||
this._updateRegions();
|
||||
},
|
||||
|
||||
// addChrome:
|
||||
@ -477,7 +506,8 @@ const LayoutManager = new Lang.Class({
|
||||
// monitor (it will be hidden whenever a fullscreen window is visible,
|
||||
// and shown otherwise)
|
||||
addChrome: function(actor, params) {
|
||||
this._chrome.addActor(actor, params);
|
||||
Main.uiGroup.add_actor(actor);
|
||||
this._trackActor(actor, params);
|
||||
},
|
||||
|
||||
// trackChrome:
|
||||
@ -492,83 +522,6 @@ const LayoutManager = new Lang.Class({
|
||||
// though some possibilities don't make sense. By default, @actor has
|
||||
// the same params as its chrome ancestor.
|
||||
trackChrome: function(actor, params) {
|
||||
this._chrome.trackActor(actor, params);
|
||||
},
|
||||
|
||||
// untrackChrome:
|
||||
// @actor: an actor previously tracked via trackChrome()
|
||||
//
|
||||
// Undoes the effect of trackChrome()
|
||||
untrackChrome: function(actor) {
|
||||
this._chrome.untrackActor(actor);
|
||||
},
|
||||
|
||||
// removeChrome:
|
||||
// @actor: a chrome actor
|
||||
//
|
||||
// Removes @actor from the chrome
|
||||
removeChrome: function(actor) {
|
||||
this._chrome.removeActor(actor);
|
||||
},
|
||||
|
||||
findMonitorForActor: function(actor) {
|
||||
return this.monitors[this._chrome.findIndexForActor(actor)];
|
||||
},
|
||||
|
||||
findMonitorForWindow: function(window) {
|
||||
return this.monitors[this._chrome.findIndexForWindow(window)];
|
||||
},
|
||||
});
|
||||
Signals.addSignalMethods(LayoutManager.prototype);
|
||||
|
||||
|
||||
// This manages the shell "chrome"; the UI that's visible in the
|
||||
// normal mode (ie, outside the Overview), that surrounds the main
|
||||
// workspace content.
|
||||
|
||||
const defaultParams = {
|
||||
trackFullscreen: false,
|
||||
affectsStruts: false,
|
||||
affectsInputRegion: true
|
||||
};
|
||||
|
||||
const Chrome = new Lang.Class({
|
||||
Name: 'Chrome',
|
||||
|
||||
_init: function(layoutManager) {
|
||||
this._layoutManager = layoutManager;
|
||||
|
||||
this._monitors = [];
|
||||
this._inOverview = false;
|
||||
this._updateRegionIdle = 0;
|
||||
this._freezeUpdateCount = 0;
|
||||
|
||||
this._trackedActors = [];
|
||||
|
||||
this._layoutManager.connect('monitors-changed',
|
||||
Lang.bind(this, this._relayout));
|
||||
global.screen.connect('restacked',
|
||||
Lang.bind(this, this._windowsRestacked));
|
||||
|
||||
// Need to update struts on new workspaces when they are added
|
||||
global.screen.connect('notify::n-workspaces',
|
||||
Lang.bind(this, this._queueUpdateRegions));
|
||||
|
||||
this._relayout();
|
||||
},
|
||||
|
||||
init: function() {
|
||||
Main.overview.connect('showing', Lang.bind(this, this._overviewShowing));
|
||||
Main.overview.connect('hidden', Lang.bind(this, this._overviewHidden));
|
||||
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
|
||||
},
|
||||
|
||||
addActor: function(actor, params) {
|
||||
Main.uiGroup.add_actor(actor);
|
||||
this._trackActor(actor, params);
|
||||
},
|
||||
|
||||
trackActor: function(actor, params) {
|
||||
let ancestor = actor.get_parent();
|
||||
let index = this._findActor(ancestor);
|
||||
while (ancestor && index == -1) {
|
||||
@ -591,11 +544,19 @@ const Chrome = new Lang.Class({
|
||||
this._trackActor(actor, params);
|
||||
},
|
||||
|
||||
untrackActor: function(actor) {
|
||||
// untrackChrome:
|
||||
// @actor: an actor previously tracked via trackChrome()
|
||||
//
|
||||
// Undoes the effect of trackChrome()
|
||||
untrackChrome: function(actor) {
|
||||
this._untrackActor(actor);
|
||||
},
|
||||
|
||||
removeActor: function(actor) {
|
||||
// removeChrome:
|
||||
// @actor: a chrome actor
|
||||
//
|
||||
// Removes @actor from the chrome
|
||||
removeChrome: function(actor) {
|
||||
Main.uiGroup.remove_actor(actor);
|
||||
this._untrackActor(actor);
|
||||
},
|
||||
@ -673,46 +634,19 @@ const Chrome = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_overviewShowing: function() {
|
||||
this._inOverview = true;
|
||||
this._updateVisibility();
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
_overviewHidden: function() {
|
||||
this._inOverview = false;
|
||||
this._updateVisibility();
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
_sessionUpdated: function() {
|
||||
this._updateVisibility();
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
_relayout: function() {
|
||||
this._monitors = this._layoutManager.monitors;
|
||||
this._primaryIndex = this._layoutManager.primaryIndex;
|
||||
this._primaryMonitor = this._layoutManager.primaryMonitor;
|
||||
|
||||
this._updateFullscreen();
|
||||
this._updateVisibility();
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
_findMonitorForRect: function(x, y, w, h) {
|
||||
// First look at what monitor the center of the rectangle is at
|
||||
let cx = x + w/2;
|
||||
let cy = y + h/2;
|
||||
for (let i = 0; i < this._monitors.length; i++) {
|
||||
let monitor = this._monitors[i];
|
||||
for (let i = 0; i < this.monitors.length; i++) {
|
||||
let monitor = this.monitors[i];
|
||||
if (cx >= monitor.x && cx < monitor.x + monitor.width &&
|
||||
cy >= monitor.y && cy < monitor.y + monitor.height)
|
||||
return i;
|
||||
}
|
||||
// If the center is not on a monitor, return the first overlapping monitor
|
||||
for (let i = 0; i < this._monitors.length; i++) {
|
||||
let monitor = this._monitors[i];
|
||||
for (let i = 0; i < this.monitors.length; i++) {
|
||||
let monitor = this.monitors[i];
|
||||
if (x + w > monitor.x && x < monitor.x + monitor.width &&
|
||||
y + h > monitor.y && y < monitor.y + monitor.height)
|
||||
return i;
|
||||
@ -726,7 +660,7 @@ const Chrome = new Lang.Class({
|
||||
let i = this._findMonitorForRect(rect.x, rect.y, rect.width, rect.height);
|
||||
if (i >= 0)
|
||||
return i;
|
||||
return this._primaryIndex; // Not on any monitor, pretend its on the primary
|
||||
return this.primaryIndex; // Not on any monitor, pretend its on the primary
|
||||
},
|
||||
|
||||
// This call guarantees that we return some monitor to simplify usage of it
|
||||
@ -737,35 +671,35 @@ const Chrome = new Lang.Class({
|
||||
let i = this._findMonitorForRect(x, y, w, h);
|
||||
if (i >= 0)
|
||||
return i;
|
||||
return this._primaryIndex; // Not on any monitor, pretend its on the primary
|
||||
return this.primaryIndex; // Not on any monitor, pretend its on the primary
|
||||
},
|
||||
|
||||
findMonitorForWindow: function(window) {
|
||||
let rect = window.get_input_rect();
|
||||
let i = this._findMonitorForRect(rect.x, rect.y, rect.width, rect.height);
|
||||
if (i >= 0)
|
||||
return this._monitors[i];
|
||||
return this.monitors[i];
|
||||
else
|
||||
return null;
|
||||
},
|
||||
|
||||
findMonitorForActor: function(actor) {
|
||||
return this._monitors[this.findIndexForActor(actor)];
|
||||
return this.monitors[this.findIndexForActor(actor)];
|
||||
},
|
||||
|
||||
_queueUpdateRegions: function() {
|
||||
if (!this._updateRegionIdle && !this._freezeUpdateCount)
|
||||
this._updateRegionIdle = Mainloop.idle_add(Lang.bind(this, this.updateRegions),
|
||||
this._updateRegionIdle = Mainloop.idle_add(Lang.bind(this, this._updateRegions),
|
||||
Meta.PRIORITY_BEFORE_REDRAW);
|
||||
},
|
||||
|
||||
freezeUpdateRegions: function() {
|
||||
_freezeUpdateRegions: function() {
|
||||
if (this._updateRegionIdle)
|
||||
this.updateRegions();
|
||||
this._updateRegions();
|
||||
this._freezeUpdateCount++;
|
||||
},
|
||||
|
||||
thawUpdateRegions: function() {
|
||||
_thawUpdateRegions: function() {
|
||||
this._freezeUpdateCount--;
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
@ -774,8 +708,8 @@ const Chrome = new Lang.Class({
|
||||
let windows = Main.getWindowActorsForWorkspace(global.screen.get_active_workspace_index());
|
||||
|
||||
// Reset all monitors to not fullscreen
|
||||
for (let i = 0; i < this._monitors.length; i++)
|
||||
this._monitors[i].inFullscreen = false;
|
||||
for (let i = 0; i < this.monitors.length; i++)
|
||||
this.monitors[i].inFullscreen = false;
|
||||
|
||||
// Ordinary chrome should be visible unless there is a window
|
||||
// with layer FULLSCREEN, or a window with layer
|
||||
@ -811,8 +745,8 @@ const Chrome = new Lang.Class({
|
||||
window.height == global.screen_height);
|
||||
|
||||
if (isScreenSized) {
|
||||
for (let i = 0; i < this._monitors.length; i++)
|
||||
this._monitors[i].inFullscreen = true;
|
||||
for (let i = 0; i < this.monitors.length; i++)
|
||||
this.monitors[i].inFullscreen = true;
|
||||
}
|
||||
|
||||
// Or whether it is monitor sized
|
||||
@ -830,16 +764,16 @@ const Chrome = new Lang.Class({
|
||||
|
||||
_windowsRestacked: function() {
|
||||
let wasInFullscreen = [];
|
||||
for (let i = 0; i < this._monitors.length; i++)
|
||||
wasInFullscreen[i] = this._monitors[i].inFullscreen;
|
||||
for (let i = 0; i < this.monitors.length; i++)
|
||||
wasInFullscreen[i] = this.monitors[i].inFullscreen;
|
||||
|
||||
let primaryWasInFullscreen = this._primaryMonitor.inFullscreen;
|
||||
let primaryWasInFullscreen = this.primaryMonitor.inFullscreen;
|
||||
|
||||
this._updateFullscreen();
|
||||
|
||||
let changed = false;
|
||||
for (let i = 0; i < wasInFullscreen.length; i++) {
|
||||
if (wasInFullscreen[i] != this._monitors[i].inFullscreen) {
|
||||
if (wasInFullscreen[i] != this.monitors[i].inFullscreen) {
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
@ -850,12 +784,12 @@ const Chrome = new Lang.Class({
|
||||
this._queueUpdateRegions();
|
||||
}
|
||||
|
||||
if (primaryWasInFullscreen != this._primaryMonitor.inFullscreen) {
|
||||
this.emit('primary-fullscreen-changed', this._primaryMonitor.inFullscreen);
|
||||
if (primaryWasInFullscreen != this.primaryMonitor.inFullscreen) {
|
||||
this.emit('primary-fullscreen-changed', this.primaryMonitor.inFullscreen);
|
||||
}
|
||||
},
|
||||
|
||||
updateRegions: function() {
|
||||
_updateRegions: function() {
|
||||
let rects = [], struts = [], i;
|
||||
|
||||
if (this._updateRegionIdle) {
|
||||
@ -908,7 +842,7 @@ const Chrome = new Lang.Class({
|
||||
// the width/height across the middle of the screen, then
|
||||
// we don't create a strut for it at all.
|
||||
let side;
|
||||
let primary = this._primaryMonitor;
|
||||
let primary = this.primaryMonitor;
|
||||
if (x1 <= primary.x && x2 >= primary.x + primary.width) {
|
||||
if (y1 <= primary.y)
|
||||
side = Meta.Side.TOP;
|
||||
@ -967,8 +901,7 @@ const Chrome = new Lang.Class({
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
Signals.addSignalMethods(Chrome.prototype);
|
||||
Signals.addSignalMethods(LayoutManager.prototype);
|
||||
|
||||
|
||||
// HotCorner:
|
||||
|
Loading…
Reference in New Issue
Block a user