[gnome-shell] Rearchitect the Shell to have a components system
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] Rearchitect the Shell to have a components system
- Date: Tue, 4 Sep 2012 21:43:13 +0000 (UTC)
commit 2a800e4ce0912f098b4a469fc7a680ad094b3bfa
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Sun Sep 2 22:23:50 2012 -0300
Rearchitect the Shell to have a components system
Components are pieces of the shell code that can be added/removed
at runtime, like extension, but are tied more directly to a session
mode. The session polkit agent, the network agent, autorun/automount,
are all components, keyring, recorder and telepathy client are all
now copmonents.
https://bugzilla.gnome.org/show_bug.cgi?id=683156
js/Makefile.am | 20 +++--
js/ui/components/__init__.js | 61 ++++++++++++++
js/ui/{ => components}/automountManager.js | 66 +++++----------
js/ui/{ => components}/autorunManager.js | 60 ++++++++------
js/ui/{keyringPrompt.js => components/keyring.js} | 40 ++++++---
js/ui/{ => components}/networkAgent.js | 30 ++-----
.../polkitAgent.js} | 38 +++------
js/ui/components/recorder.js | 58 +++++++++++++
js/ui/{ => components}/telepathyClient.js | 34 +++++---
js/ui/main.js | 74 +----------------
js/ui/sessionMode.js | 15 +--
src/shell-polkit-authentication-agent.c | 87 ++++++++++----------
src/shell-polkit-authentication-agent.h | 3 +
13 files changed, 314 insertions(+), 272 deletions(-)
---
diff --git a/js/Makefile.am b/js/Makefile.am
index 3300981..351ced1 100644
--- a/js/Makefile.am
+++ b/js/Makefile.am
@@ -1,3 +1,4 @@
+NULL =
EXTRA_DIST = misc/config.js.in
CLEANFILES = misc/config.js
@@ -37,8 +38,6 @@ nobase_dist_js_DATA = \
ui/altTab.js \
ui/appDisplay.js \
ui/appFavorites.js \
- ui/automountManager.js \
- ui/autorunManager.js \
ui/boxpointer.js \
ui/calendar.js \
ui/checkBox.js \
@@ -47,15 +46,14 @@ nobase_dist_js_DATA = \
ui/dateMenu.js \
ui/dnd.js \
ui/endSessionDialog.js \
- ui/environment.js \
ui/extensionSystem.js \
ui/extensionDownloader.js \
+ ui/environment.js \
ui/flashspot.js \
ui/ibusCandidatePopup.js\
ui/grabHelper.js \
ui/iconGrid.js \
ui/keyboard.js \
- ui/keyringPrompt.js \
ui/layout.js \
ui/lightbox.js \
ui/lookingGlass.js \
@@ -64,7 +62,6 @@ nobase_dist_js_DATA = \
ui/main.js \
ui/messageTray.js \
ui/modalDialog.js \
- ui/networkAgent.js \
ui/sessionMode.js \
ui/shellEntry.js \
ui/shellMountOperation.js \
@@ -74,7 +71,6 @@ nobase_dist_js_DATA = \
ui/panelMenu.js \
ui/placeDisplay.js \
ui/pointerWatcher.js \
- ui/polkitAuthenticationAgent.js \
ui/popupMenu.js \
ui/remoteSearch.js \
ui/runDialog.js \
@@ -90,7 +86,6 @@ nobase_dist_js_DATA = \
ui/status/power.js \
ui/status/volume.js \
ui/status/bluetooth.js \
- ui/telepathyClient.js \
ui/tweener.js \
ui/unlockDialog.js \
ui/userMenu.js \
@@ -102,4 +97,13 @@ nobase_dist_js_DATA = \
ui/workspaceThumbnail.js \
ui/workspacesView.js \
ui/workspaceSwitcherPopup.js \
- ui/xdndHandler.js
+ ui/xdndHandler.js \
+ ui/components/__init__.js \
+ ui/components/autorunManager.js \
+ ui/components/automountManager.js \
+ ui/components/networkAgent.js \
+ ui/components/polkitAgent.js \
+ ui/components/recorder.js \
+ ui/components/telepathyClient.js \
+ ui/components/keyring.js \
+ $(NULL)
diff --git a/js/ui/components/__init__.js b/js/ui/components/__init__.js
new file mode 100644
index 0000000..763c87d
--- /dev/null
+++ b/js/ui/components/__init__.js
@@ -0,0 +1,61 @@
+
+const Lang = imports.lang;
+const Main = imports.ui.main;
+
+const ComponentManager = new Lang.Class({
+ Name: 'ComponentManager',
+
+ _init: function() {
+ this._allComponents = {};
+ this._enabledComponents = [];
+
+ Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
+ this._sessionUpdated();
+ },
+
+ _sessionUpdated: function() {
+ let newEnabledComponents = Main.sessionMode.components;
+
+ newEnabledComponents.filter(Lang.bind(this, function(name) {
+ return this._enabledComponents.indexOf(name) == -1;
+ })).forEach(Lang.bind(this, function(name) {
+ this._enableComponent(name);
+ }));
+
+ this._enabledComponents.filter(Lang.bind(this, function(name) {
+ return newEnabledComponents.indexOf(name) == -1;
+ })).forEach(Lang.bind(this, function(name) {
+ this._disableComponent(name);
+ }));
+
+ this._enabledComponents = newEnabledComponents;
+ },
+
+ _importComponent: function(name) {
+ let module = imports.ui.components[name];
+ return module.Component;
+ },
+
+ _ensureComponent: function(name) {
+ let component = this._allComponents[name];
+ if (component)
+ return component;
+
+ let constructor = this._importComponent(name);
+ component = new constructor();
+ this._allComponents[name] = component;
+ return component;
+ },
+
+ _enableComponent: function(name) {
+ let component = this._ensureComponent(name);
+ component.enable();
+ },
+
+ _disableComponent: function(name) {
+ let component = this._allComponents[name];
+ if (component == null)
+ return;
+ component.disable();
+ }
+});
diff --git a/js/ui/automountManager.js b/js/ui/components/automountManager.js
similarity index 82%
rename from js/ui/automountManager.js
rename to js/ui/components/automountManager.js
index a49eb17..9081e80 100644
--- a/js/ui/automountManager.js
+++ b/js/ui/components/automountManager.js
@@ -34,28 +34,30 @@ const AutomountManager = new Lang.Class({
this._inhibited = false;
this._loginManager = LoginManager.getLoginManager();
+ this._volumeMonitor = Gio.VolumeMonitor.get();
+ },
- Main.screenShield.connect('lock-status-changed', Lang.bind(this, this._lockStatusChanged));
+ enable: function() {
+ this._volumeAddedId = this._volumeMonitor.connect('volume-added', Lang.bind(this, this._onVolumeAdded));
+ this._volumeRemovedId = this._volumeMonitor.connect('volume-removed', Lang.bind(this, this._onVolumeRemoved));
+ this._driveConnectedId = this._volumeMonitor.connect('drive-connected', Lang.bind(this, this._onDriveConnected));
+ this._driveDisconnectedId = this._volumeMonitor.connect('drive-disconnected', Lang.bind(this, this._onDriveDisconnected));
+ this._driveEjectButtonId = this._volumeMonitor.connect('drive-eject-button', Lang.bind(this, this._onDriveEjectButton));
- this._volumeMonitor = Gio.VolumeMonitor.get();
+ this._mountAllId = Mainloop.idle_add(Lang.bind(this, this._startupMountAll));
+ },
+
+ disable: function() {
+ this._volumeMonitor.disconnect(this._volumeAddedId);
+ this._volumeMonitor.disconnect(this._volumeRemovedId);
+ this._volumeMonitor.disconnect(this._driveConnectedId);
+ this._volumeMonitor.disconnect(this._driveDisconnectedId);
+ this._volumeMonitor.disconnect(this._driveEjectButtonId);
- this._volumeMonitor.connect('volume-added',
- Lang.bind(this,
- this._onVolumeAdded));
- this._volumeMonitor.connect('volume-removed',
- Lang.bind(this,
- this._onVolumeRemoved));
- this._volumeMonitor.connect('drive-connected',
- Lang.bind(this,
- this._onDriveConnected));
- this._volumeMonitor.connect('drive-disconnected',
- Lang.bind(this,
- this._onDriveDisconnected));
- this._volumeMonitor.connect('drive-eject-button',
- Lang.bind(this,
- this._onDriveEjectButton));
-
- Mainloop.idle_add(Lang.bind(this, this._startupMountAll));
+ if (this._mountAllId > 0) {
+ Mainloop.source_remove(this._mountAllId);
+ this._mountAllId = 0;
+ }
},
_InhibitorsChanged: function(object, senderName, [inhibtor]) {
@@ -68,17 +70,6 @@ const AutomountManager = new Lang.Class({
}));
},
- _lockStatusChanged: function(shield, locked) {
- if (!locked) {
- this._volumeQueue.forEach(Lang.bind(this, function(volume) {
- this._checkAndMountVolume(volume);
- }));
- }
-
- // clear the queue anyway
- this._volumeQueue = [];
- },
-
_startupMountAll: function() {
let volumes = this._volumeMonitor.get_volumes();
volumes.forEach(Lang.bind(this, function(volume) {
@@ -87,6 +78,7 @@ const AutomountManager = new Lang.Class({
allowAutorun: false });
}));
+ this._mountAllId = 0;
return false;
},
@@ -96,9 +88,6 @@ const AutomountManager = new Lang.Class({
if (!this._loginManager.sessionActive)
return;
- if (Main.screenShield.locked)
- return;
-
global.play_theme_sound(0, 'device-added-media');
},
@@ -108,9 +97,6 @@ const AutomountManager = new Lang.Class({
if (!this._loginManager.sessionActive)
return;
- if (Main.screenShield.locked)
- return;
-
global.play_theme_sound(0, 'device-removed-media');
},
@@ -159,13 +145,6 @@ const AutomountManager = new Lang.Class({
// don't attempt automount
if (!this._loginManager.sessionActive)
return;
-
- if (Main.screenShield.locked) {
- if (this._volumeQueue.indexOf(volume) == -1)
- this._volumeQueue.push(volume);
-
- return;
- }
}
if (this._inhibited)
@@ -259,3 +238,4 @@ const AutomountManager = new Lang.Class({
});
}
});
+const Component = AutomountManager;
diff --git a/js/ui/autorunManager.js b/js/ui/components/autorunManager.js
similarity index 93%
rename from js/ui/autorunManager.js
rename to js/ui/components/autorunManager.js
index 2776fbb..3434e9b 100644
--- a/js/ui/autorunManager.js
+++ b/js/ui/components/autorunManager.js
@@ -147,18 +147,25 @@ const AutorunManager = new Lang.Class({
this._volumeMonitor = Gio.VolumeMonitor.get();
- this._volumeMonitor.connect('mount-added',
- Lang.bind(this,
- this._onMountAdded));
- this._volumeMonitor.connect('mount-removed',
- Lang.bind(this,
- this._onMountRemoved));
+ this._transDispatcher = new AutorunTransientDispatcher(this);
+ },
- this._transDispatcher = new AutorunTransientDispatcher();
- this._createResidentSource();
+ enable: function() {
+ this._residentSource = new AutorunResidentSource(this);
+ this._scanMounts();
- let mounts = this._volumeMonitor.get_mounts();
+ this._mountAddedId = this._volumeMonitor.connect('mount-added', Lang.bind(this, this._onMountAdded));
+ this._mountRemovedId = this._volumeMonitor.connect('mount-removed', Lang.bind(this, this._onMountRemoved));
+ },
+
+ disable: function() {
+ this._residentSource.destroy();
+ this._volumeMonitor.disconnect(this._mountAddedId);
+ this._volumeMonitor.disconnect(this._mountRemovedId);
+ },
+ _scanMounts: function() {
+ let mounts = this._volumeMonitor.get_mounts();
mounts.forEach(Lang.bind(this, function (mount) {
let discoverer = new ContentTypeDiscoverer(Lang.bind (this,
function (mount, apps) {
@@ -169,13 +176,6 @@ const AutorunManager = new Lang.Class({
}));
},
- _createResidentSource: function() {
- this._residentSource = new AutorunResidentSource();
- this._residentSource.connect('destroy',
- Lang.bind(this,
- this._createResidentSource));
- },
-
_onMountAdded: function(monitor, mount) {
// don't do anything if our session is not the currently
// active one
@@ -260,13 +260,14 @@ const AutorunResidentSource = new Lang.Class({
Name: 'AutorunResidentSource',
Extends: MessageTray.Source,
- _init: function() {
+ _init: function(manager) {
this.parent(_("Removable Devices"), 'media-removable');
this.showInLockScreen = false;
this._mounts = [];
- this._notification = new AutorunResidentNotification(this);
+ this._notification = new AutorunResidentNotification(this._manager, this);
+ this._manager = manager;
},
addMount: function(mount, apps) {
@@ -316,7 +317,7 @@ const AutorunResidentNotification = new Lang.Class({
Name: 'AutorunResidentNotification',
Extends: MessageTray.Notification,
- _init: function(source) {
+ _init: function(manager, source) {
this.parent(source, source.title, null, { customContent: true });
// set the notification as resident
@@ -324,6 +325,7 @@ const AutorunResidentNotification = new Lang.Class({
this._layout = new St.BoxLayout ({ style_class: 'hotplug-resident-box',
vertical: true });
+ this._manager = manager;
this.addActor(this._layout,
{ x_expand: true,
@@ -382,11 +384,11 @@ const AutorunResidentNotification = new Lang.Class({
// now connect signals
mountButton.connect('clicked', Lang.bind(this, function(actor, event) {
- startAppForMount(apps[0], mount);
+ this._manager.startAppForMount(apps[0], mount);
}));
ejectButton.connect('clicked', Lang.bind(this, function() {
- Main.autorunManager.ejectMount(mount);
+ this._manager.ejectMount(mount);
}));
return item;
@@ -396,7 +398,8 @@ const AutorunResidentNotification = new Lang.Class({
const AutorunTransientDispatcher = new Lang.Class({
Name: 'AutorunTransientDispatcher',
- _init: function() {
+ _init: function(manager) {
+ this._manager = manager;
this._sources = [];
this._settings = new Gio.Settings({ schema: SETTINGS_SCHEMA });
},
@@ -439,7 +442,7 @@ const AutorunTransientDispatcher = new Lang.Class({
return;
// add a new source
- this._sources.push(new AutorunTransientSource(mount, apps));
+ this._sources.push(new AutorunTransientSource(this._manager, mount, apps));
},
addMount: function(mount, apps, contentTypes) {
@@ -492,13 +495,14 @@ const AutorunTransientSource = new Lang.Class({
Name: 'AutorunTransientSource',
Extends: MessageTray.Source,
- _init: function(mount, apps) {
+ _init: function(manager, mount, apps) {
+ this._manager = manager;
this.mount = mount;
this.apps = apps;
this.parent(mount.get_name());
- this._notification = new AutorunTransientNotification(this);
+ this._notification = new AutorunTransientNotification(this._manager, this);
// add ourselves as a source, and popup the notification
Main.messageTray.add(this);
@@ -515,9 +519,10 @@ const AutorunTransientNotification = new Lang.Class({
Name: 'AutorunTransientNotification',
Extends: MessageTray.Notification,
- _init: function(source) {
+ _init: function(manager, source) {
this.parent(source, source.title, null, { customContent: true });
+ this._manager = manager;
this._box = new St.BoxLayout({ style_class: 'hotplug-transient-box',
vertical: true });
this.addActor(this._box);
@@ -586,10 +591,11 @@ const AutorunTransientNotification = new Lang.Class({
style_class: 'hotplug-notification-item' });
button.connect('clicked', Lang.bind(this, function() {
- Main.autorunManager.ejectMount(this._mount);
+ this._manager.ejectMount(this._mount);
}));
return button;
}
});
+const Component = AutorunManager;
diff --git a/js/ui/keyringPrompt.js b/js/ui/components/keyring.js
similarity index 91%
rename from js/ui/keyringPrompt.js
rename to js/ui/components/keyring.js
index 814c946..dfa7cc0 100644
--- a/js/ui/keyringPrompt.js
+++ b/js/ui/components/keyring.js
@@ -192,23 +192,35 @@ const KeyringDialog = new Lang.Class({
},
_onContinueButton: function() {
- this.prompt.complete()
+ this.prompt.complete();
},
_onCancelButton: function() {
- this.prompt.cancel()
+ this.prompt.cancel();
},
});
-function init() {
- prompter = new Gcr.SystemPrompter();
- prompter.connect('new-prompt', function(prompter) {
- let dialog = new KeyringDialog();
- return dialog.prompt;
- });
-
- let connection = Gio.DBus.session;
- prompter.register(connection);
- Gio.bus_own_name_on_connection (connection, 'org.gnome.keyring.SystemPrompter',
- Gio.BusNameOwnerFlags.REPLACE, null, null);
-}
+const KeyringPrompter = new Lang.Class({
+ Name: 'KeyringPrompter',
+
+ _init: function() {
+ this._prompter = new Gcr.SystemPrompter();
+ this._prompter.connect('new-prompt', function(prompter) {
+ let dialog = new KeyringDialog();
+ return dialog.prompt;
+ });
+ this._dbusId = null;
+ },
+
+ enable: function() {
+ this._prompter.register(Gio.DBus.session);
+ this._dbusId = Gio.DBus.session.own_name('org.gnome.keyring.SystemPrompter',
+ Gio.BusNameOwnerFlags.REPLACE, null, null);
+ },
+
+ disable: function() {
+ Gio.DBus.session.unown_name(this._dbusId);
+ }
+});
+
+const Component = KeyringPrompter;
diff --git a/js/ui/networkAgent.js b/js/ui/components/networkAgent.js
similarity index 97%
rename from js/ui/networkAgent.js
rename to js/ui/components/networkAgent.js
index dbfb758..2eaca0c 100644
--- a/js/ui/networkAgent.js
+++ b/js/ui/components/networkAgent.js
@@ -1,23 +1,4 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
-/*
- * Copyright 2011 Giovanni Campagna <scampa giovanni gmail com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- */
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
@@ -603,7 +584,7 @@ const NetworkAgent = new Lang.Class({
Name: 'NetworkAgent',
_init: function() {
- this._native = new Shell.NetworkAgent({ auto_register: true,
+ this._native = new Shell.NetworkAgent({ auto_register: false,
identifier: 'org.gnome.Shell.NetworkAgent' });
this._dialogs = { };
@@ -613,6 +594,14 @@ const NetworkAgent = new Lang.Class({
this._native.connect('cancel-request', Lang.bind(this, this._cancelRequest));
},
+ enable: function() {
+ this._native.register();
+ },
+
+ disable: function() {
+ this._native.unregister();
+ },
+
_newRequest: function(agent, requestId, connection, settingName, hints, flags) {
if (settingName == 'vpn') {
this._vpnRequest(requestId, connection, hints, flags);
@@ -702,3 +691,4 @@ const NetworkAgent = new Lang.Class({
}
}
});
+const Component = NetworkAgent;
diff --git a/js/ui/polkitAuthenticationAgent.js b/js/ui/components/polkitAgent.js
similarity index 94%
rename from js/ui/polkitAuthenticationAgent.js
rename to js/ui/components/polkitAgent.js
index 92e4c6a..0fa9ba4 100644
--- a/js/ui/polkitAuthenticationAgent.js
+++ b/js/ui/components/polkitAgent.js
@@ -1,24 +1,4 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
-/*
- * Copyright 2010 Red Hat, Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
-*
- * Author: David Zeuthen <davidz redhat com>
- */
const Lang = imports.lang;
const Signals = imports.signals;
@@ -33,6 +13,7 @@ const Mainloop = imports.mainloop;
const Polkit = imports.gi.Polkit;
const PolkitAgent = imports.gi.PolkitAgent;
+const Components = imports.ui.components;
const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry;
const UserMenu = imports.ui.userMenu;
@@ -336,11 +317,20 @@ const AuthenticationAgent = new Lang.Class({
Name: 'AuthenticationAgent',
_init: function() {
+ this._currentDialog = null;
+ this._isCompleting = false;
+ this._handle = null;
this._native = new Shell.PolkitAuthenticationAgent();
this._native.connect('initiate', Lang.bind(this, this._onInitiate));
this._native.connect('cancel', Lang.bind(this, this._onCancel));
- this._currentDialog = null;
- this._isCompleting = false;
+ },
+
+ enable: function() {
+ this._native.register();
+ },
+
+ disable: function() {
+ this._native.unregister();
},
_onInitiate: function(nativeAgent, actionId, message, iconName, cookie, userNames) {
@@ -398,6 +388,4 @@ const AuthenticationAgent = new Lang.Class({
}
});
-function init() {
- let agent = new AuthenticationAgent();
-}
+const Component = AuthenticationAgent;
diff --git a/js/ui/components/recorder.js b/js/ui/components/recorder.js
new file mode 100644
index 0000000..94c49ce
--- /dev/null
+++ b/js/ui/components/recorder.js
@@ -0,0 +1,58 @@
+
+const Lang = imports.lang;
+
+const Gio = imports.gi.Gio;
+const Meta = imports.gi.Meta;
+const Shell = imports.gi.Shell;
+
+const Recorder = new Lang.Class({
+ Name: 'Recorder',
+
+ _init: function() {
+ this._recorderSettings = new Gio.Settings({ schema: 'org.gnome.shell.recorder' });
+ this._desktopLockdownSettings = new Gio.Settings({ schema: 'org.gnome.desktop.lockdown' });
+ this._bindingSettings = new Gio.Settings({ schema: 'org.gnome.shell.keybindings' });
+ this._recorder = null;
+ },
+
+ enable: function() {
+ global.display.add_keybinding('toggle-recording',
+ this._bindingSettings,
+ Meta.KeyBindingFlags.NONE, Lang.bind(this, this._toggleRecorder));
+ },
+
+ disable: function() {
+ global.display.remove_keybinding('toggle-recording');
+ },
+
+ _ensureRecorder: function() {
+ if (this._recorder == null)
+ this._recorder = new Shell.Recorder({ stage: global.stage });
+ return this._recorder;
+ },
+
+ _toggleRecorder: function() {
+ let recorder = this._ensureRecorder();
+ if (recorder.is_recording()) {
+ recorder.close();
+ Meta.enable_unredirect_for_screen(global.screen);
+ } else if (!desktopLockdownSettings.get_boolean('disable-save-to-disk')) {
+ // read the parameters from GSettings always in case they have changed
+ recorder.set_framerate(recorderSettings.get_int('framerate'));
+ /* Translators: this is a filename used for screencast recording */
+ // xgettext:no-c-format
+ recorder.set_filename(_("Screencast from %d %t") + '.' + recorderSettings.get_string('file-extension'));
+ let pipeline = recorderSettings.get_string('pipeline');
+
+ if (!pipeline.match(/^\s*$/))
+ recorder.set_pipeline(pipeline);
+ else
+ recorder.set_pipeline(null);
+
+ Meta.disable_unredirect_for_screen(global.screen);
+ recorder.record();
+ }
+ }
+});
+
+const Component = Recorder;
diff --git a/js/ui/telepathyClient.js b/js/ui/components/telepathyClient.js
similarity index 98%
rename from js/ui/telepathyClient.js
rename to js/ui/components/telepathyClient.js
index 08218d7..a6abeb1 100644
--- a/js/ui/telepathyClient.js
+++ b/js/ui/components/telepathyClient.js
@@ -63,10 +63,10 @@ function makeMessageFromTplEvent(event) {
};
}
-const Client = new Lang.Class({
- Name: 'Client',
+const TelepathyClient = new Lang.Class({
+ Name: 'TelepathyClient',
- _init : function() {
+ _init: function() {
// channel path -> ChatSource
this._chatSources = {};
this._chatState = Tp.ChannelChatState.ACTIVE;
@@ -89,9 +89,9 @@ const Client = new Lang.Class({
// channel matching its filters is detected.
// The second argument, recover, means _observeChannels will be run
// for any existing channel as well.
- this._tpClient = new Shell.TpClient({ 'account-manager': this._accountManager,
- 'name': 'GnomeShell',
- 'uniquify-name': true })
+ this._tpClient = new Shell.TpClient({ name: 'GnomeShell',
+ account_manager: this._accountManager,
+ uniquify_name: true });
this._tpClient.set_observe_channels_func(
Lang.bind(this, this._observeChannels));
this._tpClient.set_approve_channels_func(
@@ -99,6 +99,10 @@ const Client = new Lang.Class({
this._tpClient.set_handle_channels_func(
Lang.bind(this, this._handleChannels));
+ // Watch subscription requests and connection errors
+ this._subscriptionSource = null;
+ this._accountSource = null;
+
// Workaround for gjs not supporting GPtrArray in signals.
// See BGO bug #653941 for context.
this._tpClient.set_contact_list_changed_func(
@@ -108,21 +112,26 @@ const Client = new Lang.Class({
// needed
this._tpClient.set_delegated_channels_callback(
Lang.bind(this, this._delegatedChannelsCb));
+ },
+ enable: function() {
try {
this._tpClient.register();
} catch (e) {
throw new Error('Couldn\'t register Telepathy client. Error: \n' + e);
}
- // Watch subscription requests and connection errors
- this._subscriptionSource = null;
- this._accountSource = null;
+ this._accountManagerValidityChangedId = this._accountManager.connect('account-validity-changed',
+ Lang.bind(this, this._accountValidityChanged));
- this._accountManager.connect('account-validity-changed',
- Lang.bind(this, this._accountValidityChanged));
+ if (!this._accountManager.is_prepared(Tp.AccountManager.get_feature_quark_core()))
+ this._accountManager.prepare_async(null, Lang.bind(this, this._accountManagerPrepared));
+ },
- this._accountManager.prepare_async(null, Lang.bind(this, this._accountManagerPrepared));
+ disable: function() {
+ this._tpClient.unregister();
+ this._accountManager.disconnect(this._accountManagerValidityChangedId);
+ this._accountManagerValidityChangedId = 0;
},
_observeChannels: function(observer, account, conn, channels,
@@ -1399,3 +1408,4 @@ const AccountNotification = new Lang.Class({
this.parent();
}
});
+const Component = TelepathyClient;
diff --git a/js/ui/main.js b/js/ui/main.js
index 1d8ad4c..9410c23 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -10,12 +10,9 @@ const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
-const AutomountManager = imports.ui.automountManager;
-const AutorunManager = imports.ui.autorunManager;
+const Components = imports.ui.components;
const CtrlAltTab = imports.ui.ctrlAltTab;
const EndSessionDialog = imports.ui.endSessionDialog;
-const PolkitAuthenticationAgent = imports.ui.polkitAuthenticationAgent;
-const KeyringPrompt = imports.ui.keyringPrompt;
const Environment = imports.ui.environment;
const ExtensionSystem = imports.ui.extensionSystem;
const ExtensionDownloader = imports.ui.extensionDownloader;
@@ -27,7 +24,6 @@ const PlaceDisplay = imports.ui.placeDisplay;
const RunDialog = imports.ui.runDialog;
const Layout = imports.ui.layout;
const LookingGlass = imports.ui.lookingGlass;
-const NetworkAgent = imports.ui.networkAgent;
const NotificationDaemon = imports.ui.notificationDaemon;
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
const ScreenShield = imports.ui.screenShield;
@@ -35,7 +31,6 @@ const Scripting = imports.ui.scripting;
const SessionMode = imports.ui.sessionMode;
const ShellDBus = imports.ui.shellDBus;
const ShellMountOperation = imports.ui.shellMountOperation;
-const TelepathyClient = imports.ui.telepathyClient;
const UnlockDialog = imports.ui.unlockDialog;
const WindowManager = imports.ui.windowManager;
const Magnifier = imports.ui.magnifier;
@@ -45,8 +40,7 @@ const Util = imports.misc.util;
const OVERRIDES_SCHEMA = 'org.gnome.shell.overrides';
const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2266bbff);
-let automountManager = null;
-let autorunManager = null;
+let componentManager = null;
let panel = null;
let overview = null;
let runDialog = null;
@@ -56,9 +50,7 @@ let messageTray = null;
let screenShield = null;
let notificationDaemon = null;
let windowAttentionHandler = null;
-let telepathyClient = null;
let ctrlAltTabManager = null;
-let recorder = null;
let sessionMode = null;
let shellDBusService = null;
let shellMountOpDBusService = null;
@@ -70,7 +62,6 @@ let magnifier = null;
let xdndHandler = null;
let keyboard = null;
let layoutManager = null;
-let networkAgent = null;
let _startDate;
let _defaultCssStylesheet = null;
let _cssStylesheet = null;
@@ -78,19 +69,6 @@ let _overridesSettings = null;
let background = null;
-function createUserSession() {
- telepathyClient = new TelepathyClient.Client();
- automountManager = new AutomountManager.AutomountManager();
- autorunManager = new AutorunManager.AutorunManager();
- networkAgent = new NetworkAgent.NetworkAgent();
-
- _initRecorder();
-}
-
-function createGDMSession() {
- screenShield.showDialog();
-}
-
function createGDMLoginDialog(parentActor) {
// We do this this here instead of at the top to prevent GDM
// related code from getting loaded in normal user sessions
@@ -105,47 +83,8 @@ function createSessionUnlockDialog(parentActor) {
return [dialog, false];
}
-function createInitialSetupSession() {
- networkAgent = new NetworkAgent.NetworkAgent();
-}
-
-function _initRecorder() {
- let recorderSettings = new Gio.Settings({ schema: 'org.gnome.shell.recorder' });
- let desktopLockdownSettings = new Gio.Settings({ schema: 'org.gnome.desktop.lockdown' });
- let bindingSettings = new Gio.Settings({ schema: 'org.gnome.shell.keybindings' });
-
- global.display.add_keybinding('toggle-recording',
- bindingSettings,
- Meta.KeyBindingFlags.NONE, function() {
- if (recorder == null) {
- recorder = new Shell.Recorder({ stage: global.stage });
- }
-
- if (recorder.is_recording()) {
- recorder.close();
- Meta.enable_unredirect_for_screen(global.screen);
- } else if (!desktopLockdownSettings.get_boolean('disable-save-to-disk')) {
- // read the parameters from GSettings always in case they have changed
- recorder.set_framerate(recorderSettings.get_int('framerate'));
- /* Translators: this is a filename used for screencast recording */
- // xgettext:no-c-format
- recorder.set_filename(_("Screencast from %d %t") + '.' + recorderSettings.get_string('file-extension'));
- let pipeline = recorderSettings.get_string('pipeline');
-
- if (!pipeline.match(/^\s*$/))
- recorder.set_pipeline(pipeline);
- else
- recorder.set_pipeline(null);
-
- Meta.disable_unredirect_for_screen(global.screen);
- recorder.record();
- }
- });
-}
-
function _sessionUpdated() {
Meta.keybindings_set_custom_handler('panel-run-dialog', sessionMode.hasRunDialog ? openRunDialog : null);
- loadTheme();
}
function start() {
@@ -219,8 +158,7 @@ function start() {
keyboard = new Keyboard.Keyboard();
notificationDaemon = new NotificationDaemon.NotificationDaemon();
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
-
- sessionMode.createSession();
+ componentManager = new Components.ComponentManager();
layoutManager.init();
keyboard.init();
@@ -238,12 +176,6 @@ function start() {
// initiate logouts.
EndSessionDialog.init();
- // Attempt to become a PolicyKit authentication agent
- PolkitAuthenticationAgent.init()
-
- // Become a prompter for gnome keyring
- KeyringPrompt.init();
-
_startDate = new Date();
global.stage.connect('captured-event', _globalKeyPressHandler);
diff --git a/js/ui/sessionMode.js b/js/ui/sessionMode.js
index 09c0560..5728643 100644
--- a/js/ui/sessionMode.js
+++ b/js/ui/sessionMode.js
@@ -17,8 +17,8 @@ const _modes = {
hasRunDialog: false,
hasWorkspaces: false,
hasWindows: false,
- createSession: Main.createGDMSession,
createUnlockDialog: Main.createGDMLoginDialog,
+ components: [],
panel: {
left: [],
center: ['dateMenu'],
@@ -36,6 +36,7 @@ const _modes = {
hasRunDialog: false,
hasWorkspaces: false,
hasWindows: false,
+ components: ['networkAgent', 'polkitAgent', 'telepathyClient'],
panel: {
left: ['userMenu'],
center: [],
@@ -50,7 +51,7 @@ const _modes = {
allowKeybindingsWhenModal: false,
hasRunDialog: false,
hasWorkspaces: false,
- createSession: Main.createInitialSetupSession,
+ components: ['keyring'],
panel: {
left: [],
center: ['dateMenu'],
@@ -66,8 +67,9 @@ const _modes = {
hasRunDialog: true,
hasWorkspaces: true,
hasWindows: true,
- createSession: Main.createUserSession,
createUnlockDialog: Main.createSessionUnlockDialog,
+ components: ['networkAgent', 'polkitAgent', 'telepathyClient',
+ 'keyring', 'recorder', 'autorunManager', 'automountManager'],
panel: {
left: ['activities', 'appMenu'],
center: ['dateMenu'],
@@ -112,8 +114,6 @@ const SessionMode = new Lang.Class({
let params = _modes[this.currentMode];
params = Params.parse(params, _modes[DEFAULT_MODE]);
- this._createSession = params.createSession;
- delete params.createSession;
this._createUnlockDialog = params.createUnlockDialog;
delete params.createUnlockDialog;
@@ -121,11 +121,6 @@ const SessionMode = new Lang.Class({
this.emit('updated');
},
- createSession: function() {
- if (this._createSession)
- this._createSession();
- },
-
createUnlockDialog: function() {
if (this._createUnlockDialog)
return this._createUnlockDialog.apply(this, arguments);
diff --git a/src/shell-polkit-authentication-agent.c b/src/shell-polkit-authentication-agent.c
index e85354a..f1e8bf6 100644
--- a/src/shell-polkit-authentication-agent.c
+++ b/src/shell-polkit-authentication-agent.c
@@ -62,8 +62,9 @@ struct _ShellPolkitAuthenticationAgent {
PolkitAgentListener parent_instance;
GList *scheduled_requests;
-
AuthRequest *current_request;
+
+ gpointer handle;
};
/* Signals */
@@ -93,55 +94,40 @@ static gboolean initiate_authentication_finish (PolkitAgentListener *listener,
GAsyncResult *res,
GError **error);
-static void
+void
shell_polkit_authentication_agent_init (ShellPolkitAuthenticationAgent *agent)
{
- gpointer handle;
- PolkitSubject *subject;
- GError *error;
+}
- subject = NULL;
+void
+shell_polkit_authentication_agent_register (ShellPolkitAuthenticationAgent *agent,
+ GError **error_out)
+{
+ GError *error = NULL;
+ PolkitSubject *subject;
- error = NULL;
subject = polkit_unix_session_new_for_process_sync (getpid (),
NULL, /* GCancellable* */
&error);
if (subject == NULL)
{
- if (error) /* polkit version 104 and older don't properly set error on failure */
- {
- g_warning ("Error getting session for the process we are in: %s (%s %d)",
- error->message,
- g_quark_to_string (error->domain),
- error->code);
- g_error_free (error);
- }
- else
- {
- g_warning ("Error getting session for the process we are in");
- }
+ if (error == NULL) /* polkit version 104 and older don't properly set error on failure */
+ error = g_error_new (POLKIT_ERROR, POLKIT_ERROR_FAILED,
+ "PolKit failed to properly get our session");
goto out;
}
- handle = polkit_agent_listener_register (POLKIT_AGENT_LISTENER (agent),
- POLKIT_AGENT_REGISTER_FLAGS_NONE,
- subject,
- NULL, /* use default object path */
- NULL, /* GCancellable */
- &error);
- if (handle == NULL)
- {
- g_warning ("Error registering polkit authentication agent: %s (%s %d)",
- error->message,
- g_quark_to_string (error->domain),
- error->code);
- g_error_free (error);
- goto out;
- }
-
- /* We don't need to register so skip saving handle */
+ agent->handle = polkit_agent_listener_register (POLKIT_AGENT_LISTENER (agent),
+ POLKIT_AGENT_REGISTER_FLAGS_NONE,
+ subject,
+ NULL, /* use default object path */
+ NULL, /* GCancellable */
+ &error);
out:
+ if (error != NULL)
+ g_propagate_error (error_out, error);
+
if (subject != NULL)
g_object_unref (subject);
}
@@ -149,12 +135,8 @@ shell_polkit_authentication_agent_init (ShellPolkitAuthenticationAgent *agent)
static void
shell_polkit_authentication_agent_finalize (GObject *object)
{
- /* ShellPolkitAuthenticationAgent *agent = SHELL_POLKIT_AUTHENTICATION_AGENT (object); */
-
- /* Specifically left empty since the object stays alive forever - if code
- * is reused it would need to free outstanding requests etc.
- */
-
+ ShellPolkitAuthenticationAgent *agent = SHELL_POLKIT_AUTHENTICATION_AGENT (object);
+ shell_polkit_authentication_agent_unregister (agent);
G_OBJECT_CLASS (shell_polkit_authentication_agent_parent_class)->finalize (object);
}
@@ -325,6 +307,27 @@ on_request_cancelled (GCancellable *cancellable,
g_idle_add (handle_cancelled_in_idle, request);
}
+static void
+auth_request_dismiss (AuthRequest *request)
+{
+ auth_request_complete (request, TRUE);
+}
+
+void
+shell_polkit_authentication_agent_unregister (ShellPolkitAuthenticationAgent *agent)
+{
+ if (agent->scheduled_requests != NULL)
+ {
+ g_list_foreach (agent->scheduled_requests, (GFunc)auth_request_dismiss, NULL);
+ agent->scheduled_requests = NULL;
+ }
+ if (agent->current_request != NULL)
+ auth_request_dismiss (agent->current_request);
+
+ polkit_agent_listener_unregister (agent->handle);
+ agent->handle = NULL;
+}
+
static void maybe_process_next_request (ShellPolkitAuthenticationAgent *agent);
static void
diff --git a/src/shell-polkit-authentication-agent.h b/src/shell-polkit-authentication-agent.h
index a8758ae..745f0c9 100644
--- a/src/shell-polkit-authentication-agent.h
+++ b/src/shell-polkit-authentication-agent.h
@@ -27,6 +27,9 @@ GType shell_polkit_authentication_agent_get_type (void
ShellPolkitAuthenticationAgent *shell_polkit_authentication_agent_new (void);
void shell_polkit_authentication_agent_complete (ShellPolkitAuthenticationAgent *agent,
gboolean dismissed);
+void shell_polkit_authentication_agent_register (ShellPolkitAuthenticationAgent *agent,
+ GError **error_out);
+void shell_polkit_authentication_agent_unregister (ShellPolkitAuthenticationAgent *agent);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]