[polari/wip/fmuellner/window-experiments: 349/356] app: Split actions between app and window



commit f395edb96c6ece2b7a8f654852ebefcb98ca086a
Author: Florian Müllner <fmuellner gnome org>
Date:   Thu Jul 14 16:04:43 2016 +0200

    app: Split actions between app and window
    
    Currently all our actions are added to the application, though
    conceptually some of them are clearly associated with a particular
    window. In a single-window application, this doesn't really matter,
    and the approach has some advantages, as all actions are already
    available when the UI is constructed. However in order to allow
    multiple windows, we won't get away with this any longer, so add
    window-specific actions to the window.

 data/resources/main-window.ui |    4 +-
 src/application.js            |   75 +---------------------------------
 src/mainWindow.js             |   89 +++++++++++++++++++++++++++++++++++------
 src/roomList.js               |   11 ++++-
 4 files changed, 89 insertions(+), 90 deletions(-)
---
diff --git a/data/resources/main-window.ui b/data/resources/main-window.ui
index 84c8f1d..d586beb 100644
--- a/data/resources/main-window.ui
+++ b/data/resources/main-window.ui
@@ -51,7 +51,7 @@
                 <property name="visible">True</property>
                 <property name="halign">end</property>
                 <property name="valign">center</property>
-                <property name="action_name">app.show-join-dialog</property>
+                <property name="action_name">win.show-join-dialog</property>
                 <style>
                   <class name="image-button"/>
                 </style>
@@ -166,7 +166,7 @@
               <object class="GtkToggleButton" id="showUserListButton">
                 <property name="visible">True</property>
                 <property name="focus-on-click">False</property>
-                <property name="action-name">app.user-list</property>
+                <property name="action-name">win.user-list</property>
                 <style>
                   <class name="polari-user-list-button"/>
                   <class name="text-button"/>
diff --git a/src/application.js b/src/application.js
index 37a67f0..1ec386a 100644
--- a/src/application.js
+++ b/src/application.js
@@ -130,9 +130,6 @@ const Application = new Lang.Class({
         this.parent();
 
         let actionEntries = [
-          { name: 'show-join-dialog',
-            activate: Lang.bind(this, this._onShowJoinDialog),
-            accels: ['<Primary>n'] },
           { name: 'join-room',
             activate: Lang.bind(this, this._onJoinRoom),
             parameter_type: GLib.VariantType.new('(ssu)') },
@@ -141,10 +138,6 @@ const Application = new Lang.Class({
             parameter_type: GLib.VariantType.new('(sssu)') },
           { name: 'leave-room',
             parameter_type: GLib.VariantType.new('(ss)') },
-          { name: 'leave-current-room',
-            activate: Lang.bind(this, this._onLeaveCurrentRoom),
-            create_hook: (a) => { a.enabled = false; },
-            accels: ['<Primary>w'] },
           { name: 'authenticate-account',
             parameter_type: GLib.VariantType.new('(os)') },
           { name: 'connect-account',
@@ -153,11 +146,6 @@ const Application = new Lang.Class({
           { name: 'reconnect-account',
             activate: Lang.bind(this, this._onConnectAccount),
             parameter_type: GLib.VariantType.new('o') },
-          { name: 'user-list',
-            activate: Lang.bind(this, this._onToggleAction),
-            create_hook: Lang.bind(this, this._userListCreateHook),
-            state: GLib.Variant.new('b', false),
-            accels: ['F9', '<Primary>u'] },
           { name: 'remove-connection',
             activate: Lang.bind(this, this._onRemoveConnection),
             parameter_type: GLib.VariantType.new('o') },
@@ -177,21 +165,7 @@ const Application = new Lang.Class({
             activate: Lang.bind(this, this._onShowAbout) },
           { name: 'quit',
             activate: Lang.bind(this, this._onQuit),
-            accels: ['<Primary>q'] },
-          { name: 'next-room',
-            accels: ['<Primary>Page_Down', '<Alt>Down'] },
-          { name: 'previous-room',
-            accels: ['<Primary>Page_Up', '<Alt>Up'] },
-          { name: 'first-room',
-            accels: ['<Primary>Home'] },
-          { name: 'last-room',
-            accels: ['<Primary>End'] },
-          { name: 'nth-room',
-            parameter_type: GLib.VariantType.new('i') },
-          { name: 'next-pending-room',
-            accels: ['<Alt><Shift>Down', '<Primary><Shift>Page_Down']},
-          { name: 'previous-pending-room',
-            accels: ['<Alt><Shift>Up', '<Primary><Shift>Page_Up']}
+            accels: ['<Primary>q'] }
         ];
         Utils.addActionEntries(this, 'app', actionEntries);
 
@@ -204,7 +178,7 @@ const Application = new Lang.Class({
         this._onRunInBackgroundChanged();
 
         for (let i = 1; i < 10; i++)
-            this.set_accels_for_action('app.nth-room(%d)'.format(i), ['<Alt>' + i]);
+            this.set_accels_for_action('win.nth-room(%d)'.format(i), ['<Alt>' + i]);
 
         this._telepathyClient = null;
 
@@ -246,20 +220,6 @@ const Application = new Lang.Class({
         this.active_window.present();
     },
 
-    vfunc_window_added: function(window) {
-        this.parent(window);
-
-        let action = this.lookup_action('leave-current-room');
-        window.connect('notify::active-room', () => {
-            action.enabled = window.active_room != null;
-        });
-        action.enabled = window.active_room != null;
-
-        window.connect('active-room-state-changed',
-                       Lang.bind(this, this._updateUserListAction));
-        this._updateUserListAction();
-    },
-
     vfunc_window_removed: function(window) {
         this.parent(window);
 
@@ -367,24 +327,6 @@ const Application = new Lang.Class({
             }));
     },
 
-    _updateUserListAction: function() {
-        let room = this.active_window.active_room;
-        let action = this.lookup_action('user-list');
-        action.enabled = room && room.type == Tp.HandleType.ROOM && room.channel;
-    },
-
-    _userListCreateHook: function(action) {
-        action.connect('notify::enabled', function() {
-            if (!action.enabled)
-                action.change_state(GLib.Variant.new('b', false));
-        });
-        action.enabled = false;
-    },
-
-    _onShowJoinDialog: function() {
-        this.active_window.showJoinRoomDialog();
-    },
-
     _maybePresent: function(time) {
         let [present, ] = Tp.user_action_time_should_present(time);
 
@@ -504,14 +446,6 @@ const Application = new Lang.Class({
         this._restoreAccountName(account);
     },
 
-    _onLeaveCurrentRoom: function() {
-        let room = this.active_window.active_room;
-        if (!room)
-            return;
-        let action = this.lookup_action('leave-room');
-        action.activate(GLib.Variant.new('(ss)', [room.id, '']));
-    },
-
     _onConnectAccount: function(action, parameter) {
         let accountPath = parameter.deep_unpack();
         let account = this._accountsMonitor.lookupAccount(accountPath);
@@ -520,11 +454,6 @@ const Application = new Lang.Class({
         this._retryData.delete(accountPath);
     },
 
-    _onToggleAction: function(action) {
-        let state = action.get_state();
-        action.change_state(GLib.Variant.new('b', !state.get_boolean()));
-    },
-
     _onRemoveConnection: function(action, parameter){
         let accountPath = parameter.deep_unpack();
         let account = this._accountsMonitor.lookupAccount(accountPath);
diff --git a/src/mainWindow.js b/src/mainWindow.js
index ac54726..fd56d16 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -178,18 +178,44 @@ const MainWindow = new Lang.Class({
 
         this._updateUserListLabel();
 
-        let app = this.application;
-        this._userListAction = app.lookup_action('user-list');
-
-        app.connect('action-state-changed::user-list', Lang.bind(this,
-            function(group, actionName, value) {
-                this._userListPopover.visible = value.get_boolean();
-            }));
-        this._userListPopover.connect('notify::visible', Lang.bind(this,
-            function() {
-                if (!this._userListPopover.visible)
-                    this._userListAction.change_state(GLib.Variant.new('b', false));
-            }));
+        let actionEntries = [
+          { name: 'show-join-dialog',
+            activate: Lang.bind(this, this._onShowJoinDialog),
+            accels: ['<Primary>n'] },
+          { name: 'leave-current-room',
+            activate: Lang.bind(this, this._onLeaveCurrentRoom),
+            create_hook: Lang.bind(this, this._leaveRoomCreateHook),
+            accels: ['<Primary>w'] },
+          { name: 'user-list',
+            activate: Lang.bind(this, this._onToggleAction),
+            create_hook: Lang.bind(this, this._userListCreateHook),
+            state: GLib.Variant.new('b', false),
+            accels: ['F9', '<Primary>u'] },
+          { name: 'next-room',
+            accels: ['<Primary>Page_Down', '<Alt>Down'] },
+          { name: 'previous-room',
+            accels: ['<Primary>Page_Up', '<Alt>Up'] },
+          { name: 'first-room',
+            accels: ['<Primary>Home'] },
+          { name: 'last-room',
+            accels: ['<Primary>End'] },
+          { name: 'nth-room',
+            parameter_type: GLib.VariantType.new('i') },
+          { name: 'next-pending-room',
+            accels: ['<Alt><Shift>Down', '<Primary><Shift>Page_Down']},
+          { name: 'previous-pending-room',
+            accels: ['<Alt><Shift>Up', '<Primary><Shift>Page_Up']}
+        ];
+        Utils.addActionEntries(this, 'win', actionEntries);
+
+        let action = this.lookup_action('user-list');
+        this.connect('action-state-changed::user-list', (w, name, value) => {
+            this._userListPopover.visible = value.get_boolean();
+        });
+        this._userListPopover.connect('notify::visible', () => {
+            if (!this._userListPopover.visible)
+                action.change_state(GLib.Variant.new('b', false));
+        });
 
         this._gtkSettings.connect('notify::gtk-decoration-layout',
                                   Lang.bind(this, this._updateDecorations));
@@ -375,11 +401,48 @@ const MainWindow = new Lang.Class({
             this._lastActiveRoom = null;
     },
 
-    showJoinRoomDialog: function() {
+    _onShowJoinDialog: function() {
         let dialog = new JoinDialog.JoinDialog({ transient_for: this });
         dialog.show();
     },
 
+    _onLeaveCurrentRoom: function() {
+        if (!this._room)
+            return;
+        let action = this.application.lookup_action('leave-room');
+        action.activate(GLib.Variant.new('(ss)', [this._room.id, '']));
+    },
+
+    _leaveRoomCreateHook: function(action) {
+        this.connect('notify::active-room', () => {
+            action.enabled = this._room != null;
+        });
+        action.enabled = this._room != null;
+    },
+
+    _onToggleAction: function(action) {
+        let state = action.get_state();
+        action.change_state(GLib.Variant.new('b', !state.get_boolean()));
+    },
+
+
+    _updateUserListAction: function(action) {
+        action.enabled = this._room &&
+                         this._room.type == Tp.HandleType.ROOM &&
+                         this._room.channel;
+    },
+
+    _userListCreateHook: function(action) {
+        this.connect('active-room-state-changed', () => {
+            this._updateUserListAction(action);
+        });
+        action.connect('notify::enabled', () => {
+            if (!action.enabled)
+                action.change_state(GLib.Variant.new('b', false));
+        });
+        this._updateUserListAction(action);
+    },
+
     _updateUserListLabel: function() {
         let numMembers = 0;
 
diff --git a/src/roomList.js b/src/roomList.js
index f839c21..eeae5c3 100644
--- a/src/roomList.js
+++ b/src/roomList.js
@@ -384,7 +384,14 @@ const RoomList = new Lang.Class({
                                   Lang.bind(this, this._roomRemoved));
         this._roomManager.rooms.forEach(r => { this._roomAdded(this._roomManager, r); });
 
-        let app = Gio.Application.get_default();
+        let action = Gio.Application.get_default().lookup_action('leave-room');
+        action.connect('activate', Lang.bind(this, this._onLeaveActivated));
+    },
+
+    vfunc_realize: function() {
+        this.parent();
+
+        let toplevel = this.get_toplevel();
         let actions = [
             { name: 'next-room',
               handler: () => { this._moveSelection(Gtk.DirectionType.DOWN); } },
@@ -409,7 +416,7 @@ const RoomList = new Lang.Class({
                                                        row => row.hasPending); } }
         ];
         actions.forEach(a => {
-            app.lookup_action(a.name).connect('activate', a.handler);
+            toplevel.lookup_action(a.name).connect('activate', a.handler);
         });
     },
 


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