Initial update to javascript class concept.

This commit is contained in:
spin83
2019-03-20 19:09:50 +01:00
parent 9c023670ee
commit a773cc5d70
6 changed files with 462 additions and 552 deletions

View File

@@ -41,6 +41,20 @@ const WORKSPACES_ONLY_ON_PRIMARY_ID = 'workspaces-only-on-primary';
const SHOW_INDICATOR_ID = 'show-indicator';
const SHOW_THUMBNAILS_SLIDER_ID = 'show-thumbnails-slider';
function copyClass (s, d) {
global.log(s.name +" > "+ d.name);
let propertyNames = Object.getOwnPropertyNames(s.prototype);
for (let pName of propertyNames.values()) {
global.log(" ) "+pName);
if (d.prototype.hasOwnProperty(pName)) continue;
if (pName === "prototype") continue;
if (pName === "constructor") continue;
global.log(pName);
let pDesc = Object.getOwnPropertyDescriptor(s.prototype, pName);
Object.defineProperty(d.prototype, pName, pDesc);
}
};
const MultiMonitorsAddOn = new Lang.Class({
Name: 'MultiMonitorsAddOn',

View File

@@ -18,6 +18,7 @@ along with this program; if not, visit https://www.gnu.org/licenses/.
const Lang = imports.lang;
const St = imports.gi.St;
const Gio = imports.gi.Gio;
const Util = imports.misc.util;
@@ -27,7 +28,9 @@ const PanelMenu = imports.ui.panelMenu;
const Gettext = imports.gettext.domain('multi-monitors-add-on');
const _ = Gettext.gettext;
const Convenience = imports.misc.extensionUtils.getCurrentExtension().imports.convenience;
const CE = imports.misc.extensionUtils.getCurrentExtension();
const Convenience = CE.imports.convenience;
const extensionPath = CE.path;
var MultiMonitorsIndicator = new Lang.Class({
Name: 'MultiMonitorsIndicator',
@@ -56,10 +59,12 @@ var MultiMonitorsIndicator = new Lang.Class({
Main.layoutManager.disconnect(this._viewMonitorsId);
},
_syncIndicatorsVisible() {
this._mmStatusIcon.visible = this._mmStatusIcon.get_children().some((actor) => {
return actor.visible;
});
_syncIndicatorsVisible() {
this._mmStatusIcon.visible = this._mmStatusIcon.get_children().some(a => a.visible);
},
_icon_name (icon, iconName) {
icon.set_gicon(Gio.icon_new_for_string(extensionPath+"/icons/"+iconName+".svg"));
},
_viewMonitors() {
@@ -74,10 +79,10 @@ var MultiMonitorsIndicator = new Lang.Class({
this._mmStatusIcon.add_child(icon);
icon.connect('notify::visible', this._syncIndicatorsVisible.bind(this));
if(this._leftRightIcon)
icon.icon_name = 'multi-monitors-l-symbolic';
if (this._leftRightIcon)
this._icon_name(icon, 'multi-monitors-l-symbolic');
else
icon.icon_name = 'multi-monitors-r-symbolic';
this._icon_name(icon, 'multi-monitors-r-symbolic');
this._leftRightIcon = !this._leftRightIcon;
}
this._syncIndicatorsVisible();

View File

@@ -1,10 +1,10 @@
{
"shell-version": ["3.24", "3.26", "3.28", "3.30"],
"shell-version": ["3.32"],
"uuid": "multi-monitors-add-on@spin83",
"name": "Multi Monitors Add-On",
"settings-schema": "org.gnome.shell.extensions.multi-monitors-add-on",
"gettext-domain": "multi-monitors-add-on",
"description": "Add multiple monitors overview and panel for gnome-shell.",
"url": "https://github.com/spin83/multi-monitors-add-on.git",
"version": 16.1
"version": 16.2
}

View File

@@ -16,6 +16,7 @@ along with this program; if not, visit https://www.gnu.org/licenses/.
*/
const Lang = imports.lang;
const Signals = imports.signals;
const St = imports.gi.St;
const Gio = imports.gi.Gio;
@@ -34,17 +35,15 @@ const DateMenu = imports.ui.dateMenu;
const Calendar = imports.ui.calendar;
const ExtensionUtils = imports.misc.extensionUtils;
const MultiMonitors = ExtensionUtils.getCurrentExtension();
const Convenience = MultiMonitors.imports.convenience;
const CE = ExtensionUtils.getCurrentExtension();
const MultiMonitors = CE.imports.extension;
const Convenience = CE.imports.convenience;
const Gettext_gtk30 = imports.gettext.domain('gtk30');
const gtk30_ = Gettext_gtk30.gettext;
const MultiMonitorsCalendar = new Lang.Class({
Name: 'MultiMonitorsCalendar',
Extends: Calendar.Calendar,
_init() {
const MultiMonitorsCalendar = class MultiMonitorsCalendar {
constructor() {
this._currentVersion = Config.PACKAGE_VERSION.split('.');
this._weekStart = Shell.util_get_week_start();
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.calendar' });
@@ -87,27 +86,25 @@ const MultiMonitorsCalendar = new Lang.Class({
this.actor.connect('destroy', this._onDestroy.bind(this));
this._buildHeader ();
},
}
_onDestroy(actor) {
this._settings.disconnect(this._showWeekdateKeyId);
}
});
};
Signals.addSignalMethods(MultiMonitorsCalendar.prototype);
MultiMonitors.copyClass(Calendar.Calendar, MultiMonitorsCalendar);
const MultiMonitorsEventsSection = new Lang.Class({
Name: 'MultiMonitorsEventsSection',
Extends: MessageList.MessageListSection,
_init() {
this._currentVersion = Config.PACKAGE_VERSION.split('.');
const MultiMonitorsEventsSection = class MultiMonitorsEventsSection extends MessageList.MessageListSection {
constructor() {
super();
this._currentVersion = Config.PACKAGE_VERSION.split('.');
this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
this._reloadEventsId = this._desktopSettings.connect('changed', this._reloadEvents.bind(this));
this._eventSource = new Calendar.EmptyEventSource();
this._messageById = new Map();
this.parent();
this._title = new St.Button({ style_class: 'events-section-title',
label: '',
x_align: St.Align.START,
@@ -123,39 +120,22 @@ const MultiMonitorsEventsSection = new Lang.Class({
this.actor.connect('destroy', this._onDestroy.bind(this));
this._appInstalledChanged();
},
}
_onDestroy(actor) {
this._desktopSettings.disconnect(this._reloadEventsId);
this._defaultAppSystem.disconnect(this._appInstalledChangedId);
},
}
};
MultiMonitors.copyClass(Calendar.EventsSection, MultiMonitorsEventsSection);
_ignoreEvent: Calendar.EventsSection.prototype._ignoreEvent,
setEventSource: Calendar.EventsSection.prototype.setEventSource,
get allowed() {
return Main.sessionMode.showCalendarEvents;
},
_updateTitle: Calendar.EventsSection.prototype._updateTitle,
_reloadEvents: Calendar.EventsSection.prototype._reloadEvents,
_appInstalledChanged: Calendar.EventsSection.prototype._appInstalledChanged,
_getCalendarApp: Calendar.EventsSection.prototype._getCalendarApp,
_onTitleClicked: Calendar.EventsSection.prototype._onTitleClicked,
setDate: Calendar.EventsSection.prototype.setDate,
_shouldShow: Calendar.EventsSection.prototype._shouldShow,
_sync: Calendar.EventsSection.prototype._sync
});
const MultiMonitorsNotificationSection = new Lang.Class({
Name: 'MultiMonitorsNotificationSection',
Extends: MessageList.MessageListSection,
_init() {
const MultiMonitorsNotificationSection = class MultiMonitorsNotificationSectione extends MessageList.MessageListSection {
constructor() {
super();
this._currentVersion = Config.PACKAGE_VERSION.split('.');
this.parent();
this._sources = new Map();
this._sources = new Map();
this._nUrgent = 0;
this._sourceAddedId = Main.messageTray.connect('source-added', this._sourceAdded.bind(this));
@@ -165,7 +145,7 @@ const MultiMonitorsNotificationSection = new Lang.Class({
this.actor.connect('notify::mapped', this._onMapped.bind(this));
this.actor.connect('destroy', this._onDestroy.bind(this));
},
}
_onDestroy(actor) {
Main.messageTray.disconnect(this._sourceAddedId);
@@ -173,25 +153,12 @@ const MultiMonitorsNotificationSection = new Lang.Class({
for ([source, obj] of this._sources.entries()) {
this._onSourceDestroy(source, obj);
}
},
}
};
MultiMonitors.copyClass(Calendar.NotificationSection, MultiMonitorsNotificationSection);
get allowed() {
return Main.sessionMode.hasNotifications &&
!Main.sessionMode.isGreeter;
},
_createTimeLabel: Calendar.NotificationSection.prototype._createTimeLabel,
_sourceAdded: Calendar.NotificationSection.prototype._sourceAdded,
_onNotificationAdded: Calendar.NotificationSection.prototype._onNotificationAdded,
_onSourceDestroy: Calendar.NotificationSection.prototype._onSourceDestroy,
_onMapped: Calendar.NotificationSection.prototype._onMapped
});
const MultiMonitorsCalendarMessageList = new Lang.Class({
Name: 'MultiMonitorsCalendarMessageList',
Extends: Calendar.CalendarMessageList,
_init() {
const MultiMonitorsCalendarMessageList = class MultiMonitorsCalendarMessageList {
constructor() {
this._currentVersion = Config.PACKAGE_VERSION.split('.');
this.actor = new St.Widget({ style_class: 'message-list',
@@ -242,18 +209,19 @@ const MultiMonitorsCalendarMessageList = new Lang.Class({
this._destroy = false;
this.actor.connect('destroy', this._onDestroy.bind(this));
},
}
_onDestroy(actor) {
this._destroy = true;
Main.sessionMode.disconnect(this._sessionModeUpdatedId);
},
}
_sync() {
if (this._destroy) return;
this.parent();
Calendar.CalendarMessageList.prototype._sync.call(this);
}
});
};
MultiMonitors.copyClass(Calendar.CalendarMessageList, MultiMonitorsCalendarMessageList);
var MultiMonitorsDateMenuButton = new Lang.Class({
Name: 'MultiMonitorsDateMenuButton',

View File

@@ -16,6 +16,7 @@ along with this program; if not, visit https://www.gnu.org/licenses/.
*/
const Lang = imports.lang;
const Signals = imports.signals;
const Clutter = imports.gi.Clutter;
const GObject = imports.gi.GObject;
@@ -38,16 +39,14 @@ const WorkspacesView = imports.ui.workspacesView;
const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils;
const MultiMonitors = ExtensionUtils.getCurrentExtension();
const Convenience = MultiMonitors.imports.convenience;
const CE = ExtensionUtils.getCurrentExtension();
const MultiMonitors = CE.imports.extension;
const Convenience = CE.imports.convenience;
const THUMBNAILS_ON_LEFT_SIDE_ID = 'thumbnails-on-left-side';
const MultiMonitorsWorkspaceThumbnail = new Lang.Class({
Name: 'MultiMonitorsWorkspaceThumbnail',
Extends: WorkspaceThumbnail.WorkspaceThumbnail,
_init (metaWorkspace, monitorIndex) {
const MultiMonitorsWorkspaceThumbnail = class MultiMonitorsWorkspaceThumbnail {
constructor (metaWorkspace, monitorIndex) {
this.metaWorkspace = metaWorkspace;
this.monitorIndex = monitorIndex;
@@ -94,196 +93,180 @@ const MultiMonitorsWorkspaceThumbnail = new Lang.Class({
}
// Track window changes
this._windowAddedId = this.metaWorkspace.connect('window-added', this._windowAdded.bind(this));
this._windowRemovedId = this.metaWorkspace.connect('window-removed', this._windowRemoved.bind(this));
let display;
display = global.screen || global.display;
this._windowEnteredMonitorId = display.connect('window-entered-monitor', this._windowEnteredMonitor.bind(this));
this._windowLeftMonitorId = display.connect('window-left-monitor', this._windowLeftMonitor.bind(this));
this._windowAddedId = this.metaWorkspace.connect('window-added',
this._windowAdded.bind(this));
this._windowRemovedId = this.metaWorkspace.connect('window-removed',
this._windowRemoved.bind(this));
this._windowEnteredMonitorId = global.display.connect('window-entered-monitor',
this._windowEnteredMonitor.bind(this));
this._windowLeftMonitorId = global.display.connect('window-left-monitor',
this._windowLeftMonitor.bind(this));
this.state = WorkspaceThumbnail.ThumbnailState.NORMAL;
this._slidePosition = 0; // Fully slid in
this._collapseFraction = 0; // Not collapsed
}
});
};
Signals.addSignalMethods(MultiMonitorsWorkspaceThumbnail.prototype);
MultiMonitors.copyClass(WorkspaceThumbnail.WorkspaceThumbnail, MultiMonitorsWorkspaceThumbnail);
const MultiMonitorsThumbnailsBox = new Lang.Class({
Name: 'MultiMonitorsThumbnailsBox',
Extends: WorkspaceThumbnail.ThumbnailsBox,
_init(monitorIndex) {
this._monitorIndex = monitorIndex;
this._currentVersion = Config.PACKAGE_VERSION.split('.');
this.actor = new Shell.GenericContainer({ reactive: true,
style_class: 'workspace-thumbnails',
request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT });
this.actor.connect('get-preferred-width', this._getPreferredWidth.bind(this));
this.actor.connect('get-preferred-height', this._getPreferredHeight.bind(this));
this.actor.connect('allocate', this._allocate.bind(this));
this.actor.connect('destroy', this._onDestroy.bind(this));
this.actor._delegate = this;
let indicator = new St.Bin({ style_class: 'workspace-thumbnail-indicator' });
// We don't want the indicator to affect drag-and-drop
Shell.util_set_hidden_from_pick(indicator, true);
this._indicator = indicator;
this.actor.add_actor(indicator);
this._dropWorkspace = -1;
this._dropPlaceholderPos = -1;
this._dropPlaceholder = new St.Bin({ style_class: 'placeholder' });
this.actor.add_actor(this._dropPlaceholder);
this._spliceIndex = -1;
this._targetScale = 0;
this._scale = 0;
this._pendingScaleUpdate = false;
this._stateUpdateQueued = false;
this._animatingIndicator = false;
this._indicatorY = 0; // only used when _animatingIndicator is true
this._stateCounts = {};
for (let key in WorkspaceThumbnail.ThumbnailState)
this._stateCounts[WorkspaceThumbnail.ThumbnailState[key]] = 0;
this._thumbnails = [];
this._switchWorkspaceNotifyId = 0;
this._nWorkspacesNotifyId = 0;
this._syncStackingId = 0;
this._porthole = null;
this.actor.connect('button-press-event', () => { return Clutter.EVENT_STOP; });
this.actor.connect('button-release-event', this._onButtonRelease.bind(this));
this.actor.connect('touch-event', this._onTouchEvent.bind(this));
this._showingId = Main.overview.connect('showing', this._createThumbnails.bind(this));
this._hiddenId = Main.overview.connect('hidden', this._destroyThumbnails.bind(this));
this._itemDragBeginId = Main.overview.connect('item-drag-begin', this._onDragBegin.bind(this));
this._itemDragEndId = Main.overview.connect('item-drag-end', this._onDragEnd.bind(this));
this._itemDragCancelledId = Main.overview.connect('item-drag-cancelled', this._onDragCancelled.bind(this));
this._windowDragBeginId = Main.overview.connect('window-drag-begin', this._onDragBegin.bind(this));
this._windowDragEndId = Main.overview.connect('window-drag-end', this._onDragEnd.bind(this));
this._windowDragCancelledId = Main.overview.connect('window-drag-cancelled', this._onDragCancelled.bind(this));
if (this._currentVersion[0]==3 && this._currentVersion[1]<30) {
this._settings = new Gio.Settings({ schema_id: WorkspaceThumbnail.OVERRIDE_SCHEMA });
}
else {
this._settings = new Gio.Settings({ schema_id: WorkspaceThumbnail.MUTTER_SCHEMA });
}
this._changedDynamicWorkspacesId = this._settings.connect('changed::dynamic-workspaces',
this._updateSwitcherVisibility.bind(this));
if (this._currentVersion[0]==3 && this._currentVersion[1]>24) {
const MultiMonitorsThumbnailsBox = (() => {
let MultiMonitorsThumbnailsBox = class MultiMonitorsThumbnailsBox extends St.Widget {
_init(monitorIndex) {
this._monitorIndex = monitorIndex;
this._currentVersion = Config.PACKAGE_VERSION.split('.');
super._init({ reactive: true,
style_class: 'workspace-thumbnails',
request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT });
this.actor = this;
this.actor._delegate = this;
let indicator = new St.Bin({ style_class: 'workspace-thumbnail-indicator' });
// We don't want the indicator to affect drag-and-drop
Shell.util_set_hidden_from_pick(indicator, true);
this._indicator = indicator;
this.add_actor(indicator);
// The porthole is the part of the screen we're showing in the thumbnails
this._porthole = { width: global.stage.width, height: global.stage.height,
x: global.stage.x, y: global.stage.y };
this._dropWorkspace = -1;
this._dropPlaceholderPos = -1;
this._dropPlaceholder = new St.Bin({ style_class: 'placeholder' });
this.add_actor(this._dropPlaceholder);
this._spliceIndex = -1;
this._targetScale = 0;
this._scale = 0;
this._pendingScaleUpdate = false;
this._stateUpdateQueued = false;
this._animatingIndicator = false;
this._indicatorY = 0; // only used when _animatingIndicator is true
this._stateCounts = {};
for (let key in WorkspaceThumbnail.ThumbnailState)
this._stateCounts[WorkspaceThumbnail.ThumbnailState[key]] = 0;
this._thumbnails = [];
this.connect('button-press-event', () => Clutter.EVENT_STOP);
this.connect('button-release-event', this._onButtonRelease.bind(this));
this.connect('touch-event', this._onTouchEvent.bind(this));
this._showingId = Main.overview.connect('showing',
this._createThumbnails.bind(this));
this._hiddenId = Main.overview.connect('hidden',
this._destroyThumbnails.bind(this));
this._itemDragBeginId = Main.overview.connect('item-drag-begin',
this._onDragBegin.bind(this));
this._itemDragEndId = Main.overview.connect('item-drag-end',
this._onDragEnd.bind(this));
this._itemDragCancelledId = Main.overview.connect('item-drag-cancelled',
this._onDragCancelled.bind(this));
this._windowDragBeginId = Main.overview.connect('window-drag-begin',
this._onDragBegin.bind(this));
this._windowDragEndId = Main.overview.connect('window-drag-end',
this._onDragEnd.bind(this));
this._windowDragCancelledId = Main.overview.connect('window-drag-cancelled',
this._onDragCancelled.bind(this));
this._settings = new Gio.Settings({ schema_id: WorkspaceThumbnail.MUTTER_SCHEMA });
this._changedDynamicWorkspacesId = this._settings.connect('changed::dynamic-workspaces',
this._updateSwitcherVisibility.bind(this));
this._monitorsChangedId = Main.layoutManager.connect('monitors-changed', () => {
this._destroyThumbnails();
if (Main.overview.visible)
this._createThumbnails();
});
}
this._switchWorkspaceNotifyId = 0;
this._nWorkspacesNotifyId = 0;
this._syncStackingId = 0;
this._workareasChangedId = 0;
},
_onDestroy(actor) {
this._destroyThumbnails();
this._workareasChangedPortholeId = global.display.connect('workareas-changed',
this._updatePorthole.bind(this));
this._switchWorkspaceNotifyId = 0;
this._nWorkspacesNotifyId = 0;
this._syncStackingId = 0;
this._workareasChangedId = 0;
}
_onDestroy(actor) {
this._destroyThumbnails();
Main.overview.disconnect(this._showingId);
Main.overview.disconnect(this._hiddenId);
Main.overview.disconnect(this._itemDragBeginId);
Main.overview.disconnect(this._itemDragEndId);
Main.overview.disconnect(this._itemDragCancelledId);
Main.overview.disconnect(this._windowDragBeginId);
Main.overview.disconnect(this._windowDragEndId);
Main.overview.disconnect(this._windowDragCancelledId);
this._settings.disconnect(this._changedDynamicWorkspacesId);
if (this._currentVersion[0]==3 && this._currentVersion[1]>24) {
Main.layoutManager.disconnect(this._monitorsChangedId);
}
if (this._currentVersion[0]==3 && this._currentVersion[1]>30) {
global.display.disconnect(this._workareasChangedPortholeId);
}
Tweener.removeTweens(actor);
this.actor._delegate = null;
}
addThumbnails(start, count) {
let workspaceManager = global.workspace_manager;
for (let k = start; k < start + count; k++) {
let metaWorkspace = workspaceManager.get_workspace_by_index(k);
let thumbnail = new MultiMonitorsWorkspaceThumbnail(metaWorkspace, this._monitorIndex);
thumbnail.setPorthole(this._porthole.x, this._porthole.y,
this._porthole.width, this._porthole.height);
this._thumbnails.push(thumbnail);
this.add_actor(thumbnail.actor);
if (start > 0 && this._spliceIndex == -1) {
// not the initial fill, and not splicing via DND
thumbnail.state = WorkspaceThumbnail.ThumbnailState.NEW;
thumbnail.slidePosition = 1; // start slid out
this._haveNewThumbnails = true;
} else {
thumbnail.state = WorkspaceThumbnail.ThumbnailState.NORMAL;
}
this._stateCounts[thumbnail.state]++;
}
this._queueUpdateStates();
// The thumbnails indicator actually needs to be on top of the thumbnails
this._indicator.raise_top();
// Clear the splice index, we got the message
this._spliceIndex = -1;
}
_updatePorthole() {
this._porthole = Main.layoutManager.getWorkAreaForMonitor(this._monitorIndex);
this.queue_relayout();
}
};
MultiMonitors.copyClass(WorkspaceThumbnail.ThumbnailsBox, MultiMonitorsThumbnailsBox);
return GObject.registerClass(MultiMonitorsThumbnailsBox);
})();
Main.overview.disconnect(this._showingId);
Main.overview.disconnect(this._hiddenId);
Main.overview.disconnect(this._itemDragBeginId);
Main.overview.disconnect(this._itemDragEndId);
Main.overview.disconnect(this._itemDragCancelledId);
Main.overview.disconnect(this._windowDragBeginId);
Main.overview.disconnect(this._windowDragEndId);
Main.overview.disconnect(this._windowDragCancelledId);
this._settings.disconnect(this._changedDynamicWorkspacesId);
if (this._currentVersion[0]==3 && this._currentVersion[1]>24) {
Main.layoutManager.disconnect(this._monitorsChangedId);
}
//TODO drag end ??
Tweener.removeTweens(actor);
this.actor._delegate = null;
},
addThumbnails(start, count) {
if (this._currentVersion[0]==3 && this._currentVersion[1]>24) {
if (!this._ensurePorthole())
return;
}
else {
this._ensurePorthole24();
}
let display;
display = global.screen || global.workspace_manager;
for (let k = start; k < start + count; k++) {
let metaWorkspace = display.get_workspace_by_index(k);
let thumbnail = new MultiMonitorsWorkspaceThumbnail(metaWorkspace, this._monitorIndex);
thumbnail.setPorthole(this._porthole.x, this._porthole.y,
this._porthole.width, this._porthole.height);
this._thumbnails.push(thumbnail);
this.actor.add_actor(thumbnail.actor);
if (start > 0 && this._spliceIndex == -1) {
// not the initial fill, and not splicing via DND
thumbnail.state = WorkspaceThumbnail.ThumbnailState.NEW;
thumbnail.slidePosition = 1; // start slid out
this._haveNewThumbnails = true;
} else {
thumbnail.state = WorkspaceThumbnail.ThumbnailState.NORMAL;
}
this._stateCounts[thumbnail.state]++;
}
this._queueUpdateStates();
// The thumbnails indicator actually needs to be on top of the thumbnails
this._indicator.raise_top();
// Clear the splice index, we got the message
this._spliceIndex = -1;
},
// The "porthole" is the portion of the screen that we show in the
// workspaces
_ensurePorthole() {
if (!(Main.layoutManager.monitors.length>this._monitorIndex))
return false;
if (!this._porthole)
this._porthole = Main.layoutManager.getWorkAreaForMonitor(this._monitorIndex);
return true;
},
_ensurePorthole24() {
if (!this._porthole)
this._porthole = Main.layoutManager.getWorkAreaForMonitor(this._monitorIndex);
},
});
const MultiMonitorsSlidingControl = new Lang.Class({
Name: 'MultiMonitorsSlidingControl',
Extends: OverviewControls.SlidingControl,
_init(params) {
const MultiMonitorsSlidingControl = class MultiMonitorsSlidingControl {
constructor (params) {
params = Params.parse(params, { slideDirection: OverviewControls.SlideDirection.LEFT });
this._visible = true;
@@ -310,7 +293,7 @@ const MultiMonitorsSlidingControl = new Lang.Class({
this.onAnimationBegin = null;
this.onAnimationEnd = null;
},
}
_onDestroy(actor) {
Main.overview.disconnect(this._hidingId);
@@ -324,7 +307,7 @@ const MultiMonitorsSlidingControl = new Lang.Class({
Main.overview.disconnect(this._windowDragEndId);
Tweener.removeTweens(actor);
},
}
_updateTranslation() {
let translationStart = 0;
@@ -350,15 +333,13 @@ const MultiMonitorsSlidingControl = new Lang.Class({
if (this.onAnimationEnd) this.onAnimationEnd();
},
onCompleteScope: this});
},
});
}
};
MultiMonitors.copyClass(OverviewControls.SlidingControl, MultiMonitorsSlidingControl);
const MultiMonitorsThumbnailsSlider = new Lang.Class({
Name: 'MultiMonitorsThumbnailsSlider',
Extends: MultiMonitorsSlidingControl,
_init(thumbnailsBox) {
this.parent({ slideDirection: OverviewControls.SlideDirection.RIGHT });
const MultiMonitorsThumbnailsSlider = class MultiMonitorsThumbnailsSlider extends MultiMonitorsSlidingControl {
constructor (thumbnailsBox) {
super({ slideDirection: OverviewControls.SlideDirection.RIGHT });
this._currentVersion = Config.PACKAGE_VERSION.split('.');
@@ -367,7 +348,7 @@ const MultiMonitorsThumbnailsSlider = new Lang.Class({
this.actor.request_mode = Clutter.RequestMode.WIDTH_FOR_HEIGHT;
this.actor.reactive = true;
this.actor.track_hover = true;
this.actor.add_actor(this._thumbnailsBox.actor);
this.actor.add_actor(this._thumbnailsBox);
if(this._currentVersion[0]==3 && this._currentVersion[1]>28) {
this._activeWorkspaceChangedId = global.workspace_manager.connect('active-workspace-changed',
@@ -383,8 +364,8 @@ const MultiMonitorsThumbnailsSlider = new Lang.Class({
this._switchWorkspaceId = global.window_manager.connect('switch-workspace', this._updateSlide.bind(this));
}
this._thumbnailsBox.actor.bind_property('visible', this.actor, 'visible', GObject.BindingFlags.SYNC_CREATE);
},
this._thumbnailsBox.bind_property('visible', this.actor, 'visible', GObject.BindingFlags.SYNC_CREATE);
}
_onDestroy() {
Main.layoutManager.disconnect(this._monitorsChangedId);
@@ -395,14 +376,10 @@ const MultiMonitorsThumbnailsSlider = new Lang.Class({
global.workspace_manager.disconnect(this._activeWorkspaceChangedId);
global.workspace_manager.disconnect(this._notifyNWorkspacesId);
}
this.parent();
},
_getAlwaysZoomOut: OverviewControls.ThumbnailsSlider.prototype._getAlwaysZoomOut,
getNonExpandedWidth: OverviewControls.ThumbnailsSlider.prototype.getNonExpandedWidth,
_getSlide: OverviewControls.ThumbnailsSlider.prototype._getSlide,
getVisibleWidth: OverviewControls.ThumbnailsSlider.prototype.getVisibleWidth,
});
super._onDestroy();
}
};
MultiMonitors.copyClass(OverviewControls.ThumbnailsSlider, MultiMonitorsThumbnailsSlider);
const MultiMonitorsControlsManager = new Lang.Class({
Name: 'MultiMonitorsControlsManager',
@@ -521,8 +498,8 @@ const MultiMonitorsControlsManager = new Lang.Class({
let first = this._group.get_first_child();
if(first != this._thumbnailsSlider.actor){
this._thumbnailsSlider.layout.slideDirection = OverviewControls.SlideDirection.LEFT;
this._thumbnailsBox.actor.remove_style_class_name('workspace-thumbnails');
this._thumbnailsBox.actor.set_style_class_name('workspace-thumbnails workspace-thumbnails-left');
this._thumbnailsBox.remove_style_class_name('workspace-thumbnails');
this._thumbnailsBox.set_style_class_name('workspace-thumbnails workspace-thumbnails-left');
this._group.set_child_below_sibling(this._thumbnailsSlider.actor, first)
}
}
@@ -530,8 +507,8 @@ const MultiMonitorsControlsManager = new Lang.Class({
let last = this._group.get_last_child();
if(last != this._thumbnailsSlider.actor){
this._thumbnailsSlider.layout.slideDirection = OverviewControls.SlideDirection.RIGHT;
this._thumbnailsBox.actor.remove_style_class_name('workspace-thumbnails workspace-thumbnails-left');
this._thumbnailsBox.actor.set_style_class_name('workspace-thumbnails');
this._thumbnailsBox.remove_style_class_name('workspace-thumbnails workspace-thumbnails-left');
this._thumbnailsBox.set_style_class_name('workspace-thumbnails');
this._group.set_child_above_sibling(this._thumbnailsSlider.actor, last);
}
}
@@ -758,15 +735,7 @@ var MultiMonitorsOverview = new Lang.Class({
});
var MultiMonitorsWorkspacesDisplay = new Lang.Class({
Name: 'MultiMonitorsWorkspacesDisplay',
Extends: WorkspacesView.WorkspacesDisplay,
_init() {
this.parent();
this._restackedNotifyId = 0;
},
var MultiMonitorsWorkspacesDisplay = class MultiMonitorsWorkspacesDisplay extends WorkspacesView.WorkspacesDisplay {
_workspacesOnlyOnPrimaryChanged() {
this._workspacesOnlyOnPrimary = this._settings.get_boolean('workspaces-only-on-primary');
@@ -777,7 +746,7 @@ var MultiMonitorsWorkspacesDisplay = new Lang.Class({
return;
this._updateWorkspacesViews();
},
}
_updateWorkspacesFullGeometry() {
if (this._workspacesViews.length!=Main.layoutManager.monitors.length)
@@ -798,7 +767,7 @@ var MultiMonitorsWorkspacesDisplay = new Lang.Class({
// global.log("fulllG i: "+i+" x: "+geometry.x+" y: "+geometry.y+" width: "+geometry.width+" height: "+geometry.height);
this._workspacesViews[i].setFullGeometry(geometry);
}
},
}
_updateWorkspacesActualGeometry() {
if (this._workspacesViews.length!=Main.layoutManager.monitors.length)
@@ -828,5 +797,4 @@ var MultiMonitorsWorkspacesDisplay = new Lang.Class({
}
}
}
});
};

View File

@@ -36,9 +36,10 @@ const ExtensionSystem = imports.ui.extensionSystem;
const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils;
const MultiMonitors = ExtensionUtils.getCurrentExtension();
const Convenience = MultiMonitors.imports.convenience;
const MMCalendar = MultiMonitors.imports.mmcalendar;
const CE = ExtensionUtils.getCurrentExtension();
const MultiMonitors = CE.imports.extension;
const Convenience = CE.imports.convenience;
const MMCalendar = CE.imports.mmcalendar;
const SHOW_ACTIVITIES_ID = 'show-activities';
var SHOW_APP_MENU_ID = 'show-app-menu';
@@ -374,259 +375,213 @@ const MULTI_MONITOR_PANEL_ITEM_IMPLEMENTATIONS = {
// 'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
};
var MultiMonitorsPanel = new Lang.Class({
Name: 'MultiMonitorsPanel',
Extends: Panel.Panel,
_init (monitorIndex, mmPanelBox) {
this.monitorIndex = monitorIndex;
this._currentVersion = Config.PACKAGE_VERSION.split('.');
this.actor = new Shell.GenericContainer({ name: 'panel', reactive: true });
this.actor._delegate = this;
this.actor.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
this._sessionStyle = null;
this.statusArea = {};
this.menuManager = new PopupMenu.PopupMenuManager(this);
this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
this.actor.add_actor(this._leftBox);
this._centerBox = new St.BoxLayout({ name: 'panelCenter' });
this.actor.add_actor(this._centerBox);
this._rightBox = new St.BoxLayout({ name: 'panelRight' });
this.actor.add_actor(this._rightBox);
this._leftCorner = new Panel.PanelCorner(St.Side.LEFT);
this.actor.add_actor(this._leftCorner.actor);
this._rightCorner = new Panel.PanelCorner(St.Side.RIGHT);
this.actor.add_actor(this._rightCorner.actor);
this.actor.connect('get-preferred-width', this._getPreferredWidth.bind(this));
this.actor.connect('get-preferred-height', this._getPreferredHeight.bind(this));
this.actor.connect('allocate', this._allocate.bind(this));
this.actor.connect('button-press-event', this._onButtonPress.bind(this));
if (this._currentVersion[0]==3 && this._currentVersion[1]>28) {
this.actor.connect('touch-event', this._onButtonPress.bind(this));
}
this.actor.connect('destroy', this._onDestroy.bind(this));
if (this._currentVersion[0]==3 && this._currentVersion[1]>26) {
this.actor.connect('key-press-event', this._onKeyPress.bind(this));
}
this._showingId = Main.overview.connect('showing', () => {
this.actor.add_style_pseudo_class('overview');
if (this._currentVersion[0]==3 && this._currentVersion[1]>24) {
this._updateSolidStyle();
}
});
this._hidingId = Main.overview.connect('hiding', () => {
this.actor.remove_style_pseudo_class('overview');
if (this._currentVersion[0]==3 && this._currentVersion[1]>24) {
this._updateSolidStyle();
}
});
mmPanelBox.panelBox.add(this.actor);
Main.ctrlAltTabManager.addGroup(this.actor, _("Top Bar")+" "+this.monitorIndex, 'focus-top-bar-symbolic',
{ sortGroup: CtrlAltTab.SortGroup.TOP });
this._updatedId = Main.sessionMode.connect('updated', this._updatePanel.bind(this));
if (this._currentVersion[0]==3 && this._currentVersion[1]>24) {
this._trackedWindows = new Map();
this._actorAddedId = global.window_group.connect('actor-added', this._onWindowActorAdded.bind(this));
this._actorRemovedId = global.window_group.connect('actor-removed', this._onWindowActorRemoved.bind(this));
this._switchWorkspaceId = global.window_manager.connect('switch-workspace', this._updateSolidStyle.bind(this));
global.window_group.get_children().forEach(metaWindowActor => {
if (metaWindowActor['get_meta_window'] && metaWindowActor.get_meta_window().get_window_type() != Meta.WindowType.DESKTOP)
this._onWindowActorAdded(null, metaWindowActor);
});
}
if (this._currentVersion[0]==3 && this._currentVersion[1]>26) {
let display;
//global.screen < 3.30
display = global.screen || global.display;
this._workareasChangedId = display.connect('workareas-changed', () => { this.actor.queue_relayout(); });
}
this._updatePanel();
this._settings = Convenience.getSettings();
this._showActivitiesId = this._settings.connect('changed::'+SHOW_ACTIVITIES_ID,
this._showActivities.bind(this));
this._showActivities();
this._showAppMenuId = this._settings.connect('changed::'+SHOW_APP_MENU_ID,
this._showAppMenu.bind(this));
this._showAppMenu();
this._showDateTimeId = this._settings.connect('changed::'+SHOW_DATE_TIME_ID,
this._showDateTime.bind(this));
this._showDateTime();
},
_onDestroy(actor) {
if (this._currentVersion[0]==3 && this._currentVersion[1]>26) {
let display;
display = global.screen || global.display;
display.disconnect(this._workareasChangedId);
}
if (this._currentVersion[0]==3 && this._currentVersion[1]>24) {
global.window_group.disconnect(this._actorAddedId);
global.window_group.disconnect(this._actorRemovedId);
global.window_manager.disconnect(this._switchWorkspaceId);
this._trackedWindows.forEach((value, key, map) => {
value.forEach(id => {
key.disconnect(id);
});
});
}
Main.overview.disconnect(this._showingId);
Main.overview.disconnect(this._hidingId);
this._settings.disconnect(this._showActivitiesId);
this._settings.disconnect(this._showAppMenuId);
// Tweener.removeTweens(actor);
var MultiMonitorsPanel = (() => {
let MultiMonitorsPanel = class MultiMonitorsPanel extends St.Widget {
_init (monitorIndex, mmPanelBox) {
this.monitorIndex = monitorIndex;
this._currentVersion = Config.PACKAGE_VERSION.split('.');
super._init({ name: 'panel',
reactive: true });
// For compatibility with extensions that still use the
// this.actor field
this.actor = this;
this.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
this._sessionStyle = null;
this.statusArea = {};
this.menuManager = new PopupMenu.PopupMenuManager(this);
this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
this.add_child(this._leftBox);
this._centerBox = new St.BoxLayout({ name: 'panelCenter' });
this.add_child(this._centerBox);
this._rightBox = new St.BoxLayout({ name: 'panelRight' });
this.add_child(this._rightBox);
this._leftCorner = new Panel.PanelCorner(St.Side.LEFT);
this.add_child(this._leftCorner.actor);
this._rightCorner = new Panel.PanelCorner(St.Side.RIGHT);
this.add_child(this._rightCorner.actor);
this.connect('button-press-event', this._onButtonPress.bind(this));
this.connect('touch-event', this._onButtonPress.bind(this));
this.connect('key-press-event', this._onKeyPress.bind(this));
this._showingId = Main.overview.connect('showing', () => {
this.add_style_pseudo_class('overview');
});
this._hidingId = Main.overview.connect('hiding', () => {
this.remove_style_pseudo_class('overview');
});
mmPanelBox.panelBox.add(this);
Main.ctrlAltTabManager.addGroup(this, _("Top Bar"), 'focus-top-bar-symbolic',
{ sortGroup: CtrlAltTab.SortGroup.TOP });
this._updatedId = Main.sessionMode.connect('updated', this._updatePanel.bind(this));
this._workareasChangedId = global.display.connect('workareas-changed', () => { this.queue_relayout(); });
this._updatePanel();
}
Main.ctrlAltTabManager.removeGroup(this.actor);
Main.sessionMode.disconnect(this._updatedId);
for (let name in this.statusArea) {
if(this.statusArea.hasOwnProperty(name))
this.statusArea[name].destroy();
delete this.statusArea[name];
_onDestroy(actor) {
if (this._currentVersion[0]==3 && this._currentVersion[1]>26) {
let display;
display = global.screen || global.display;
display.disconnect(this._workareasChangedId);
}
if (this._currentVersion[0]==3 && this._currentVersion[1]>24) {
global.window_group.disconnect(this._actorAddedId);
global.window_group.disconnect(this._actorRemovedId);
global.window_manager.disconnect(this._switchWorkspaceId);
this._trackedWindows.forEach((value, key, map) => {
value.forEach(id => {
key.disconnect(id);
});
});
}
Main.overview.disconnect(this._showingId);
Main.overview.disconnect(this._hidingId);
this._settings.disconnect(this._showActivitiesId);
this._settings.disconnect(this._showAppMenuId);
// Tweener.removeTweens(actor);
Main.ctrlAltTabManager.removeGroup(this.actor);
Main.sessionMode.disconnect(this._updatedId);
for (let name in this.statusArea) {
if(this.statusArea.hasOwnProperty(name))
this.statusArea[name].destroy();
delete this.statusArea[name];
}
this.actor._delegate = null;
}
this.actor._delegate = null;
},
_showActivities() {
let name = 'activities';
if(this._settings.get_boolean(SHOW_ACTIVITIES_ID)){
if(this.statusArea[name])
this.statusArea[name].actor.visible = true;
}
else{
if(this.statusArea[name])
this.statusArea[name].actor.visible = false;
}
},
_showActivities() {
let name = 'activities';
if(this._settings.get_boolean(SHOW_ACTIVITIES_ID)){
if(this.statusArea[name])
this.statusArea[name].actor.visible = true;
}
else{
if(this.statusArea[name])
this.statusArea[name].actor.visible = false;
}
}
_showDateTime() {
let name = 'dateMenu';
if(this._settings.get_boolean(SHOW_DATE_TIME_ID)){
if(this.statusArea[name])
this.statusArea[name].actor.visible = true;
}
else{
if(this.statusArea[name])
this.statusArea[name].actor.visible = false;
}
}
_showAppMenu() {
let name = 'appMenu';
if(this._settings.get_boolean(SHOW_APP_MENU_ID)){
if(!this.statusArea[name]){
let indicator = new MultiMonitorsAppMenuButton(this);
this.statusArea[name] = indicator;
let box = this._leftBox;
this._addToPanelBox(name, indicator, box.get_n_children()+1, box);
}
}
else{
if(this.statusArea[name]){
let indicator = this.statusArea[name];
this.menuManager.removeMenu(indicator.menu);
indicator.destroy();
}
}
}
_showDateTime() {
let name = 'dateMenu';
if(this._settings.get_boolean(SHOW_DATE_TIME_ID)){
if(this.statusArea[name])
this.statusArea[name].actor.visible = true;
}
else{
if(this.statusArea[name])
this.statusArea[name].actor.visible = false;
}
},
_getPreferredWidth(actor, forHeight, alloc) {
alloc.min_size = -1;
if(Main.layoutManager.monitors.length>this.monitorIndex)
alloc.natural_size = Main.layoutManager.monitors[this.monitorIndex].width;
else
alloc.natural_size = -1;
}
_updateSolidStyle() {
if (this.actor.has_style_pseudo_class('overview') || !Main.sessionMode.hasWindows) {
this._removeStyleClassName('solid');
return;
}
_showAppMenu() {
let name = 'appMenu';
if(this._settings.get_boolean(SHOW_APP_MENU_ID)){
if(!this.statusArea[name]){
let indicator = new MultiMonitorsAppMenuButton(this);
this.statusArea[name] = indicator;
let box = this._leftBox;
this._addToPanelBox(name, indicator, box.get_n_children()+1, box);
}
}
else{
if(this.statusArea[name]){
let indicator = this.statusArea[name];
this.menuManager.removeMenu(indicator.menu);
indicator.destroy();
}
}
},
_getPreferredWidth(actor, forHeight, alloc) {
alloc.min_size = -1;
if(Main.layoutManager.monitors.length>this.monitorIndex)
alloc.natural_size = Main.layoutManager.monitors[this.monitorIndex].width;
else
alloc.natural_size = -1;
},
_updateSolidStyle() {
if (this.actor.has_style_pseudo_class('overview') || !Main.sessionMode.hasWindows) {
this._removeStyleClassName('solid');
return;
}
if (!(Main.layoutManager.monitors.length>this.monitorIndex))
return;
/* Get all the windows in the active workspace that are in the primary monitor and visible */
let display;
display = global.screen || global.workspace_manager;
let activeWorkspace = display.get_active_workspace();
let monitorIndex = this.monitorIndex;
let windows = activeWorkspace.list_windows().filter((metaWindow) => {
return metaWindow.get_monitor() == monitorIndex &&
metaWindow.showing_on_its_workspace() &&
metaWindow.get_window_type() != Meta.WindowType.DESKTOP;
});
/* Check if at least one window is near enough to the panel */
let [, panelTop] = this.actor.get_transformed_position();
let panelBottom = panelTop + this.actor.get_height();
let scale = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let isNearEnough = windows.some((metaWindow) => {
let verticalPosition = metaWindow.get_frame_rect().y;
return verticalPosition < panelBottom + 5 * scale;
});
if (isNearEnough)
this._addStyleClassName('solid');
else
this._removeStyleClassName('solid');
},
_hideIndicators() {
for (let role in MULTI_MONITOR_PANEL_ITEM_IMPLEMENTATIONS) {
let indicator = this.statusArea[role];
if (!indicator)
continue;
if (this._currentVersion[0]==3 && this._currentVersion[1]>24) {
if (indicator.menu)
indicator.menu.close();
}
indicator.container.hide();
}
},
_ensureIndicator(role) {
let indicator = this.statusArea[role];
if (!indicator) {
let constructor = MULTI_MONITOR_PANEL_ITEM_IMPLEMENTATIONS[role];
if (!constructor) {
return null;
}
indicator = new constructor(this);
this.statusArea[role] = indicator;
}
return indicator;
}
});
if (!(Main.layoutManager.monitors.length>this.monitorIndex))
return;
/* Get all the windows in the active workspace that are in the primary monitor and visible */
let display;
display = global.screen || global.workspace_manager;
let activeWorkspace = display.get_active_workspace();
let monitorIndex = this.monitorIndex;
let windows = activeWorkspace.list_windows().filter((metaWindow) => {
return metaWindow.get_monitor() == monitorIndex &&
metaWindow.showing_on_its_workspace() &&
metaWindow.get_window_type() != Meta.WindowType.DESKTOP;
});
/* Check if at least one window is near enough to the panel */
let [, panelTop] = this.actor.get_transformed_position();
let panelBottom = panelTop + this.actor.get_height();
let scale = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let isNearEnough = windows.some((metaWindow) => {
let verticalPosition = metaWindow.get_frame_rect().y;
return verticalPosition < panelBottom + 5 * scale;
});
if (isNearEnough)
this._addStyleClassName('solid');
else
this._removeStyleClassName('solid');
}
_hideIndicators() {
for (let role in MULTI_MONITOR_PANEL_ITEM_IMPLEMENTATIONS) {
let indicator = this.statusArea[role];
if (!indicator)
continue;
if (this._currentVersion[0]==3 && this._currentVersion[1]>24) {
if (indicator.menu)
indicator.menu.close();
}
indicator.container.hide();
}
}
_ensureIndicator(role) {
let indicator = this.statusArea[role];
if (!indicator) {
let constructor = MULTI_MONITOR_PANEL_ITEM_IMPLEMENTATIONS[role];
if (!constructor) {
return null;
}
indicator = new constructor(this);
this.statusArea[role] = indicator;
}
return indicator;
}
};
MultiMonitors.copyClass(Panel.Panel, MultiMonitorsPanel);
return GObject.registerClass(MultiMonitorsPanel);
})();