diff --git a/js/Makefile.am b/js/Makefile.am index 330098105..351ced1f5 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 000000000..763c87d7b --- /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 a49eb1794..9081e80e6 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(); - - Main.screenShield.connect('lock-status-changed', Lang.bind(this, this._lockStatusChanged)); - this._volumeMonitor = Gio.VolumeMonitor.get(); + }, - 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)); + 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)); - Mainloop.idle_add(Lang.bind(this, this._startupMountAll)); + 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); + + 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 2776fbb6d..3434e9b88 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(); + 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 814c9467b..dfa7cc007 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; - }); +const KeyringPrompter = new Lang.Class({ + Name: 'KeyringPrompter', - let connection = Gio.DBus.session; - prompter.register(connection); - Gio.bus_own_name_on_connection (connection, 'org.gnome.keyring.SystemPrompter', - Gio.BusNameOwnerFlags.REPLACE, null, null); -} + _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 dbfb75832..2eaca0c51 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 - * - * 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 92e4c6aa0..0fa9ba449 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 - */ 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 000000000..94c49ce40 --- /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 08218d7a7..a6abeb193 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 1d8ad4c95..9410c2352 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 09c05608e..572864312 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 e85354a68..f1e8bf6d0 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; +} + +void +shell_polkit_authentication_agent_register (ShellPolkitAuthenticationAgent *agent, + GError **error_out) +{ + GError *error = NULL; PolkitSubject *subject; - GError *error; - subject = NULL; - - 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 a8758ae92..745f0c983 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