events: Re-use event messages where possible

Destroying and recreating the entire events list on every change is not only
wasteful, it also breaks the clear functionality as messages scheduled for
removal are replaced with "new" messages after the first message has been
removed.

Address both issues by keeping track of all messages and re-use them
whenever possible.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/325
This commit is contained in:
Florian Müllner 2018-06-09 13:23:35 +02:00
parent db2245d60b
commit 9c51c87d8c

View File

@ -821,6 +821,8 @@ var EventsSection = new Lang.Class({
this._desktopSettings.connect('changed', this._reloadEvents.bind(this)); this._desktopSettings.connect('changed', this._reloadEvents.bind(this));
this._eventSource = new EmptyEventSource(); this._eventSource = new EmptyEventSource();
this._messageById = new Map();
this.parent(); this.parent();
this._title = new St.Button({ style_class: 'events-section-title', this._title = new St.Button({ style_class: 'events-section-title',
@ -875,20 +877,32 @@ var EventsSection = new Lang.Class({
this._reloading = true; this._reloading = true;
this._list.destroy_all_children();
let periodBegin = _getBeginningOfDay(this._date); let periodBegin = _getBeginningOfDay(this._date);
let periodEnd = _getEndOfDay(this._date); let periodEnd = _getEndOfDay(this._date);
let events = this._eventSource.getEvents(periodBegin, periodEnd); let events = this._eventSource.getEvents(periodBegin, periodEnd);
let ids = events.map(e => e.id);
this._messageById.forEach((message, id) => {
if (ids.includes(id))
return;
this._messageById.delete(id);
this.removeMessage(message);
});
for (let i = 0; i < events.length; i++) { for (let i = 0; i < events.length; i++) {
let event = events[i]; let event = events[i];
let message = new EventMessage(event, this._date); let message = this._messageById.get(event.id);
message.connect('close', () => { if (!message) {
this._ignoreEvent(event); message = new EventMessage(event, this._date);
}); message.connect('close', () => {
this.addMessage(message, false); this._ignoreEvent(event);
});
this._messageById.set(event.id, message);
this.addMessage(message, false);
} else {
this.moveMessage(message, i, false);
}
} }
this._reloading = false; this._reloading = false;