[gnome-shell] messageList: Use St.Bin as message container and use clutter to manage the list



commit 9bb12f6f87bffe544c24f770e34486f9513de149
Author: Marco Trevisan (Treviño) <mail 3v1n0 net>
Date:   Mon May 13 20:02:26 2019 +0200

    messageList: Use St.Bin as message container and use clutter to manage the list
    
    When messages are added to the message list, we create a container for those,
    however since now the messages are actor themselves we can just create a list
    item actor that holds the message actor and refer to the message parent in order
    to get their container.
    
    This allows to remove the obj container map we used, using the native clutter
    parent-child hierarchy and handle signal connections cleanly.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/559

 js/ui/calendar.js    |  3 +-
 js/ui/messageList.js | 93 +++++++++++++++++++++++++++-------------------------
 2 files changed, 51 insertions(+), 45 deletions(-)
---
diff --git a/js/ui/calendar.js b/js/ui/calendar.js
index cf1025a96f..f25687c730 100644
--- a/js/ui/calendar.js
+++ b/js/ui/calendar.js
@@ -999,9 +999,10 @@ class NotificationSection extends MessageList.MessageListSection {
         if (!this.mapped)
             return;
 
-        for (let message of this._messages.keys())
+        this._messages.forEach(message => {
             if (message.notification.urgency != MessageTray.Urgency.CRITICAL)
                 message.notification.acknowledged = true;
+        });
     }
 
     _shouldShow() {
diff --git a/js/ui/messageList.js b/js/ui/messageList.js
index 6d87c87594..7964a92067 100644
--- a/js/ui/messageList.js
+++ b/js/ui/messageList.js
@@ -564,7 +564,6 @@ var MessageListSection = GObject.registerClass({
             Main.sessionMode.disconnect(id);
         });
 
-        this._messages = new Map();
         this._date = new Date();
         this._empty = true;
         this._canClear = false;
@@ -579,6 +578,10 @@ var MessageListSection = GObject.registerClass({
         return this._canClear;
     }
 
+    get _messages() {
+        return this._list.get_children().map(i => i.child);
+    }
+
     _onKeyFocusIn(messageActor) {
         this.emit('message-focused', messageActor);
     }
@@ -599,58 +602,62 @@ var MessageListSection = GObject.registerClass({
     }
 
     addMessageAtIndex(message, index, animate) {
-        let obj = {
-            container: null,
-            destroyId: 0,
-            keyFocusId: 0,
-            closeId: 0
-        };
-        let pivot = new Graphene.Point({ x: .5, y: .5 });
-        let scale = animate ? 0 : 1;
-        obj.container = new St.Widget({ layout_manager: new ScaleLayout(),
-                                        pivot_point: pivot,
-                                        scale_x: scale, scale_y: scale });
-        obj.keyFocusId = message.connect('key-focus-in',
-            this._onKeyFocusIn.bind(this));
-        obj.destroyId = message.connect('destroy', () => {
-            this.removeMessage(message, false);
-        });
-        obj.closeId = message.connect('close', () => {
-            this.removeMessage(message, true);
+        if (this._messages.includes(message))
+            throw new Error('Message was already added previously');
+
+        let listItem = new St.Bin({
+            child: message,
+            x_fill: true,
+            y_fill: true,
+            layout_manager: new ScaleLayout(),
+            pivot_point: new Graphene.Point({ x: .5, y: .5 }),
         });
+        listItem._connectionsIds = [];
 
-        this._messages.set(message, obj);
-        obj.container.add_actor(message);
+        listItem._connectionsIds.push(message.connect('key-focus-in',
+            this._onKeyFocusIn.bind(this)));
+        listItem._connectionsIds.push(message.connect('close', () => {
+            this.removeMessage(message, true);
+        }));
+        listItem._connectionsIds.push(message.connect('destroy', () => {
+            listItem._connectionsIds.forEach(id => message.disconnect(id));
+            listItem.destroy();
+        }));
 
-        this._list.insert_child_at_index(obj.container, index);
+        this._list.insert_child_at_index(listItem, index);
 
-        if (animate)
-            obj.container.ease({
+        if (animate) {
+            listItem.set({ scale_x: 0, scale_y: 0 });
+            listItem.ease({
                 scale_x: 1,
                 scale_y: 1,
                 duration: MESSAGE_ANIMATION_TIME,
                 mode: Clutter.AnimationMode.EASE_OUT_QUAD
             });
+        }
     }
 
     moveMessage(message, index, animate) {
-        let obj = this._messages.get(message);
+        if (!this._messages.includes(message))
+            throw new Error(`Impossible to move the untracked message ${message}`);
+
+        let listItem = message.get_parent();
 
         if (!animate) {
-            this._list.set_child_at_index(obj.container, index);
+            this._list.set_child_at_index(listItem, index);
             return;
         }
 
         let onComplete = () => {
-            this._list.set_child_at_index(obj.container, index);
-            obj.container.ease({
+            this._list.set_child_at_index(listItem, index);
+            listItem.ease({
                 scale_x: 1,
                 scale_y: 1,
                 duration: MESSAGE_ANIMATION_TIME,
                 mode: Clutter.AnimationMode.EASE_OUT_QUAD
             });
         };
-        obj.container.ease({
+        listItem.ease({
             scale_x: 0,
             scale_y: 0,
             duration: MESSAGE_ANIMATION_TIME,
@@ -660,33 +667,31 @@ var MessageListSection = GObject.registerClass({
     }
 
     removeMessage(message, animate) {
-        let obj = this._messages.get(message);
-
-        message.disconnect(obj.destroyId);
-        message.disconnect(obj.keyFocusId);
-        message.disconnect(obj.closeId);
+        if (!this._messages.includes(message))
+            throw new Error(`Impossible to remove the untracked message ${message}`);
 
-        this._messages.delete(message);
+        let listItem = message.get_parent();
+        listItem._connectionsIds.forEach(id => message.disconnect(id));
 
         if (animate) {
-            obj.container.ease({
+            listItem.ease({
                 scale_x: 0,
                 scale_y: 0,
                 duration: MESSAGE_ANIMATION_TIME,
                 mode: Clutter.AnimationMode.EASE_OUT_QUAD,
                 onComplete: () => {
-                    obj.container.destroy();
+                    listItem.destroy();
                     global.sync_pointer();
                 }
             });
         } else {
-            obj.container.destroy();
+            listItem.destroy();
             global.sync_pointer();
         }
     }
 
     clear() {
-        let messages = [...this._messages.keys()].filter(msg => msg.canClose());
+        let messages = this._messages.filter(msg => msg.canClose());
 
         // If there are few messages, letting them all zoom out looks OK
         if (messages.length < 2) {
@@ -699,9 +704,8 @@ var MessageListSection = GObject.registerClass({
             let delay = MESSAGE_ANIMATION_TIME / Math.max(messages.length, 5);
             for (let i = 0; i < messages.length; i++) {
                 let message = messages[i];
-                let obj = this._messages.get(message);
-                obj.container.ease({
-                    anchor_x: this._list.width,
+                message.get_parent().ease({
+                    translation_x: this._list.width,
                     opacity: 0,
                     duration: MESSAGE_ANIMATION_TIME,
                     delay: i * delay,
@@ -717,14 +721,15 @@ var MessageListSection = GObject.registerClass({
     }
 
     _sync() {
-        let empty = this._list.get_n_children() == 0;
+        let messages = this._messages;
+        let empty = messages.length == 0;
 
         if (this._empty != empty) {
             this._empty = empty;
             this.notify('empty');
         }
 
-        let canClear = [...this._messages.keys()].some(m => m.canClose());
+        let canClear = messages.some(m => m.canClose());
         if (this._canClear != canClear) {
             this._canClear = canClear;
             this.notify('can-clear');


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]