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
This commit is contained in:
parent
ca2e09fe8b
commit
2a800e4ce0
@ -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)
|
||||
|
61
js/ui/components/__init__.js
Normal file
61
js/ui/components/__init__.js
Normal file
@ -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();
|
||||
}
|
||||
});
|
@ -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;
|
@ -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;
|
@ -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;
|
@ -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;
|
@ -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;
|
58
js/ui/components/recorder.js
Normal file
58
js/ui/components/recorder.js
Normal file
@ -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;
|
@ -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;
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user