[MessageTray] pop out the last notification when mousing over the summary
https://bugzilla.gnome.org/show_bug.cgi?id=610726
This commit is contained in:
parent
6deee27d14
commit
ac54fed8d4
@ -677,6 +677,11 @@ StTooltip {
|
||||
max-width: 40em;
|
||||
}
|
||||
|
||||
#summary-notification-bin #notification {
|
||||
/* message-tray.height + notification.padding-bottom */
|
||||
padding-bottom: 38px;
|
||||
}
|
||||
|
||||
#notification-actions {
|
||||
spacing: 5px;
|
||||
}
|
||||
@ -699,9 +704,26 @@ StTooltip {
|
||||
background: #808080;
|
||||
}
|
||||
|
||||
/* The spacing and padding on the summary is tricky; we want to keep
|
||||
* the icons from touching each other or the edges of the screen, but
|
||||
* we also want them to be "Fitts"-y with respect to the edges, so the
|
||||
* summary area's bottom and right padding must actually be part of
|
||||
* the icons. However, we can't put *all* of the padding into the
|
||||
* icons, because then the summary would be 0x0 when there were no
|
||||
* icons in it, and so you wouldn't be able to hover over it to
|
||||
* activate it.
|
||||
*
|
||||
* The padding-right on the non-rightmost icons is noticeable and
|
||||
* slightly annoying. If StBoxLayout implemented the ":last-child"
|
||||
* pseudo-class we could fix that...
|
||||
*/
|
||||
#summary-mode {
|
||||
spacing: 10px;
|
||||
padding: 2px 4px;
|
||||
spacing: 6px;
|
||||
padding: 2px 0px 0px 4px;
|
||||
}
|
||||
|
||||
.summary-icon {
|
||||
padding: 0px 4px 2px 0px;
|
||||
}
|
||||
|
||||
/* App Switcher */
|
||||
|
@ -15,7 +15,7 @@ const ANIMATION_TIME = 0.2;
|
||||
const NOTIFICATION_TIMEOUT = 4;
|
||||
const SUMMARY_TIMEOUT = 1;
|
||||
|
||||
const MESSAGE_TRAY_TIMEOUT = 0.2;
|
||||
const HIDE_TIMEOUT = 0.2;
|
||||
|
||||
const ICON_SIZE = 24;
|
||||
|
||||
@ -339,6 +339,19 @@ Source.prototype = {
|
||||
},
|
||||
|
||||
notify: function(notification) {
|
||||
if (this.notification)
|
||||
this.notification.disconnect(this._notificationDestroyedId);
|
||||
|
||||
this.notification = notification;
|
||||
|
||||
this._notificationDestroyedId = notification.connect('destroy', Lang.bind(this,
|
||||
function () {
|
||||
if (this.notification == notification) {
|
||||
this.notification = null;
|
||||
this._notificationDestroyedId = 0;
|
||||
}
|
||||
}));
|
||||
|
||||
this.emit('notify', notification);
|
||||
},
|
||||
|
||||
@ -379,6 +392,17 @@ MessageTray.prototype = {
|
||||
this._summaryBin.child = this._summary;
|
||||
this._summaryBin.opacity = 0;
|
||||
|
||||
this._summaryNotificationBin = new St.Bin({ name: 'summary-notification-bin',
|
||||
x_align: St.Align.END,
|
||||
reactive: true,
|
||||
track_hover: true });
|
||||
this.actor.add(this._summaryNotificationBin);
|
||||
this._summaryNotificationBin.lower_bottom();
|
||||
this._summaryNotificationBin.hide();
|
||||
this._summaryNotificationBin.connect('notify::hover', Lang.bind(this, this._onSummaryNotificationHoverChanged));
|
||||
this._summaryNotification = null;
|
||||
this._hoverSource = null;
|
||||
|
||||
this._trayState = State.HIDDEN;
|
||||
this._trayLeftTimeoutId = 0;
|
||||
this._pointerInTray = false;
|
||||
@ -387,13 +411,15 @@ MessageTray.prototype = {
|
||||
this._pointerInSummary = false;
|
||||
this._notificationState = State.HIDDEN;
|
||||
this._notificationTimeoutId = 0;
|
||||
this._summaryNotificationState = State.HIDDEN;
|
||||
this._summaryNotificationTimeoutId = 0;
|
||||
this._overviewVisible = false;
|
||||
this._notificationRemoved = false;
|
||||
|
||||
this.actor.show();
|
||||
Main.chrome.addActor(this.actor, { affectsStruts: false,
|
||||
visibleInOverview: true });
|
||||
Main.chrome.trackActor(this._notificationBin, { affectsStruts: false });
|
||||
Main.chrome.trackActor(this._summaryNotificationBin, { affectsStruts: false });
|
||||
|
||||
global.connect('screen-size-changed',
|
||||
Lang.bind(this, this._setSizePosition));
|
||||
@ -420,8 +446,8 @@ MessageTray.prototype = {
|
||||
this.actor.y = primary.y + primary.height - 1;
|
||||
this.actor.width = primary.width;
|
||||
|
||||
this._notificationBin.x = this._summaryBin.x = 0;
|
||||
this._notificationBin.width = this._summaryBin.width = primary.width;
|
||||
this._notificationBin.x = this._summaryBin.x = this._summaryNotificationBin.x = 0;
|
||||
this._notificationBin.width = this._summaryBin.width = this._summaryNotificationBin.width = primary.width;
|
||||
},
|
||||
|
||||
contains: function(source) {
|
||||
@ -434,7 +460,8 @@ MessageTray.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
let iconBox = new St.Clickable({ reactive: true });
|
||||
let iconBox = new St.Clickable({ style_class: 'summary-icon',
|
||||
reactive: true });
|
||||
iconBox.child = source.createIcon(ICON_SIZE);
|
||||
this._summary.insert_actor(iconBox, 0);
|
||||
this._summaryNeedsToBeShown = true;
|
||||
@ -443,6 +470,10 @@ MessageTray.prototype = {
|
||||
|
||||
source.connect('notify', Lang.bind(this, this._onNotify));
|
||||
|
||||
iconBox.connect('notify::hover', Lang.bind(this,
|
||||
function () {
|
||||
this._onSourceHoverChanged(source, iconBox.hover);
|
||||
}));
|
||||
iconBox.connect('clicked', Lang.bind(this,
|
||||
function () {
|
||||
source.clicked();
|
||||
@ -474,14 +505,23 @@ MessageTray.prototype = {
|
||||
delete this._icons[source.id];
|
||||
delete this._sources[source.id];
|
||||
|
||||
let needUpdate = false;
|
||||
|
||||
if (this._notification && this._notification.source == source) {
|
||||
if (this._notificationTimeoutId) {
|
||||
Mainloop.source_remove(this._notificationTimeoutId);
|
||||
this._notificationTimeoutId = 0;
|
||||
}
|
||||
this._notificationRemoved = true;
|
||||
this._updateState();
|
||||
needUpdate = true;
|
||||
}
|
||||
if (this._hoverSource == source) {
|
||||
this._hoverSource = null;
|
||||
needUpdate = true;
|
||||
}
|
||||
|
||||
if (needUpdate);
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
removeSourceByApp: function(app) {
|
||||
@ -532,6 +572,39 @@ MessageTray.prototype = {
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
_onSourceHoverChanged: function(source, hover) {
|
||||
if (!source.notification)
|
||||
return;
|
||||
|
||||
if (this._summaryNotificationTimeoutId != 0) {
|
||||
Mainloop.source_remove(this._summaryNotificationTimeoutId);
|
||||
this._summaryNotificationTimeoutId = 0;
|
||||
}
|
||||
|
||||
if (hover) {
|
||||
this._hoverSource = source;
|
||||
this._updateState();
|
||||
} else if (this._hoverSource == source) {
|
||||
let timeout = HIDE_TIMEOUT * 1000;
|
||||
this._summaryNotificationTimeoutId = Mainloop.timeout_add(timeout, Lang.bind(this, this._onSourceHoverChangedTimeout, source));
|
||||
}
|
||||
},
|
||||
|
||||
_onSourceHoverChangedTimeout: function(source) {
|
||||
this._summaryNotificationTimeoutId = 0;
|
||||
if (this._hoverSource == source) {
|
||||
this._hoverSource = null;
|
||||
this._updateState();
|
||||
}
|
||||
},
|
||||
|
||||
_onSummaryNotificationHoverChanged: function() {
|
||||
if (!this._summaryNotification)
|
||||
return;
|
||||
this._onSourceHoverChanged(this._summaryNotification.source,
|
||||
this._summaryNotificationBin.hover);
|
||||
},
|
||||
|
||||
_onSummaryHoverChanged: function() {
|
||||
this._pointerInSummary = this._summary.hover;
|
||||
this._updateState();
|
||||
@ -550,7 +623,7 @@ MessageTray.prototype = {
|
||||
} else {
|
||||
// We wait just a little before hiding the message tray in case the
|
||||
// user quickly moves the mouse back into it.
|
||||
let timeout = MESSAGE_TRAY_TIMEOUT * 1000;
|
||||
let timeout = HIDE_TIMEOUT * 1000;
|
||||
this._trayLeftTimeoutId = Mainloop.timeout_add(timeout, Lang.bind(this, this._onTrayLeftTimeout));
|
||||
}
|
||||
},
|
||||
@ -603,6 +676,22 @@ MessageTray.prototype = {
|
||||
this._hideSummary();
|
||||
}
|
||||
|
||||
// Summary notification
|
||||
let haveSummaryNotification = this._hoverSource != null;
|
||||
let summaryNotificationIsMainNotification = (haveSummaryNotification &&
|
||||
this._hoverSource.notification == this._notification);
|
||||
let canShowSummaryNotification = this._summaryState == State.SHOWN;
|
||||
let wrongSummaryNotification = (haveSummaryNotification &&
|
||||
this._summaryNotification != this._hoverSource.notification);
|
||||
|
||||
if (this._summaryNotificationState == State.HIDDEN) {
|
||||
if (haveSummaryNotification && !summaryNotificationIsMainNotification && canShowSummaryNotification)
|
||||
this._showSummaryNotification();
|
||||
} else if (this._summaryNotificationState == State.SHOWN) {
|
||||
if (!haveSummaryNotification || !canShowSummaryNotification || wrongSummaryNotification)
|
||||
this._hideSummaryNotification();
|
||||
}
|
||||
|
||||
// Tray itself
|
||||
let trayIsVisible = (this._trayState == State.SHOWING ||
|
||||
this._trayState == State.SHOWN);
|
||||
@ -753,5 +842,46 @@ MessageTray.prototype = {
|
||||
transition: "easeOutQuad"
|
||||
});
|
||||
this._summaryNeedsToBeShown = false;
|
||||
},
|
||||
|
||||
_showSummaryNotification: function() {
|
||||
this._summaryNotification = this._hoverSource.notification;
|
||||
|
||||
let index = this._notificationQueue.indexOf(this._summaryNotification);
|
||||
if (index != -1)
|
||||
this._notificationQueue.splice(index, 1);
|
||||
|
||||
this._summaryNotificationBin.child = this._summaryNotification.actor;
|
||||
this._summaryNotification.popOut();
|
||||
|
||||
this._summaryNotificationBin.opacity = 0;
|
||||
this._summaryNotificationBin.y = this.actor.height;
|
||||
this._summaryNotificationBin.show();
|
||||
|
||||
this._tween(this._summaryNotificationBin, "_summaryNotificationState", State.SHOWN,
|
||||
{ y: this.actor.height - this._summaryNotificationBin.height,
|
||||
opacity: 255,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
});
|
||||
},
|
||||
|
||||
_hideSummaryNotification: function() {
|
||||
this._summaryNotification.popIn();
|
||||
|
||||
this._tween(this._summaryNotificationBin, "_summaryNotificationState", State.HIDDEN,
|
||||
{ y: this.actor.height,
|
||||
opacity: 0,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._hideSummaryNotificationCompleted,
|
||||
onCompleteScope: this
|
||||
});
|
||||
},
|
||||
|
||||
_hideSummaryNotificationCompleted: function() {
|
||||
this._summaryNotificationBin.hide();
|
||||
this._summaryNotificationBin.child = null;
|
||||
this._summaryNotification = null;
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user