diff --git a/data/metadata.json.in b/data/metadata.json.in index 44af32a..5f3a515 100644 --- a/data/metadata.json.in +++ b/data/metadata.json.in @@ -2,7 +2,7 @@ "uuid": "@uuid@", "name": "Top Notification", "description": "Place shell notifications under the panel instead of above the message-tray", -"shell-version": [ "3.8" ], +"shell-version": [ "3.8", "3.10" ], "localedir": "@LOCALEDIR@", "url": "@url@" } diff --git a/src/extension.js b/src/extension.js index 2728335..589f78b 100644 --- a/src/extension.js +++ b/src/extension.js @@ -12,6 +12,8 @@ * The idea comes from 'Shell OSD' gnome-shell extension by * mpnordland@gmail.com */ +const ExtensionUtils = imports.misc.extensionUtils; +const Config = imports.misc.config; const Main = imports.ui.main; const Tweener = imports.ui.tweener; const MessageTray = imports.ui.messageTray; @@ -34,6 +36,8 @@ let originalHideNotification = Main.messageTray._hideNotification; let notificationWidget = Main.messageTray._notificationWidget; let panel = Main.layoutManager.panelBox; +let originalNotificationWidgetX = notificationWidget.x; + /* * We need these constants to call Tween with values consistent to the * MessageTray @@ -89,24 +93,27 @@ let extensionShowNotification = function () { ); this._notificationBin.child = this._notification.actor; this._notificationWidget.opacity = 0; - /* - * for .y we use the panel's height, to move it just below the panel. - * we calculate .height every time, to prevent using gnome-shell's startup - * panel height before the themes are loaded. - * - * If you set this to .0, the OSD is animated (Tweened) in from outside - * the screen, but the very first frame moves *all* windows down to make - * space for the OSD. Subsequent frames moves the windows back. - * - * I don't know how to fix that. - */ - this._notificationWidget.y = panel.height; - /* - * for .x we Math.round() to prevent 1/2 pixels; which can cause blurry - * font rendering - */ - this._notificationWidget.x = Math.round((panel.width / 2) - - (this._notificationWidget.width / 2)); + + if (!ExtensionUtils.versionCheck(['3.9', '3.10'], Config.PACKAGE_VERSION)) { + /* + * for .y we use the panel's height, to move it just below the panel. + * we calculate .height every time, to prevent using gnome-shell's startup + * panel height before the themes are loaded. + * + * If you set this to .0, the OSD is animated (Tweened) in from outside + * the screen, but the very first frame moves *all* windows down to make + * space for the OSD. Subsequent frames moves the windows back. + * + * I don't know how to fix that. + */ + this._notificationWidget.y = panel.height; + /* + * for .x we Math.round() to prevent 1/2 pixels; which can cause blurry + * font rendering + */ + this._notificationWidget.x = Math.round((panel.width / 2) - + (this._notificationWidget.width) / 2); + } this._notificationWidget.show(); this._updateShowingNotification(); let [x, y, mods] = global.get_pointer(); @@ -127,11 +134,17 @@ let extensionShowNotification = function () { * I stripped the original comments out so that my changes (and comments) could * be highlighted. It's really just a tiny change. */ -let extensionHideNotification = function() { +let extensionHideNotification = function(animate) { +if (ExtensionUtils.versionCheck(['3.9', '3.10'], Config.PACKAGE_VERSION)) { + this._notificationFocusGrabber.ungrabFocus(); +} +else +{ this._notificationState = State.HIDING; if (!this._notification) { return; } this._grabHelper.ungrab({ actor: this._notification.actor }); +} if (this._notificationExpandedId) { this._notification.disconnect(this._notificationExpandedId); @@ -145,42 +158,72 @@ let extensionHideNotification = function() { this._notification.disconnect(this._notificationUnfocusedId); this._notificationUnfocusedId = 0; } - this._useLongerTrayLeftTimeout = false; - if (this._trayLeftTimeoutId) { - Mainloop.source_remove(this._trayLeftTimeoutId); - this._trayLeftTimeoutId = 0; - this._trayLeftMouseX = -1; - this._trayLeftMouseY = -1; + if (ExtensionUtils.versionCheck(['3.9', '3.10'], Config.PACKAGE_VERSION)) { + this._useLongerNotificationLeftTimeout = false; + if (this._notificationLeftTimeoutId) { + Mainloop.source_remove(this._notificationLeftTimeoutId); + this._notificationLeftTimeoutId = 0; + this._notificationLeftMouseX = -1; + this._notificationLeftMouseY = -1; + } + + if (animate) { + this._tween(this._notificationWidget, '_notificationState', State.HIDDEN, { + y: 0, + opacity: 0, + time: ANIMATION_TIME, + transition: 'easeOutQuad', + onComplete: this._hideNotificationCompleted, + onCompleteScope: this + }); + } else { + Tweener.removeTweens(this._notificationWidget); + this._notificationWidget.y = 0; + this._notificationWidget.opacity = 0; + this._notificationState = State.HIDDEN; + this._hideNotificationCompleted(); + } } + else + { + this._useLongerTrayLeftTimeout = false; + if (this._trayLeftTimeoutId) { + Mainloop.source_remove(this._trayLeftTimeoutId); + this._trayLeftTimeoutId = 0; + this._trayLeftMouseX = -1; + this._trayLeftMouseY = -1; + } - if (this._notificationRemoved) { - Tweener.removeTweens(this._notificationWidget); - this._notificationWidget.y = this.actor.height; - this._notificationWidget.opacity = 0; - this._notificationState = State.HIDDEN; - this._hideNotificationCompleted(); - } else { - /* - * We leave the widget.y at panel.height, and not .0; because the - * showing animation is opacity-only. - * - * Can be animated out to .0 if you want; there are no artifacts on - * screen when animating out. - */ - this._tween(this._notificationWidget, '_notificationState', State.HIDDEN, - { y: panel.height, - opacity: 0, - time: ANIMATION_TIME, - transition: 'easeOutQuad', - onComplete: this._hideNotificationCompleted, - onCompleteScope: this - }); + if (this._notificationRemoved) { + Tweener.removeTweens(this._notificationWidget); + this._notificationWidget.y = this.actor.height; + this._notificationWidget.opacity = 0; + this._notificationState = State.HIDDEN; + this._hideNotificationCompleted(); + } else { + // + // We leave the widget.y at panel.height, and not .0; because the + // showing animation is opacity-only. + // + // Can be animated out to .0 if you want; there are no artifacts on + // screen when animating out. + // + this._tween(this._notificationWidget, '_notificationState', State.HIDDEN, + { y: panel.height, + opacity: 0, + time: ANIMATION_TIME, + transition: 'easeOutQuad', + onComplete: this._hideNotificationCompleted, + onCompleteScope: this + }); + } } } /* * Copied from MessageTray._updateNotification() + * Copied from MessageTray._updateShowingNotification() * * We only change the .y and .x values to move the OSD. We need to copy * the whole method to prevent the animation from moving the OSD across the @@ -190,25 +233,54 @@ let extensionHideNotification = function() { * be highlighted. It's really just a tiny change. */ let extensionUpdateShowingNotification = function() { - this._notification.acknowledged = true; - this._notification.playSound(); - if (this._notification.urgency == Urgency.CRITICAL || - this._notification.source.policy.forceExpanded) - this._expandNotification(true); - /* - * As noted above, panel.height is constant to prevent an artifact, - * so in effect only the opacity changes. - */ - let tweenParams = { opacity: 255, - y: panel.height, - time: ANIMATION_TIME, - transition: 'easeOutQuad', - onComplete: this._showNotificationCompleted, - onCompleteScope: this - }; - this._tween(this._notificationWidget, '_notificationState', State.SHOWN, tweenParams); + this._notification.acknowledged = true; + this._notification.playSound(); + if (this._notification.urgency == Urgency.CRITICAL || + this._notification.source.policy.forceExpanded) + this._expandNotification(true); + this._notificationWidget.x = Math.round((panel.width / 2) - + (this._notificationWidget.width) / 2); + /* + * As noted above, panel.height is constant to prevent an artifact, + * so in effect only the opacity changes. + */ + let tweenParams = { + opacity: 255, + // opacity: 187, + y: panel.height, + time: ANIMATION_TIME, + transition: 'easeOutQuad', + onComplete: this._showNotificationCompleted, + onCompleteScope: this + }; + this._tween(this._notificationWidget, '_notificationState', State.SHOWN, tweenParams); } +let extensiononNotificationExpanded = function() { + let expandedY = panel.height; +// this._closeButton.y = expandedY; + this._closeButton.show(); + log('this._notificationWidget.y = ' + this._notificationWidget.y); + log('this._notificationWidget.height = ' + this._notificationWidget.height); + log('panel.height = ' + panel.height); + // Don't animate the notification to its new position if it has shrunk: + // there will be a very visible "gap" that breaks the illusion. + if (this._notificationWidget.y < expandedY) { + this._notificationWidget.y = expandedY; + } else if (this._notification.y != expandedY) { + // Tween also opacity here, to override a possible tween that's + // currently hiding the notification. + this._tween(this._notificationWidget, '_notificationState', State.SHOWN, { + y: expandedY, + opacity: 255, + time: ANIMATION_TIME, + transition: 'easeOutQuad' + }); + log('this._notificationWidget.y = ' + this._notificationWidget.y); + log('this._notificationWidget.height = ' + this._notificationWidget.height); + } + +} /* * Overload the methods. @@ -221,13 +293,24 @@ let extensionUpdateShowingNotification = function() { * lost. */ function enable() { - Main.messageTray._showNotification = extensionShowNotification; - Main.messageTray._hideNotification = extensionHideNotification; - Main.messageTray._updateShowingNotification = extensionUpdateShowingNotification; - LayoutManager.untrackChrome(notificationWidget); + Main.messageTray._showNotification = extensionShowNotification; + Main.messageTray._hideNotification = extensionHideNotification; + Main.messageTray._updateShowingNotification = extensionUpdateShowingNotification; + LayoutManager.untrackChrome(notificationWidget); + if (ExtensionUtils.versionCheck(['3.9', '3.10'], Config.PACKAGE_VERSION)) { + Main.messageTray._onNotificationExpanded = extensiononNotificationExpanded; + LayoutManager.trayBox.remove_actor(notificationWidget); + Main.uiGroup.add_actor(notificationWidget); + Main.uiGroup.set_child_below_sibling(notificationWidget, + panel); + } + else + { Main.messageTray.actor.remove_actor(notificationWidget); panel.add_actor(notificationWidget); LayoutManager.trackChrome(notificationWidget); + } + } @@ -235,13 +318,21 @@ function enable() { * Put everything back. */ function disable() { + Main.messageTray._showNotification = originalShowNotification; + Main.messageTray._hideNotification = originalHideNotification; + Main.messageTray._updateShowingNotification = originalUpdateShowingNotification; + if (ExtensionUtils.versionCheck(['3.9', '3.10'], Config.PACKAGE_VERSION)) { Main.messageTray._onNotificationExpanded = originalExpandMethod; - Main.messageTray._showNotification = originalShowNotification; - Main.messageTray._hideNotification = originalHideNotification; - Main.messageTray._updateShowingNotification = originalUpdateShowingNotification; - LayoutManager.untrackChrome(notificationWidget); - panel.remove_actor(notificationWidget); - Main.messageTray.actor.add_actor(notificationWidget); - LayoutManager.trackChrome(notificationWidget); -} + notificationWidget.x = originalNotificationWidgetX; + Main.uiGroup.remove_actor(notificationWidget); + Main.layoutManager.trayBox.add_actor(notificationWidget); + } + else + { + LayoutManager.untrackChrome(notificationWidget); + panel.remove_actor(notificationWidget); + Main.messageTray.actor.add_actor(notificationWidget); + } + LayoutManager.trackChrome(notificationWidget); +}