diff --git a/Settings.ui b/Settings.ui index ec5d1fa..fa83fc7 100644 --- a/Settings.ui +++ b/Settings.ui @@ -1,5 +1,5 @@ - + @@ -4385,8 +4385,6 @@ True True - 6 - 6 True diff --git a/appIcons.js b/appIcons.js index 804fe25..4019d66 100644 --- a/appIcons.js +++ b/appIcons.js @@ -41,7 +41,6 @@ const DND = imports.ui.dnd; const IconGrid = imports.ui.iconGrid; const Main = imports.ui.main; const PopupMenu = imports.ui.popupMenu; -const Tweener = imports.ui.tweener; const Util = imports.misc.util; const Workspace = imports.ui.workspace; @@ -404,6 +403,8 @@ var taskbarAppIcon = Utils.defineClass({ } else { this._focusedDots = new St.DrawingArea(), this._unfocusedDots = new St.DrawingArea(); + this._focusedDots._tweeningToSize = null, + this._unfocusedDots._tweeningToSize = null; this._focusedDots.connect('repaint', Lang.bind(this, function() { if(this._dashItemContainer.animatingOut) { @@ -709,7 +710,7 @@ var taskbarAppIcon = Utils.defineClass({ tweenOpts[sizeProp] = newSize; dots._tweeningToSize = newSize; - Tweener.addTween(dots, tweenOpts); + Utils.animate(dots, tweenOpts); } }, @@ -1559,19 +1560,17 @@ function ItemShowLabel() { this.label.set_position(Math.round(x), Math.round(y)); - if (Dash.DASH_ITEM_LABEL_SHOW_TIME < 1) { - Tweener.addTween(this.label, { - opacity: 255, - time: Dash.DASH_ITEM_LABEL_SHOW_TIME, - transition: 'easeOutQuad', - }); - } else { - this.label.ease({ - opacity: 255, - duration: Dash.DASH_ITEM_LABEL_SHOW_TIME, - mode: Clutter.AnimationMode.EASE_OUT_QUAD - }); + let duration = Dash.DASH_ITEM_LABEL_SHOW_TIME; + + if (duration > 1) { + duration /= 1000; } + + Utils.animate(this.label, { + opacity: 255, + time: duration, + transition: 'easeOutQuad', + }); }; /** diff --git a/extension.js b/extension.js index 14e55c9..a1f6d39 100644 --- a/extension.js +++ b/extension.js @@ -45,6 +45,9 @@ let extensionSystem = (Main.extensionManager || imports.ui.extensionSystem); function init() { Convenience.initTranslations(Utils.TRANSLATION_DOMAIN); + + //create an object that persists until gnome-shell is restarted, even if the extension is disabled + Me.persistentStorage = {}; } function enable() { @@ -136,7 +139,7 @@ function disable(reset) { // Re-enable Ubuntu Dock if it was disabled by dash to panel if (disabledUbuntuDock && Main.sessionMode.allowExtensions) { - extensionSystem.enableExtension(UBUNTU_DOCK_UUID); + (extensionSystem._callExtensionEnable || extensionSystem.enableExtension).call(extensionSystem, UBUNTU_DOCK_UUID); } } } \ No newline at end of file diff --git a/intellihide.js b/intellihide.js index 8f594f1..e99e108 100644 --- a/intellihide.js +++ b/intellihide.js @@ -26,7 +26,6 @@ const Layout = imports.ui.layout; const Main = imports.ui.main; const OverviewControls = imports.ui.overviewControls; const PointerWatcher = imports.ui.pointerWatcher; -const Tweener = imports.ui.tweener; const Me = imports.misc.extensionUtils.getCurrentExtension(); const Panel = Me.imports.panel; @@ -357,13 +356,13 @@ var Intellihide = Utils.defineClass({ }, _animatePanel: function(destination, immediate) { - let animating = Tweener.isTweening(this._panelBox); + let animating = Utils.isAnimating(this._panelBox, this._translationProp); if (!((animating && destination === this._animationDestination) || (!animating && destination === this._panelBox[this._translationProp]))) { //the panel isn't already at, or animating to the asked destination if (animating) { - Tweener.removeTweens(this._panelBox); + Utils.stopAnimations(this._panelBox); } this._animationDestination = destination; @@ -388,7 +387,7 @@ var Intellihide = Utils.defineClass({ }; tweenOpts[this._translationProp] = destination; - Tweener.addTween(this._panelBox, tweenOpts); + Utils.animate(this._panelBox, tweenOpts); } } diff --git a/panel.js b/panel.js index e103a3a..c1f0a12 100644 --- a/panel.js +++ b/panel.js @@ -52,7 +52,6 @@ const PopupMenu = imports.ui.popupMenu; const IconGrid = imports.ui.iconGrid; const ViewSelector = imports.ui.viewSelector; const DateMenu = imports.ui.dateMenu; -const Tweener = imports.ui.tweener; const Volume = imports.ui.status.volume; const Progress = Me.imports.progress; @@ -74,6 +73,7 @@ const T3 = 'allocationThrottleTimeout'; const T4 = 'showDesktopTimeout'; const T5 = 'trackerFocusAppTimeout'; const T6 = 'scrollPanelDelayTimeout'; +const T7 = 'waitPanelBoxAllocation'; function getPosition() { let position = Me.settings.get_string('panel-position'); @@ -574,7 +574,7 @@ var dtpPanel = Utils.defineClass({ if (!Me.settings.get_boolean(settingName)) { this._removePanelMenu(propName); } else if (!this.statusArea[propName]) { - this.statusArea[propName] = new constr(); + this.statusArea[propName] = this._getPanelMenu(propName, constr); this.menuManager.addMenu(this.statusArea[propName].menu); container.insert_child_at_index(this.statusArea[propName].container, 0); } @@ -588,12 +588,29 @@ var dtpPanel = Utils.defineClass({ parent.remove_actor(this.statusArea[propName].container); } - //this.statusArea[propName].destroy(); //buggy for now, gnome-shell never destroys those menus - this.menuManager.removeMenu(this.statusArea[propName].menu); + //calling this.statusArea[propName].destroy(); is buggy for now, gnome-shell never + //destroys those panel menus... + //since we can't destroy the menu (hence properly disconnect its signals), let's + //store it so the next time a panel needs one of its kind, we can reuse it instead + //of creating a new one + let panelMenu = this.statusArea[propName]; + + this.menuManager.removeMenu(panelMenu.menu); + Me.persistentStorage[propName].push(panelMenu); this.statusArea[propName] = null; } }, + _getPanelMenu: function(propName, constr) { + Me.persistentStorage[propName] = Me.persistentStorage[propName] || []; + + if (!Me.persistentStorage[propName].length) { + Me.persistentStorage[propName].push(new constr()); + } + + return Me.persistentStorage[propName].pop(); + }, + _setPanelGhostSize: function() { this._myPanelGhost.set_size(this.width, checkIfVertical() ? 1 : this.height); }, @@ -797,7 +814,7 @@ var dtpPanel = Utils.defineClass({ this.panel.actor[(St.Side[p] == this.geom.position ? 'add' : 'remove') + '_style_class_name'](cssName); }); - Utils.setClip(clipContainer, clipContainer.x, clipContainer.y, this.panelBox.width, this.panelBox.height); + this._timeoutsHandler.add([T7, 0, () => Utils.setClip(clipContainer, clipContainer.x, clipContainer.y, this.panelBox.width, this.panelBox.height)]); Main.layoutManager._updateHotCorners(); Main.layoutManager._updatePanelBarrier(this); @@ -1187,6 +1204,8 @@ var dtpSecondaryAggregateMenu = Utils.defineClass({ _init: function() { this.callParent('_init', 0.0, C_("System menu in the top bar", "System"), false); + Utils.wrapActor(this); + this.menu.actor.add_style_class_name('aggregate-menu'); let menuLayout = new Panel.AggregateLayout(); diff --git a/taskbar.js b/taskbar.js index 5e26469..09ff7f6 100644 --- a/taskbar.js +++ b/taskbar.js @@ -41,7 +41,6 @@ const DND = imports.ui.dnd; const IconGrid = imports.ui.iconGrid; const Main = imports.ui.main; const PopupMenu = imports.ui.popupMenu; -const Tweener = imports.ui.tweener; const Workspace = imports.ui.workspace; const Me = imports.misc.extensionUtils.getCurrentExtension(); @@ -737,7 +736,7 @@ var taskbar = Utils.defineClass({ // tween to the new size icon.icon.set_size(icon.icon.width * scale, icon.icon.height * scale); - Tweener.addTween(icon.icon, + Utils.animate(icon.icon, { width: targetWidth, height: targetHeight, time: DASH_ANIMATION_TIME, diff --git a/utils.js b/utils.js index 038379d..57f6a54 100644 --- a/utils.js +++ b/utils.js @@ -35,12 +35,17 @@ const St = imports.gi.St; const Mainloop = imports.mainloop; const Main = imports.ui.main; const MessageTray = imports.ui.messageTray; -const Tweener = imports.ui.tweener; const Util = imports.misc.util; var TRANSLATION_DOMAIN = imports.misc.extensionUtils.getCurrentExtension().metadata['gettext-domain']; var SCROLL_TIME = Util.SCROLL_TIME / (Util.SCROLL_TIME > 1 ? 1000 : 1); +//Clutter implicit animations are available since 3.34 +//prefer those over Tweener if available +if (Config.PACKAGE_VERSION < '3.34') { + var Tweener = imports.ui.tweener; +} + var defineClass = function (classDef) { let parentProto = classDef.Extends ? classDef.Extends.prototype : null; @@ -443,9 +448,51 @@ var animateWindowOpacity = function(window, tweenOpts) { return window.visible = (tweenOpts.opacity == 255); } - Tweener.addTween(window, tweenOpts); + animate(window, tweenOpts); }; +var animate = function(actor, options) { + if (Tweener) { + return Tweener.addTween(actor, options); + } + + //to support both Tweener and Clutter animations, we use Tweener + //"time" property defined in seconds, as opposed to Clutter animations + //"duration" which is defined in milliseconds + options.duration = options.time * 1000; + delete options.time; + + if (options.transition) { + //map Tweener easing equations to Clutter animation modes + options.mode = { + 'easeInCubic': Clutter.AnimationMode.EASE_IN_CUBIC, + 'easeInOutCubic': Clutter.AnimationMode.EASE_IN_OUT_CUBIC, + 'easeInOutQuad': Clutter.AnimationMode.EASE_IN_OUT_QUAD, + 'easeOutQuad': Clutter.AnimationMode.EASE_OUT_QUAD + }[options.transition] || Clutter.AnimationMode.LINEAR; + + delete options.transition; + } + + actor.ease(options); +} + +var isAnimating = function(actor, prop) { + if (Tweener) { + return Tweener.isTweening(actor); + } + + return !!actor.get_transition(prop); +} + +var stopAnimations = function(actor) { + if (Tweener) { + return Tweener.removeTweens(actor); + } + + actor.remove_all_transitions(); +} + var getIndicators = function(delegate) { if (delegate instanceof St.BoxLayout) { return delegate; @@ -545,11 +592,11 @@ var ensureActorVisibleInScrollView = function(scrollView, actor, fadeSize, onCom }; if (vvalue !== vvalue0) { - Tweener.addTween(vadjustment, mergeObjects(tweenOpts, { value: vvalue })); + animate(vadjustment, mergeObjects(tweenOpts, { value: vvalue })); } if (hvalue !== hvalue0) { - Tweener.addTween(hadjustment, mergeObjects(tweenOpts, { value: hvalue })); + animate(hadjustment, mergeObjects(tweenOpts, { value: hvalue })); } return [hvalue- hvalue0, vvalue - vvalue0]; diff --git a/windowPreview.js b/windowPreview.js index b788de6..75f2270 100644 --- a/windowPreview.js +++ b/windowPreview.js @@ -26,7 +26,6 @@ const PopupMenu = imports.ui.popupMenu; const Signals = imports.signals; const Shell = imports.gi.Shell; const St = imports.gi.St; -const Tweener = imports.ui.tweener; const WindowManager = imports.ui.windowManager; const Workspace = imports.ui.workspace; @@ -208,7 +207,7 @@ var PreviewMenu = Utils.defineClass({ this._endPeek(); if (immediate) { - Tweener.removeTweens(this.menu); + Utils.stopAnimations(this.menu); this._resetHiddenState(); } else { this._animateOpenOrClose(false, () => this._resetHiddenState()); @@ -484,7 +483,7 @@ var PreviewMenu = Utils.defineClass({ this.menu.set_position(x, y); this.menu.set_size(previewsWidth, previewsHeight); } else { - Tweener.addTween(this.menu, getTweenOpts({ x: x, y: y, width: previewsWidth, height: previewsHeight })); + Utils.animate(this.menu, getTweenOpts({ x: x, y: y, width: previewsWidth, height: previewsHeight })); } }, @@ -579,7 +578,7 @@ var PreviewMenu = Utils.defineClass({ tweenOpts[this._translationProp] = show ? this._translationDirection : this._translationOffset; - Tweener.addTween(this.menu, getTweenOpts(tweenOpts)); + Utils.animate(this.menu, getTweenOpts(tweenOpts)); }, _peek: function(window) { @@ -816,8 +815,8 @@ var Preview = Utils.defineClass({ this.animatingOut = true; - Tweener.removeTweens(this); - Tweener.addTween(this, tweenOpts); + Utils.stopAnimations(this); + Utils.animate(this, tweenOpts); } }, @@ -825,8 +824,8 @@ var Preview = Utils.defineClass({ if (this.animatingOut) { this.animatingOut = false; - Tweener.removeTweens(this); - Tweener.addTween(this, getTweenOpts({ opacity: 255 })); + Utils.stopAnimations(this); + Utils.animate(this, getTweenOpts({ opacity: 255 })); } }, @@ -965,7 +964,7 @@ var Preview = Utils.defineClass({ _hideOrShowCloseButton: function(hide) { if (this._needsCloseButton) { - Tweener.addTween(this._closeButtonBin, getTweenOpts({ opacity: hide ? 0 : 255 })); + Utils.animate(this._closeButtonBin, getTweenOpts({ opacity: hide ? 0 : 255 })); } }, @@ -1009,7 +1008,7 @@ var Preview = Utils.defineClass({ } currentClones.forEach(c => c.destroy()); - Tweener.addTween(currentCloneBin, currentCloneOpts); + Utils.animate(currentCloneBin, currentCloneOpts); } else if (animateSize) { newCloneBin.width = 0; newCloneBin.height = 0; @@ -1017,7 +1016,7 @@ var Preview = Utils.defineClass({ newCloneOpts.height = this.cloneHeight; } - Tweener.addTween(newCloneBin, newCloneOpts); + Utils.animate(newCloneBin, newCloneOpts); }, _getWindowCloneBin: function(window) {