2011-06-13 13:54:05 +00:00
|
|
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
|
|
|
|
|
|
const Lang = imports.lang;
|
|
|
|
const Signals = imports.signals;
|
|
|
|
const St = imports.gi.St;
|
|
|
|
|
|
|
|
const Main = imports.ui.main;
|
|
|
|
const Panel = imports.ui.panel;
|
|
|
|
|
|
|
|
function LayoutManager() {
|
|
|
|
this._init.apply(this, arguments);
|
|
|
|
}
|
|
|
|
|
|
|
|
LayoutManager.prototype = {
|
|
|
|
_init: function () {
|
|
|
|
this._rtl = (St.Widget.get_default_direction() == St.TextDirection.RTL);
|
|
|
|
this.monitors = [];
|
|
|
|
this.primaryMonitor = null;
|
|
|
|
this.primaryIndex = -1;
|
|
|
|
this._hotCorners = [];
|
|
|
|
|
|
|
|
this._updateMonitors();
|
|
|
|
},
|
|
|
|
|
|
|
|
// This is called by Main after everything else is constructed;
|
|
|
|
// _updateHotCorners needs access to Main.panel, which didn't exist
|
|
|
|
// yet when the LayoutManager was constructed.
|
|
|
|
init: function() {
|
|
|
|
global.screen.connect('monitors-changed', Lang.bind(this, this._monitorsChanged));
|
|
|
|
this._updateHotCorners();
|
|
|
|
},
|
|
|
|
|
|
|
|
_updateMonitors: function() {
|
|
|
|
let screen = global.screen;
|
|
|
|
|
|
|
|
this.monitors = [];
|
|
|
|
let nMonitors = screen.get_n_monitors();
|
|
|
|
for (let i = 0; i < nMonitors; i++)
|
|
|
|
this.monitors.push(screen.get_monitor_geometry(i));
|
|
|
|
|
2011-06-13 14:37:10 +00:00
|
|
|
if (nMonitors == 1) {
|
|
|
|
this.primaryIndex = this.bottomIndex = 0;
|
|
|
|
} else {
|
|
|
|
// If there are monitors below the primary, then we need
|
|
|
|
// to split primary from bottom.
|
|
|
|
this.primaryIndex = this.bottomIndex = screen.get_primary_monitor();
|
|
|
|
for (let i = 0; i < this.monitors.length; i++) {
|
|
|
|
let monitor = this.monitors[i];
|
|
|
|
if (this._isAboveOrBelowPrimary(monitor)) {
|
|
|
|
if (monitor.y > this.monitors[this.bottomIndex].y)
|
|
|
|
this.bottomIndex = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-06-13 13:54:05 +00:00
|
|
|
this.primaryMonitor = this.monitors[this.primaryIndex];
|
2011-06-13 14:37:10 +00:00
|
|
|
this.bottomMonitor = this.monitors[this.bottomIndex];
|
2011-06-13 13:54:05 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
_updateHotCorners: function() {
|
|
|
|
// destroy old hot corners
|
|
|
|
for (let i = 0; i < this._hotCorners.length; i++)
|
|
|
|
this._hotCorners[i].destroy();
|
|
|
|
this._hotCorners = [];
|
|
|
|
|
|
|
|
// build new hot corners
|
|
|
|
for (let i = 0; i < this.monitors.length; i++) {
|
|
|
|
let monitor = this.monitors[i];
|
|
|
|
let cornerX = this._rtl ? monitor.x + monitor.width : monitor.x;
|
|
|
|
let cornerY = monitor.y;
|
|
|
|
|
|
|
|
let haveTopLeftCorner = true;
|
|
|
|
|
|
|
|
if (i != this.primaryIndex) {
|
|
|
|
// Check if we have a top left (right for RTL) corner.
|
|
|
|
// I.e. if there is no monitor directly above or to the left(right)
|
|
|
|
let besideX = this._rtl ? monitor.x + 1 : cornerX - 1;
|
|
|
|
let besideY = cornerY;
|
|
|
|
let aboveX = cornerX;
|
|
|
|
let aboveY = cornerY - 1;
|
|
|
|
|
|
|
|
for (let j = 0; j < this.monitors.length; j++) {
|
|
|
|
if (i == j)
|
|
|
|
continue;
|
|
|
|
let otherMonitor = this.monitors[j];
|
|
|
|
if (besideX >= otherMonitor.x &&
|
|
|
|
besideX < otherMonitor.x + otherMonitor.width &&
|
|
|
|
besideY >= otherMonitor.y &&
|
|
|
|
besideY < otherMonitor.y + otherMonitor.height) {
|
|
|
|
haveTopLeftCorner = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (aboveX >= otherMonitor.x &&
|
|
|
|
aboveX < otherMonitor.x + otherMonitor.width &&
|
|
|
|
aboveY >= otherMonitor.y &&
|
|
|
|
aboveY < otherMonitor.y + otherMonitor.height) {
|
|
|
|
haveTopLeftCorner = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!haveTopLeftCorner)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
let corner = new Panel.HotCorner(i == this.primaryIndex ? Main.panel.button : null);
|
|
|
|
this._hotCorners.push(corner);
|
|
|
|
corner.actor.set_position(cornerX, cornerY);
|
|
|
|
if (i == this.primaryIndex)
|
|
|
|
Main.panel.setHotCorner(corner);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
_monitorsChanged: function() {
|
|
|
|
this._updateMonitors();
|
|
|
|
this._updateHotCorners();
|
|
|
|
|
|
|
|
this.emit('monitors-changed');
|
|
|
|
},
|
|
|
|
|
2011-06-13 14:37:10 +00:00
|
|
|
_isAboveOrBelowPrimary: function(monitor) {
|
|
|
|
let primary = this.monitors[this.primaryIndex];
|
|
|
|
let monitorLeft = monitor.x, monitorRight = monitor.x + monitor.width;
|
|
|
|
let primaryLeft = primary.x, primaryRight = primary.x + primary.width;
|
|
|
|
|
|
|
|
if ((monitorLeft >= primaryLeft && monitorLeft <= primaryRight) ||
|
|
|
|
(monitorRight >= primaryLeft && monitorRight <= primaryRight) ||
|
|
|
|
(primaryLeft >= monitorLeft && primaryLeft <= monitorRight) ||
|
|
|
|
(primaryRight >= monitorLeft && primaryRight <= monitorRight))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
2011-06-13 13:54:05 +00:00
|
|
|
get focusIndex() {
|
|
|
|
let screen = global.screen;
|
|
|
|
let display = screen.get_display();
|
|
|
|
let focusWindow = display.focus_window;
|
|
|
|
|
|
|
|
if (focusWindow) {
|
|
|
|
let wrect = focusWindow.get_outer_rect();
|
|
|
|
for (let i = 0; i < this.monitors.length; i++) {
|
|
|
|
let monitor = this.monitors[i];
|
|
|
|
|
|
|
|
if (monitor.x <= wrect.x && monitor.y <= wrect.y &&
|
|
|
|
monitor.x + monitor.width > wrect.x &&
|
|
|
|
monitor.y + monitor.height > wrect.y)
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.primaryIndex;
|
|
|
|
},
|
|
|
|
|
|
|
|
get focusMonitor() {
|
|
|
|
return this.monitors[this.focusIndex];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Signals.addSignalMethods(LayoutManager.prototype);
|