From 8ae941ba8bf08e2ffd57eff405a18b6cbf319bf9 Mon Sep 17 00:00:00 2001 From: Charles Gagnon Date: Tue, 12 Feb 2019 21:49:20 -0500 Subject: [PATCH] Add es6 class support for 3.32 --- appIcons.js | 31 +++++++++---------- intellihide.js | 2 +- overview.js | 2 +- panel.js | 21 ++++++++----- panelManager.js | 2 +- panelStyle.js | 3 +- proximity.js | 4 +-- taskbar.js | 20 ++++++------- transparency.js | 2 +- utils.js | 77 ++++++++++++++++++++++++++++++++++++++++++++---- windowPreview.js | 26 +++++++++------- 11 files changed, 133 insertions(+), 57 deletions(-) diff --git a/appIcons.js b/appIcons.js index 4aa36c4..00ccd70 100644 --- a/appIcons.js +++ b/appIcons.js @@ -92,11 +92,12 @@ let tracker = Shell.WindowTracker.get_default(); * */ -var taskbarAppIcon = new Lang.Class({ +var taskbarAppIcon = Utils.defineClass({ Name: 'DashToPanel.TaskbarAppIcon', Extends: AppDisplay.AppIcon, + ParentConstrParams: [[1, 'app'], [3]], - _init: function(settings, appInfo, panelWrapper, iconParams, onActivateOverride) { + _init: function(settings, appInfo, panelWrapper, iconParams) { // a prefix is required to avoid conflicting with the parent class variable this._dtpSettings = settings; @@ -126,7 +127,7 @@ var taskbarAppIcon = new Lang.Class({ this._removeMenuTimeout(); }; - this.parent(appInfo.app, iconParams, onActivateOverride); + this.callParent('_init', appInfo.app, iconParams); this._dot.set_width(0); this._focused = tracker.focus_app == this.app; @@ -325,7 +326,7 @@ var taskbarAppIcon = new Lang.Class({ }, _onDestroy: function() { - this.parent(); + this.callParent('_onDestroy'); this._destroyed = true; // Disconect global signals @@ -730,7 +731,7 @@ var taskbarAppIcon = new Lang.Class({ // Keep default behaviour: launch new window // By calling the parent method I make it compatible // with other extensions tweaking ctrl + click - this.parent(button); + this.callParent('activate', button); return; } @@ -1255,20 +1256,20 @@ function cssHexTocssRgba(cssHex, opacity) { * (https://github.com/deuill/shell-extension-quitfromdash) */ -var taskbarSecondaryMenu = new Lang.Class({ +var taskbarSecondaryMenu = Utils.defineClass({ Name: 'DashToPanel.SecondaryMenu', Extends: AppDisplay.AppIconMenu, + ParentConstrParams: [[0]], _init: function(source, settings) { this._dtpSettings = settings; - let side = Taskbar.getPosition(); - // Damm it, there has to be a proper way of doing this... // As I can't call the parent parent constructor (?) passing the side // parameter, I overwite what I need later - this.parent(source); + this.callParent('_init', source); + let side = Taskbar.getPosition(); // Change the initialized side where required. this._arrowSide = side; this._boxPointer._arrowSide = side; @@ -1281,7 +1282,7 @@ var taskbarSecondaryMenu = new Lang.Class({ }, _redisplay: function() { - this.parent(); + this.callParent('_redisplay'); // Remove "Show Details" menu item if(!this._dtpSettings.get_boolean('secondarymenu-contains-showdetails')) { @@ -1451,7 +1452,7 @@ function ItemShowLabel() { * use of this class in place of the original showAppsButton. * */ -var ShowAppsIconWrapper = new Lang.Class({ +var ShowAppsIconWrapper = Utils.defineClass({ Name: 'DashToDock.ShowAppsIconWrapper', _init: function(settings) { @@ -1567,14 +1568,10 @@ Signals.addSignalMethods(ShowAppsIconWrapper.prototype); /** * A menu for the showAppsIcon */ -var MyShowAppsIconMenu = new Lang.Class({ +var MyShowAppsIconMenu = Utils.defineClass({ Name: 'DashToPanel.ShowAppsIconMenu', Extends: taskbarSecondaryMenu, - - _init: function(showAppsIconWrapper, settings) { - this.parent(showAppsIconWrapper); - this._dtpSettings = settings; - }, + ParentConstrParams: [[0]], _redisplay: function() { this.removeAll(); diff --git a/intellihide.js b/intellihide.js index b88b3e9..b83c12a 100644 --- a/intellihide.js +++ b/intellihide.js @@ -47,7 +47,7 @@ var Hold = { PERMANENT: 2 }; -var Intellihide = new Lang.Class({ +var Intellihide = Utils.defineClass({ Name: 'DashToPanel.Intellihide', _init: function(dtpPanel) { diff --git a/overview.js b/overview.js index a2a1f19..6669c97 100644 --- a/overview.js +++ b/overview.js @@ -34,7 +34,7 @@ const Mainloop = imports.mainloop; const Meta = imports.gi.Meta; -var dtpOverview = new Lang.Class({ +var dtpOverview = Utils.defineClass({ Name: 'DashToPanel.Overview', _numHotkeys: 10, diff --git a/panel.js b/panel.js index 1046273..ae0ddfd 100644 --- a/panel.js +++ b/panel.js @@ -57,7 +57,7 @@ const Transparency = Me.imports.transparency; let tracker = Shell.WindowTracker.get_default(); -var dtpPanelWrapper = new Lang.Class({ +var dtpPanelWrapper = Utils.defineClass({ Name: 'DashToPanel.PanelWrapper', _init: function(panelManager, monitor, panel, panelBox, isSecondary) { @@ -131,7 +131,7 @@ var dtpPanelWrapper = new Lang.Class({ if (!this.isSecondary) { if (this.panel.vfunc_allocate) { this._panelConnectId = 0; - Utils.hookVfunc(this.panel.__proto__, 'allocate', (box, flags) => this._allocate(null, box, flags)); + Utils.hookVfunc(this.panel.__proto__, 'allocate', (box, flags) => this._vfunc_allocate(box, flags)); } else { this._panelConnectId = this.panel.actor.connect('allocate', (actor,box,flags) => this._allocate(actor,box,flags)); } @@ -387,6 +387,11 @@ var dtpPanelWrapper = new Lang.Class({ this.panelBox[isShown ? 'show' : 'hide'](); }, + + _vfunc_allocate: function(box, flags) { + this.panel.set_allocation(box, flags); + this._allocate(null, box, flags); + }, _allocate: function(actor, box, flags) { let panelAllocWidth = box.x2 - box.x1; @@ -705,12 +710,13 @@ var dtpPanelWrapper = new Lang.Class({ }, }); -var dtpSecondaryPanel = new Lang.Class({ +var dtpSecondaryPanel = Utils.defineClass({ Name: 'DashToPanel-SecondaryPanel', Extends: St.Widget, _init: function(settings, monitor) { - this.parent({ name: 'panel', reactive: true }); + this.callParent('_init', { name: 'panel', reactive: true }); + this._dtpSettings = settings; this.actor = this; @@ -757,7 +763,7 @@ var dtpSecondaryPanel = new Lang.Class({ vfunc_allocate: function(box, flags) { if(this.delegate) { - this.delegate._allocate(null, box, flags); + this.delegate._vfunc_allocate(box, flags); } }, @@ -800,12 +806,13 @@ var dtpSecondaryPanel = new Lang.Class({ }, }); -var dtpSecondaryAggregateMenu = new Lang.Class({ +var dtpSecondaryAggregateMenu = Utils.defineClass({ Name: 'dtpSecondaryAggregateMenu', Extends: PanelMenu.Button, _init: function() { - this.parent(0.0, C_("System menu in the top bar", "System"), false); + this.callParent('_init', 0.0, C_("System menu in the top bar", "System"), false); + this.menu.actor.add_style_class_name('aggregate-menu'); let menuLayout = new Panel.AggregateLayout(); diff --git a/panelManager.js b/panelManager.js index 9825ba1..8373edc 100755 --- a/panelManager.js +++ b/panelManager.js @@ -53,7 +53,7 @@ const WorkspacesView = imports.ui.workspacesView; const ATSPI_MOUSE = 'mouse:button:'; const ATSPI_MOUSE_EVENTS = ['1p', '1r']; -var dtpPanelManager = new Lang.Class({ +var dtpPanelManager = Utils.defineClass({ Name: 'DashToPanel.PanelManager', _init: function(settings) { diff --git a/panelStyle.js b/panelStyle.js index 7e9fe28..0c15fdd 100644 --- a/panelStyle.js +++ b/panelStyle.js @@ -30,8 +30,9 @@ const St = imports.gi.St; const Shell = imports.gi.Shell; const Taskbar = Me.imports.taskbar; +const Utils = Me.imports.utils; -var dtpPanelStyle = new Lang.Class({ +var dtpPanelStyle = Utils.defineClass({ Name: 'DashToPanel.PanelStyle', _init: function(settings) { diff --git a/proximity.js b/proximity.js index 6849bd1..a49dbd7 100644 --- a/proximity.js +++ b/proximity.js @@ -36,7 +36,7 @@ var Mode = { MAXIMIZED_WINDOWS: 2 }; -var ProximityWatch = new Lang.Class({ +var ProximityWatch = Utils.defineClass({ Name: 'DashToPanel.ProximityWatch', _init: function(actor, mode, xThreshold, yThreshold, handler) { @@ -73,7 +73,7 @@ var ProximityWatch = new Lang.Class({ }, }); -var ProximityManager = new Lang.Class({ +var ProximityManager = Utils.defineClass({ Name: 'DashToPanel.ProximityManager', _init: function() { diff --git a/taskbar.js b/taskbar.js index a10bc55..72e7b1d 100644 --- a/taskbar.js +++ b/taskbar.js @@ -98,16 +98,16 @@ function findIndex(array, predicate) { return -1; }; -var taskbarActor = new Lang.Class({ +var taskbarActor = Utils.defineClass({ Name: 'DashToPanel-TaskbarActor', Extends: St.Widget, _init: function(delegate) { this._delegate = delegate; this._currentBackgroundColor = 0; - this.parent({ name: 'dashtopanelTaskbar', - layout_manager: new Clutter.BoxLayout({ orientation: Clutter.Orientation.HORIZONTAL }), - clip_to_allocation: true }); + this.callParent('_init', { name: 'dashtopanelTaskbar', + layout_manager: new Clutter.BoxLayout({ orientation: Clutter.Orientation.HORIZONTAL }), + clip_to_allocation: true }); }, vfunc_allocate: function(box, flags)  { @@ -148,11 +148,11 @@ var taskbarActor = new Lang.Class({ rightFade.allocate(childBox, flags); }, - vfunc_get_preferred_width: function(actor, forHeight) { + vfunc_get_preferred_width: function(forHeight) { // We want to request the natural width of all our children // as our natural width, so we chain up to StWidget (which // then calls BoxLayout) - let [, natWidth] = this.parent(forHeight); + let [, natWidth] = St.Widget.prototype.vfunc_get_preferred_width.call(this, forHeight); return [0, natWidth]; }, @@ -172,7 +172,7 @@ var taskbarActor = new Lang.Class({ * - Sync minimization application target position. */ -var taskbar = new Lang.Class({ +var taskbar = Utils.defineClass({ Name: 'DashToPanel.Taskbar', _init : function(settings, panelWrapper) { @@ -1229,12 +1229,12 @@ var taskbar = new Lang.Class({ Signals.addSignalMethods(taskbar.prototype); -var DragPlaceholderItem = new Lang.Class({ +var DragPlaceholderItem = Utils.defineClass({ Name: 'DashToPanel-DragPlaceholderItem', Extends: St.Widget, _init: function(appIcon, iconSize) { - this.parent({ style_class: 'dtp-icon-container', layout_manager: new Clutter.BinLayout() }); + this.callParent('_init', { style_class: 'dtp-icon-container', layout_manager: new Clutter.BinLayout() }); this.child = { _delegate: appIcon }; @@ -1249,7 +1249,7 @@ var DragPlaceholderItem = new Lang.Class({ destroy: function() { this._clone.destroy(); - this.parent(); + this.callParent('destroy'); }, }); diff --git a/transparency.js b/transparency.js index 2d79dff..568a217 100644 --- a/transparency.js +++ b/transparency.js @@ -26,7 +26,7 @@ const Me = imports.misc.extensionUtils.getCurrentExtension(); const Proximity = Me.imports.proximity; const Utils = Me.imports.utils; -var DynamicTransparency = new Lang.Class({ +var DynamicTransparency = Utils.defineClass({ Name: 'DashToPanel.DynamicTransparency', _init: function(dtpPanel) { diff --git a/utils.js b/utils.js index b0062ba..2d98da2 100644 --- a/utils.js +++ b/utils.js @@ -26,9 +26,76 @@ const Lang = imports.lang; const Mainloop = imports.mainloop; const Meta = imports.gi.Meta; +let es6Support = imports.misc.config.PACKAGE_VERSION >= '3.31.9'; + +var defineClass = function (classDef) { + let parentProto = !!classDef.Extends ? classDef.Extends.prototype : null; + let isGObject = parentProto instanceof imports.gi.GObject.Object; + let needsSuper = es6Support && !!parentProto && !isGObject; + + if (!es6Support) { + if (parentProto && classDef.Extends.name.indexOf('DashToPanel') < 0) { + classDef.callParent = function() { + let args = Array.prototype.slice.call(arguments); + let func = args.shift(); + + this.__caller__._owner.__super__.prototype[func].apply(this, args); + }; + } + + return new imports.lang.Class(classDef); + } + + let getParentArgs = function(args) { + let parentArgs = []; + + (classDef.ParentConstrParams || parentArgs).forEach(p => { + if (p.constructor === Array) { + let param = args[p[0]]; + + parentArgs.push(p[1] ? param[p[1]] : param); + } else { + parentArgs.push(p); + } + }); + + return parentArgs; + }; + + let C = eval( + '(class C ' + (needsSuper ? 'extends Object' : '') + ' { ' + + ' constructor(...args) { ' + + (needsSuper ? 'super(...getParentArgs(args));' : '') + + (needsSuper || !parentProto ? 'this._init(...args);' : '') + + ' }' + + ' callParent(...args) { ' + + ' let func = args.shift(); ' + + ' if (!(func === \'_init\' && needsSuper))' + + ' super[func](...args); ' + + ' }' + + '})' + ); + + if (parentProto) { + Object.setPrototypeOf(C.prototype, parentProto); + Object.setPrototypeOf(C, classDef.Extends); + } + + Object.defineProperty(C, 'name', { value: classDef.Name }); + Object.keys(classDef) + .filter(k => classDef.hasOwnProperty(k) && classDef[k] instanceof Function) + .forEach(k => C.prototype[k] = classDef[k]); + + if (isGObject) { + C = imports.gi.GObject.registerClass(C); + } + + return C; +}; + // simplify global signals and function injections handling // abstract class -var BasicHandler = new Lang.Class({ +var BasicHandler = defineClass({ Name: 'DashToPanel.BasicHandler', _init: function(){ @@ -89,7 +156,7 @@ var BasicHandler = new Lang.Class({ }); // Manage global signals -var GlobalSignalsHandler = new Lang.Class({ +var GlobalSignalsHandler = defineClass({ Name: 'DashToPanel.GlobalSignalsHandler', Extends: BasicHandler, @@ -119,7 +186,7 @@ var GlobalSignalsHandler = new Lang.Class({ * Manage function injection: both instances and prototype can be overridden * and restored */ -var InjectionsHandler = new Lang.Class({ +var InjectionsHandler = defineClass({ Name: 'DashToPanel.InjectionsHandler', Extends: BasicHandler, @@ -144,7 +211,7 @@ var InjectionsHandler = new Lang.Class({ /** * Manage timeouts: the added timeouts have their id reset on completion */ -var TimeoutsHandler = new Lang.Class({ +var TimeoutsHandler = defineClass({ Name: 'DashToPanel.TimeoutsHandler', Extends: BasicHandler, @@ -204,4 +271,4 @@ var hookVfunc = function(proto, symbol, func) { } else { Gi.hook_up_vfunc(proto, symbol, func); } -}; \ No newline at end of file +}; diff --git a/windowPreview.js b/windowPreview.js index 3af1bdf..a8235c2 100644 --- a/windowPreview.js +++ b/windowPreview.js @@ -49,16 +49,17 @@ let HOVER_APP_BLACKLIST = [ "Remmina" ] -var thumbnailPreviewMenu = new Lang.Class({ +var thumbnailPreviewMenu = Utils.defineClass({ Name: 'DashToPanel.ThumbnailPreviewMenu', Extends: PopupMenu.PopupMenu, + ParentConstrParams: [[0, 'actor'], 0.5, Taskbar.getPosition()], _init: function(source, settings) { this._dtpSettings = settings; let side = Taskbar.getPosition(); - this.parent(source.actor, 0.5, side); + this.callParent('_init', source.actor, 0.5, side); // We want to keep the item hovered while the menu is up this.blockSourceEvents = false; @@ -244,7 +245,7 @@ var thumbnailPreviewMenu = new Lang.Class({ if (this._leaveMenuId) this.actor.disconnect(this._leaveMenuId); - this.parent(); + this.callParent('destroy'); }, close: function(animate) { @@ -503,9 +504,10 @@ var thumbnailPreviewMenu = new Lang.Class({ } }); -var thumbnailPreview = new Lang.Class({ +var thumbnailPreview = Utils.defineClass({ Name: 'DashToPanel.ThumbnailPreview', Extends: PopupMenu.PopupBaseMenuItem, + ParentConstrParams: [{ reactive: true }], _init: function(window, settings) { this._dtpSettings = settings; @@ -518,7 +520,8 @@ var thumbnailPreview = new Lang.Class({ this._thumbnailWidth = this._dtpSettings.get_int('window-preview-width')*scaleFactor; this._thumbnailHeight = this._dtpSettings.get_int('window-preview-height')*scaleFactor; - this.parent({reactive: true}); + this.callParent('_init', {reactive: true}); + this._workId = Main.initializeDeferredWork(this.actor, Lang.bind(this, this._onResize)); this.preview = this.getThumbnail(); @@ -857,18 +860,18 @@ var thumbnailPreview = new Lang.Class({ } } - this.parent(); + this.callParent('destroy'); } }); -var thumbnailPreviewList = new Lang.Class({ +var thumbnailPreviewList = Utils.defineClass({ Name: 'DashToPanel.ThumbnailPreviewList', Extends: PopupMenu.PopupMenuSection, _init: function(app, source, settings) { this._dtpSettings = settings; - this.parent(); + this.callParent('_init'); this._ensurePreviewVisibilityTimeoutId = 0; @@ -1151,12 +1154,13 @@ var thumbnailPreviewList = new Lang.Class({ } }); -var previewMenuPopup = new Lang.Class({ +var previewMenuPopup = Utils.defineClass({ Name: 'previewMenuPopup', Extends: WindowMenu.WindowMenu, + ParentConstrParams: [[0], [1]], _init: function(window, sourceActor) { - this.parent(window, sourceActor); + this.callParent('_init', window, sourceActor); let side = Taskbar.getPosition(); this._arrowSide = side; @@ -1167,7 +1171,7 @@ var previewMenuPopup = new Lang.Class({ // Otherwise, just let the parent do its thing? }); -var previewMenuPopupManager = new Lang.Class({ +var previewMenuPopupManager = Utils.defineClass({ Name: 'previewMenuPopupManagerTest', _init: function(window, source) {