You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
696 lines
24 KiB
696 lines
24 KiB
/* jshint esnext:true */
|
|
/*
|
|
*
|
|
* GNOME Shell Extension Panel OSD
|
|
*
|
|
* Copyright (C) 2014 - 2015
|
|
* Jens Lody <jens@jenslody.de>,
|
|
|
|
* Idea: Grab MessageTray OSD widget, and give it new .x and .y co-ordinates.
|
|
*
|
|
* We're grabbing "private" methods (start with _), so expect this to break
|
|
* with different versions of Gnome Shell.
|
|
*
|
|
* It was tested with 3.10 to 3.17.4 with various themes.
|
|
*
|
|
* Most of this code is a direct copy from gnome-shell/js/ui/messageTray.js,
|
|
* which is released under GPLv2+.
|
|
*
|
|
* The idea comes from 'Shell OSD' gnome-shell extension by
|
|
* mpnordland@gmail.com
|
|
*
|
|
* This file is part of gnome-shell-extension-panel-osd.
|
|
*
|
|
* gnome-shell-extension-panel-osd is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* gnome-shell-extension-panel-osd is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with gnome-shell-extension-panel-osd. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
/*
|
|
*/
|
|
const ExtensionUtils = imports.misc.extensionUtils;
|
|
const Config = imports.misc.config;
|
|
const Main = imports.ui.main;
|
|
const Tweener = imports.ui.tweener;
|
|
const Lang = imports.lang;
|
|
const Mainloop = imports.mainloop;
|
|
const Me = ExtensionUtils.getCurrentExtension();
|
|
const Convenience = Me.imports.convenience;
|
|
const St = imports.gi.St;
|
|
const Meta = imports.gi.Meta;
|
|
const Clutter = imports.gi.Clutter;
|
|
|
|
|
|
const Gettext = imports.gettext.domain('gnome-shell-extension-panel-osd');
|
|
const _ = Gettext.gettext;
|
|
|
|
const PANEL_OSD_SETTINGS_SCHEMA = 'org.gnome.shell.extensions.panel-osd';
|
|
const PANEL_OSD_X_POS_KEY = 'x-pos';
|
|
const PANEL_OSD_Y_POS_KEY = 'y-pos';
|
|
const PANEL_OSD_FORCE_EXPAND = 'force-expand';
|
|
const PANEL_OSD_TEST_DELAY = 'test-delay';
|
|
const PANEL_OSD_TEST_NOTIFICATION = 'test-notification';
|
|
|
|
/*
|
|
* Save MessageTray's original methods. We're going to change these
|
|
* in our extension to move the OSD.
|
|
*/
|
|
let originalExpandMethod;
|
|
let originalShowNotification;
|
|
let originalUpdateShowingNotification;
|
|
let originalHideNotification;
|
|
|
|
/*
|
|
* The widget we're interested in
|
|
*/
|
|
let notificationWidget;
|
|
let panel;
|
|
|
|
/*
|
|
* We need these constants to call Tween with values consistent to the
|
|
* MessageTray
|
|
*/
|
|
const IDLE_TIME = 1000;
|
|
const ANIMATION_TIME = 0.2;
|
|
const Urgency = {
|
|
LOW: 0,
|
|
NORMAL: 1,
|
|
HIGH: 2,
|
|
CRITICAL: 3
|
|
};
|
|
const State = {
|
|
HIDDEN: 0,
|
|
SHOWING: 1,
|
|
SHOWN: 2,
|
|
HIDING: 3
|
|
};
|
|
|
|
let _availablePrimaryRect = new Meta.Rectangle({
|
|
x: 0,
|
|
y: 0,
|
|
width: 0,
|
|
height: 0
|
|
})
|
|
|
|
function init() {
|
|
Convenience.initTranslations('gnome-shell-extension-panel-osd');
|
|
}
|
|
|
|
let Settings;
|
|
let SettingsC;
|
|
|
|
let showTestNotificationTimeout;
|
|
|
|
let loadConfig = function() {
|
|
Settings = Convenience.getSettings(PANEL_OSD_SETTINGS_SCHEMA);
|
|
SettingsC = Settings.connect("changed", function() {
|
|
if (getTestNotification()) {
|
|
if (showTestNotificationTimeout !== undefined)
|
|
Mainloop.source_remove(showTestNotificationTimeout);
|
|
|
|
showTestNotificationTimeout = Mainloop.timeout_add(getTestDelay(), Lang.bind(this, function() {
|
|
Main.notify("Panel OSD", _("This is just a multiline test-message to show where the notification will be placed and to test expansion (showing details)."));
|
|
return false;
|
|
}));
|
|
setTestNotification(false);
|
|
}
|
|
});
|
|
};
|
|
|
|
let versionAtLeast = function(atleast, current) {
|
|
let currentArray = current.split('.');
|
|
let major = currentArray[0];
|
|
let minor = currentArray[1];
|
|
let point = currentArray[2];
|
|
let atleastArray = atleast.split('.');
|
|
if ((atleastArray[0] < major) ||
|
|
(atleastArray[0] == major &&
|
|
atleastArray[1] < minor) ||
|
|
(atleastArray[0] == major &&
|
|
atleastArray[1] == minor) &&
|
|
(atleastArray[2] == undefined ||
|
|
atleastArray[2] <= point))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
|
|
let getX_position = function() {
|
|
if (!Settings)
|
|
loadConfig();
|
|
return Settings.get_double(PANEL_OSD_X_POS_KEY);
|
|
};
|
|
|
|
let getY_position = function() {
|
|
if (!Settings)
|
|
loadConfig();
|
|
return Settings.get_double(PANEL_OSD_Y_POS_KEY);
|
|
};
|
|
|
|
let getForce_expand = function() {
|
|
if (!Settings)
|
|
loadConfig();
|
|
return Settings.get_boolean(PANEL_OSD_FORCE_EXPAND);
|
|
};
|
|
|
|
let getTestDelay = function() {
|
|
if (!Settings)
|
|
loadConfig();
|
|
return Math.floor(1000 * Settings.get_double(PANEL_OSD_TEST_DELAY));
|
|
};
|
|
|
|
let getTestNotification = function() {
|
|
if (!Settings)
|
|
loadConfig();
|
|
return Settings.get_boolean(PANEL_OSD_TEST_NOTIFICATION);
|
|
};
|
|
|
|
let setTestNotification = function(v) {
|
|
if (!Settings)
|
|
loadConfig();
|
|
Settings.set_boolean(PANEL_OSD_TEST_NOTIFICATION, v);
|
|
};
|
|
|
|
let updateAvailablePrimaryRect = function() {
|
|
let monitor=Main.layoutManager.primaryMonitor;
|
|
_availablePrimaryRect.x=monitor.x;
|
|
_availablePrimaryRect.y=monitor.y;
|
|
_availablePrimaryRect.width=monitor.width;
|
|
_availablePrimaryRect.height=monitor.height;
|
|
|
|
let panelRect = new Meta.Rectangle({ x: panel.x,
|
|
y: panel.y,
|
|
width: panel.width,
|
|
height: panel.height });
|
|
let [panelIntersects, rect] = _availablePrimaryRect.intersect(panelRect);
|
|
|
|
if (panelIntersects)
|
|
{
|
|
if (monitor.width == rect.width)
|
|
{
|
|
_availablePrimaryRect.height = monitor.height - rect.height;
|
|
if (monitor.y == rect.y)
|
|
_availablePrimaryRect.y = rect.height;
|
|
}
|
|
if (monitor.height == rect.height)
|
|
{
|
|
_availablePrimaryRect.width = monitor.width - rect.width;
|
|
if (monitor.x == rect.x)
|
|
_availablePrimaryRect.x = rect.width;
|
|
}
|
|
}
|
|
};
|
|
|
|
/*
|
|
* Copied from MessageTray._showNotification()
|
|
*
|
|
* 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
|
|
* entire screen.
|
|
*/
|
|
let extensionShowNotification = function() {
|
|
this._notification = this._notificationQueue.shift();
|
|
if (versionAtLeast('3.16', Config.PACKAGE_VERSION)) {
|
|
this.emit('queue-changed');
|
|
}
|
|
|
|
this._userActiveWhileNotificationShown = this.idleMonitor.get_idletime() <= IDLE_TIME;
|
|
if (!this._userActiveWhileNotificationShown) {
|
|
// If the user isn't active, set up a watch to let us know
|
|
// when the user becomes active.
|
|
this.idleMonitor.add_user_active_watch(Lang.bind(this, this._onIdleMonitorBecameActive));
|
|
}
|
|
|
|
if (versionAtLeast('3.16', Config.PACKAGE_VERSION)) {
|
|
this._banner = this._notification.createBanner();
|
|
this._bannerClickedId = this._banner.connect('done-displaying',
|
|
Lang.bind(this, this._escapeTray));
|
|
this._bannerUnfocusedId = this._banner.connect('unfocused', Lang.bind(this, function() {
|
|
this._updateState();
|
|
}));
|
|
|
|
this._bannerBin.add_actor(this._banner.actor);
|
|
|
|
if (!versionAtLeast('3.34', Config.PACKAGE_VERSION)) {
|
|
this._bannerBin._opacity = 0;
|
|
}
|
|
this._bannerBin.opacity = 0;
|
|
|
|
if (getY_position() < 50)
|
|
this._bannerBin.y = Main.layoutManager.monitors[0].height;
|
|
else
|
|
this._bannerBin.y = -this._banner.actor.height;
|
|
|
|
this.actor.show();
|
|
} else
|
|
{
|
|
this._notificationClickedId = this._notification.connect('done-displaying',
|
|
Lang.bind(this, this._escapeTray));
|
|
this._notificationUnfocusedId = this._notification.connect('unfocused', Lang.bind(this, function() {
|
|
this._updateState();
|
|
}));
|
|
this._notificationBin.child = this._notification.actor;
|
|
|
|
this._notificationWidget.opacity = 0;
|
|
// JRL changes begin
|
|
//this._notificationWidget.y = 0;
|
|
if (getY_position() < 50)
|
|
this._notificationWidget.y = this.actor.height;
|
|
else
|
|
this._notificationWidget.y = -(Main.layoutManager.monitors[0].y + Main.layoutManager.monitors[0].height);
|
|
// JRL changes end
|
|
|
|
|
|
this._notificationWidget.show();
|
|
}
|
|
|
|
if (versionAtLeast('3.30', Config.PACKAGE_VERSION)) {
|
|
Meta.disable_unredirect_for_display(global.display);
|
|
}
|
|
this._updateShowingNotification();
|
|
|
|
let [x, y, mods] = global.get_pointer();
|
|
// We save the position of the mouse at the time when we started showing the notification
|
|
// in order to determine if the notification popped up under it. We make that check if
|
|
// the user starts moving the mouse and _onTrayHoverChanged() gets called. We don't
|
|
// expand the notification if it just happened to pop up under the mouse unless the user
|
|
// explicitly mouses away from it and then mouses back in.
|
|
this._showNotificationMouseX = x;
|
|
this._showNotificationMouseY = y;
|
|
// We save the coordinates of the mouse at the time when we started showing the notification
|
|
// and then we update it in _notificationTimeout(). We don't pop down the notification if
|
|
// the mouse is moving towards it or within it.
|
|
this._lastSeenMouseX = x;
|
|
this._lastSeenMouseY = y;
|
|
if (versionAtLeast('3.14', Config.PACKAGE_VERSION)) {
|
|
this._resetNotificationLeftTimeout();
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
* Copied from MessageTray._hideNotification()
|
|
*
|
|
* 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
|
|
* entire screen.
|
|
*/
|
|
let extensionHideNotification = function(animate) {
|
|
this._notificationFocusGrabber.ungrabFocus();
|
|
|
|
let yPos;
|
|
if (versionAtLeast('3.16', Config.PACKAGE_VERSION)) {
|
|
if (getY_position() < 50)
|
|
yPos = Main.layoutManager.monitors[0].y + Main.layoutManager.monitors[0].height;
|
|
else
|
|
yPos = -this._bannerBin.height;
|
|
|
|
if (this._bannerClickedId) {
|
|
this._banner.disconnect(this._bannerClickedId);
|
|
this._bannerClickedId = 0;
|
|
}
|
|
if (this._bannerUnfocusedId) {
|
|
this._banner.disconnect(this._bannerUnfocusedId);
|
|
this._bannerUnfocusedId = 0;
|
|
}
|
|
|
|
}else
|
|
{
|
|
if (this._notificationExpandedId) {
|
|
this._notification.disconnect(this._notificationExpandedId);
|
|
this._notificationExpandedId = 0;
|
|
}
|
|
// JRL changes begin
|
|
if (getY_position() < 50)
|
|
yPos = this.actor.height;
|
|
else
|
|
yPos = -(Main.layoutManager.monitors[0].y + Main.layoutManager.monitors[0].height);
|
|
// JRL changes end
|
|
if (this._notificationClickedId) {
|
|
this._notification.disconnect(this._notificationClickedId);
|
|
this._notificationClickedId = 0;
|
|
}
|
|
if (this._notificationUnfocusedId) {
|
|
this._notification.disconnect(this._notificationUnfocusedId);
|
|
this._notificationUnfocusedId = 0;
|
|
}
|
|
}
|
|
|
|
if (versionAtLeast('3.14', Config.PACKAGE_VERSION)) {
|
|
this._resetNotificationLeftTimeout();
|
|
}
|
|
else
|
|
{
|
|
if (this._notificationLeftTimeoutId) {
|
|
Mainloop.source_remove(this._notificationLeftTimeoutId);
|
|
this._notificationLeftTimeoutId = 0;
|
|
this._notificationLeftMouseX = -1;
|
|
this._notificationLeftMouseY = -1;
|
|
}
|
|
}
|
|
|
|
if (versionAtLeast('3.34', Config.PACKAGE_VERSION)) {
|
|
this._bannerBin.remove_all_transitions();
|
|
|
|
if (animate) {
|
|
this._notificationState = State.HIDING;
|
|
this._bannerBin.ease({
|
|
opacity: 0,
|
|
duration: ANIMATION_TIME,
|
|
mode: Clutter.AnimationMode.EASE_OUT_BACK
|
|
});
|
|
this._bannerBin.ease({
|
|
// JRL changes begin
|
|
y: yPos,
|
|
// JRL changes end
|
|
duration: ANIMATION_TIME,
|
|
mode: Clutter.AnimationMode.EASE_OUT_BACK,
|
|
onComplete: () => {
|
|
this._notificationState = State.HIDDEN;
|
|
this._hideNotificationCompleted();
|
|
this._updateState();
|
|
}
|
|
});
|
|
} else {
|
|
// JRL changes begin
|
|
y: yPos,
|
|
// JRL changes end
|
|
this._bannerBin.opacity = 0;
|
|
this._notificationState = State.HIDDEN;
|
|
this._hideNotificationCompleted();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// JRL changes begin
|
|
let theNotification;
|
|
if (versionAtLeast('3.16', Config.PACKAGE_VERSION)) {
|
|
theNotification = this._bannerBin;
|
|
}else
|
|
{
|
|
theNotification = this._notificationWidget;
|
|
}
|
|
// JRL changes end
|
|
|
|
|
|
if (animate) {
|
|
if (versionAtLeast('3.16', Config.PACKAGE_VERSION)) {
|
|
// JRL changes begin
|
|
this._tween(theNotification, '_notificationState', State.HIDDEN,
|
|
{ y: yPos,
|
|
// JRL changes end
|
|
_opacity: 0,
|
|
time: ANIMATION_TIME,
|
|
transition: 'easeOutBack',
|
|
onUpdate: this._clampOpacity,
|
|
onUpdateScope: this,
|
|
onComplete: this._hideNotificationCompleted,
|
|
onCompleteScope: this
|
|
});
|
|
} else {
|
|
// JRL changes begin
|
|
this._tween(theNotification, '_notificationState', State.HIDDEN,
|
|
{ y: yPos,
|
|
// JRL changes end
|
|
opacity: 0,
|
|
time: ANIMATION_TIME,
|
|
transition: 'easeOutQuad',
|
|
onComplete: this._hideNotificationCompleted,
|
|
onCompleteScope: this
|
|
});
|
|
}
|
|
} else {
|
|
// JRL changes begin
|
|
Tweener.removeTweens(theNotification);
|
|
theNotification.y = yPos;
|
|
theNotification.opacity = 0;
|
|
// JRL changes end
|
|
this._notificationState = State.HIDDEN;
|
|
this._hideNotificationCompleted();
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
* 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
|
|
* entire screen.
|
|
*
|
|
*/
|
|
let extensionUpdateShowingNotification = function() {
|
|
// JRL changes begin
|
|
// first reset the border-radius to the default
|
|
if (!versionAtLeast('3.16', Config.PACKAGE_VERSION)) {
|
|
this._notification._table.set_style('border-radius:;');
|
|
if (getY_position() > 0.1)
|
|
{
|
|
// fix the border-radiuses, depending on the position
|
|
let tl, tr;
|
|
let bl = this._notification._table.get_theme_node().get_border_radius(St.Corner.TOPLEFT);
|
|
let br = this._notification._table.get_theme_node().get_border_radius(St.Corner.TOPRIGHT);
|
|
if (getY_position() >= 99.9)
|
|
{
|
|
tl = this._notification._table.get_theme_node().get_border_radius(St.Corner.BOTTOMLEFT);
|
|
tr = this._notification._table.get_theme_node().get_border_radius(St.Corner.BOTTOMRIGHT);
|
|
}
|
|
else
|
|
{
|
|
tl = bl;
|
|
tr = br;
|
|
}
|
|
this._notification._table.set_style('border-radius: '+tl+'px '+tr+'px '+bl+'px '+br+'px;');
|
|
}
|
|
}
|
|
// JRL changes end
|
|
this._notification.acknowledged = true;
|
|
this._notification.playSound();
|
|
// We auto-expand notifications with CRITICAL urgency, or for which the relevant setting
|
|
// is on in the control center.
|
|
if (this._notification.urgency == Urgency.CRITICAL ||
|
|
// JRL changes begin
|
|
getForce_expand() ||
|
|
// JRL changes end
|
|
this._notification.source.policy.forceExpanded)
|
|
{
|
|
if (versionAtLeast('3.16', Config.PACKAGE_VERSION))
|
|
this._expandBanner(true);
|
|
else
|
|
this._expandNotification(true);
|
|
}
|
|
|
|
|
|
// JRL changes begin
|
|
let theNotification;
|
|
if (versionAtLeast('3.16', Config.PACKAGE_VERSION)) {
|
|
theNotification = this._bannerBin;
|
|
}else
|
|
{
|
|
theNotification =this._notificationWidget;
|
|
}
|
|
// use panel's y and height property to determine the bottom of the top-panel.
|
|
// needed because the "hide top bar" and "hide top panel" use different approaches to hide the
|
|
// top bar.
|
|
// "hide top panel" keeps the height and just moves the panel out of the visible area, so using
|
|
// the panels-height is not enough.
|
|
let yPos;
|
|
updateAvailablePrimaryRect();
|
|
if (versionAtLeast('3.16', Config.PACKAGE_VERSION)) {
|
|
|
|
yPos = (_availablePrimaryRect.height - theNotification.height) * (100-getY_position()) / 100;
|
|
|
|
}else
|
|
{
|
|
let yTop = -(Main.layoutManager.bottomMonitor.y + Main.layoutManager.bottomMonitor.height);
|
|
if (Main.layoutManager.bottomMonitor == Main.layoutManager.primaryMonitor)
|
|
yTop += (panel.y + panel.height);
|
|
if (yTop < (-Main.layoutManager.bottomMonitor.height))
|
|
yTop = -Main.layoutManager.bottomMonitor.height;
|
|
let yBottom = -theNotification.height;
|
|
|
|
yPos = (yTop - yBottom) * getY_position() / 100 + yBottom;
|
|
//
|
|
}
|
|
theNotification.x = (_availablePrimaryRect.width - theNotification.width) * (getX_position() - 50) / 50;
|
|
// JRL changes end
|
|
// We tween all notifications to full opacity. This ensures that both new notifications and
|
|
// notifications that might have been in the process of hiding get full opacity.
|
|
//
|
|
// We tween any notification showing in the banner mode to the appropriate height
|
|
// (which is banner height or expanded height, depending on the notification state)
|
|
// This ensures that both new notifications and notifications in the banner mode that might
|
|
// have been in the process of hiding are shown with the correct height.
|
|
//
|
|
// We use this._showNotificationCompleted() onComplete callback to extend the time the updated
|
|
// notification is being shown.
|
|
|
|
if (versionAtLeast('3.34', Config.PACKAGE_VERSION)) {
|
|
this._notificationState = State.SHOWING;
|
|
this._bannerBin.remove_all_transitions();
|
|
this._bannerBin.ease({
|
|
opacity: 255,
|
|
duration: ANIMATION_TIME,
|
|
mode: Clutter.AnimationMode.LINEAR
|
|
});
|
|
this._bannerBin.ease({
|
|
// JRL changes begin
|
|
y: yPos,
|
|
// JRL changes end
|
|
duration: ANIMATION_TIME,
|
|
mode: Clutter.AnimationMode.EASE_OUT_BACK,
|
|
onComplete: () => {
|
|
this._notificationState = State.SHOWN;
|
|
this._showNotificationCompleted();
|
|
this._updateState();
|
|
}
|
|
});
|
|
}
|
|
else
|
|
{
|
|
let tweenParams;
|
|
if (versionAtLeast('3.16', Config.PACKAGE_VERSION)) {
|
|
tweenParams = { _opacity: 255,
|
|
// JRL changes begin
|
|
y: yPos,
|
|
// JRL changes end
|
|
time: ANIMATION_TIME,
|
|
transition: 'easeOutBack',
|
|
onUpdate: this._clampOpacity,
|
|
onUpdateScope: this,
|
|
onComplete: this._showNotificationCompleted,
|
|
onCompleteScope: this
|
|
};
|
|
}else
|
|
{
|
|
tweenParams = { opacity: 255,
|
|
// JRL changes begin
|
|
y: yPos,
|
|
// JRL changes end
|
|
time: ANIMATION_TIME,
|
|
transition: 'easeOutQuad',
|
|
onComplete: this._showNotificationCompleted,
|
|
onCompleteScope: this
|
|
};
|
|
}
|
|
|
|
this._tween(theNotification, '_notificationState', State.SHOWN, tweenParams);
|
|
}
|
|
};
|
|
|
|
/*
|
|
* Copied from MessageTray._onNotificationExpanded()
|
|
*
|
|
* 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
|
|
* entire screen.
|
|
*
|
|
*/
|
|
let extensiononNotificationExpanded = function() {
|
|
// JRL changes begin
|
|
//let expandedY = - this._notificationWidget.height;
|
|
let yTop = -(Main.layoutManager.monitors[0].y + Main.layoutManager.monitors[0].height);
|
|
if (Main.layoutManager.monitors[0] == Main.layoutManager.primaryMonitor)
|
|
yTop += (panel.y + panel.height);
|
|
if (yTop < (-Main.layoutManager.monitors[0].height))
|
|
yTop = -Main.layoutManager.monitors[0].height;
|
|
let yBottom = -this._notificationWidget.height;
|
|
|
|
let expandedY = (yTop - yBottom) * getY_position() / 100 + yBottom;
|
|
// JRL changes end
|
|
this._closeButton.show();
|
|
|
|
// 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.
|
|
if (versionAtLeast('3.14', Config.PACKAGE_VERSION)) {
|
|
Tweener.addTween(this._notificationWidget,
|
|
{ y: expandedY,
|
|
opacity: 255,
|
|
time: ANIMATION_TIME,
|
|
transition: 'easeOutQuad',
|
|
// HACK: Drive the state machine here better,
|
|
// instead of overwriting tweens
|
|
onComplete: Lang.bind(this, function() {
|
|
this._notificationState = State.SHOWN;
|
|
}),
|
|
});
|
|
}
|
|
else
|
|
{
|
|
this._tween(this._notificationWidget, '_notificationState', State.SHOWN,
|
|
{ y: expandedY,
|
|
opacity: 255,
|
|
time: ANIMATION_TIME,
|
|
transition: 'easeOutQuad'
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
/*
|
|
* Overload the methods.
|
|
*/
|
|
function enable() {
|
|
if (versionAtLeast('3.16', Config.PACKAGE_VERSION)) {
|
|
notificationWidget = Main.messageTray._bannerBin;
|
|
}else
|
|
{
|
|
notificationWidget = Main.messageTray._notificationWidget;
|
|
originalExpandMethod = Main.messageTray._onNotificationExpanded;
|
|
Main.messageTray._onNotificationExpanded = extensiononNotificationExpanded;
|
|
}
|
|
originalShowNotification = Main.messageTray._showNotification;
|
|
Main.messageTray._showNotification = extensionShowNotification;
|
|
|
|
originalUpdateShowingNotification = Main.messageTray._updateShowingNotification;
|
|
Main.messageTray._updateShowingNotification = extensionUpdateShowingNotification;
|
|
|
|
originalHideNotification = Main.messageTray._hideNotification;
|
|
Main.messageTray._hideNotification = extensionHideNotification;
|
|
|
|
panel = Main.layoutManager.panelBox;
|
|
|
|
loadConfig();
|
|
}
|
|
|
|
|
|
/*
|
|
* Put everything back.
|
|
*/
|
|
function disable() {
|
|
if (SettingsC) {
|
|
Settings.disconnect(SettingsC);
|
|
SettingsC = undefined;
|
|
}
|
|
|
|
if (showTestNotificationTimeout !== undefined)
|
|
Mainloop.source_remove(showTestNotificationTimeout);
|
|
|
|
// reset x-position
|
|
notificationWidget.x = 0;
|
|
|
|
Main.messageTray._showNotification = originalShowNotification;
|
|
Main.messageTray._hideNotification = originalHideNotification;
|
|
Main.messageTray._updateShowingNotification = originalUpdateShowingNotification;
|
|
if (!versionAtLeast('3.16', Config.PACKAGE_VERSION)) {
|
|
// remove our (inline-)style, in case we just show a notification, otherwise the radius is drawn incorrect
|
|
if (Main.messageTray._notification)
|
|
Main.messageTray._notification._table.set_style('border-radius:;');
|
|
Main.messageTray._onNotificationExpanded = originalExpandMethod;
|
|
}
|
|
}
|
|
|