[polari/wip/fmuellner/window-experiments: 19/32] mainWindow: Manage active room via an :active-room property



commit cc20b5f22ba078219930e0575f3d59c2496a959f
Author: Florian Müllner <fmuellner gnome org>
Date:   Thu Jul 14 04:55:39 2016 +0200

    mainWindow: Manage active room via an :active-room property
    
    Which room is active is currently controlled by the chatroomManager.
    While having that functionality on a singleton is convenient as it
    can be accessed easily from anywhere, a global active room doesn't
    make sense with multiple windows - after all, the whole point for
    allowing additional windows is the ability to display multiple rooms
    at the same time. Moving that functionality into the window instead
    allows for that use case, and makes sense conceptually - it's the
    room that is selected in the window's sidebar, whose chat log is shown
    in the window's content area, whose users the window's user popover
    shows etc.

 src/chatroomManager.js |   34 +++++++++++++---------------------
 src/joinDialog.js      |    3 ++-
 src/mainWindow.js      |   44 +++++++++++++++++++++++++++++++-------------
 src/roomList.js        |   17 ++++++++++-------
 src/roomStack.js       |   20 ++++++++++++++------
 src/userList.js        |   15 +++++++++------
 6 files changed, 79 insertions(+), 54 deletions(-)
---
diff --git a/src/chatroomManager.js b/src/chatroomManager.js
index 50a9f80..62cabc1 100644
--- a/src/chatroomManager.js
+++ b/src/chatroomManager.js
@@ -158,6 +158,10 @@ const _ChatroomManager = new Lang.Class({
 
         this._app.connect('prepare-shutdown',
                           Lang.bind(this, this._onPrepareShutdown));
+        this._app.connect('window-added', (a, w) => {
+            w.connect('notify::active-room',
+                      Lang.bind(this, this._onActiveRoomChanged));
+        });
 
         this._settings = new Gio.Settings({ schema_id: 'org.gnome.Polari' });
 
@@ -314,7 +318,7 @@ const _ChatroomManager = new Lang.Class({
         let room = this._ensureRoom(account, channelName, Tp.HandleType.ROOM);
         let [present, ] = Tp.user_action_time_should_present(time);
         if (present)
-            this.setActiveRoom(room);
+            this._setActiveRoom(room);
     },
 
     _onQueryActivated: function(action, parameter) {
@@ -328,7 +332,7 @@ const _ChatroomManager = new Lang.Class({
         let room = this._ensureRoom(account, channelName, Tp.HandleType.CONTACT);
         let [present, ] = Tp.user_action_time_should_present(time);
         if (present)
-            this.setActiveRoom(room);
+            this._setActiveRoom(room);
     },
 
     _onLeaveActivated: function(action, parameter) {
@@ -407,7 +411,7 @@ const _ChatroomManager = new Lang.Class({
 
                 let room = this._ensureRoomForChannel(channel);
                 if (this.roomCount == 1)
-                    this.setActiveRoom(room);
+                    this._setActiveRoom(room);
             }));
     },
 
@@ -431,7 +435,7 @@ const _ChatroomManager = new Lang.Class({
                 //channel.join_async('', null);
 
                 if (present || this.roomCount == 1)
-                    this.setActiveRoom(room);
+                    this._setActiveRoom(room);
 
                 if (present)
                     this._app.activate();
@@ -442,17 +446,11 @@ const _ChatroomManager = new Lang.Class({
         if (this._rooms.has(room.id))
             return;
 
-        room._channelChangedId = room.connect('notify::channel', Lang.bind(this,
-            function(room) {
-                if (room == this._activeRoom)
-                    this.emit('active-state-changed');
-            }));
-
         this._rooms.set(room.id, room);
         this.emit('room-added', room);
 
         if (this.roomCount == 1)
-            this.setActiveRoom(room);
+            this._setActiveRoom(room);
     },
 
     _removeRoom: function(room) {
@@ -462,8 +460,6 @@ const _ChatroomManager = new Lang.Class({
         if (room == this._lastActiveRoom)
             this._lastActiveRoom = null;
 
-        room.disconnect(room._channelChangedId);
-        delete room._channelChangedId;
         this.emit('room-removed', room);
     },
 
@@ -478,20 +474,16 @@ const _ChatroomManager = new Lang.Class({
         }
     },
 
-    setActiveRoom: function(room) {
-        if (room == this._activeRoom)
-            return;
+    _onActiveRoomChanged: function(window) {
+        let room = window.active_room;
 
         if (room && room.type == Tp.HandleType.ROOM)
             this._lastActiveRoom = room;
-
         this._activeRoom = room;
-        this.emit('active-changed', room);
-        this.emit('active-state-changed');
     },
 
-    getActiveRoom: function() {
-        return this._activeRoom;
+    _setActiveRoom: function(room) {
+        this._app.active_window.active_room = room;
     },
 
     getRoomByName: function(name) {
diff --git a/src/joinDialog.js b/src/joinDialog.js
index 9194786..9933841 100644
--- a/src/joinDialog.js
+++ b/src/joinDialog.js
@@ -232,7 +232,8 @@ const JoinDialog = new Lang.Class({
             this._connectionCombo.append(names[i], names[i]);
         this._connectionCombo.sensitive = names.length > 1;
 
-        let activeRoom = this._roomManager.getActiveRoom();
+        let activeRoom = this.transient_for ? this.transient_for.active_room
+                                            : null;
         let activeIndex = 0;
         if(activeRoom)
             activeIndex = Math.max(names.indexOf(activeRoom.account.display_name), 0);
diff --git a/src/mainWindow.js b/src/mainWindow.js
index abc243e..07cb620 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -3,11 +3,11 @@ const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
 const GObject = imports.gi.GObject;
 const Gtk = imports.gi.Gtk;
+const Polari = imports.gi.Polari;
 const Tp = imports.gi.TelepathyGLib;
 
 const AccountsMonitor = imports.accountsMonitor;
 const AppNotifications = imports.appNotifications;
-const ChatroomManager = imports.chatroomManager;
 const JoinDialog = imports.joinDialog;
 const Lang = imports.lang;
 const Mainloop = imports.mainloop;
@@ -109,8 +109,14 @@ const MainWindow = new Lang.Class({
                                                       'subtitle-visible',
                                                       'subtitle-visible',
                                                       GObject.ParamFlags.READABLE,
-                                                      false)
+                                                      false),
+        'active-room': GObject.ParamSpec.object('active-room',
+                                                'active-room',
+                                                'active-room',
+                                                GObject.ParamFlags.READWRITE,
+                                                Polari.Room.$gtype)
     },
+    Signals: { 'active-room-state-changed': {} },
 
     _init: function(params) {
         this._subtitle = '';
@@ -163,12 +169,6 @@ const MainWindow = new Lang.Class({
                                       Lang.bind(this, this._onAccountsChanged));
         this._onAccountsChanged(this._accountsMonitor);
 
-        this._roomManager = ChatroomManager.getDefault();
-        this._roomManager.connect('active-changed',
-                                  Lang.bind(this, this._activeRoomChanged));
-        this._roomManager.connect('active-state-changed',
-                                  Lang.bind(this, this._updateUserListLabel));
-
         this._updateUserListLabel();
 
         let actionEntries = [
@@ -276,19 +276,32 @@ const MainWindow = new Lang.Class({
         this._titlebarRight.set_decoration_layout(layoutRight);
     },
 
-    _activeRoomChanged: function(manager, room) {
+    get active_room() {
+        return this._room;
+    },
+
+    set active_room(room) {
+        if (room == this._room)
+            return;
+
         if (this._room) {
             this._room.disconnect(this._displayNameChangedId);
             this._room.disconnect(this._topicChangedId);
             this._room.disconnect(this._membersChangedId);
+            this._room.disconnect(this._channelChangedId);
         }
         this._displayNameChangedId = 0;
         this._topicChangedId = 0;
         this._membersChangedId = 0;
+        this._channelChangedId = 0;
 
         this._room = room;
 
         this._updateTitlebar();
+        this._updateUserListLabel();
+
+        this.notify('active-room');
+        this.emit('active-room-state-changed');
 
         if (!this._room)
             return; // finished
@@ -302,6 +315,11 @@ const MainWindow = new Lang.Class({
         this._membersChangedId =
             this._room.connect('members-changed',
                                Lang.bind(this, this._updateUserListLabel));
+        this._channelChangedId =
+            this._room.connect('notify::channel', () => {
+                this._updateUserListLabel();
+                this.emit('active-room-state-changed');
+            });
     },
 
     _addApplicationStyle: function() {
@@ -333,10 +351,10 @@ const MainWindow = new Lang.Class({
     },
 
     _leaveRoomCreateHook: function(action) {
-        this._roomManager.connect('active-changed', () => {
-            action.enabled = this._roomManager.getActiveRoom() != null;
+        this.connect('notify::active-room', () => {
+            action.enabled = this._room != null;
         });
-        action.enabled = this._roomManager.getActiveRoom() != null;
+        action.enabled = this._room != null;
     },
 
     _onToggleAction: function(action) {
@@ -352,7 +370,7 @@ const MainWindow = new Lang.Class({
     },
 
     _userListCreateHook: function(action) {
-        this._roomManager.connect('active-state-changed', () => {
+        this.connect('active-room-state-changed', () => {
             this._updateUserListAction(action);
         });
         action.connect('notify::enabled', () => {
diff --git a/src/roomList.js b/src/roomList.js
index 03a25d7..d621904 100644
--- a/src/roomList.js
+++ b/src/roomList.js
@@ -364,8 +364,6 @@ const RoomList = new Lang.Class({
                                   Lang.bind(this, this._roomAdded));
         this._roomManager.connect('room-removed',
                                   Lang.bind(this, this._roomRemoved));
-        this._roomManager.connect('active-changed',
-                                  Lang.bind(this, this._activeRoomChanged));
 
         let action = Gio.Application.get_default().lookup_action('leave-room');
         action.connect('activate', Lang.bind(this, this._onLeaveActivated));
@@ -375,6 +373,10 @@ const RoomList = new Lang.Class({
         this.parent();
 
         let toplevel = this.get_toplevel();
+        toplevel.connect('notify::active-room',
+                         Lang.bind(this, this._activeRoomChanged));
+        this._activeRoomChanged();
+
         let actions = [
             { name: 'next-room',
               handler: () => { this._moveSelection(Gtk.DirectionType.DOWN); } },
@@ -464,8 +466,8 @@ const RoomList = new Lang.Class({
         if (this._roomManager.roomCount == 0)
             return;
 
-        let activeRoom = this._roomManager.getActiveRoom();
-        let current = this._roomRows[activeRoom.id];
+        let toplevel = this.get_toplevel();
+        let current = this._roomRows[toplevel.active_room.id];
 
         if (current != row)
             return;
@@ -481,7 +483,7 @@ const RoomList = new Lang.Class({
         let newSelected = this.get_selected_row();
         if (newSelected != row)
             newActive = newSelected.room;
-        this._roomManager.setActiveRoom(newActive);
+        toplevel.active_room = newActive;
 
         if (selected != row)
             this.select_row(selected);
@@ -553,7 +555,8 @@ const RoomList = new Lang.Class({
         this._placeholders[account].visible = !hasRooms;
     },
 
-    _activeRoomChanged: function(roomManager, room) {
+    _activeRoomChanged: function() {
+        let room = this.get_toplevel().active_room;
         if (!room)
             return;
         let row = this._roomRows[room.id];
@@ -566,7 +569,7 @@ const RoomList = new Lang.Class({
     },
 
     vfunc_row_selected: function(row) {
-        this._roomManager.setActiveRoom(row ? row.room : null);
+        this.get_toplevel().active_room = row ? row.room : null;
         if (row)
             row.selected();
     },
diff --git a/src/roomStack.js b/src/roomStack.js
index 80d161d..a718016 100644
--- a/src/roomStack.js
+++ b/src/roomStack.js
@@ -32,10 +32,6 @@ const RoomStack = new Lang.Class({
                                   Lang.bind(this, this._roomAdded));
         this._roomManager.connect('room-removed',
                                   Lang.bind(this, this._roomRemoved));
-        this._roomManager.connect('active-changed',
-                                  Lang.bind(this, this._activeRoomChanged));
-        this._roomManager.connect('active-state-changed',
-                                  Lang.bind(this, this._updateSensitivity));
 
         this.add_named(new ChatPlaceholder(this._sizeGroup), 'placeholder');
 
@@ -47,6 +43,17 @@ const RoomStack = new Lang.Class({
             }));
     },
 
+    vfunc_realize: function() {
+        this.parent();
+
+        let toplevel = this.get_toplevel();
+
+        toplevel.connect('notify::active-room',
+                         Lang.bind(this, this._activeRoomChanged));
+        toplevel.connect('active-room-state-changed',
+                         Lang.bind(this, this._updateSensitivity));
+    },
+
     get entry_area_height() {
         return this._entryAreaHeight;
     },
@@ -65,12 +72,13 @@ const RoomStack = new Lang.Class({
         delete this._rooms[room.id];
     },
 
-    _activeRoomChanged: function(manager, room) {
+    _activeRoomChanged: function() {
+        let room = this.get_toplevel().active_room;
         this.set_visible_child_name(room ? room.id : 'placeholder');
     },
 
     _updateSensitivity: function() {
-        let room = this._roomManager.getActiveRoom();
+        let room = this.get_toplevel().active_room;
         if (!room)
             return;
         let sensitive = room && room.channel;
diff --git a/src/userList.js b/src/userList.js
index 6009c1d..4850fdb 100644
--- a/src/userList.js
+++ b/src/userList.js
@@ -6,7 +6,6 @@ const Gtk = imports.gi.Gtk;
 const Pango = imports.gi.Pango;
 const Tp = imports.gi.TelepathyGLib;
 
-const ChatroomManager = imports.chatroomManager;
 const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
@@ -34,10 +33,14 @@ const UserListPopover = new Lang.Class({
         this._revealer.connect('notify::child-revealed', Lang.bind(this, function() {
             this._revealer.transition_duration = 250;
         }));
+    },
+
+    vfunc_realize: function() {
+        this.parent();
 
-        this._roomManager = new ChatroomManager.getDefault();
-        this._roomManager.connect('active-changed',
-                                  Lang.bind(this, this._activeRoomChanged));
+        let toplevel = this.get_toplevel();
+        toplevel.connect('notify::active-room',
+                         Lang.bind(this, this._activeRoomChanged));
     },
 
     _createWidget: function() {
@@ -59,7 +62,7 @@ const UserListPopover = new Lang.Class({
         this._box.show_all();
     },
 
-    _activeRoomChanged: function(manager, room) {
+    _activeRoomChanged: function() {
         this._entry.text = '';
 
         if (this._userList)
@@ -71,7 +74,7 @@ const UserListPopover = new Lang.Class({
         if (this._userList)
             return;
 
-        let room = this._roomManager.getActiveRoom();
+        let room = this.get_toplevel().active_room;
         if (!room || room.type != Tp.HandleType.ROOM)
             return;
 


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