ScreenShield: show notifications in the locked screen
Track screen lock status in the message tray, and filter banner notifications. The message tray is completely hidden when the screen is locked, but exceptions can be made for individual transient notifications, such as shell messages and the on screen keyboard. Non transient sources are shown in the middle of the lock screen. Resident notifications (such as those from Rhythmbox) are shown in full, while persistent ones are displayed as icon and message count. https://bugzilla.gnome.org/show_bug.cgi?id=619955
This commit is contained in:
parent
c3afe1a83a
commit
22eea750f3
@ -2221,3 +2221,30 @@ StScrollBar StButton#vhandle:hover
|
|||||||
.screen-shield-clock-date {
|
.screen-shield-clock-date {
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#screenShieldNotifications {
|
||||||
|
border-radius: 24px;
|
||||||
|
background-color: rgba(0.0, 0.0, 0.0, 0.9);
|
||||||
|
border: 2px solid #868686;
|
||||||
|
}
|
||||||
|
|
||||||
|
#screenShieldNotifications, .screen-shield-notifications-box {
|
||||||
|
spacing: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.screen-shield-notification-source {
|
||||||
|
padding: 24px 8px;
|
||||||
|
spacing: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.screen-shield-notification-label {
|
||||||
|
font-size: 1.2em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove background from notifications, otherwise
|
||||||
|
opacity is doubled and they look darker
|
||||||
|
*/
|
||||||
|
.screen-shield-notifications-box .notification {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
@ -535,6 +535,7 @@ function notify(msg, details) {
|
|||||||
messageTray.add(source);
|
messageTray.add(source);
|
||||||
let notification = new MessageTray.Notification(source, msg, details);
|
let notification = new MessageTray.Notification(source, msg, details);
|
||||||
notification.setTransient(true);
|
notification.setTransient(true);
|
||||||
|
notification.setShowWhenLocked(true);
|
||||||
source.notify(notification);
|
source.notify(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,6 +420,7 @@ const Notification = new Lang.Class({
|
|||||||
// 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
|
// 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
|
||||||
this.isTransient = false;
|
this.isTransient = false;
|
||||||
this.expanded = false;
|
this.expanded = false;
|
||||||
|
this.showWhenLocked = false;
|
||||||
this._destroyed = false;
|
this._destroyed = false;
|
||||||
this._useActionIcons = false;
|
this._useActionIcons = false;
|
||||||
this._customContent = false;
|
this._customContent = false;
|
||||||
@ -816,6 +817,14 @@ const Notification = new Lang.Class({
|
|||||||
this.isTransient = isTransient;
|
this.isTransient = isTransient;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setShowWhenLocked: function(show) {
|
||||||
|
if (show && !this.isTransient) {
|
||||||
|
throw new Error('ShowWhenLocked can only be set on a transient notification');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showWhenLocked = show;
|
||||||
|
},
|
||||||
|
|
||||||
setUseActionIcons: function(useIcons) {
|
setUseActionIcons: function(useIcons) {
|
||||||
this._useActionIcons = useIcons;
|
this._useActionIcons = useIcons;
|
||||||
},
|
},
|
||||||
@ -1237,6 +1246,10 @@ const Source = new Lang.Class({
|
|||||||
// Default implementation is to destroy this source, but subclasses can override
|
// Default implementation is to destroy this source, but subclasses can override
|
||||||
_lastNotificationRemoved: function() {
|
_lastNotificationRemoved: function() {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
|
hasResidentNotification: function() {
|
||||||
|
return this.notifications.some(function(n) { return n.resident; });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(Source.prototype);
|
Signals.addSignalMethods(Source.prototype);
|
||||||
@ -1578,6 +1591,9 @@ const MessageTray = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
this._isScreenLocked = false;
|
||||||
|
Main.screenShield.connect('lock-status-changed', Lang.bind(this, this._onScreenLockStatusChanged));
|
||||||
|
|
||||||
this._summaryItems = [];
|
this._summaryItems = [];
|
||||||
// We keep a list of new summary items that were added to the summary since the last
|
// We keep a list of new summary items that were added to the summary since the last
|
||||||
// time it was shown to the user. We automatically show the summary to the user if there
|
// time it was shown to the user. We automatically show the summary to the user if there
|
||||||
@ -1684,6 +1700,12 @@ const MessageTray = new Lang.Class({
|
|||||||
// *first* and not show the summary item until after it hides.
|
// *first* and not show the summary item until after it hides.
|
||||||
// So postpone calling _updateState() a tiny bit.
|
// So postpone calling _updateState() a tiny bit.
|
||||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() { this._updateState(); return false; }));
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() { this._updateState(); return false; }));
|
||||||
|
|
||||||
|
this.emit('summary-item-added', summaryItem);
|
||||||
|
},
|
||||||
|
|
||||||
|
getSummaryItems: function() {
|
||||||
|
return this._summaryItems;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onSourceDestroy: function(source) {
|
_onSourceDestroy: function(source) {
|
||||||
@ -1758,6 +1780,11 @@ const MessageTray = new Lang.Class({
|
|||||||
this._notificationQueue.splice(index, 1);
|
this._notificationQueue.splice(index, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onScreenLockStatusChanged: function(screenShield, locked) {
|
||||||
|
this._isScreenLocked = locked;
|
||||||
|
this._updateState();
|
||||||
|
},
|
||||||
|
|
||||||
_lock: function() {
|
_lock: function() {
|
||||||
this._locked = true;
|
this._locked = true;
|
||||||
},
|
},
|
||||||
@ -2088,18 +2115,36 @@ const MessageTray = new Lang.Class({
|
|||||||
// at the present time.
|
// at the present time.
|
||||||
_updateState: function() {
|
_updateState: function() {
|
||||||
// Notifications
|
// Notifications
|
||||||
let notificationUrgent = this._notificationQueue.length > 0 && this._notificationQueue[0].urgency == Urgency.CRITICAL;
|
let notificationQueue = this._notificationQueue.filter(Lang.bind(this, function(notification) {
|
||||||
let notificationsPending = this._notificationQueue.length > 0 && ((!this._busy && !this._inFullscreen) || notificationUrgent);
|
if (this._isScreenLocked)
|
||||||
|
return notification.showWhenLocked;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}));
|
||||||
|
let notificationUrgent = notificationQueue.length > 0 && notificationQueue[0].urgency == Urgency.CRITICAL;
|
||||||
|
// notificationsLimited is false when the screen is locked, because they go through
|
||||||
|
// different filtering, and we want to show non urgent messages at times
|
||||||
|
let notificationsLimited = (this._busy || this._inFullscreen) && !this._isScreenLocked;
|
||||||
|
let notificationsPending = notificationQueue.length > 0 && (!notificationsLimited || notificationUrgent);
|
||||||
|
let nextNotification = notificationQueue.length > 0 ? notificationQueue[0] : null;
|
||||||
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
|
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
|
||||||
let notificationExpanded = this._notificationBin.y < - this.actor.height;
|
let notificationExpanded = this._notificationBin.y < - this.actor.height;
|
||||||
let notificationExpired = (this._notificationTimeoutId == 0 && !(this._notification && this._notification.urgency == Urgency.CRITICAL) && !this._pointerInTray && !this._locked && !(this._pointerInKeyboard && notificationExpanded)) || this._notificationRemoved;
|
let notificationExpired = this._notificationTimeoutId == 0 &&
|
||||||
|
!(this._notification && this._notification.urgency == Urgency.CRITICAL) &&
|
||||||
|
!this._pointerInTray &&
|
||||||
|
!this._locked &&
|
||||||
|
!(this._pointerInKeyboard && notificationExpanded);
|
||||||
|
let notificationLockedOut = this._isScreenLocked && (this._notification && !this._notification.showWhenLocked);
|
||||||
|
let notificationMustClose = this._notificationRemoved || notificationLockedOut || notificationExpired;
|
||||||
let canShowNotification = notificationsPending && this._summaryState == State.HIDDEN;
|
let canShowNotification = notificationsPending && this._summaryState == State.HIDDEN;
|
||||||
|
|
||||||
if (this._notificationState == State.HIDDEN) {
|
if (this._notificationState == State.HIDDEN) {
|
||||||
if (canShowNotification)
|
if (canShowNotification) {
|
||||||
this._showNotification();
|
this._showNotification(nextNotification);
|
||||||
|
this._notificationQueue.splice(this._notificationQueue.indexOf(nextNotification), 1);
|
||||||
|
}
|
||||||
} else if (this._notificationState == State.SHOWN) {
|
} else if (this._notificationState == State.SHOWN) {
|
||||||
if (notificationExpired)
|
if (notificationMustClose)
|
||||||
this._hideNotification();
|
this._hideNotification();
|
||||||
else if (notificationPinned && !notificationExpanded)
|
else if (notificationPinned && !notificationExpanded)
|
||||||
this._expandNotification(false);
|
this._expandNotification(false);
|
||||||
@ -2120,7 +2165,7 @@ const MessageTray = new Lang.Class({
|
|||||||
|
|
||||||
let summaryOptionalInOverview = this._overviewVisible && !this._locked && !summaryHovered;
|
let summaryOptionalInOverview = this._overviewVisible && !this._locked && !summaryHovered;
|
||||||
let mustHideSummary = (notificationsPending && (notificationUrgent || summaryOptionalInOverview))
|
let mustHideSummary = (notificationsPending && (notificationUrgent || summaryOptionalInOverview))
|
||||||
|| notificationsVisible;
|
|| notificationsVisible || this._isScreenLocked;
|
||||||
|
|
||||||
if (this._summaryState == State.HIDDEN && !mustHideSummary) {
|
if (this._summaryState == State.HIDDEN && !mustHideSummary) {
|
||||||
if (summarySummoned) {
|
if (summarySummoned) {
|
||||||
@ -2237,8 +2282,8 @@ const MessageTray = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_showNotification: function() {
|
_showNotification: function(notification) {
|
||||||
this._notification = this._notificationQueue.shift();
|
this._notification = notification;
|
||||||
this._unseenNotifications.push(this._notification);
|
this._unseenNotifications.push(this._notification);
|
||||||
if (this._idleMonitorWatchId == 0)
|
if (this._idleMonitorWatchId == 0)
|
||||||
this._idleMonitorWatchId = this.idleMonitor.add_watch(1000,
|
this._idleMonitorWatchId = this.idleMonitor.add_watch(1000,
|
||||||
@ -2587,6 +2632,7 @@ const MessageTray = new Lang.Class({
|
|||||||
this._updateState();
|
this._updateState();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Signals.addSignalMethods(MessageTray.prototype);
|
||||||
|
|
||||||
const SystemNotificationSource = new Lang.Class({
|
const SystemNotificationSource = new Lang.Class({
|
||||||
Name: 'SystemNotificationSource',
|
Name: 'SystemNotificationSource',
|
||||||
@ -2594,6 +2640,7 @@ const SystemNotificationSource = new Lang.Class({
|
|||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(_("System Information"), 'dialog-information', St.IconType.SYMBOLIC);
|
this.parent(_("System Information"), 'dialog-information', St.IconType.SYMBOLIC);
|
||||||
|
this.setTransient(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
open: function() {
|
open: function() {
|
||||||
|
@ -75,6 +75,7 @@ const ShellInfo = new Lang.Class({
|
|||||||
let notification = null;
|
let notification = null;
|
||||||
if (this._source.notifications.length == 0) {
|
if (this._source.notifications.length == 0) {
|
||||||
notification = new MessageTray.Notification(this._source, text, null);
|
notification = new MessageTray.Notification(this._source, text, null);
|
||||||
|
notification.setShowWhenLocked(true);
|
||||||
} else {
|
} else {
|
||||||
notification = this._source.notifications[0];
|
notification = this._source.notifications[0];
|
||||||
notification.update(text, null, { clear: true });
|
notification.update(text, null, { clear: true });
|
||||||
|
@ -11,6 +11,7 @@ const St = imports.gi.St;
|
|||||||
const GnomeSession = imports.misc.gnomeSession;
|
const GnomeSession = imports.misc.gnomeSession;
|
||||||
const Lightbox = imports.ui.lightbox;
|
const Lightbox = imports.ui.lightbox;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
const MessageTray = imports.ui.messageTray;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
|
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
|
||||||
@ -21,6 +22,8 @@ const CURTAIN_SLIDE_TIME = 1.2;
|
|||||||
// the slide up automatically
|
// the slide up automatically
|
||||||
const ARROW_DRAG_TRESHOLD = 0.4;
|
const ARROW_DRAG_TRESHOLD = 0.4;
|
||||||
|
|
||||||
|
const SUMMARY_ICON_SIZE = 48;
|
||||||
|
|
||||||
const Clock = new Lang.Class({
|
const Clock = new Lang.Class({
|
||||||
Name: 'ScreenShieldClock',
|
Name: 'ScreenShieldClock',
|
||||||
|
|
||||||
@ -58,6 +61,191 @@ const Clock = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const NotificationsBox = new Lang.Class({
|
||||||
|
Name: 'NotificationsBox',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.actor = new St.BoxLayout({ vertical: true,
|
||||||
|
name: 'screenShieldNotifications',
|
||||||
|
margin_top: 20
|
||||||
|
});
|
||||||
|
|
||||||
|
this._residentNotificationBox = new St.BoxLayout({ vertical: true,
|
||||||
|
style_class: 'screen-shield-notifications-box' });
|
||||||
|
this._persistentNotificationBox = new St.BoxLayout({ vertical: true,
|
||||||
|
style_class: 'screen-shield-notifications-box' });
|
||||||
|
|
||||||
|
this.actor.add(this._residentNotificationBox, { x_fill: true });
|
||||||
|
this.actor.add(this._persistentNotificationBox, { x_fill: false, x_align: St.Align.MIDDLE });
|
||||||
|
|
||||||
|
this._items = [];
|
||||||
|
Main.messageTray.getSummaryItems().forEach(Lang.bind(this, function(item) {
|
||||||
|
this._summaryItemAdded(Main.messageTray, item);
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._summaryAddedId = Main.messageTray.connect('summary-item-added', Lang.bind(this, this._summaryItemAdded));
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
if (this._summaryAddedId) {
|
||||||
|
Main.messageTray.disconnect(this._summaryAddedId);
|
||||||
|
this._summaryAddedId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < this._items.length; i++)
|
||||||
|
this._removeItem(this._items[i]);
|
||||||
|
this._items = [];
|
||||||
|
|
||||||
|
this.actor.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateVisibility: function() {
|
||||||
|
if (this._residentNotificationBox.get_n_children() > 0) {
|
||||||
|
this.actor.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let children = this._persistentNotificationBox.get_children()
|
||||||
|
this.actor.visible = children.some(function(a) { return a.visible; });
|
||||||
|
},
|
||||||
|
|
||||||
|
_sourceIsResident: function(source) {
|
||||||
|
return source.hasResidentNotification() && !source.isChat;
|
||||||
|
},
|
||||||
|
|
||||||
|
_makeNotificationCountText: function(source) {
|
||||||
|
if (source.isChat)
|
||||||
|
return ngettext("%d new message", "%d new messages", source.count).format(source.count);
|
||||||
|
else
|
||||||
|
return ngettext("%d new notification", "%d new notifications", source.count).format(source.count);
|
||||||
|
},
|
||||||
|
|
||||||
|
_makeNotificationSource: function(source) {
|
||||||
|
let box = new St.BoxLayout({ style_class: 'screen-shield-notification-source' });
|
||||||
|
|
||||||
|
let iconClone = source.createIcon(SUMMARY_ICON_SIZE);
|
||||||
|
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
|
||||||
|
sourceActor.setIcon(iconClone);
|
||||||
|
box.add(sourceActor.actor, { y_fill: true });
|
||||||
|
|
||||||
|
let textBox = new St.BoxLayout({ vertical: true });
|
||||||
|
box.add(textBox, { y_fill: true, expand: true });
|
||||||
|
|
||||||
|
let label = new St.Label({ text: source.title,
|
||||||
|
style_class: 'screen-shield-notification-label' });
|
||||||
|
textBox.add(label);
|
||||||
|
|
||||||
|
let countLabel = new St.Label({ text: this._makeNotificationCountText(source),
|
||||||
|
style_class: 'screen-shield-notification-count-text' });
|
||||||
|
textBox.add(countLabel);
|
||||||
|
|
||||||
|
box.visible = source.count != 0;
|
||||||
|
return [box, countLabel];
|
||||||
|
},
|
||||||
|
|
||||||
|
_summaryItemAdded: function(tray, item) {
|
||||||
|
// Ignore transient sources
|
||||||
|
if (item.source.isTransient)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let obj = {
|
||||||
|
item: item,
|
||||||
|
source: item.source,
|
||||||
|
resident: this._sourceIsResident(item.source),
|
||||||
|
contentUpdatedId: 0,
|
||||||
|
sourceDestroyId: 0,
|
||||||
|
sourceBox: null,
|
||||||
|
countLabel: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (obj.resident) {
|
||||||
|
item.prepareNotificationStackForShowing();
|
||||||
|
this._residentNotificationBox.add(item.notificationStackView);
|
||||||
|
} else {
|
||||||
|
[obj.sourceBox, obj.countLabel] = this._makeNotificationSource(item.source);
|
||||||
|
this._persistentNotificationBox.add(obj.sourceBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.contentUpdatedId = item.connect('content-updated', Lang.bind(this, this._onItemContentUpdated));
|
||||||
|
obj.sourceCountChangedId = item.source.connect('count-changed', Lang.bind(this, this._onSourceCountChanged));
|
||||||
|
obj.sourceDestroyId = item.source.connect('destroy', Lang.bind(this, this._onSourceDestroy));
|
||||||
|
this._items.push(obj);
|
||||||
|
|
||||||
|
this._updateVisibility();
|
||||||
|
},
|
||||||
|
|
||||||
|
_findSource: function(source) {
|
||||||
|
for (let i = 0; i < this._items.length; i++) {
|
||||||
|
if (this._items[i].source == source)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onItemContentUpdated: function(item) {
|
||||||
|
let obj = this._items[this._findSource(item.source)];
|
||||||
|
this._updateItem(obj);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onSourceCountChanged: function(source) {
|
||||||
|
let obj = this._items[this._findSource(source)];
|
||||||
|
this._updateItem(obj);
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateItem: function(obj) {
|
||||||
|
let itemShouldBeResident = this._sourceIsResident(obj.source);
|
||||||
|
|
||||||
|
if (itemShouldBeResident && obj.resident) {
|
||||||
|
// Nothing to do here, the actor is already updated
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.resident && !itemShouldBeResident) {
|
||||||
|
// make into a regular item
|
||||||
|
this._residentNotificationBox.remove_actor(obj.item.notificationStackView);
|
||||||
|
|
||||||
|
[obj.sourceBox, obj.countLabel] = this._makeNotificationSource(obj.source);
|
||||||
|
this._persistentNotificationBox.add(obj.sourceBox);
|
||||||
|
} else if (itemShouldBeResident && !obj.resident) {
|
||||||
|
// make into a resident item
|
||||||
|
obj.sourceBox.destroy();
|
||||||
|
obj.sourceBox = obj.countLabel = null;
|
||||||
|
|
||||||
|
obj.item.prepareNotificationStackForShowing();
|
||||||
|
this._residentNotificationBox.add(obj.item.notificationStackView);
|
||||||
|
} else {
|
||||||
|
// just update the counter
|
||||||
|
obj.countLabel.text = this._makeNotificationCountText(obj.item.source);
|
||||||
|
obj.sourceBox.visible = obj.source.count != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateVisibility();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onSourceDestroy: function(source) {
|
||||||
|
let idx = this._findSource(source);
|
||||||
|
|
||||||
|
this._removeItem(this._items[idx]);
|
||||||
|
this._items.splice(idx, 1);
|
||||||
|
|
||||||
|
this._updateVisibility();
|
||||||
|
},
|
||||||
|
|
||||||
|
_removeItem: function(obj) {
|
||||||
|
if (obj.resident) {
|
||||||
|
this._residentNotificationBox.remove_actor(obj.item.notificationStackView);
|
||||||
|
obj.item.doneShowingNotificationStack();
|
||||||
|
} else {
|
||||||
|
obj.sourceBox.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.item.disconnect(obj.contentUpdatedId);
|
||||||
|
obj.source.disconnect(obj.sourceDestroyId);
|
||||||
|
obj.source.disconnect(obj.sourceCountChangedId);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To test screen shield, make sure to kill gnome-screensaver.
|
* To test screen shield, make sure to kill gnome-screensaver.
|
||||||
*
|
*
|
||||||
@ -298,6 +486,13 @@ const ScreenShield = new Lang.Class({
|
|||||||
|
|
||||||
this._lockScreenGroup.add_actor(this._lockScreenContentsBox);
|
this._lockScreenGroup.add_actor(this._lockScreenContentsBox);
|
||||||
|
|
||||||
|
if (this._settings.get_boolean('show-notifications')) {
|
||||||
|
this._notificationsBox = new NotificationsBox();
|
||||||
|
this._lockScreenContentsBox.add(this._notificationsBox.actor, { x_fill: true,
|
||||||
|
y_fill: true,
|
||||||
|
expand: true });
|
||||||
|
}
|
||||||
|
|
||||||
this._hasLockScreen = true;
|
this._hasLockScreen = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -305,6 +500,11 @@ const ScreenShield = new Lang.Class({
|
|||||||
this._clock.destroy();
|
this._clock.destroy();
|
||||||
this._clock = null;
|
this._clock = null;
|
||||||
|
|
||||||
|
if (this._notificationsBox) {
|
||||||
|
this._notificationsBox.destroy();
|
||||||
|
this._notificationsBox = null;
|
||||||
|
}
|
||||||
|
|
||||||
this._lockScreenContentsBox.destroy();
|
this._lockScreenContentsBox.destroy();
|
||||||
|
|
||||||
this._hasLockScreen = false;
|
this._hasLockScreen = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user