Compare commits

..

1 Commits

Author SHA1 Message Date
Florian Müllner
078a1bda14 shellDBus: Return error on invalid app IDs
When passing an invalid or unknown app ID to FocusApp(), we currently
open the app picker and silently fail to select the desired app.
Instead of half-working like that, make it clear that the argument
was invalid by returning an appropriate error. (It's easy to get the
ID wrong, as unlike appstream/flatpak IDs, we include the ".desktop"
suffix).

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/337
2019-01-08 22:40:56 +01:00
162 changed files with 9907 additions and 7021 deletions

View File

@@ -82,6 +82,7 @@ don't use.
```javascript
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const St = imports.gi.St;
const Main = imports.ui.main;
@@ -120,51 +121,58 @@ See [What's new in JavaScript 1.7](https://developer.mozilla.org/en/JavaScript/N
## Classes
There are many approaches to classes in JavaScript. We use standard ES6 classes
whenever possible, that is when not inheriting from GObjects.
There are many approaches to classes in JavaScript. We use our own class framework
(sigh), which is built in gjs. The advantage is that it supports inheriting from
GObjects, although this feature isn't used very often in the Shell itself.
```javascript
var IconLabelMenuItem = class extends PopupMenu.PopupMenuBaseItem {
constructor(icon, label) {
super({ reactive: false });
var IconLabelMenuItem = new Lang.Class({
Name: 'IconLabelMenuItem',
Extends: PopupMenu.PopupMenuBaseItem,
_init(icon, label) {
this.parent({ reactive: false });
this.actor.add_child(icon);
this.actor.add_child(label);
}
},
open() {
log("menu opened!");
}
};
```
For GObject inheritence, we use the GObject.registerClass() function provided
by gjs.
```javascript
var MyActor = GObject.registerClass(
class MyActor extends Clutter.Actor {
_init(params) {
super._init(params);
this.name = 'MyCustomActor';
}
});
```
* 'Name' is required. 'Extends' is optional. If you leave it out, you will
automatically inherit from Object.
* Leave a blank line between the "class header" (Name, Extends, and other
things) and the "class body" (methods). Leave a blank line between each
method.
* No space before the colon, one space after.
* No trailing comma after the last item.
* Make sure to use a semicolon after the closing paren to the class. It's
still a giant function call, even though it may resemble a more
conventional syntax.
## GObject Introspection
GObject Introspection is a powerful feature that allows us to have native
bindings for almost any library built around GObject. If a library requires
you to inherit from a type to use it, you can do so:
```javascript
var MyClutterActor = GObject.registerClass(
class MyClutterActor extends Clutter.Actor {
var MyClutterActor = new Lang.Class({
Name: 'MyClutterActor',
Extends: Clutter.Actor,
vfunc_get_preferred_width(actor, forHeight) {
return [100, 100];
}
},
vfunc_get_preferred_height(actor, forWidth) {
return [100, 100];
}
},
vfunc_paint(actor) {
let alloc = this.get_allocation_box();
@@ -199,18 +207,20 @@ that has a property called `actor`. We call this wrapper class the "delegate".
We sometimes use expando properties to set a property called `_delegate` on
the actor itself:
```javascript
var MyClass = class {
constructor() {
var MyClass = new Lang.Class({
Name: 'MyClass',
_init() {
this.actor = new St.Button({ text: "This is a button" });
this.actor._delegate = this;
this.actor.connect('clicked', this._onClicked.bind(this));
}
},
_onClicked(actor) {
actor.set_label("You clicked the button!");
}
};
});
```
The 'delegate' property is important for anything which trying to get the
@@ -236,6 +246,8 @@ variable that can be captured in closures.
All closures should be wrapped with Function.prototype.bind or use arrow
notation.
```javascript
const Lang = imports.lang;
let closure1 = () => { this._fnorbate(); };
let closure2 = this._fnorbate.bind(this);
```
@@ -243,18 +255,19 @@ notation.
A more realistic example would be connecting to a signal on a method of a
prototype:
```javascript
const Lang = imports.lang;
const FnorbLib = imports.fborbLib;
var MyClass = class {
var MyClass = new Lang.Class({
_init() {
let fnorb = new FnorbLib.Fnorb();
fnorb.connect('frobate', this._onFnorbFrobate.bind(this));
}
},
_onFnorbFrobate(fnorb) {
this._updateFnorb();
}
};
});
```
## Object literal syntax
@@ -288,21 +301,23 @@ property.
```javascript
var ANIMATION_TIME = 2000;
var MyClass = class {
constructor() {
var MyClass = new Lang.Class({
Name: 'MyClass',
_init() {
this.actor = new St.BoxLayout();
this._position = 0;
}
},
get position() {
return this._position;
}
},
set position(value) {
this._position = value;
this.actor.set_position(value, value);
}
};
});
let myThing = new MyClass();
Tweener.addTween(myThing,

21
NEWS
View File

@@ -1,24 +1,3 @@
3.31.4
======
* Improve icon grid performance [Daniel; #174]
* Remove browser plugin [Michael; #766776]
* Add DBus API for introspecting the application state [Jonas, Olivier; !326]
* Always allow leaving the overview via the hot-corner [Pascal; #429]
* Misc. bug fixes [Florian, Jasper, Andrea, Sam, Dani, Cosimo, Jonas, Carlos;
#643595, #673767, !293, #783, #781, !298, !297, #782, !301, !314, !305, #799,
#632, !327]
Contributors:
Jonas Ådahl, Andrea Azzarone, Michael Catanzaro, Cosimo Cecchi, daniruiz,
Olivier Fourdan, Carlos Garnacho, Sam Hewitt, Andre Klapper, Florian Müllner,
Pascal Nowack, Jasper St. Pierre, RyuzakiKK, Marco Trevisan (Treviño),
João Paulo Rechi Vita, Daniel van Vugt
Translators:
Kristjan SCHMIDT [eo], Matej Urbančič [sl], Daniel Mustieles [es],
Fabio Tomat [fur], Emin Tufan Çetin [tr], Anders Jonsson [sv],
Ryuta Fujii [ja]
3.31.2
======
* Port away from and remove ShellGenericContainer [Georges; !153]

View File

@@ -1,6 +1,5 @@
dbus_interfaces = [
'org.gnome.Shell.Extensions.xml',
'org.gnome.Shell.Introspect.xml',
'org.gnome.Shell.PadOsd.xml',
'org.gnome.Shell.Screencast.xml',
'org.gnome.Shell.Screenshot.xml',

View File

@@ -1,61 +0,0 @@
<!DOCTYPE node PUBLIC
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
<node>
<!--
org.gnome.Shell.Introspect:
@short_description: Introspection interface
The interface used to introspect the state of Shell, such as running
applications, currently active application, etc.
-->
<interface name="org.gnome.Shell.Introspect">
<!--
RunningApplicationsChanged:
@short_description: Notifies when the running applications changes
-->
<signal name="RunningApplicationsChanged" />
<!--
GetRunningApplications:
@short_description: Retrieves the description of all running applications
Each application is associated by an application ID. The details of
each application consists of a varlist of keys and values. Available
keys are listed below.
'active-on-seats' - (as) list of seats the application is active on
(a seat only has at most one active
application)
-->
<method name="GetRunningApplications">
<arg name="apps" direction="out" type="a{sa{sv}}" />
</method>
<!--
GetWindows:
@short_description: Retrieves the current list of windows and their properties
A window is exposed as:
* t ID: unique ID of the window
* a{sv} properties: high-level properties
Known properties:
- "title" (s): (readonly) title of the window
- "app-id" (s): (readonly) application ID of the window
- "wm-class" (s): (readonly) class of the window
- "client-type" (u): (readonly) 0 for Wayland, 1 for X11
- "is-hidden" (b): (readonly) if the window is currently hidden
- "has-focus" (b): (readonly) if the window currently have
keyboard focus
- "width" (u): (readonly) width of the window
- "height" (u): (readonly) height of the window
-->
<method name="GetWindows">
<arg name="windows" direction="out" type="a{ta{sv}}" />
</method>
</interface>
</node>

View File

@@ -40,7 +40,6 @@
<file preprocess="xml-stripblanks">org.gnome.SettingsDaemon.Wacom.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.AudioDeviceSelection.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.Extensions.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.Introspect.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.HotplugSniffer.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.PerfHelper.xml</file>
<file preprocess="xml-stripblanks">org.gnome.Shell.PortalHelper.xml</file>

View File

@@ -90,20 +90,19 @@
adapter is ever seen not to have devices associated to it.
</description>
</key>
<key name="introspect" type="b">
<default>false</default>
<summary>Enable introspection API</summary>
<description>
Enables a D-Bus API that allows to introspect the application state of
the shell.
</description>
</key>
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
<child name="keyboard" schema="org.gnome.shell.keyboard"/>
</schema>
<schema id="org.gnome.shell.keybindings" path="/org/gnome/shell/keybindings/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="open-application-menu" type="as">
<default>["&lt;Super&gt;F10"]</default>
<summary>Keybinding to open the application menu</summary>
<description>
Keybinding to open the application menu.
</description>
</key>
<key name="toggle-application-view" type="as">
<default>["&lt;Super&gt;a"]</default>
<summary>Keybinding to open the “Show Applications” view</summary>

View File

@@ -1084,8 +1084,8 @@ StScrollBar {
background-color: $bg_color;
border: 2px solid $bg_color;
border-radius: 2px;
icon-size: 32px !important;
padding: 6px; }
icon-size: 16px;
padding: 8px; }
}

View File

@@ -1,3 +1,5 @@
const Lang = imports.lang;
const Gettext = imports.gettext;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
@@ -22,8 +24,9 @@ function stripPrefix(string, prefix) {
return string;
}
var Application = class {
constructor() {
var Application = new Lang.Class({
Name: 'Application',
_init() {
GLib.set_prgname('gnome-shell-extension-prefs');
this.application = new Gtk.Application({
application_id: 'org.gnome.shell.ExtensionPrefs',
@@ -39,7 +42,7 @@ var Application = class {
this._startupUuid = null;
this._loaded = false;
this._skipMainWindow = false;
}
},
_extensionAvailable(uuid) {
let extension = ExtensionUtils.extensions[uuid];
@@ -51,7 +54,7 @@ var Application = class {
return false;
return true;
}
},
_getExtensionPrefsModule(extension) {
let uuid = extension.metadata.uuid;
@@ -66,7 +69,7 @@ var Application = class {
this._extensionPrefsModules[uuid] = prefsModule;
return prefsModule;
}
},
_selectExtension(uuid) {
if (!this._extensionAvailable(uuid))
@@ -101,7 +104,7 @@ var Application = class {
dialog.set_default_size(600, 400);
dialog.add(widget);
dialog.show();
}
},
_buildErrorUI(extension, exc) {
let box = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
@@ -127,7 +130,7 @@ var Application = class {
box.show_all();
return box;
}
},
_buildUI(app) {
this._window = new Gtk.ApplicationWindow({ application: app,
@@ -164,13 +167,13 @@ var Application = class {
});
this._window.show_all();
}
},
_sortList(row1, row2) {
let name1 = ExtensionUtils.extensions[row1.uuid].metadata.name;
let name2 = ExtensionUtils.extensions[row2.uuid].metadata.name;
return name1.localeCompare(name2);
}
},
_updateHeader(row, before) {
if (!before || row.get_header())
@@ -178,14 +181,14 @@ var Application = class {
let sep = new Gtk.Separator({ orientation: Gtk.Orientation.HORIZONTAL });
row.set_header(sep);
}
},
_scanExtensions() {
let finder = new ExtensionUtils.ExtensionFinder();
finder.connect('extension-found', this._extensionFound.bind(this));
finder.scanExtensions();
this._extensionsLoaded();
}
},
_extensionFound(finder, extension) {
let row = new ExtensionRow(extension.uuid);
@@ -197,7 +200,7 @@ var Application = class {
row.show_all();
this._extensionSelector.add(row);
}
},
_extensionsLoaded() {
if (this._startupUuid && this._extensionAvailable(this._startupUuid))
@@ -205,16 +208,16 @@ var Application = class {
this._startupUuid = null;
this._skipMainWindow = false;
this._loaded = true;
}
},
_onActivate() {
this._window.present();
}
},
_onStartup(app) {
this._buildUI(app);
this._scanExtensions();
}
},
_onCommandLine(app, commandLine) {
app.activate();
@@ -237,22 +240,26 @@ var Application = class {
}
return 0;
}
};
});
var DescriptionLabel = new Lang.Class({
Name: 'DescriptionLabel',
Extends: Gtk.Label,
var DescriptionLabel = GObject.registerClass(
class DescriptionLabel extends Gtk.Label {
vfunc_get_preferred_height_for_width(width) {
// Hack: Request the maximum height allowed by the line limit
if (this.lines > 0)
return super.vfunc_get_preferred_height_for_width(0);
return super.vfunc_get_preferred_height_for_width(width);
return this.parent(0);
return this.parent(width);
}
});
var ExtensionRow = GObject.registerClass(
class ExtensionRow extends Gtk.ListBoxRow {
var ExtensionRow = new Lang.Class({
Name: 'ExtensionRow',
Extends: Gtk.ListBoxRow,
_init(uuid) {
super._init();
this.parent();
this.uuid = uuid;
@@ -270,7 +277,7 @@ class ExtensionRow extends Gtk.ListBoxRow {
});
this._buildUI();
}
},
_buildUI() {
let extension = ExtensionUtils.extensions[this.uuid];
@@ -317,7 +324,7 @@ class ExtensionRow extends Gtk.ListBoxRow {
});
this._switch.connect('state-set', () => true);
hbox.add(this._switch);
}
},
_canEnable() {
let extension = ExtensionUtils.extensions[this.uuid];
@@ -325,12 +332,12 @@ class ExtensionRow extends Gtk.ListBoxRow {
return !this._settings.get_boolean('disable-user-extensions') &&
!(checkVersion && ExtensionUtils.isOutOfDate(extension));
}
},
_isEnabled() {
let extensions = this._settings.get_strv('enabled-extensions');
return extensions.indexOf(this.uuid) != -1;
}
},
_enable() {
let extensions = this._settings.get_strv('enabled-extensions');
@@ -339,7 +346,7 @@ class ExtensionRow extends Gtk.ListBoxRow {
extensions.push(this.uuid);
this._settings.set_strv('enabled-extensions', extensions);
}
},
_disable() {
let extensions = this._settings.get_strv('enabled-extensions');

View File

@@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Pango = imports.gi.Pango;
const Signals = imports.signals;
const St = imports.gi.St;
@@ -37,8 +38,10 @@ var BeginRequestType = {
DONT_PROVIDE_USERNAME: 1
};
var AuthPrompt = class {
constructor(gdmClient, mode) {
var AuthPrompt = new Lang.Class({
Name: 'AuthPrompt',
_init(gdmClient, mode) {
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this._gdmClient = gdmClient;
@@ -124,16 +127,17 @@ var AuthPrompt = class {
this._initButtons();
this._spinner = new Animation.Spinner(DEFAULT_BUTTON_WELL_ICON_SIZE);
let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
this._spinner = new Animation.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE);
this._spinner.actor.opacity = 0;
this._spinner.actor.show();
this._defaultButtonWell.add_child(this._spinner.actor);
}
},
_onDestroy() {
this._userVerifier.destroy();
this._userVerifier = null;
}
},
_initButtons() {
this.cancelButton = new St.Button({ style_class: 'modal-dialog-button button',
@@ -181,7 +185,7 @@ var AuthPrompt = class {
if (this.nextButton.reactive)
this.emit('next');
});
}
},
_onAskQuestion(verifier, serviceName, question, passwordChar) {
if (this._queryingService)
@@ -207,12 +211,12 @@ var AuthPrompt = class {
this.updateSensitivity(true);
this.emit('prompted');
}
},
_onOVirtUserAuthenticated() {
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
this.reset();
}
},
_onSmartcardStatusChanged() {
this.smartcardDetected = this._userVerifier.smartcardDetected;
@@ -231,12 +235,12 @@ var AuthPrompt = class {
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
this.reset();
}
},
_onShowMessage(userVerifier, message, type) {
this.setMessage(message, type);
this.emit('prompted');
}
},
_onVerificationFailed(userVerifier, canRetry) {
this._queryingService = null;
@@ -245,22 +249,22 @@ var AuthPrompt = class {
this.updateSensitivity(canRetry);
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
}
},
_onVerificationComplete() {
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED;
this.cancelButton.reactive = false;
}
},
_onReset() {
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this.reset();
}
},
addActorToDefaultButtonWell(actor) {
this._defaultButtonWell.add_child(actor);
}
},
setActorInDefaultButtonWell(actor, animate) {
if (!this._defaultButtonWellActor &&
@@ -324,25 +328,25 @@ var AuthPrompt = class {
}
this._defaultButtonWellActor = actor;
}
},
startSpinning() {
this.setActorInDefaultButtonWell(this._spinner.actor, true);
}
},
stopSpinning() {
this.setActorInDefaultButtonWell(null, false);
}
},
clear() {
this._entry.text = '';
this.stopSpinning();
}
},
setPasswordChar(passwordChar) {
this._entry.clutter_text.set_password_char(passwordChar);
this._entry.menu.isPassword = passwordChar != '';
}
},
setQuestion(question) {
this._label.set_text(question);
@@ -351,7 +355,7 @@ var AuthPrompt = class {
this._entry.show();
this._entry.grab_key_focus();
}
},
getAnswer() {
let text;
@@ -364,7 +368,7 @@ var AuthPrompt = class {
}
return text;
}
},
_fadeOutMessage() {
if (this._message.opacity == 0)
@@ -375,7 +379,7 @@ var AuthPrompt = class {
time: MESSAGE_FADE_OUT_ANIMATION_TIME,
transition: 'easeOutQuad'
});
}
},
setMessage(message, type) {
if (type == GdmUtil.MessageType.ERROR)
@@ -395,18 +399,18 @@ var AuthPrompt = class {
} else {
this._message.opacity = 0;
}
}
},
_updateNextButtonSensitivity(sensitive) {
this.nextButton.reactive = sensitive;
this.nextButton.can_focus = sensitive;
}
},
updateSensitivity(sensitive) {
this._updateNextButtonSensitivity(sensitive && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING));
this._entry.reactive = sensitive;
this._entry.clutter_text.editable = sensitive;
}
},
hide() {
this.setActorInDefaultButtonWell(null, true);
@@ -417,7 +421,7 @@ var AuthPrompt = class {
this.updateSensitivity(true);
this._entry.set_text('');
}
},
setUser(user) {
let oldChild = this._userWell.get_child();
@@ -428,7 +432,7 @@ var AuthPrompt = class {
let userWidget = new UserWidget.UserWidget(user);
this._userWell.set_child(userWidget.actor);
}
}
},
reset() {
let oldStatus = this.verificationStatus;
@@ -466,7 +470,7 @@ var AuthPrompt = class {
}
this.emit('reset', beginRequestType);
}
},
addCharacter(unichar) {
if (!this._entry.visible)
@@ -474,7 +478,7 @@ var AuthPrompt = class {
this._entry.grab_key_focus();
this._entry.clutter_text.insert_unichar(unichar);
}
},
begin(params) {
params = Params.parse(params, { userName: null,
@@ -488,7 +492,7 @@ var AuthPrompt = class {
this._userVerifier.begin(params.userName, hold);
this.verificationStatus = AuthPromptStatus.VERIFYING;
}
},
finish(onComplete) {
if (!this._userVerifier.hasPendingMessages) {
@@ -502,7 +506,7 @@ var AuthPrompt = class {
this._userVerifier.clear();
onComplete();
});
}
},
cancel() {
if (this.verificationStatus == AuthPromptStatus.VERIFICATION_SUCCEEDED) {
@@ -511,5 +515,5 @@ var AuthPrompt = class {
this.reset();
this.emit('cancelled');
}
};
});
Signals.addSignalMethods(AuthPrompt.prototype);

View File

@@ -44,39 +44,45 @@
* replaced by something else.
*/
const Lang = imports.lang;
const Signals = imports.signals;
var Task = class {
constructor(scope, handler) {
var Task = new Lang.Class({
Name: 'Task',
_init(scope, handler) {
if (scope)
this.scope = scope;
else
this.scope = this;
this.handler = handler;
}
},
run() {
if (this.handler)
return this.handler.call(this.scope);
return null;
}
};
},
});
Signals.addSignalMethods(Task.prototype);
var Hold = class extends Task {
constructor() {
super(null, () => this);
var Hold = new Lang.Class({
Name: 'Hold',
Extends: Task,
_init() {
this.parent(this, () => this);
this._acquisitions = 1;
}
},
acquire() {
if (this._acquisitions <= 0)
throw new Error("Cannot acquire hold after it's been released");
this._acquisitions++;
}
},
acquireUntilAfter(hold) {
if (!hold.isAcquired())
@@ -87,24 +93,27 @@ var Hold = class extends Task {
hold.disconnect(signalId);
this.release();
});
}
},
release() {
this._acquisitions--;
if (this._acquisitions == 0)
this.emit('release');
}
},
isAcquired() {
return this._acquisitions > 0;
}
};
});
Signals.addSignalMethods(Hold.prototype);
var Batch = class extends Task {
constructor(scope, tasks) {
super();
var Batch = new Lang.Class({
Name: 'Batch',
Extends: Task,
_init(scope, tasks) {
this.parent();
this.tasks = [];
@@ -121,11 +130,11 @@ var Batch = class extends Task {
this.tasks.push(task);
}
}
},
process() {
throw new Error('Not implemented');
}
},
runTask() {
if (!(this._currentTaskIndex in this.tasks)) {
@@ -133,11 +142,11 @@ var Batch = class extends Task {
}
return this.tasks[this._currentTaskIndex].run();
}
},
_finish() {
this.hold.release();
}
},
nextTask() {
this._currentTaskIndex++;
@@ -150,7 +159,7 @@ var Batch = class extends Task {
}
this.process();
}
},
_start() {
// acquire a hold to get released when the entire
@@ -158,7 +167,7 @@ var Batch = class extends Task {
this.hold = new Hold();
this._currentTaskIndex = 0;
this.process();
}
},
run() {
this._start();
@@ -166,15 +175,18 @@ var Batch = class extends Task {
// hold may be destroyed at this point
// if we're already done running
return this.hold;
}
},
cancel() {
this.tasks = this.tasks.splice(0, this._currentTaskIndex + 1);
}
};
});
Signals.addSignalMethods(Batch.prototype);
var ConcurrentBatch = class extends Batch {
var ConcurrentBatch = new Lang.Class({
Name: 'ConcurrentBatch',
Extends: Batch,
process() {
let hold = this.runTask();
@@ -187,10 +199,13 @@ var ConcurrentBatch = class extends Batch {
// concurrently.
this.nextTask();
}
};
});
Signals.addSignalMethods(ConcurrentBatch.prototype);
var ConsecutiveBatch = class extends Batch {
var ConsecutiveBatch = new Lang.Class({
Name: 'ConsecutiveBatch',
Extends: Batch,
process() {
let hold = this.runTask();
@@ -207,5 +222,5 @@ var ConsecutiveBatch = class extends Batch {
this.nextTask();
}
}
};
});
Signals.addSignalMethods(ConsecutiveBatch.prototype);

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;

View File

@@ -24,6 +24,7 @@ const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
@@ -49,8 +50,10 @@ const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _LOGO_ICON_HEIGHT = 48;
const _MAX_BOTTOM_MENU_ITEMS = 5;
var UserListItem = class {
constructor(user) {
var UserListItem = new Lang.Class({
Name: 'UserListItem',
_init(user) {
this.user = user;
this._userChangedId = this.user.connect('changed',
this._onUserChanged.bind(this));
@@ -88,26 +91,26 @@ var UserListItem = class {
this.actor.connect('clicked', this._onClicked.bind(this));
this._onUserChanged();
}
},
_onUserChanged() {
this._updateLoggedIn();
}
},
_updateLoggedIn() {
if (this.user.is_logged_in())
this.actor.add_style_pseudo_class('logged-in');
else
this.actor.remove_style_pseudo_class('logged-in');
}
},
_onDestroy() {
this.user.disconnect(this._userChangedId);
}
},
_onClicked() {
this.emit('activate');
}
},
_setSelected(selected) {
if (selected) {
@@ -116,7 +119,7 @@ var UserListItem = class {
} else {
this.actor.remove_style_pseudo_class('selected');
}
}
},
showTimedLoginIndicator(time) {
let hold = new Batch.Hold();
@@ -144,7 +147,7 @@ var UserListItem = class {
GLib.Source.set_name_by_id(this._timedLoginTimeoutId, '[gnome-shell] this._timedLoginTimeoutId');
return hold;
}
},
hideTimedLoginIndicator() {
if (this._timedLoginTimeoutId) {
@@ -155,11 +158,13 @@ var UserListItem = class {
this._timedLoginIndicator.visible = false;
this._timedLoginIndicator.scale_x = 0.;
}
};
});
Signals.addSignalMethods(UserListItem.prototype);
var UserList = class {
constructor() {
var UserList = new Lang.Class({
Name: 'UserList',
_init() {
this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view'});
this.actor.set_policy(Gtk.PolicyType.NEVER,
Gtk.PolicyType.AUTOMATIC);
@@ -172,7 +177,7 @@ var UserList = class {
this._items = {};
this.actor.connect('key-focus-in', this._moveFocusToItems.bind(this));
}
},
_moveFocusToItems() {
let hasItems = Object.keys(this._items).length > 0;
@@ -190,11 +195,11 @@ var UserList = class {
return false;
});
}
}
},
_onItemActivated(activatedItem) {
this.emit('activate', activatedItem);
}
},
updateStyle(isExpanded) {
let tasks = [];
@@ -208,7 +213,7 @@ var UserList = class {
let item = this._items[userName];
item.actor.sync_hover();
}
}
},
scrollToItem(item) {
let box = item.actor.get_allocation_box();
@@ -221,7 +226,7 @@ var UserList = class {
{ value: value,
time: _SCROLL_ANIMATION_TIME,
transition: 'easeOutQuad' });
}
},
jumpToItem(item) {
let box = item.actor.get_allocation_box();
@@ -231,7 +236,7 @@ var UserList = class {
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
adjustment.set_value(value);
}
},
getItemFromUserName(userName) {
let item = this._items[userName];
@@ -240,11 +245,11 @@ var UserList = class {
return null;
return item;
}
},
containsUser(user) {
return this._items[user.get_user_name()] != null;
}
},
addUser(user) {
if (!user.is_loaded)
@@ -276,7 +281,7 @@ var UserList = class {
this._moveFocusToItems();
this.emit('item-added', item);
}
},
removeUser(user) {
if (!user.is_loaded)
@@ -294,16 +299,18 @@ var UserList = class {
item.actor.destroy();
delete this._items[userName];
}
},
numItems() {
return Object.keys(this._items).length;
}
};
});
Signals.addSignalMethods(UserList.prototype);
var SessionMenuButton = class {
constructor() {
var SessionMenuButton = new Lang.Class({
Name: 'SessionMenuButton',
_init() {
let gearIcon = new St.Icon({ icon_name: 'emblem-system-symbolic' });
this._button = new St.Button({ style_class: 'login-dialog-session-list-button',
reactive: true,
@@ -343,13 +350,13 @@ var SessionMenuButton = class {
this._items = {};
this._activeSessionId = null;
this._populate();
}
},
updateSensitivity(sensitive) {
this._button.reactive = sensitive;
this._button.can_focus = sensitive;
this._menu.close(BoxPointer.PopupAnimation.NONE);
}
},
_updateOrnament() {
let itemIds = Object.keys(this._items);
@@ -359,7 +366,7 @@ var SessionMenuButton = class {
else
this._items[itemIds[i]].setOrnament(PopupMenu.Ornament.NONE);
}
}
},
setActiveSession(sessionId) {
if (sessionId == this._activeSessionId)
@@ -367,11 +374,11 @@ var SessionMenuButton = class {
this._activeSessionId = sessionId;
this._updateOrnament();
}
},
close() {
this._menu.close();
}
},
_populate() {
let ids = Gdm.get_session_ids();
@@ -396,14 +403,16 @@ var SessionMenuButton = class {
});
}
}
};
});
Signals.addSignalMethods(SessionMenuButton.prototype);
var LoginDialog = GObject.registerClass({
var LoginDialog = new Lang.Class({
Name: 'LoginDialog',
Extends: St.Widget,
Signals: { 'failed': {} },
}, class LoginDialog extends St.Widget {
_init(parentActor) {
super._init({ style_class: 'login-dialog',
this.parent({ style_class: 'login-dialog',
visible: false });
this.get_accessible().set_role(Atk.Role.WINDOW);
@@ -521,7 +530,7 @@ var LoginDialog = GObject.registerClass({
// focus later
this._startupCompleteId = Main.layoutManager.connect('startup-complete',
this._updateDisableUserList.bind(this));
}
},
_getBannerAllocation(dialogBox) {
let actorBox = new Clutter.ActorBox();
@@ -535,7 +544,7 @@ var LoginDialog = GObject.registerClass({
actorBox.y2 = actorBox.y1 + natHeight;
return actorBox;
}
},
_getLogoBinAllocation(dialogBox) {
let actorBox = new Clutter.ActorBox();
@@ -549,7 +558,7 @@ var LoginDialog = GObject.registerClass({
actorBox.y2 = actorBox.y1 + natHeight;
return actorBox;
}
},
_getCenterActorAllocation(dialogBox, actor) {
let actorBox = new Clutter.ActorBox();
@@ -567,7 +576,7 @@ var LoginDialog = GObject.registerClass({
actorBox.y2 = actorBox.y1 + natHeight;
return actorBox;
}
},
vfunc_allocate(dialogBox, flags) {
this.set_allocation(dialogBox, flags);
@@ -710,7 +719,7 @@ var LoginDialog = GObject.registerClass({
if (logoAllocation)
this._logoBin.allocate(logoAllocation, flags);
}
},
_ensureUserListLoaded() {
if (!this._userManager.is_loaded) {
@@ -726,7 +735,7 @@ var LoginDialog = GObject.registerClass({
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, this._loadUserList.bind(this));
GLib.Source.set_name_by_id(id, '[gnome-shell] _loadUserList');
}
}
},
_updateDisableUserList() {
let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY);
@@ -741,7 +750,7 @@ var LoginDialog = GObject.registerClass({
if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
this._authPrompt.reset();
}
}
},
_updateCancelButton() {
let cancelVisible;
@@ -754,7 +763,7 @@ var LoginDialog = GObject.registerClass({
cancelVisible = true;
this._authPrompt.cancelButton.visible = cancelVisible;
}
},
_updateBanner() {
let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY);
@@ -766,7 +775,7 @@ var LoginDialog = GObject.registerClass({
} else {
this._bannerLabel.hide();
}
}
},
_fadeInBannerView() {
this._bannerView.show();
@@ -774,13 +783,13 @@ var LoginDialog = GObject.registerClass({
{ opacity: 255,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad' });
}
},
_hideBannerView() {
Tweener.removeTweens(this._bannerView);
this._bannerView.opacity = 0;
this._bannerView.hide();
}
},
_updateLogoTexture(cache, file) {
if (this._logoFile && !this._logoFile.equal(file))
@@ -793,14 +802,14 @@ var LoginDialog = GObject.registerClass({
-1, _LOGO_ICON_HEIGHT,
scaleFactor));
}
}
},
_updateLogo() {
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
this._logoFile = path ? Gio.file_new_for_path(path) : null;
this._updateLogoTexture(this._textureCache, this._logoFile);
}
},
_onPrompted() {
if (this._shouldShowSessionMenuButton()) {
@@ -810,7 +819,7 @@ var LoginDialog = GObject.registerClass({
this._sessionMenuButton.updateSensitivity(false);
}
this._showPrompt();
}
},
_resetGreeterProxy() {
if (GLib.getenv('GDM_GREETER_TEST') != '1') {
@@ -826,7 +835,7 @@ var LoginDialog = GObject.registerClass({
this._timedLoginRequestedId = this._greeter.connect('timed-login-requested',
this._onTimedLoginRequested.bind(this));
}
}
},
_onReset(authPrompt, beginRequest) {
this._resetGreeterProxy();
@@ -847,11 +856,11 @@ var LoginDialog = GObject.registerClass({
} else {
this._hideUserListAndBeginVerification();
}
}
},
_onDefaultSessionChanged(client, sessionId) {
this._sessionMenuButton.setActiveSession(sessionId);
}
},
_shouldShowSessionMenuButton() {
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING &&
@@ -862,7 +871,7 @@ var LoginDialog = GObject.registerClass({
return false;
return true;
}
},
_showPrompt() {
if (this._authPrompt.actor.visible)
@@ -874,7 +883,7 @@ var LoginDialog = GObject.registerClass({
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad' });
this._fadeInBannerView();
}
},
_showRealmLoginHint(realmManager, hint) {
if (!hint)
@@ -887,7 +896,7 @@ var LoginDialog = GObject.registerClass({
// Translators: this message is shown below the username entry field
// to clue the user in on how to login to the local network realm
this._authPrompt.setMessage(_("(e.g., user or %s)").format(hint), GdmUtil.MessageType.HINT);
}
},
_askForUsernameAndBeginVerification() {
this._authPrompt.setPasswordChar('');
@@ -914,7 +923,7 @@ var LoginDialog = GObject.registerClass({
this._sessionMenuButton.updateSensitivity(false);
this._authPrompt.updateSensitivity(true);
this._showPrompt();
}
},
_loginScreenSessionActivated() {
if (this.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
@@ -938,7 +947,7 @@ var LoginDialog = GObject.registerClass({
this._authPrompt.reset();
},
onCompleteScope: this });
}
},
_gotGreeterSessionProxy(proxy) {
this._greeterSessionProxy = proxy;
@@ -947,7 +956,7 @@ var LoginDialog = GObject.registerClass({
if (proxy.Active)
this._loginScreenSessionActivated();
});
}
},
_startSession(serviceName) {
Tweener.addTween(this,
@@ -967,11 +976,11 @@ var LoginDialog = GObject.registerClass({
this._greeter.call_start_session_when_ready_sync(serviceName, true, null);
},
onCompleteScope: this });
}
},
_onSessionOpened(client, serviceName) {
this._authPrompt.finish(() => { this._startSession(serviceName); });
}
},
_waitForItemForUser(userName) {
let item = this._userList.getItemFromUserName(userName);
@@ -991,7 +1000,7 @@ var LoginDialog = GObject.registerClass({
hold.connect('release', () => { this._userList.disconnect(signalId); });
return hold;
}
},
_blockTimedLoginUntilIdle() {
let hold = new Batch.Hold();
@@ -1004,7 +1013,7 @@ var LoginDialog = GObject.registerClass({
});
GLib.Source.set_name_by_id(this._timedLoginIdleTimeOutId, '[gnome-shell] this._timedLoginIdleTimeOutId');
return hold;
}
},
_startTimedLogin(userName, delay) {
let firstRun = true;
@@ -1077,7 +1086,7 @@ var LoginDialog = GObject.registerClass({
this._timedLoginBatch = new Batch.ConsecutiveBatch(this, tasks);
return this._timedLoginBatch.run();
}
},
_onTimedLoginRequested(client, userName, seconds) {
if (this._timedLoginBatch)
@@ -1094,28 +1103,28 @@ var LoginDialog = GObject.registerClass({
return Clutter.EVENT_PROPAGATE;
});
}
},
_setUserListExpanded(expanded) {
this._userList.updateStyle(expanded);
this._userSelectionBox.visible = expanded;
}
},
_hideUserList() {
this._setUserListExpanded(false);
if (this._userSelectionBox.visible)
GdmUtil.cloneAndFadeOutActor(this._userSelectionBox);
}
},
_hideUserListAskForUsernameAndBeginVerification() {
this._hideUserList();
this._askForUsernameAndBeginVerification();
}
},
_hideUserListAndBeginVerification() {
this._hideUserList();
this._authPrompt.begin();
}
},
_showUserList() {
this._ensureUserListLoaded();
@@ -1125,7 +1134,7 @@ var LoginDialog = GObject.registerClass({
this._setUserListExpanded(true);
this._notListedButton.show();
this._userList.actor.grab_key_focus();
}
},
_beginVerificationForItem(item) {
this._authPrompt.setUser(item.user);
@@ -1136,7 +1145,7 @@ var LoginDialog = GObject.registerClass({
this._authPrompt.begin({ userName: userName,
hold: hold });
return hold;
}
},
_onUserListActivated(activatedItem) {
this._user = activatedItem.user;
@@ -1146,7 +1155,7 @@ var LoginDialog = GObject.registerClass({
let batch = new Batch.ConcurrentBatch(this, [GdmUtil.cloneAndFadeOutActor(this._userSelectionBox),
this._beginVerificationForItem(activatedItem)]);
batch.run();
}
},
_onDestroy() {
if (this._userManagerLoadedId) {
@@ -1187,7 +1196,7 @@ var LoginDialog = GObject.registerClass({
this._realmManager.release();
this._realmManager = null;
}
}
},
_loadUserList() {
if (this._userListLoaded)
@@ -1225,7 +1234,7 @@ var LoginDialog = GObject.registerClass({
});
return GLib.SOURCE_REMOVE;
}
},
open() {
Main.ctrlAltTabManager.addGroup(this,
@@ -1244,22 +1253,22 @@ var LoginDialog = GObject.registerClass({
transition: 'easeInQuad' });
return true;
}
},
close() {
Main.popModal(this);
Main.ctrlAltTabManager.removeGroup(this);
}
},
cancel() {
this._authPrompt.cancel();
}
},
addCharacter(unichar) {
// Don't allow type ahead at the login screen
}
},
finish(onComplete) {
this._authPrompt.finish(onComplete);
}
},
});

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Signals = imports.signals;
const OVirtCredentialsIface = `
@@ -27,32 +28,33 @@ function OVirtCredentials() {
return self;
}
var OVirtCredentialsManager = class {
constructor() {
var OVirtCredentialsManager = new Lang.Class({
Name: 'OVirtCredentialsManager',
_init() {
this._token = null;
this._credentials = new OVirtCredentials();
this._credentials.connectSignal('UserAuthenticated',
this._onUserAuthenticated.bind(this));
}
},
_onUserAuthenticated(proxy, sender, [token]) {
this._token = token;
this.emit('user-authenticated', token);
}
},
hasToken() {
return this._token != null;
}
},
getToken() {
return this._token;
}
},
resetToken() {
this._token = null;
}
};
});
Signals.addSignalMethods(OVirtCredentialsManager.prototype);
function getOVirtCredentialsManager() {

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@@ -15,8 +16,10 @@ const Service = Gio.DBusProxy.makeProxyWrapper(ServiceIface);
const RealmIface = loadInterfaceXML("org.freedesktop.realmd.Realm");
const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface);
var Manager = class {
constructor(parentActor) {
var Manager = new Lang.Class({
Name: 'Manager',
_init(parentActor) {
this._aggregateProvider = Provider(Gio.DBus.system,
'org.freedesktop.realmd',
'/org/freedesktop/realmd',
@@ -28,7 +31,7 @@ var Manager = class {
if ('Realms' in properties.deep_unpack())
this._reloadRealms();
});
}
},
_reloadRealms() {
let realmPaths = this._aggregateProvider.Realms;
@@ -42,7 +45,7 @@ var Manager = class {
realmPaths[i],
this._onRealmLoaded.bind(this));
}
}
},
_reloadRealm(realm) {
if (!realm.Configured) {
@@ -55,7 +58,7 @@ var Manager = class {
this._realms[realm.get_object_path()] = realm;
this._updateLoginFormat();
}
},
_onRealmLoaded(realm, error) {
if (error)
@@ -67,7 +70,7 @@ var Manager = class {
if ('Configured' in properties.deep_unpack())
this._reloadRealm(realm);
});
}
},
_updateLoginFormat() {
let newLoginFormat;
@@ -84,7 +87,7 @@ var Manager = class {
this._loginFormat = newLoginFormat;
this.emit('login-format-changed', newLoginFormat);
}
}
},
get loginFormat() {
if (this._loginFormat !== undefined)
@@ -93,7 +96,7 @@ var Manager = class {
this._updateLoginFormat();
return this._loginFormat;
}
},
release() {
Service(Gio.DBus.system,
@@ -104,5 +107,5 @@ var Manager = class {
this._realms = { };
this._updateLoginFormat();
}
};
});
Signals.addSignalMethods(Manager.prototype)

View File

@@ -3,6 +3,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
const St = imports.gi.St;
@@ -118,8 +119,10 @@ function cloneAndFadeOutActor(actor) {
return hold;
}
var ShellUserVerifier = class {
constructor(client, params) {
var ShellUserVerifier = new Lang.Class({
Name: 'ShellUserVerifier',
_init(client, params) {
params = Params.parse(params, { reauthenticationOnly: false });
this._reauthOnly = params.reauthenticationOnly;
@@ -162,7 +165,7 @@ var ShellUserVerifier = class {
this._oVirtUserAuthenticatedId = this._oVirtCredentialsManager.connect('user-authenticated',
this._oVirtUserAuthenticated.bind(this));
}
},
begin(userName, hold) {
this._cancellable = new Gio.Cancellable();
@@ -180,7 +183,7 @@ var ShellUserVerifier = class {
} else {
this._client.get_user_verifier(this._cancellable, this._userVerifierGot.bind(this));
}
}
},
cancel() {
if (this._cancellable)
@@ -190,14 +193,14 @@ var ShellUserVerifier = class {
this._userVerifier.call_cancel_sync(null);
this.clear();
}
}
},
_clearUserVerifier() {
if (this._userVerifier) {
this._userVerifier.run_dispose();
this._userVerifier = null;
}
}
},
clear() {
if (this._cancellable) {
@@ -207,7 +210,7 @@ var ShellUserVerifier = class {
this._clearUserVerifier();
this._clearMessageQueue();
}
},
destroy() {
this.clear();
@@ -221,7 +224,7 @@ var ShellUserVerifier = class {
this._oVirtCredentialsManager.disconnect(this._oVirtUserAuthenticatedId);
this._oVirtCredentialsManager = null;
}
},
answerQuery(serviceName, answer) {
if (!this.hasPendingMessages) {
@@ -232,12 +235,12 @@ var ShellUserVerifier = class {
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
});
}
}
},
_getIntervalForMessage(message) {
// We probably could be smarter here
return message.length * USER_READ_TIME;
}
},
finishMessageQueue() {
if (!this.hasPendingMessages)
@@ -247,7 +250,7 @@ var ShellUserVerifier = class {
this.hasPendingMessages = false;
this.emit('no-more-messages');
}
},
_queueMessageTimeout() {
if (this._messageQueue.length == 0) {
@@ -270,7 +273,7 @@ var ShellUserVerifier = class {
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._messageQueueTimeoutId, '[gnome-shell] this._queueMessageTimeout');
}
},
_queueMessage(message, messageType) {
let interval = this._getIntervalForMessage(message);
@@ -278,7 +281,7 @@ var ShellUserVerifier = class {
this.hasPendingMessages = true;
this._messageQueue.push({ text: message, type: messageType, interval: interval });
this._queueMessageTimeout();
}
},
_clearMessageQueue() {
this.finishMessageQueue();
@@ -288,7 +291,7 @@ var ShellUserVerifier = class {
this._messageQueueTimeoutId = 0;
}
this.emit('show-message', null, MessageType.NONE);
}
},
_checkForFingerprintReader() {
this._haveFingerprintReader = false;
@@ -306,12 +309,12 @@ var ShellUserVerifier = class {
this._updateDefaultService();
}
});
}
},
_oVirtUserAuthenticated(token) {
this._preemptingService = OVIRT_SERVICE_NAME;
this.emit('ovirt-user-authenticated');
}
},
_checkForSmartcard() {
let smartcardDetected;
@@ -333,7 +336,7 @@ var ShellUserVerifier = class {
this.emit('smartcard-status-changed');
}
}
},
_reportInitError(where, error) {
logError(error, where);
@@ -341,7 +344,7 @@ var ShellUserVerifier = class {
this._queueMessage(_("Authentication error"), MessageType.ERROR);
this._verificationFailed(false);
}
},
_reauthenticationChannelOpened(client, result) {
try {
@@ -368,7 +371,7 @@ var ShellUserVerifier = class {
this._connectSignals();
this._beginVerification();
this._hold.release();
}
},
_userVerifierGot(client, result) {
try {
@@ -384,7 +387,7 @@ var ShellUserVerifier = class {
this._connectSignals();
this._beginVerification();
this._hold.release();
}
},
_connectSignals() {
this._userVerifier.connect('info', this._onInfo.bind(this));
@@ -394,22 +397,22 @@ var ShellUserVerifier = class {
this._userVerifier.connect('conversation-stopped', this._onConversationStopped.bind(this));
this._userVerifier.connect('reset', this._onReset.bind(this));
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
}
},
_getForegroundService() {
if (this._preemptingService)
return this._preemptingService;
return this._defaultService;
}
},
serviceIsForeground(serviceName) {
return serviceName == this._getForegroundService();
}
},
serviceIsDefault(serviceName) {
return serviceName == this._defaultService;
}
},
_updateDefaultService() {
if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY))
@@ -423,7 +426,7 @@ var ShellUserVerifier = class {
log("no authentication service is enabled, using password authentication");
this._defaultService = PASSWORD_SERVICE_NAME;
}
}
},
_startService(serviceName) {
this._hold.acquire();
@@ -459,14 +462,14 @@ var ShellUserVerifier = class {
this._hold.release();
});
}
}
},
_beginVerification() {
this._startService(this._getForegroundService());
if (this._userName && this._haveFingerprintReader && !this.serviceIsForeground(FINGERPRINT_SERVICE_NAME))
this._startService(FINGERPRINT_SERVICE_NAME);
}
},
_onInfo(client, serviceName, info) {
if (this.serviceIsForeground(serviceName)) {
@@ -481,21 +484,21 @@ var ShellUserVerifier = class {
// to indicate the user can swipe their finger instead
this._queueMessage(_("(or swipe finger)"), MessageType.HINT);
}
}
},
_onProblem(client, serviceName, problem) {
if (!this.serviceIsForeground(serviceName))
return;
this._queueMessage(problem, MessageType.ERROR);
}
},
_onInfoQuery(client, serviceName, question) {
if (!this.serviceIsForeground(serviceName))
return;
this.emit('ask-question', serviceName, question, '');
}
},
_onSecretInfoQuery(client, serviceName, secretQuestion) {
if (!this.serviceIsForeground(serviceName))
@@ -508,7 +511,7 @@ var ShellUserVerifier = class {
}
this.emit('ask-question', serviceName, secretQuestion, '\u25cf');
}
},
_onReset() {
// Clear previous attempts to authenticate
@@ -516,20 +519,20 @@ var ShellUserVerifier = class {
this._updateDefaultService();
this.emit('reset');
}
},
_onVerificationComplete() {
this.emit('verification-complete');
}
},
_cancelAndReset() {
this.cancel();
this._onReset();
}
},
_retry() {
this.begin(this._userName, new Batch.Hold());
}
},
_verificationFailed(retry) {
// For Not Listed / enterprise logins, immediately reset
@@ -564,7 +567,7 @@ var ShellUserVerifier = class {
}
this.emit('verification-failed', canRetry);
}
},
_onConversationStopped(client, serviceName) {
// If the login failed with the preauthenticated oVirt credentials
@@ -583,6 +586,6 @@ var ShellUserVerifier = class {
if (this.serviceIsForeground(serviceName)) {
this._verificationFailed(true);
}
}
};
},
});
Signals.addSignalMethods(ShellUserVerifier.prototype);

View File

@@ -16,7 +16,6 @@
<file>misc/history.js</file>
<file>misc/ibusManager.js</file>
<file>misc/inputMethod.js</file>
<file>misc/introspect.js</file>
<file>misc/jsParse.js</file>
<file>misc/keyboardManager.js</file>
<file>misc/loginManager.js</file>
@@ -82,6 +81,7 @@
<file>ui/panelMenu.js</file>
<file>ui/pointerWatcher.js</file>
<file>ui/popupMenu.js</file>
<file>ui/remoteMenu.js</file>
<file>ui/remoteSearch.js</file>
<file>ui/runDialog.js</file>
<file>ui/screenShield.js</file>

View File

@@ -3,6 +3,7 @@
// Common utils for the extension system and the extension
// preferences tool
const Lang = imports.lang;
const Signals = imports.signals;
const Gio = imports.gi.Gio;
@@ -159,7 +160,9 @@ function installImporter(extension) {
imports.searchPath = oldSearchPath;
}
var ExtensionFinder = class {
var ExtensionFinder = new Lang.Class({
Name: 'ExtensionFinder',
_loadExtension(extensionDir, info, perUserDir) {
let fileType = info.get_file_type();
if (fileType != Gio.FileType.DIRECTORY)
@@ -181,7 +184,7 @@ var ExtensionFinder = class {
return;
}
this.emit('extension-found', extension);
}
},
scanExtensions() {
let perUserDir = Gio.File.new_for_path(global.userdatadir);
@@ -189,5 +192,5 @@ var ExtensionFinder = class {
this._loadExtension(dir, info, perUserDir);
});
}
};
});
Signals.addSignalMethods(ExtensionFinder.prototype);

View File

@@ -2,6 +2,7 @@
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Config = imports.misc.config;
const Params = imports.misc.params;

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Signals = imports.signals;
const { loadInterfaceXML } = imports.misc.fileUtils;

View File

@@ -1,13 +1,16 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Signals = imports.signals;
const Clutter = imports.gi.Clutter;
const Params = imports.misc.params;
var DEFAULT_LIMIT = 512;
var HistoryManager = class {
constructor(params) {
var HistoryManager = new Lang.Class({
Name: 'HistoryManager',
_init(params) {
params = Params.parse(params, { gsettingsKey: null,
limit: DEFAULT_LIMIT,
entry: null });
@@ -31,12 +34,12 @@ var HistoryManager = class {
this._entry.connect('key-press-event',
this._onEntryKeyPress.bind(this));
}
}
},
_historyChanged() {
this._history = global.settings.get_strv(this._key);
this._historyIndex = this._history.length;
}
},
_setPrevItem(text) {
if (this._historyIndex <= 0)
@@ -47,7 +50,7 @@ var HistoryManager = class {
this._historyIndex--;
this._indexChanged();
return true;
}
},
_setNextItem(text) {
if (this._historyIndex >= this._history.length)
@@ -58,7 +61,7 @@ var HistoryManager = class {
this._historyIndex++;
this._indexChanged();
return true;
}
},
lastItem() {
if (this._historyIndex != this._history.length) {
@@ -67,7 +70,7 @@ var HistoryManager = class {
}
return this._historyIndex ? this._history[this._historyIndex -1] : null;
}
},
addItem(input) {
if (this._history.length == 0 ||
@@ -78,7 +81,7 @@ var HistoryManager = class {
this._save();
}
this._historyIndex = this._history.length;
}
},
_onEntryKeyPress(entry, event) {
let symbol = event.get_key_symbol();
@@ -88,7 +91,7 @@ var HistoryManager = class {
return this._setNextItem(entry.get_text());
}
return Clutter.EVENT_PROPAGATE;
}
},
_indexChanged() {
let current = this._history[this._historyIndex] || '';
@@ -96,7 +99,7 @@ var HistoryManager = class {
if (this._entry)
this._entry.set_text(current);
}
},
_save() {
if (this._history.length > this._limit)
@@ -105,5 +108,5 @@ var HistoryManager = class {
if (this._key)
global.settings.set_strv(this._key, this._history);
}
};
});
Signals.addSignalMethods(HistoryManager.prototype);

View File

@@ -2,6 +2,7 @@
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
@@ -31,16 +32,17 @@ function getIBusManager() {
return _ibusManager;
}
var IBusManager = class {
constructor() {
var IBusManager = new Lang.Class({
Name: 'IBusManager',
// This is the longest we'll keep the keyboard frozen until an input
// source is active.
_MAX_INPUT_SOURCE_ACTIVATION_TIME: 4000, // ms
_PRELOAD_ENGINES_DELAY_TIME: 30, // sec
_init() {
IBus.init();
// This is the longest we'll keep the keyboard frozen until an input
// source is active.
this._MAX_INPUT_SOURCE_ACTIVATION_TIME = 4000; // ms
this._PRELOAD_ENGINES_DELAY_TIME = 30; // sec
this._candidatePopup = new IBusCandidatePopup.CandidatePopup();
this._panelService = null;
@@ -58,7 +60,7 @@ var IBusManager = class {
this._ibus.connect('global-engine-changed', this._engineChanged.bind(this));
this._spawn();
}
},
_spawn() {
try {
@@ -67,7 +69,7 @@ var IBusManager = class {
} catch(e) {
log('Failed to launch ibus-daemon: ' + e.message);
}
}
},
_clear() {
if (this._panelService)
@@ -83,7 +85,7 @@ var IBusManager = class {
this.emit('ready', false);
this._spawn();
}
},
_onConnected() {
this._ibus.list_engines_async(-1, null, this._initEngines.bind(this));
@@ -91,7 +93,7 @@ var IBusManager = class {
IBus.BusNameFlag.REPLACE_EXISTING,
-1, null,
this._initPanelService.bind(this));
}
},
_initEngines(ibus, result) {
let enginesList = this._ibus.list_engines_async_finish(result);
@@ -104,7 +106,7 @@ var IBusManager = class {
} else {
this._clear();
}
}
},
_initPanelService(ibus, result) {
let success = this._ibus.request_name_async_finish(result);
@@ -149,13 +151,13 @@ var IBusManager = class {
} else {
this._clear();
}
}
},
_updateReadiness() {
this._ready = (Object.keys(this._engines).length > 0 &&
this._panelService != null);
this.emit('ready', this._ready);
}
},
_engineChanged(bus, engineName) {
if (!this._ready)
@@ -176,26 +178,26 @@ var IBusManager = class {
this.emit('properties-registered', this._currentEngineName, props);
});
}
},
_updateProperty(panel, prop) {
this.emit('property-updated', this._currentEngineName, prop);
}
},
_setContentType(panel, purpose, hints) {
this.emit('set-content-type', purpose, hints);
}
},
activateProperty(key, state) {
this._panelService.property_activate(key, state);
}
},
getEngineDesc(id) {
if (!this._ready || !this._engines.hasOwnProperty(id))
return null;
return this._engines[id];
}
},
setEngine(id, callback) {
// Send id even if id == this._currentEngineName
@@ -209,7 +211,7 @@ var IBusManager = class {
this._ibus.set_global_engine_async(id, this._MAX_INPUT_SOURCE_ACTIVATION_TIME,
null, callback || null);
}
},
preloadEngines(ids) {
if (!this._ibus || ids.length == 0)
@@ -231,6 +233,6 @@ var IBusManager = class {
this._preloadEnginesId = 0;
return GLib.SOURCE_REMOVE;
});
}
};
},
});
Signals.addSignalMethods(IBusManager.prototype);

View File

@@ -1,16 +1,19 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GObject = imports.gi.GObject;
const IBus = imports.gi.IBus;
const Keyboard = imports.ui.status.keyboard;
const Lang = imports.lang;
const Signals = imports.signals;
var InputMethod = GObject.registerClass(
class InputMethod extends Clutter.InputMethod {
var InputMethod = new Lang.Class({
Name: 'InputMethod',
Extends: Clutter.InputMethod,
_init() {
super._init();
this.parent();
this._hints = 0;
this._purpose = 0;
this._enabled = true;
this._currentFocus = null;
this._preeditStr = '';
this._preeditPos = 0;
@@ -27,11 +30,11 @@ class InputMethod extends Clutter.InputMethod {
if (this._ibus.is_connected())
this._onConnected();
}
},
get currentFocus() {
return this._currentFocus;
}
},
_updateCapabilities() {
let caps = 0;
@@ -46,19 +49,21 @@ class InputMethod extends Clutter.InputMethod {
if (this._context)
this._context.set_capabilities(caps);
}
},
_onSourceChanged() {
this._currentSource = this._inputSourceManager.currentSource;
}
},
_onConnected() {
this._ibus.create_input_context_async ('gnome-shell', -1, null,
this._setContext.bind(this));
}
},
_setContext(bus, res) {
this._context = this._ibus.create_input_context_async_finish(res);
this._context.connect('enabled', () => { this._enabled = true });
this._context.connect('disabled', () => { this._enabled = false });
this._context.connect('commit-text', this._onCommitText.bind(this));
this._context.connect('delete-surrounding-text', this._onDeleteSurroundingText.bind(this));
this._context.connect('update-preedit-text', this._onUpdatePreeditText.bind(this));
@@ -67,29 +72,30 @@ class InputMethod extends Clutter.InputMethod {
this._context.connect('forward-key-event', this._onForwardKeyEvent.bind(this));
this._updateCapabilities();
}
},
_clear() {
this._context = null;
this._hints = 0;
this._purpose = 0;
this._enabled = false;
this._preeditStr = ''
this._preeditPos = 0;
this._preeditVisible = false;
}
},
_emitRequestSurrounding() {
if (this._context.needs_surrounding_text())
this.emit('request-surrounding');
}
},
_onCommitText(context, text) {
this.commit(text.get_text());
}
},
_onDeleteSurroundingText(context) {
this.delete_surrounding();
}
},
_onUpdatePreeditText(context, text, pos, visible) {
if (text == null)
@@ -105,17 +111,17 @@ class InputMethod extends Clutter.InputMethod {
this._preeditStr = preedit;
this._preeditPos = pos;
this._preeditVisible = visible;
}
},
_onShowPreeditText(context) {
this._preeditVisible = true;
this.set_preedit_text(this._preeditStr, this._preeditPos);
}
},
_onHidePreeditText(context) {
this.set_preedit_text(null, this._preeditPos);
this._preeditVisible = false;
}
},
_onForwardKeyEvent(context, keyval, keycode, state) {
let press = (state & IBus.ModifierType.RELEASE_MASK) == 0;
@@ -129,7 +135,7 @@ class InputMethod extends Clutter.InputMethod {
time = global.display.get_current_time_roundtrip();
this.forward_key(keyval, keycode + 8, state & Clutter.ModifierType.MODIFIER_MASK, time, press);
}
},
vfunc_focus_in(focus) {
this._currentFocus = focus;
@@ -138,7 +144,7 @@ class InputMethod extends Clutter.InputMethod {
this._updateCapabilities();
this._emitRequestSurrounding();
}
}
},
vfunc_focus_out() {
this._currentFocus = null;
@@ -152,7 +158,7 @@ class InputMethod extends Clutter.InputMethod {
this.set_preedit_text(null, 0);
this._preeditStr = null;
}
}
},
vfunc_reset() {
if (this._context) {
@@ -165,7 +171,7 @@ class InputMethod extends Clutter.InputMethod {
this.set_preedit_text(null, 0);
this._preeditStr = null;
}
}
},
vfunc_set_cursor_location(rect) {
if (this._context) {
@@ -173,7 +179,7 @@ class InputMethod extends Clutter.InputMethod {
rect.get_width(), rect.get_height());
this._emitRequestSurrounding();
}
}
},
vfunc_set_surrounding(text, cursor, anchor) {
if (!this._context || !text)
@@ -181,7 +187,7 @@ class InputMethod extends Clutter.InputMethod {
let ibusText = IBus.Text.new_from_string(text);
this._context.set_surrounding_text(ibusText, cursor, anchor);
}
},
vfunc_update_content_hints(hints) {
let ibusHints = 0;
@@ -201,7 +207,7 @@ class InputMethod extends Clutter.InputMethod {
this._hints = ibusHints;
if (this._context)
this._context.set_content_type(this._purpose, this._hints);
}
},
vfunc_update_content_purpose(purpose) {
let ibusPurpose = 0;
@@ -227,10 +233,10 @@ class InputMethod extends Clutter.InputMethod {
this._purpose = ibusPurpose;
if (this._context)
this._context.set_content_type(this._purpose, this._hints);
}
},
vfunc_filter_key_event(event) {
if (!this._context)
if (!this._context || !this._enabled)
return false;
if (!this._currentSource)
return false;
@@ -254,5 +260,5 @@ class InputMethod extends Clutter.InputMethod {
}
});
return true;
}
},
});

View File

@@ -1,163 +0,0 @@
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const INTROSPECT_SCHEMA = 'org.gnome.shell';
const INTROSPECT_KEY = 'introspect';
const APP_WHITELIST = ['org.freedesktop.impl.portal.desktop.gtk'];
const { loadInterfaceXML } = imports.misc.fileUtils;
const IntrospectDBusIface = loadInterfaceXML('org.gnome.Shell.Introspect');
var IntrospectService = class {
constructor() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(IntrospectDBusIface,
this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Introspect');
Gio.DBus.session.own_name('org.gnome.Shell.Introspect',
Gio.BusNameOwnerFlags.REPLACE,
null, null);
this._runningApplications = {};
this._runningApplicationsDirty = true;
this._activeApplication = null;
this._activeApplicationDirty = true;
this._appSystem = Shell.AppSystem.get_default();
this._appSystem.connect('app-state-changed',
() => {
this._runningApplicationsDirty = true;
this._syncRunningApplications();
});
this._settings = new Gio.Settings({ schema_id: INTROSPECT_SCHEMA });
let tracker = Shell.WindowTracker.get_default();
tracker.connect('notify::focus-app',
() => {
this._activeApplicationDirty = true;
this._syncRunningApplications();
});
this._syncRunningApplications();
}
_isStandaloneApp(app) {
let windows = app.get_windows();
return app.get_windows().some(w => w.transient_for == null);
}
_isIntrospectEnabled() {
return this._settings.get_boolean(INTROSPECT_KEY);
}
_isSenderWhitelisted(sender) {
return APP_WHITELIST.includes(sender);
}
_syncRunningApplications() {
let tracker = Shell.WindowTracker.get_default();
let apps = this._appSystem.get_running();
let seatName = "seat0";
let newRunningApplications = {};
let newActiveApplication = null;
let focusedApp = tracker.focus_app;
for (let app of apps) {
let appInfo = {};
let isAppActive = (focusedApp == app);
if (!this._isStandaloneApp(app))
continue;
if (isAppActive) {
appInfo['active-on-seats'] = new GLib.Variant('as', [seatName]);
newActiveApplication = app.get_id();
}
newRunningApplications[app.get_id()] = appInfo;
}
if (this._runningApplicationsDirty ||
(this._activeApplicationDirty &&
this._activeApplication != newActiveApplication)) {
this._runningApplications = newRunningApplications;
this._activeApplication = newActiveApplication;
this._dbusImpl.emit_signal('RunningApplicationsChanged', null);
}
this._runningApplicationsDirty = false;
this._activeApplicationDirty = false;
}
_isEligibleWindow(window) {
if (window.is_override_redirect())
return false;
let type = window.get_window_type();
return (type == Meta.WindowType.NORMAL ||
type == Meta.WindowType.DIALOG ||
type == Meta.WindowType.MODAL_DIALOG ||
type == Meta.WindowType.UTILITY);
}
GetRunningApplicationsAsync(params, invocation) {
if (!this._isIntrospectEnabled() &&
!this._isSenderWhitelisted(invocation.get_sender())) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'App introspection not allowed');
return;
}
invocation.return_value(new GLib.Variant('(a{sa{sv}})', [this._runningApplications]));
}
GetWindowsAsync(params, invocation) {
let focusWindow = global.display.get_focus_window();
let apps = this._appSystem.get_running();
let windowsList = {};
if (!this._isIntrospectEnabled()) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'App introspection not allowed');
return;
}
for (let app of apps) {
let windows = app.get_windows();
for (let window of windows) {
if (!this._isEligibleWindow(window))
continue;
let windowId = window.get_id();
let frameRect = window.get_frame_rect();
let title = window.get_title();
let wmClass = window.get_wm_class();
windowsList[windowId] = {
'app-id': GLib.Variant.new('s', app.get_id()),
'client-type': GLib.Variant.new('u', window.get_client_type()),
'is-hidden': GLib.Variant.new('b', window.is_hidden()),
'has-focus': GLib.Variant.new('b', (window == focusWindow)),
'width': GLib.Variant.new('u', frameRect.width),
'height': GLib.Variant.new('u', frameRect.height)
};
// These properties may not be available for all windows:
if (title != null)
windowsList[windowId]['title'] = GLib.Variant.new('s', title);
if (wmClass != null)
windowsList[windowId]['wm-class'] = GLib.Variant.new('s', wmClass);
}
}
invocation.return_value(new GLib.Variant('(a{ta{sv}})', [windowsList]));
}
};

View File

@@ -2,6 +2,7 @@
const GLib = imports.gi.GLib;
const GnomeDesktop = imports.gi.GnomeDesktop;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Main = imports.ui.main;
@@ -37,20 +38,22 @@ function holdKeyboard() {
global.display.freeze_keyboard(global.get_current_time());
}
var KeyboardManager = class {
constructor() {
// The XKB protocol doesn't allow for more that 4 layouts in a
// keymap. Wayland doesn't impose this limit and libxkbcommon can
// handle up to 32 layouts but since we need to support X clients
// even as a Wayland compositor, we can't bump this.
this.MAX_LAYOUTS_PER_GROUP = 4;
var KeyboardManager = new Lang.Class({
Name: 'KeyboardManager',
// The XKB protocol doesn't allow for more that 4 layouts in a
// keymap. Wayland doesn't impose this limit and libxkbcommon can
// handle up to 32 layouts but since we need to support X clients
// even as a Wayland compositor, we can't bump this.
MAX_LAYOUTS_PER_GROUP: 4,
_init() {
this._xkbInfo = getXkbInfo();
this._current = null;
this._localeLayoutInfo = this._getLocaleLayout();
this._layoutInfos = {};
this._currentKeymap = null;
}
},
_applyLayoutGroup(group) {
let options = this._buildOptionsString();
@@ -64,11 +67,11 @@ var KeyboardManager = class {
this._currentKeymap = {layouts, variants, options};
Meta.get_backend().set_keymap(layouts, variants, options);
}
},
_applyLayoutGroupIndex(idx) {
Meta.get_backend().lock_layout_group(idx);
}
},
apply(id) {
let info = this._layoutInfos[id];
@@ -84,7 +87,7 @@ var KeyboardManager = class {
}
this._current = info;
}
},
reapply() {
if (!this._current)
@@ -92,7 +95,7 @@ var KeyboardManager = class {
this._applyLayoutGroup(this._current.group);
this._applyLayoutGroupIndex(this._current.groupIndex);
}
},
setUserLayouts(ids) {
this._current = null;
@@ -123,7 +126,7 @@ var KeyboardManager = class {
i += 1;
}
}
},
_getLocaleLayout() {
let locale = GLib.get_language_names()[0];
@@ -140,21 +143,21 @@ var KeyboardManager = class {
return { layout: _layout, variant: _variant };
else
return { layout: DEFAULT_LAYOUT, variant: DEFAULT_VARIANT };
}
},
_buildGroupStrings(_group) {
let group = _group.concat(this._localeLayoutInfo);
let layouts = group.map(g => g.layout).join(',');
let variants = group.map(g => g.variant).join(',');
return [layouts, variants];
}
},
setKeyboardOptions(options) {
this._xkbOptions = options;
}
},
_buildOptionsString() {
let options = this._xkbOptions.join(',');
return options;
}
};
});

View File

@@ -2,6 +2,7 @@
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@@ -69,8 +70,10 @@ function getLoginManager() {
return _loginManager;
}
var LoginManagerSystemd = class {
constructor() {
var LoginManagerSystemd = new Lang.Class({
Name: 'LoginManagerSystemd',
_init() {
this._proxy = new SystemdLoginManager(Gio.DBus.system,
'org.freedesktop.login1',
'/org/freedesktop/login1');
@@ -79,7 +82,7 @@ var LoginManagerSystemd = class {
'/org/freedesktop/login1/user/self');
this._proxy.connectSignal('PrepareForSleep',
this._prepareForSleep.bind(this));
}
},
getCurrentSessionProxy(callback) {
if (this._currentSession) {
@@ -126,7 +129,7 @@ var LoginManagerSystemd = class {
callback(this._currentSession);
}
});
}
},
canSuspend(asyncCallback) {
this._proxy.CanSuspendRemote((result, error) => {
@@ -138,7 +141,7 @@ var LoginManagerSystemd = class {
asyncCallback(canSuspend, needsAuth);
}
});
}
},
listSessions(asyncCallback) {
this._proxy.ListSessionsRemote((result, error) => {
@@ -147,11 +150,11 @@ var LoginManagerSystemd = class {
else
asyncCallback(result[0]);
});
}
},
suspend() {
this._proxy.SuspendRemote(true);
}
},
inhibit(reason, callback) {
let inVariant = GLib.Variant.new('(ssss)',
@@ -171,36 +174,38 @@ var LoginManagerSystemd = class {
callback(null);
}
});
}
},
_prepareForSleep(proxy, sender, [aboutToSuspend]) {
this.emit('prepare-for-sleep', aboutToSuspend);
}
};
});
Signals.addSignalMethods(LoginManagerSystemd.prototype);
var LoginManagerDummy = class {
var LoginManagerDummy = new Lang.Class({
Name: 'LoginManagerDummy',
getCurrentSessionProxy(callback) {
// we could return a DummySession object that fakes whatever callers
// expect (at the time of writing: connect() and connectSignal()
// methods), but just never calling the callback should be safer
}
},
canSuspend(asyncCallback) {
asyncCallback(false, false);
}
},
listSessions(asyncCallback) {
asyncCallback([]);
}
},
suspend() {
this.emit('prepare-for-sleep', true);
this.emit('prepare-for-sleep', false);
}
},
inhibit(reason, callback) {
callback(null);
}
};
});
Signals.addSignalMethods(LoginManagerDummy.prototype);

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const NMA = imports.gi.NMA;
const Signals = imports.signals;
@@ -99,8 +100,10 @@ const ModemGsmNetworkProxy = Gio.DBusProxy.makeProxyWrapper(ModemGsmNetworkInter
const ModemCdmaInterface = loadInterfaceXML('org.freedesktop.ModemManager.Modem.Cdma');
const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface);
var ModemGsm = class {
constructor(path) {
var ModemGsm = new Lang.Class({
Name: 'ModemGsm',
_init(path) {
this._proxy = new ModemGsmNetworkProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
this.signal_quality = 0;
@@ -136,11 +139,13 @@ var ModemGsm = class {
this.emit('notify::signal-quality');
});
}
};
});
Signals.addSignalMethods(ModemGsm.prototype);
var ModemCdma = class {
constructor(path) {
var ModemCdma = new Lang.Class({
Name: 'ModemCdma',
_init(path) {
this._proxy = new ModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
this.signal_quality = 0;
@@ -164,7 +169,7 @@ var ModemCdma = class {
}
this.emit('notify::signal-quality');
});
}
},
_refreshServingSystem() {
this._proxy.GetServingSystemRemote(([result], err) => {
@@ -179,7 +184,7 @@ var ModemCdma = class {
this.emit('notify::operator-name');
});
}
};
});
Signals.addSignalMethods(ModemCdma.prototype);
@@ -196,8 +201,10 @@ const BroadbandModem3gppProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModem3gp
const BroadbandModemCdmaInterface = loadInterfaceXML('org.freedesktop.ModemManager1.Modem.ModemCdma');
const BroadbandModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemCdmaInterface);
var BroadbandModem = class {
constructor(path, capabilities) {
var BroadbandModem = new Lang.Class({
Name: 'BroadbandModem',
_init(path, capabilities) {
this._proxy = new BroadbandModemProxy(Gio.DBus.system, 'org.freedesktop.ModemManager1', path);
this._proxy_3gpp = new BroadbandModem3gppProxy(Gio.DBus.system, 'org.freedesktop.ModemManager1', path);
this._proxy_cdma = new BroadbandModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager1', path);
@@ -222,13 +229,13 @@ var BroadbandModem = class {
this._reloadCdmaOperatorName();
});
this._reloadCdmaOperatorName();
}
},
_reloadSignalQuality() {
let [quality, recent] = this._proxy.SignalQuality;
this.signal_quality = quality;
this.emit('notify::signal-quality');
}
},
_reloadOperatorName() {
let new_name = "";
@@ -243,19 +250,19 @@ var BroadbandModem = class {
this.operator_name = new_name;
this.emit('notify::operator-name');
}
},
_reload3gppOperatorName() {
let name = this._proxy_3gpp.OperatorName;
let code = this._proxy_3gpp.OperatorCode;
this.operator_name_3gpp = _findProviderForMccMnc(name, code);
this._reloadOperatorName();
}
},
_reloadCdmaOperatorName() {
let sid = this._proxy_cdma.Sid;
this.operator_name_cdma = _findProviderForSid(sid);
this._reloadOperatorName();
}
};
});
Signals.addSignalMethods(BroadbandModem.prototype);

View File

@@ -2,6 +2,7 @@
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Params = imports.misc.params;
const Signals = imports.signals;
@@ -26,8 +27,9 @@ const ObjectManagerIface = `
const ObjectManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ObjectManagerIface);
var ObjectManager = class {
constructor(params) {
var ObjectManager = new Lang.Class({
Name: 'ObjectManager',
_init(params) {
params = Params.parse(params, { connection: null,
name: null,
objectPath: null,
@@ -61,7 +63,7 @@ var ObjectManager = class {
this._managerProxy.init_async(GLib.PRIORITY_DEFAULT,
this._cancellable,
this._onManagerProxyLoaded.bind(this));
}
},
_tryToCompleteLoad() {
if (this._numLoadInhibitors == 0)
@@ -72,7 +74,7 @@ var ObjectManager = class {
if (this._onLoaded)
this._onLoaded();
}
}
},
_addInterface(objectPath, interfaceName, onFinished) {
let info = this._interfaceInfos[interfaceName];
@@ -127,7 +129,7 @@ var ObjectManager = class {
if (onFinished)
onFinished();
});
}
},
_removeInterface(objectPath, interfaceName) {
if (!this._objects[objectPath])
@@ -153,7 +155,7 @@ var ObjectManager = class {
delete this._objects[objectPath];
this.emit('object-removed', objectPath);
}
}
},
_onManagerProxyLoaded(initable, result) {
let error = null;
@@ -192,7 +194,7 @@ var ObjectManager = class {
if (this._managerProxy.g_name_owner)
this._onNameAppeared();
}
},
_onNameAppeared() {
this._managerProxy.GetManagedObjectsRemote((result, error) => {
@@ -230,7 +232,7 @@ var ObjectManager = class {
}
this._tryToCompleteLoad();
});
}
},
_onNameVanished() {
let objectPaths = Object.keys(this._objects);
@@ -246,14 +248,14 @@ var ObjectManager = class {
this._removeInterface(objectPath, interfaceName);
}
}
}
},
_registerInterfaces(interfaces) {
for (let i = 0; i < interfaces.length; i++) {
let info = Gio.DBusInterfaceInfo.new_for_xml(interfaces[i]);
this._interfaceInfos[info.name] = info;
}
}
},
getProxy(objectPath, interfaceName) {
let object = this._objects[objectPath];
@@ -262,7 +264,7 @@ var ObjectManager = class {
return null;
return object[interfaceName];
}
},
getProxiesForInterface(interfaceName) {
let proxyList = this._interfaces[interfaceName];
@@ -271,7 +273,7 @@ var ObjectManager = class {
return [];
return proxyList;
}
},
getAllProxies() {
let proxies = [];
@@ -290,5 +292,5 @@ var ObjectManager = class {
return proxies;
}
};
});
Signals.addSignalMethods(ObjectManager.prototype);

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@@ -25,8 +26,9 @@ function getSmartcardManager() {
return _smartcardManager;
}
var SmartcardManager = class {
constructor() {
var SmartcardManager = new Lang.Class({
Name: 'SmartcardManager',
_init() {
this._objectManager = new ObjectManager.ObjectManager({ connection: Gio.DBus.session,
name: "org.gnome.SettingsDaemon.Smartcard",
objectPath: '/org/gnome/SettingsDaemon/Smartcard',
@@ -34,7 +36,7 @@ var SmartcardManager = class {
onLoaded: this._onLoaded.bind(this) });
this._insertedTokens = {};
this._loginToken = null;
}
},
_onLoaded() {
let tokens = this._objectManager.getProxiesForInterface('org.gnome.SettingsDaemon.Smartcard.Token');
@@ -51,7 +53,7 @@ var SmartcardManager = class {
if (interfaceName == 'org.gnome.SettingsDaemon.Smartcard.Token')
this._removeToken(proxy);
});
}
},
_updateToken(token) {
let objectPath = token.get_object_path();
@@ -63,7 +65,7 @@ var SmartcardManager = class {
if (token.UsedToLogin)
this._loginToken = token;
}
},
_addToken(token) {
this._updateToken(token);
@@ -83,7 +85,7 @@ var SmartcardManager = class {
// Emit a smartcard-inserted at startup if it's already plugged in
if (token.IsInserted)
this.emit('smartcard-inserted', token);
}
},
_removeToken(token) {
let objectPath = token.get_object_path();
@@ -97,11 +99,11 @@ var SmartcardManager = class {
this._loginToken = null;
token.disconnectAll();
}
},
hasInsertedTokens() {
return Object.keys(this._insertedTokens).length > 0;
}
},
hasInsertedLoginToken() {
if (!this._loginToken)
@@ -113,5 +115,5 @@ var SmartcardManager = class {
return true;
}
};
});
Signals.addSignalMethods(SmartcardManager.prototype);

View File

@@ -3,6 +3,7 @@ const Clutter = imports.gi.Clutter;
const Gdm = imports.gi.Gdm;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const GObject = imports.gi.GObject;
@@ -43,7 +44,9 @@ function getDefault() {
return _singleton;
}
const SystemActions = GObject.registerClass({
const SystemActions = new Lang.Class({
Name: 'SystemActions',
Extends: GObject.Object,
Properties: {
'can-power-off': GObject.ParamSpec.boolean('can-power-off',
'can-power-off',
@@ -80,10 +83,10 @@ const SystemActions = GObject.registerClass({
'orientation-lock-icon',
GObject.ParamFlags.READWRITE,
null)
}
}, class SystemActions extends GObject.Object {
},
_init() {
super._init();
this.parent();
this._canHavePowerOff = true;
this._canHaveSuspend = true;
@@ -183,35 +186,35 @@ const SystemActions = GObject.registerClass({
Main.sessionMode.connect('updated', () => { this._sessionUpdated(); });
this._sessionUpdated();
}
},
get can_power_off() {
return this._actions.get(POWER_OFF_ACTION_ID).available;
}
},
get can_suspend() {
return this._actions.get(SUSPEND_ACTION_ID).available;
}
},
get can_lock_screen() {
return this._actions.get(LOCK_SCREEN_ACTION_ID).available;
}
},
get can_switch_user() {
return this._actions.get(SWITCH_USER_ACTION_ID).available;
}
},
get can_logout() {
return this._actions.get(LOGOUT_ACTION_ID).available;
}
},
get can_lock_orientation() {
return this._actions.get(LOCK_ORIENTATION_ACTION_ID).available;
}
},
get orientation_lock_icon() {
return this._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName;
}
},
_sensorProxyAppeared() {
this._sensorProxy = new SensorProxy(Gio.DBus.system, SENSOR_BUS_NAME, SENSOR_OBJECT_PATH,
@@ -224,7 +227,7 @@ const SystemActions = GObject.registerClass({
() => { this._updateOrientationLock(); });
this._updateOrientationLock();
});
}
},
_updateOrientationLock() {
let available = false;
@@ -235,7 +238,7 @@ const SystemActions = GObject.registerClass({
this._actions.get(LOCK_ORIENTATION_ACTION_ID).available = available;
this.notify('can-lock-orientation');
}
},
_updateOrientationLockIcon() {
let locked = this._orientationSettings.get_boolean('orientation-lock');
@@ -244,14 +247,14 @@ const SystemActions = GObject.registerClass({
this._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName = iconName;
this.notify('orientation-lock-icon');
}
},
_sessionUpdated() {
this._updateLockScreen();
this._updatePowerOff();
this._updateSuspend();
this._updateMultiUser();
}
},
forceUpdate() {
// Whether those actions are available or not depends on both lockdown
@@ -259,7 +262,7 @@ const SystemActions = GObject.registerClass({
// latter, so their value may be outdated; force an update now
this._updateHaveShutdown();
this._updateHaveSuspend();
}
},
getMatchingActions(terms) {
// terms is a list of strings
@@ -272,15 +275,15 @@ const SystemActions = GObject.registerClass({
results.push(key);
return results;
}
},
getName(id) {
return this._actions.get(id).name;
}
},
getIconName(id) {
return this._actions.get(id).iconName;
}
},
activateAction(id) {
switch (id) {
@@ -303,14 +306,14 @@ const SystemActions = GObject.registerClass({
this.activateLockOrientation();
break;
}
}
},
_updateLockScreen() {
let showLock = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
this._actions.get(LOCK_SCREEN_ACTION_ID).available = showLock && allowLockScreen && LoginManager.canLock();
this.notify('can-lock-screen');
}
},
_updateHaveShutdown() {
this._session.CanShutdownRemote((result, error) => {
@@ -320,7 +323,7 @@ const SystemActions = GObject.registerClass({
this._canHavePowerOff = result[0];
this._updatePowerOff();
});
}
},
_updatePowerOff() {
let disabled = Main.sessionMode.isLocked ||
@@ -328,7 +331,7 @@ const SystemActions = GObject.registerClass({
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
this._actions.get(POWER_OFF_ACTION_ID).available = this._canHavePowerOff && !disabled;
this.notify('can-power-off');
}
},
_updateHaveSuspend() {
this._loginManager.canSuspend(
@@ -337,7 +340,7 @@ const SystemActions = GObject.registerClass({
this._suspendNeedsAuth = needsAuth;
this._updateSuspend();
});
}
},
_updateSuspend() {
let disabled = (Main.sessionMode.isLocked &&
@@ -346,12 +349,12 @@ const SystemActions = GObject.registerClass({
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
this._actions.get(SUSPEND_ACTION_ID).available = this._canHaveSuspend && !disabled;
this.notify('can-suspend');
}
},
_updateMultiUser() {
this._updateLogout();
this._updateSwitchUser();
}
},
_updateSwitchUser() {
let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY);
@@ -363,7 +366,7 @@ const SystemActions = GObject.registerClass({
this.notify('can-switch-user');
return visible;
}
},
_updateLogout() {
let user = this._userManager.get_user(GLib.get_user_name());
@@ -381,7 +384,7 @@ const SystemActions = GObject.registerClass({
this.notify('can-logout');
return visible;
}
},
activateLockOrientation() {
if (!this._actions.get(LOCK_ORIENTATION_ACTION_ID).available)
@@ -389,14 +392,14 @@ const SystemActions = GObject.registerClass({
let locked = this._orientationSettings.get_boolean('orientation-lock');
this._orientationSettings.set_boolean('orientation-lock', !locked);
}
},
activateLockScreen() {
if (!this._actions.get(LOCK_SCREEN_ACTION_ID).available)
throw new Error('The lock-screen action is not available!');
Main.screenShield.lock(true);
}
},
activateSwitchUser() {
if (!this._actions.get(SWITCH_USER_ACTION_ID).available)
@@ -409,7 +412,7 @@ const SystemActions = GObject.registerClass({
Gdm.goto_login_session_sync(null);
return false;
});
}
},
activateLogout() {
if (!this._actions.get(LOGOUT_ACTION_ID).available)
@@ -417,14 +420,14 @@ const SystemActions = GObject.registerClass({
Main.overview.hide();
this._session.LogoutRemote(0);
}
},
activatePowerOff() {
if (!this._actions.get(POWER_OFF_ACTION_ID).available)
throw new Error('The power-off action is not available!');
this._session.ShutdownRemote(0);
}
},
activateSuspend() {
if (!this._actions.get(SUSPEND_ACTION_ID).available)

View File

@@ -4,7 +4,7 @@ const Clutter = imports.gi.Clutter;
const Gettext = imports.gettext;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
const Shell = imports.gi.Shell;
@@ -348,10 +348,12 @@ function insertSorted(array, val, cmp) {
return pos;
}
var CloseButton = GObject.registerClass(
class CloseButton extends St.Button {
var CloseButton = new Lang.Class({
Name: 'CloseButton',
Extends: St.Button,
_init(boxpointer) {
super._init({ style_class: 'notification-close'});
this.parent({ style_class: 'notification-close'});
// This is a bit tricky. St.Bin has its own x-align/y-align properties
// that compete with Clutter's properties. This should be fixed for
@@ -368,7 +370,7 @@ class CloseButton extends St.Button {
this._boxPointer = boxpointer;
if (boxpointer)
this._boxPointer.connect('arrow-side-changed', this._sync.bind(this));
}
},
_computeBoxPointerOffset() {
if (!this._boxPointer || !this._boxPointer.actor.get_stage())
@@ -379,7 +381,7 @@ class CloseButton extends St.Button {
return this._boxPointer.getArrowHeight();
else
return 0;
}
},
_sync() {
let themeNode = this.get_theme_node();
@@ -387,12 +389,12 @@ class CloseButton extends St.Button {
let offY = this._computeBoxPointerOffset();
this.translation_x = themeNode.get_length('-shell-close-overlap-x')
this.translation_y = themeNode.get_length('-shell-close-overlap-y') + offY;
}
},
vfunc_style_changed() {
this._sync();
super.vfunc_style_changed();
}
this.parent();
},
});
function makeCloseButton(boxpointer) {
@@ -435,8 +437,10 @@ function ensureActorVisibleInScrollView(scrollView, actor) {
transition: 'easeOutQuad' });
}
var AppSettingsMonitor = class {
constructor(appId, schemaId) {
var AppSettingsMonitor = new Lang.Class({
Name: 'AppSettingsMonitor',
_init(appId, schemaId) {
this._appId = appId;
this._schemaId = schemaId;
@@ -450,23 +454,23 @@ var AppSettingsMonitor = class {
this._appSystem.connect('installed-changed',
this._onInstalledChanged.bind(this));
this._onInstalledChanged();
}
},
get available() {
return this._app != null && this._settings != null;
}
},
activateApp() {
if (this._app)
this._app.activate();
}
},
watchSetting(key, callback) {
let handler = { id: 0, key: key, callback: callback };
this._handlers.push(handler);
this._connectHandler(handler);
}
},
_connectHandler(handler) {
if (!this._settings || handler.id > 0)
@@ -475,13 +479,13 @@ var AppSettingsMonitor = class {
handler.id = this._settings.connect('changed::' + handler.key,
handler.callback);
handler.callback(this._settings, handler.key);
}
},
_disconnectHandler(handler) {
if (this._settings && handler.id > 0)
this._settings.disconnect(handler.id);
handler.id = 0;
}
},
_onInstalledChanged() {
let hadApp = (this._app != null);
@@ -495,7 +499,7 @@ var AppSettingsMonitor = class {
this._checkSettings();
else
this._setSettings(null);
}
},
_setSettings(settings) {
this._handlers.forEach((handler) => { this._disconnectHandler(handler); });
@@ -508,7 +512,7 @@ var AppSettingsMonitor = class {
if (hadSettings != haveSettings)
this.emit('available-changed');
}
},
_checkSettings() {
let schema = this._schemaSource.lookup(this._schemaId, true);
@@ -521,5 +525,5 @@ var AppSettingsMonitor = class {
});
}
}
};
});
Signals.addSignalMethods(AppSettingsMonitor.prototype);

View File

@@ -4,6 +4,7 @@ const Geoclue = imports.gi.Geoclue;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GWeather = imports.gi.GWeather;
const Lang = imports.lang;
const Signals = imports.signals;
const PermissionStore = imports.misc.permissionStore;
@@ -12,8 +13,10 @@ const Util = imports.misc.util;
// Minimum time between updates to show loading indication
var UPDATE_THRESHOLD = 10 * GLib.TIME_SPAN_MINUTE;
var WeatherClient = class {
constructor() {
var WeatherClient = new Lang.Class({
Name: 'WeatherClient',
_init() {
this._loading = false;
this._locationValid = false;
this._lastUpdate = GLib.DateTime.new_from_unix_local(0);
@@ -68,27 +71,27 @@ var WeatherClient = class {
this._onAutomaticLocationChanged.bind(this));
this._weatherAppMon.watchSetting('locations',
this._onLocationsChanged.bind(this));
}
},
get available() {
return this._weatherAppMon.available;
}
},
get loading() {
return this._loading;
}
},
get hasLocation() {
return this._locationValid;
}
},
get info() {
return this._weatherInfo;
}
},
activateApp() {
this._weatherAppMon.activateApp();
}
},
update() {
if (!this._locationValid)
@@ -101,13 +104,13 @@ var WeatherClient = class {
this._weatherInfo.update();
else
this._loadInfo();
}
},
get _useAutoLocation() {
return this._autoLocationRequested &&
this._locationSettings.get_boolean('enabled') &&
this._weatherAuthorized;
}
},
_loadInfo() {
let id = this._weatherInfo.connect('updated', () => {
@@ -119,7 +122,7 @@ var WeatherClient = class {
this.emit('changed');
this._weatherInfo.update();
}
},
_locationsEqual(loc1, loc2) {
if (loc1 == loc2)
@@ -129,7 +132,7 @@ var WeatherClient = class {
return false;
return loc1.equal(loc2);
}
},
_setLocation(location) {
if (this._locationsEqual(this._weatherInfo.location, location))
@@ -145,7 +148,7 @@ var WeatherClient = class {
this._loadInfo();
else
this.emit('changed');
}
},
_updateLocationMonitoring() {
if (this._useAutoLocation) {
@@ -161,7 +164,7 @@ var WeatherClient = class {
this._gclueService.disconnect(this._gclueLocationChangedId);
this._gclueLocationChangedId = 0;
}
}
},
_startGClueService() {
if (this._gclueStarting)
@@ -182,7 +185,7 @@ var WeatherClient = class {
this._gclueService.get_client().distance_threshold = 100;
this._updateLocationMonitoring();
});
}
},
_onGClueLocationChanged() {
let geoLocation = this._gclueService.location;
@@ -191,7 +194,7 @@ var WeatherClient = class {
geoLocation.latitude,
geoLocation.longitude);
this._setLocation(location);
}
},
_onAutomaticLocationChanged(settings, key) {
let useAutoLocation = settings.get_boolean(key);
@@ -201,7 +204,7 @@ var WeatherClient = class {
this._autoLocationRequested = useAutoLocation;
this._updateAutoLocation();
}
},
_updateAutoLocation() {
this._updateLocationMonitoring();
@@ -210,7 +213,7 @@ var WeatherClient = class {
this._startGClueService();
else
this._setLocation(this._mostRecentLocation);
}
},
_onLocationsChanged(settings, key) {
let serialized = settings.get_value(key).deep_unpack().shift();
@@ -226,7 +229,7 @@ var WeatherClient = class {
if (!this._useAutoLocation || !this._gclueStarted)
this._setLocation(this._mostRecentLocation);
}
},
_onPermStoreChanged(proxy, sender, params) {
let [table, id, deleted, data, perms] = params;
@@ -240,5 +243,5 @@ var WeatherClient = class {
this._updateAutoLocation();
}
};
});
Signals.addSignalMethods(WeatherClient.prototype);

View File

@@ -4,6 +4,7 @@ const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Pango = imports.gi.Pango;
const Soup = imports.gi.Soup;
const WebKit = imports.gi.WebKit2;
@@ -32,10 +33,12 @@ const CONNECTIVITY_RECHECK_RATELIMIT_TIMEOUT = 30 * GLib.USEC_PER_SEC;
const HelperDBusInterface = loadInterfaceXML('org.gnome.Shell.PortalHelper');
var PortalHeaderBar = GObject.registerClass(
class PortalHeaderBar extends Gtk.HeaderBar {
var PortalHeaderBar = new Lang.Class({
Name: 'PortalHeaderBar',
Extends: Gtk.HeaderBar,
_init() {
super._init({ show_close_button: true });
this.parent({ show_close_button: true });
// See ephy-title-box.c in epiphany for the layout
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
@@ -70,11 +73,11 @@ class PortalHeaderBar extends Gtk.HeaderBar {
hbox.add(this.subtitleLabel);
vbox.show_all();
}
},
setSubtitle(label) {
this.subtitleLabel.set_text(label);
}
},
setSecurityIcon(securityLevel) {
switch (securityLevel) {
@@ -92,13 +95,15 @@ class PortalHeaderBar extends Gtk.HeaderBar {
this._lockImage.set_tooltip_text(_('Your connection to this hotspot login is not secure. Passwords or other information you enter on this page can be viewed by people nearby.'));
break;
}
}
},
});
var PortalWindow = GObject.registerClass(
class PortalWindow extends Gtk.ApplicationWindow {
var PortalWindow = new Lang.Class({
Name: 'PortalWindow',
Extends: Gtk.ApplicationWindow,
_init(application, url, timestamp, doneCallback) {
super._init({ application: application });
this.parent({ application: application });
this.connect('delete-event', this.destroyWindow.bind(this));
this._headerBar = new PortalHeaderBar();
@@ -139,11 +144,11 @@ class PortalWindow extends Gtk.ApplicationWindow {
this.present_with_time(timestamp);
this.application.set_accels_for_action('app.quit', ['<Primary>q', '<Primary>w']);
}
},
destroyWindow() {
this.destroy();
}
},
_syncUri() {
let uri = this._webView.uri;
@@ -151,12 +156,12 @@ class PortalWindow extends Gtk.ApplicationWindow {
this._headerBar.setSubtitle(GLib.uri_unescape_string(uri, null));
else
this._headerBar.setSubtitle('');
}
},
refresh() {
this._everSeenRedirect = false;
this._webView.load_uri(this._originalUrl);
}
},
vfunc_delete_event(event) {
if (this._recheckAtExit)
@@ -164,7 +169,7 @@ class PortalWindow extends Gtk.ApplicationWindow {
else
this._doneCallback(PortalHelperResult.CANCELLED);
return false;
}
},
_onLoadChanged(view, loadEvent) {
if (loadEvent == WebKit.LoadEvent.STARTED) {
@@ -178,11 +183,11 @@ class PortalWindow extends Gtk.ApplicationWindow {
else
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
}
}
},
_onInsecureContentDetected() {
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
}
},
_onLoadFailedWithTlsErrors(view, failingURI, certificate, errors) {
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
@@ -190,7 +195,7 @@ class PortalWindow extends Gtk.ApplicationWindow {
this._webContext.allow_tls_certificate_for_host(certificate, uri.get_host());
this._webView.load_uri(failingURI);
return true;
}
},
_onDecidePolicy(view, decision, type) {
if (type == WebKit.PolicyDecisionType.NEW_WINDOW_ACTION) {
@@ -257,13 +262,15 @@ class PortalWindow extends Gtk.ApplicationWindow {
decision.use();
return true;
}
},
});
var WebPortalHelper = GObject.registerClass(
class WebPortalHelper extends Gtk.Application {
var WebPortalHelper = new Lang.Class({
Name: 'WebPortalHelper',
Extends: Gtk.Application,
_init() {
super._init({ application_id: 'org.gnome.Shell.PortalHelper',
this.parent({ application_id: 'org.gnome.Shell.PortalHelper',
flags: Gio.ApplicationFlags.IS_SERVICE,
inactivity_timeout: 30000 });
@@ -273,30 +280,30 @@ class WebPortalHelper extends Gtk.Application {
let action = new Gio.SimpleAction({ name: 'quit' });
action.connect('activate', () => { this.active_window.destroyWindow(); });
this.add_action(action);
}
},
vfunc_dbus_register(connection, path) {
this._dbusImpl.export(connection, path);
super.vfunc_dbus_register(connection, path);
this.parent(connection, path);
return true;
}
},
vfunc_dbus_unregister(connection, path) {
this._dbusImpl.unexport_from_connection(connection);
super.vfunc_dbus_unregister(connection, path);
}
this.parent(connection, path);
},
vfunc_activate() {
// If launched manually (for example for testing), force a dummy authentication
// session with the default url
this.Authenticate('/org/gnome/dummy', '', 0);
}
},
Authenticate(connection, url, timestamp) {
this._queue.push({ connection: connection, url: url, timestamp: timestamp });
this._processQueue();
}
},
Close(connection) {
for (let i = 0; i < this._queue.length; i++) {
@@ -311,7 +318,7 @@ class WebPortalHelper extends Gtk.Application {
}
this._processQueue();
}
},
Refresh(connection) {
for (let i = 0; i < this._queue.length; i++) {
@@ -323,7 +330,7 @@ class WebPortalHelper extends Gtk.Application {
break;
}
}
}
},
_processQueue() {
if (this._queue.length == 0)
@@ -336,7 +343,7 @@ class WebPortalHelper extends Gtk.Application {
top.window = new PortalWindow(this, top.url, top.timestamp, result => {
this._dbusImpl.emit_signal('Done', new GLib.Variant('(ou)', [top.connection, result]));
});
}
},
});
function initEnvironment() {

View File

@@ -1,6 +1,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@@ -20,9 +21,12 @@ var DialogResponse = {
CLOSED: 2
};
var AccessDialog = class extends ModalDialog.ModalDialog {
constructor(invocation, handle, title, subtitle, body, options) {
super({ styleClass: 'access-dialog' });
var AccessDialog = new Lang.Class({
Name: 'AccessDialog',
Extends: ModalDialog.ModalDialog,
_init(invocation, handle, title, subtitle, body, options) {
this.parent({ styleClass: 'access-dialog' });
this._invocation = invocation;
this._handle = handle;
@@ -34,7 +38,7 @@ var AccessDialog = class extends ModalDialog.ModalDialog {
options[option] = options[option].deep_unpack();
this._buildLayout(title, subtitle, body, options);
}
},
_buildLayout(title, subtitle, body, options) {
// No support for non-modal system dialogs, so ignore the option
@@ -74,14 +78,14 @@ var AccessDialog = class extends ModalDialog.ModalDialog {
action: () => {
this._sendResponse(DialogResponse.OK);
}});
}
},
open() {
super.open();
this.parent();
let connection = this._invocation.get_connection();
this._requestExported = this._request.export(connection, this._handle);
}
},
CloseAsync(invocation, params) {
if (this._invocation.get_sender() != invocation.get_sender()) {
@@ -92,7 +96,7 @@ var AccessDialog = class extends ModalDialog.ModalDialog {
}
this._sendResponse(DialogResponse.CLOSED);
}
},
_sendResponse(response) {
if (this._requestExported)
@@ -114,10 +118,12 @@ var AccessDialog = class extends ModalDialog.ModalDialog {
});
this.close();
}
};
});
var AccessDialogDBus = class {
constructor() {
var AccessDialogDBus = new Lang.Class({
Name: 'AccessDialogDBus',
_init() {
this._accessDialog = null;
this._windowTracker = Shell.WindowTracker.get_default();
@@ -126,7 +132,7 @@ var AccessDialogDBus = class {
this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/portal/desktop');
Gio.DBus.session.own_name('org.freedesktop.impl.portal.desktop.gnome', Gio.BusNameOwnerFlags.REPLACE, null, null);
}
},
AccessDialogAsync(params, invocation) {
if (this._accessDialog) {
@@ -154,4 +160,4 @@ var AccessDialogDBus = class {
this._accessDialog = dialog;
}
};
});

View File

@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
@@ -58,10 +59,12 @@ function getWindows(workspace) {
}).filter((w, i, a) => !w.skip_taskbar && a.indexOf(w) == i);
}
var AppSwitcherPopup = GObject.registerClass(
class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
var AppSwitcherPopup = new Lang.Class({
Name: 'AppSwitcherPopup',
Extends: SwitcherPopup.SwitcherPopup,
_init() {
super._init();
this.parent();
this._thumbnails = null;
this._thumbnailTimeoutId = 0;
@@ -76,10 +79,10 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
this._switcherList = new AppSwitcher(apps, this);
this._items = this._switcherList.icons;
}
},
vfunc_allocate(box, flags) {
super.vfunc_allocate(box, flags);
this.parent(box, flags);
// Allocate the thumbnails
// We try to avoid overflowing the screen so we base the resulting size on
@@ -114,7 +117,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
childBox.y2 = childBox.y1 + childNaturalHeight;
this._thumbnails.allocate(childBox, flags);
}
}
},
_initialSelection(backward, binding) {
if (binding == 'switch-group') {
@@ -137,7 +140,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
} else {
this._select(1);
}
}
},
_nextWindow() {
// We actually want the second window if we're in the unset state
@@ -145,15 +148,14 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
this._currentWindow = 0;
return SwitcherPopup.mod(this._currentWindow + 1,
this._items[this._selectedIndex].cachedWindows.length);
}
},
_previousWindow() {
// Also assume second window here
if (this._currentWindow == -1)
this._currentWindow = 1;
return SwitcherPopup.mod(this._currentWindow - 1,
this._items[this._selectedIndex].cachedWindows.length);
}
},
_closeAppWindow(appIndex, windowIndex) {
let appIcon = this._items[appIndex];
@@ -165,7 +167,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
return;
window.delete(global.get_current_time());
}
},
_quitApplication(appIndex) {
let appIcon = this._items[appIndex];
@@ -173,7 +175,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
return;
appIcon.app.request_quit();
}
},
_keyPressHandler(keysym, action) {
if (action == Meta.KeyBindingAction.SWITCH_GROUP) {
@@ -212,7 +214,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
}
return Clutter.EVENT_STOP;
}
},
_scrollHandler(direction) {
if (direction == Clutter.ScrollDirection.UP) {
@@ -242,7 +244,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
this._select(this._next());
}
}
}
},
_itemActivatedHandler(n) {
// If the user clicks on the selected app, activate the
@@ -252,24 +254,24 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
this._select(n, this._currentWindow);
else
this._select(n);
}
},
_itemEnteredHandler(n) {
this._select(n);
}
},
_windowActivated(thumbnailList, n) {
let appIcon = this._items[this._selectedIndex];
Main.activateWindow(appIcon.cachedWindows[n]);
this.fadeAndDestroy();
}
},
_windowEntered(thumbnailList, n) {
if (!this.mouseActive)
return;
this._select(this._selectedIndex, n);
}
},
_windowRemoved(thumbnailList, n) {
let appIcon = this._items[this._selectedIndex];
@@ -280,7 +282,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
let newIndex = Math.min(n, appIcon.cachedWindows.length - 1);
this._select(this._selectedIndex, newIndex);
}
}
},
_finish(timestamp) {
let appIcon = this._items[this._selectedIndex];
@@ -289,17 +291,17 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
else if (appIcon.cachedWindows[this._currentWindow])
Main.activateWindow(appIcon.cachedWindows[this._currentWindow], timestamp);
super._finish(timestamp);
}
this.parent();
},
_onDestroy() {
super._onDestroy();
this.parent();
if (this._thumbnails)
this._destroyThumbnails();
if (this._thumbnailTimeoutId != 0)
Mainloop.source_remove(this._thumbnailTimeoutId);
}
},
/**
* _select:
@@ -355,7 +357,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
this._timeoutPopupThumbnails.bind(this));
GLib.Source.set_name_by_id(this._thumbnailTimeoutId, '[gnome-shell] this._timeoutPopupThumbnails');
}
}
},
_timeoutPopupThumbnails() {
if (!this._thumbnails)
@@ -363,7 +365,7 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
this._thumbnailTimeoutId = 0;
this._thumbnailsFocused = false;
return GLib.SOURCE_REMOVE;
}
},
_destroyThumbnails() {
let thumbnailsActor = this._thumbnails;
@@ -377,9 +379,9 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
}
});
this._thumbnails = null;
if (this._switcherList._items[this._selectedIndex])
if (this._switcherList._items[this._selectedIndex])
this._switcherList._items[this._selectedIndex].remove_accessible_state (Atk.StateType.EXPANDED);
}
},
_createThumbnails() {
this._thumbnails = new ThumbnailList (this._items[this._selectedIndex].cachedWindows);
@@ -409,8 +411,10 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
}
});
class CyclerHighlight {
constructor() {
var CyclerHighlight = new Lang.Class({
Name: 'CyclerHighlight',
_init() {
this._window = null;
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout() });
@@ -430,7 +434,7 @@ class CyclerHighlight {
this.actor.connect('notify::allocation',
this._onAllocationChanged.bind(this));
this.actor.connect('destroy', this._onDestroy.bind(this));
}
},
set window(w) {
if (this._window == w)
@@ -448,7 +452,7 @@ class CyclerHighlight {
windowActor.hide();
this._clone.source = windowActor;
}
},
_onAllocationChanged() {
if (!this._window) {
@@ -461,33 +465,35 @@ class CyclerHighlight {
this._highlight.set_position(rect.x - x, rect.y - y);
this._highlight.show();
}
}
},
_onDestroy() {
this.window = null;
}
};
});
// We don't show an actual popup, so just provide what SwitcherPopup
// expects instead of inheriting from SwitcherList
var CyclerList = GObject.registerClass({
var CyclerList = new Lang.Class({
Name: 'CyclerList',
Extends: St.Widget,
Signals: { 'item-activated': { param_types: [GObject.TYPE_INT] },
'item-entered': { param_types: [GObject.TYPE_INT] },
'item-removed': { param_types: [GObject.TYPE_INT] },
'item-highlighted': { param_types: [GObject.TYPE_INT] } },
}, class CyclerList extends St.Widget {
highlight(index, justOutline) {
this.emit('item-highlighted', index);
}
});
var CyclerPopup = GObject.registerClass(
class CyclerPopup extends SwitcherPopup.SwitcherPopup {
_init() {
if (new.target === CyclerPopup)
throw new TypeError('Cannot instantiate abstract class ' + new.target.name);
var CyclerPopup = new Lang.Class({
Name: 'CyclerPopup',
Extends: SwitcherPopup.SwitcherPopup,
Abstract: true,
super._init();
_init() {
this.parent();
this._items = this._getWindows();
@@ -501,12 +507,12 @@ class CyclerPopup extends SwitcherPopup.SwitcherPopup {
this._switcherList.connect('item-highlighted', (list, index) => {
this._highlightItem(index);
});
}
},
_highlightItem(index, justOutline) {
this._highlight.window = this._items[index];
global.window_group.set_child_above_sibling(this._highlight.actor, null);
}
},
_finish() {
let window = this._items[this._selectedIndex];
@@ -531,23 +537,25 @@ class CyclerPopup extends SwitcherPopup.SwitcherPopup {
Main.wm.actionMoveWindow(window, ws);
}
super._finish();
}
this.parent();
},
_onDestroy() {
this._highlight.actor.destroy();
super._onDestroy();
this.parent();
}
});
var GroupCyclerPopup = GObject.registerClass(
class GroupCyclerPopup extends CyclerPopup {
var GroupCyclerPopup = new Lang.Class({
Name: 'GroupCyclerPopup',
Extends: CyclerPopup,
_getWindows() {
let app = Shell.WindowTracker.get_default().focus_app;
return app ? app.get_windows() : [];
}
},
_keyPressHandler(keysym, action) {
if (action == Meta.KeyBindingAction.CYCLE_GROUP)
@@ -561,10 +569,12 @@ class GroupCyclerPopup extends CyclerPopup {
}
});
var WindowSwitcherPopup = GObject.registerClass(
class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup {
var WindowSwitcherPopup = new Lang.Class({
Name: 'WindowSwitcherPopup',
Extends: SwitcherPopup.SwitcherPopup,
_init() {
super._init();
this.parent();
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
let windows = this._getWindowList();
@@ -575,7 +585,7 @@ class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup {
let mode = this._settings.get_enum('app-icon-mode');
this._switcherList = new WindowList(windows, mode);
this._items = this._switcherList.icons;
}
},
_getWindowList() {
let workspace = null;
@@ -587,7 +597,7 @@ class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup {
}
return getWindows(workspace);
}
},
_closeWindow(windowIndex) {
let windowIcon = this._items[windowIndex];
@@ -595,7 +605,7 @@ class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup {
return;
windowIcon.window.delete(global.get_current_time());
}
},
_keyPressHandler(keysym, action) {
if (action == Meta.KeyBindingAction.SWITCH_WINDOWS) {
@@ -614,22 +624,23 @@ class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup {
}
return Clutter.EVENT_STOP;
}
},
_finish() {
Main.activateWindow(this._items[this._selectedIndex].window);
super._finish();
this.parent();
}
});
var WindowCyclerPopup = GObject.registerClass(
class WindowCyclerPopup extends CyclerPopup {
_init() {
super._init();
var WindowCyclerPopup = new Lang.Class({
Name: 'WindowCyclerPopup',
Extends: CyclerPopup,
_init() {
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
}
this.parent();
},
_getWindows() {
let workspace = null;
@@ -641,7 +652,7 @@ class WindowCyclerPopup extends CyclerPopup {
}
return getWindows(workspace);
}
},
_keyPressHandler(keysym, action) {
if (action == Meta.KeyBindingAction.CYCLE_WINDOWS)
@@ -655,10 +666,12 @@ class WindowCyclerPopup extends CyclerPopup {
}
});
var AppIcon = GObject.registerClass(
class AppIcon extends St.BoxLayout {
var AppIcon = new Lang.Class({
Name: 'AppIcon',
Extends: St.BoxLayout,
_init(app) {
super._init({ style_class: 'alt-tab-app',
this.parent({ style_class: 'alt-tab-app',
vertical: true });
this.app = app;
@@ -668,26 +681,28 @@ class AppIcon extends St.BoxLayout {
this.add(this._iconBin, { x_fill: false, y_fill: false } );
this.label = new St.Label({ text: this.app.get_name() });
this.add(this.label, { x_fill: false });
}
},
set_size(size) {
this.icon = this.app.create_icon_texture(size);
this._iconBin.child = this.icon;
this._iconBin.set_size(size, size);
}
},
vfunc_get_preferred_width(forHeight) {
let [minWidth, ] = super.vfunc_get_preferred_width(forHeight);
let [minWidth, ] = this.parent(forHeight);
minWidth = Math.max(minWidth, forHeight);
return [minWidth, minWidth];
}
});
var AppSwitcher = GObject.registerClass(
class AppSwitcher extends SwitcherPopup.SwitcherList {
var AppSwitcher = new Lang.Class({
Name: 'AppSwitcher',
Extends: SwitcherPopup.SwitcherList,
_init(apps, altTabPopup) {
super._init(true);
this.parent(true);
this.icons = [];
this._arrows = [];
@@ -721,7 +736,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
this._mouseTimeOutId = 0;
this.connect('destroy', this._onDestroy.bind(this));
}
},
_onDestroy() {
if (this._mouseTimeOutId != 0)
@@ -730,7 +745,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
this.icons.forEach(icon => {
icon.app.disconnect(icon._stateChangedId);
});
}
},
_setIconSize() {
let j = 0;
@@ -771,16 +786,16 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
break;
this.icons[i].set_size(iconSize);
}
}
},
vfunc_get_preferred_height(forWidth) {
this._setIconSize();
return super.vfunc_get_preferred_height(forWidth);
}
return this.parent(forWidth);
},
vfunc_allocate(box, flags) {
// Allocate the main list items
super.vfunc_allocate(box, flags);
this.parent(box, flags);
let contentBox = this.get_theme_node().get_content_box(box);
@@ -797,7 +812,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
childBox.y2 = childBox.y1 + arrowHeight;
this._arrows[i].allocate(childBox, flags);
}
}
},
// We override SwitcherList's _onItemEnter method to delay
// activation when the thumbnail list is open
@@ -814,14 +829,14 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
GLib.Source.set_name_by_id(this._mouseTimeOutId, '[gnome-shell] this._enterItem');
} else
this._itemEntered(index);
}
},
_enterItem(index) {
let [x, y, mask] = global.get_pointer();
let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.ALL, x, y);
if (this._items[index].contains(pickedActor))
this._itemEntered(index);
}
},
// We override SwitcherList's highlight() method to also deal with
// the AppSwitcher->ThumbnailList arrows. Apps with only 1 window
@@ -838,7 +853,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
this._arrows[this._curApp].remove_style_pseudo_class('highlighted');
}
super.highlight(n, justOutline);
this.parent(n, justOutline);
this._curApp = n;
if (this._curApp != -1) {
@@ -847,7 +862,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
else
this._arrows[this._curApp].add_style_pseudo_class('highlighted');
}
}
},
_addIcon(appIcon) {
this.icons.push(appIcon);
@@ -868,7 +883,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
arrow.hide();
else
item.add_accessible_state (Atk.StateType.EXPANDABLE);
}
},
_removeIcon(app) {
let index = this.icons.findIndex(icon => {
@@ -879,13 +894,15 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
this.icons.splice(index, 1);
this.removeItem(index);
}
},
});
var ThumbnailList = GObject.registerClass(
class ThumbnailList extends SwitcherPopup.SwitcherList {
var ThumbnailList = new Lang.Class({
Name: 'ThumbnailList',
Extends: SwitcherPopup.SwitcherList,
_init(windows) {
super._init(false);
this.parent(false);
this._labels = new Array();
this._thumbnailBins = new Array();
@@ -918,7 +935,7 @@ class ThumbnailList extends SwitcherPopup.SwitcherList {
}
this.connect('destroy', this._onDestroy.bind(this));
}
},
addClones(availHeight) {
if (!this._thumbnailBins.length)
@@ -951,7 +968,7 @@ class ThumbnailList extends SwitcherPopup.SwitcherList {
// Make sure we only do this once
this._thumbnailBins = new Array();
}
},
_removeThumbnail(source, clone) {
let index = this._clones.indexOf(clone);
@@ -967,20 +984,23 @@ class ThumbnailList extends SwitcherPopup.SwitcherList {
this.highlight(SwitcherPopup.mod(index, this._clones.length));
else
this.destroy();
}
},
_onDestroy() {
this._clones.forEach(clone => {
if (clone.source)
clone.source.disconnect(clone._destroyId);
});
}
},
});
var WindowIcon = GObject.registerClass(
class WindowIcon extends St.BoxLayout {
var WindowIcon = new Lang.Class({
Name: 'WindowIcon',
Extends: St.BoxLayout,
_init(window, mode) {
super._init({ style_class: 'alt-tab-app',
this.parent({ style_class: 'alt-tab-app',
vertical: true });
this.window = window;
@@ -1021,7 +1041,7 @@ class WindowIcon extends St.BoxLayout {
}
this._icon.set_size(size * scaleFactor, size * scaleFactor);
}
},
_createAppIcon(app, size) {
let appIcon = app ? app.create_icon_texture(size)
@@ -1034,10 +1054,12 @@ class WindowIcon extends St.BoxLayout {
}
});
var WindowList = GObject.registerClass(
class WindowList extends SwitcherPopup.SwitcherList {
var WindowList = new Lang.Class({
Name: 'WindowList',
Extends: SwitcherPopup.SwitcherList,
_init(windows, mode) {
super._init(true);
this.parent(true);
this._label = new St.Label({ x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER });
@@ -1059,16 +1081,16 @@ class WindowList extends SwitcherPopup.SwitcherList {
}
this.connect('destroy', this._onDestroy.bind(this));
}
},
_onDestroy() {
this.icons.forEach(icon => {
icon.window.disconnect(icon._unmanagedSignalId);
});
}
},
vfunc_get_preferred_height(forWidth) {
let [minHeight, natHeight] = super.vfunc_get_preferred_height(forWidth);
let [minHeight, natHeight] = this.parent(forWidth);
let spacing = this.get_theme_node().get_padding(St.Side.BOTTOM);
let [labelMin, labelNat] = this._label.get_preferred_height(-1);
@@ -1077,7 +1099,7 @@ class WindowList extends SwitcherPopup.SwitcherList {
natHeight += labelNat + spacing;
return [minHeight, natHeight];
}
},
vfunc_allocate(box, flags) {
let themeNode = this.get_theme_node();
@@ -1095,19 +1117,19 @@ class WindowList extends SwitcherPopup.SwitcherList {
childBox.x2 = box.x2;
childBox.y1 = box.y1;
childBox.y2 = box.y2 - totalLabelHeight;
super.vfunc_allocate(childBox, flags);
this.parent(childBox, flags);
// Hooking up the parent vfunc will call this.set_allocation() with
// the height without the label height, so call it again with the
// correct size here.
this.set_allocation(box, flags);
}
},
highlight(index, justOutline) {
super.highlight(index, justOutline);
this.parent(index, justOutline);
this._label.set_text(index == -1 ? '' : this.icons[index].label.text);
}
},
_removeWindow(window) {
let index = this.icons.findIndex(icon => {

View File

@@ -1,20 +1,18 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const St = imports.gi.St;
const Signals = imports.signals;
const Atk = imports.gi.Atk;
const Tweener = imports.ui.tweener;
var ANIMATED_ICON_UPDATE_TIMEOUT = 16;
var SPINNER_ANIMATION_TIME = 0.3;
var SPINNER_ANIMATION_DELAY = 1.0;
var Animation = class {
constructor(file, width, height, speed) {
var Animation = new Lang.Class({
Name: 'Animation',
_init(file, width, height, speed) {
this.actor = new St.Bin();
this.actor.connect('destroy', this._onDestroy.bind(this));
this._speed = speed;
@@ -28,7 +26,7 @@ var Animation = class {
this._animations = St.TextureCache.get_default().load_sliced_image (file, width, height, scaleFactor,
this._animationsLoaded.bind(this));
this.actor.set_child(this._animations);
}
},
play() {
if (this._isLoaded && this._timeoutId == 0) {
@@ -40,7 +38,7 @@ var Animation = class {
}
this._isPlaying = true;
}
},
stop() {
if (this._timeoutId > 0) {
@@ -49,7 +47,7 @@ var Animation = class {
}
this._isPlaying = false;
}
},
_showFrame(frame) {
let oldFrameActor = this._animations.get_child_at_index(this._frame);
@@ -61,77 +59,30 @@ var Animation = class {
let newFrameActor = this._animations.get_child_at_index(this._frame);
if (newFrameActor)
newFrameActor.show();
}
},
_update() {
this._showFrame(this._frame + 1);
return GLib.SOURCE_CONTINUE;
}
},
_animationsLoaded() {
this._isLoaded = this._animations.get_n_children() > 0;
if (this._isPlaying)
this.play();
}
},
_onDestroy() {
this.stop();
}
};
});
var AnimatedIcon = class extends Animation {
constructor(file, size) {
super(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
var AnimatedIcon = new Lang.Class({
Name: 'AnimatedIcon',
Extends: Animation,
_init(file, size) {
this.parent(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
}
};
var Spinner = class extends AnimatedIcon {
constructor(size, animate=false) {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
super(file, size);
this.actor.opacity = 0;
this._animate = animate;
}
_onDestroy() {
this._animate = false;
super._onDestroy();
}
play() {
Tweener.removeTweens(this.actor);
if (this._animate) {
super.play();
Tweener.addTween(this.actor, {
opacity: 255,
delay: SPINNER_ANIMATION_DELAY,
time: SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
this.actor.opacity = 255;
super.play();
}
}
stop() {
Tweener.removeTweens(this.actor);
if (this._animate) {
Tweener.addTween(this.actor, {
opacity: 0,
time: SPINNER_ANIMATION_TIME,
transition: 'linear',
onComplete: () => {
this.stop(false);
}
});
} else {
this.actor.opacity = 0;
super.stop();
}
}
};
});

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Shell = imports.gi.Shell;
const Lang = imports.lang;
const Signals = imports.signals;
const Main = imports.ui.main;
@@ -29,7 +30,6 @@ const RENAMED_DESKTOP_IDS = {
'gnome-documents.desktop': 'org.gnome.Documents.desktop',
'gnome-font-viewer.desktop': 'org.gnome.font-viewer.desktop',
'gnome-nibbles.desktop': 'org.gnome.Nibbles.desktop',
'gnome-mahjongg.desktop': 'org.gnome.Mahjongg.desktop',
'gnome-music.desktop': 'org.gnome.Music.desktop',
'gnome-photos.desktop': 'org.gnome.Photos.desktop',
'gnome-screenshot.desktop': 'org.gnome.Screenshot.desktop',
@@ -41,25 +41,27 @@ const RENAMED_DESKTOP_IDS = {
'gnotravex.desktop': 'gnome-tetravex.desktop',
'gnotski.desktop': 'gnome-klotski.desktop',
'gtali.desktop': 'tali.desktop',
'iagno.desktop': 'org.gnome.Iagno.desktop',
'nautilus.desktop': 'org.gnome.Nautilus.desktop',
'polari.desktop': 'org.gnome.Polari.desktop',
'totem.desktop': 'org.gnome.Totem.desktop',
'evince.desktop': 'org.gnome.Evince.desktop',
};
class AppFavorites {
constructor() {
this.FAVORITE_APPS_KEY = 'favorite-apps';
var AppFavorites = new Lang.Class({
Name: 'AppFavorites',
FAVORITE_APPS_KEY: 'favorite-apps',
_init() {
this._favorites = {};
global.settings.connect('changed::' + this.FAVORITE_APPS_KEY, this._onFavsChanged.bind(this));
this.reload();
}
},
_onFavsChanged() {
this.reload();
this.emit('changed');
}
},
reload() {
let ids = global.settings.get_strv(this.FAVORITE_APPS_KEY);
@@ -87,29 +89,29 @@ class AppFavorites {
let app = apps[i];
this._favorites[app.get_id()] = app;
}
}
},
_getIds() {
let ret = [];
for (let id in this._favorites)
ret.push(id);
return ret;
}
},
getFavoriteMap() {
return this._favorites;
}
},
getFavorites() {
let ret = [];
for (let id in this._favorites)
ret.push(this._favorites[id]);
return ret;
}
},
isFavorite(appId) {
return appId in this._favorites;
}
},
_addFavorite(appId, pos) {
if (appId in this._favorites)
@@ -127,7 +129,7 @@ class AppFavorites {
ids.splice(pos, 0, appId);
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
return true;
}
},
addFavoriteAtPos(appId, pos) {
if (!this._addFavorite(appId, pos))
@@ -141,16 +143,16 @@ class AppFavorites {
this._removeFavorite(appId);
}
});
}
},
addFavorite(appId) {
this.addFavoriteAtPos(appId, -1);
}
},
moveFavoriteToPos(appId, pos) {
this._removeFavorite(appId);
this._addFavorite(appId, pos);
}
},
_removeFavorite(appId) {
if (!appId in this._favorites)
@@ -159,7 +161,7 @@ class AppFavorites {
let ids = this._getIds().filter(id => id != appId);
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
return true;
}
},
removeFavorite(appId) {
let ids = this._getIds();
@@ -176,7 +178,7 @@ class AppFavorites {
}
});
}
};
});
Signals.addSignalMethods(AppFavorites.prototype);
var appFavoritesInstance = null;

View File

@@ -1,6 +1,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@@ -18,10 +19,12 @@ var AudioDevice = {
const AudioDeviceSelectionIface = loadInterfaceXML('org.gnome.Shell.AudioDeviceSelection');
var AudioDeviceSelectionDialog =
class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
constructor(devices) {
super({ styleClass: 'audio-device-selection-dialog' });
var AudioDeviceSelectionDialog = new Lang.Class({
Name: 'AudioDeviceSelectionDialog',
Extends: ModalDialog.ModalDialog,
_init(devices) {
this.parent({ styleClass: 'audio-device-selection-dialog' });
this._deviceItems = {};
@@ -36,11 +39,11 @@ class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
if (this._selectionBox.get_n_children() < 2)
throw new Error('Too few devices for a selection');
}
},
destroy() {
super.destroy();
}
this.parent();
},
_buildLayout(devices) {
let title = new St.Label({ style_class: 'audio-selection-title',
@@ -53,13 +56,12 @@ class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
this._selectionBox = new St.BoxLayout({ style_class: 'audio-selection-box' });
this.contentLayout.add(this._selectionBox, { expand: true });
if (Main.sessionMode.allowSettings)
this.addButton({ action: this._openSettings.bind(this),
label: _("Sound Settings") });
this.addButton({ action: this._openSettings.bind(this),
label: _("Sound Settings") });
this.addButton({ action: this.close.bind(this),
label: _("Cancel"),
key: Clutter.Escape });
}
},
_getDeviceLabel(device) {
switch(device) {
@@ -72,7 +74,7 @@ class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
default:
return null;
}
}
},
_getDeviceIcon(device) {
switch(device) {
@@ -85,7 +87,7 @@ class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
default:
return null;
}
}
},
_addDevice(device) {
let box = new St.BoxLayout({ style_class: 'audio-selection-device-box',
@@ -115,7 +117,7 @@ class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
this.close();
Main.overview.hide();
});
}
},
_openSettings() {
let desktopFile = 'gnome-sound-panel.desktop'
@@ -130,21 +132,23 @@ class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
Main.overview.hide();
app.activate();
}
};
});
var AudioDeviceSelectionDBus = class AudioDeviceSelectionDBus {
constructor() {
var AudioDeviceSelectionDBus = new Lang.Class({
Name: 'AudioDeviceSelectionDBus',
_init() {
this._audioSelectionDialog = null;
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(AudioDeviceSelectionIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/AudioDeviceSelection');
Gio.DBus.session.own_name('org.gnome.Shell.AudioDeviceSelection', Gio.BusNameOwnerFlags.REPLACE, null, null);
}
},
_onDialogClosed() {
this._audioSelectionDialog = null;
}
},
_onDeviceSelected(dialog, device) {
let connection = this._dbusImpl.get_connection();
@@ -157,7 +161,7 @@ var AudioDeviceSelectionDBus = class AudioDeviceSelectionDBus {
info ? info.name : null,
'DeviceSelected',
GLib.Variant.new('(s)', [deviceName]));
}
},
OpenAsync(params, invocation) {
if (this._audioSelectionDialog) {
@@ -185,7 +189,7 @@ var AudioDeviceSelectionDBus = class AudioDeviceSelectionDBus {
this._audioSelectionDialog = dialog;
invocation.return_value(null);
}
},
CloseAsync(params, invocation) {
if (this._audioSelectionDialog &&
@@ -194,4 +198,4 @@ var AudioDeviceSelectionDBus = class AudioDeviceSelectionDBus {
invocation.return_value(null);
}
};
});

View File

@@ -98,6 +98,7 @@ const GDesktopEnums = imports.gi.GDesktopEnums;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GnomeDesktop = imports.gi.GnomeDesktop;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Signals = imports.signals;
@@ -137,12 +138,14 @@ function _fileEqual0(file1, file2) {
return file1.equal(file2);
}
var BackgroundCache = class BackgroundCache {
constructor() {
var BackgroundCache = new Lang.Class({
Name: 'BackgroundCache',
_init() {
this._fileMonitors = {};
this._backgroundSources = {};
this._animations = {};
}
},
monitorFile(file) {
let key = file.hash();
@@ -160,7 +163,7 @@ var BackgroundCache = class BackgroundCache {
});
this._fileMonitors[key] = monitor;
}
},
getAnimation(params) {
params = Params.parse(params, { file: null,
@@ -192,7 +195,7 @@ var BackgroundCache = class BackgroundCache {
GLib.Source.set_name_by_id(id, '[gnome-shell] params.onLoaded');
}
});
}
},
getBackgroundSource(layoutManager, settingsSchema) {
// The layoutManager is always the same one; we pass in it since
@@ -206,7 +209,7 @@ var BackgroundCache = class BackgroundCache {
}
return this._backgroundSources[settingsSchema];
}
},
releaseBackgroundSource(settingsSchema) {
if (settingsSchema in this._backgroundSources) {
@@ -218,7 +221,7 @@ var BackgroundCache = class BackgroundCache {
}
}
}
};
});
Signals.addSignalMethods(BackgroundCache.prototype);
function getBackgroundCache() {
@@ -227,8 +230,10 @@ function getBackgroundCache() {
return _backgroundCache;
}
var Background = class Background {
constructor(params) {
var Background = new Lang.Class({
Name: 'Background',
_init(params) {
params = Params.parse(params, { monitorIndex: 0,
layoutManager: Main.layoutManager,
settings: null,
@@ -267,7 +272,7 @@ var Background = class Background {
});
this._load();
}
},
destroy() {
this._cancellable.cancel();
@@ -293,12 +298,12 @@ var Background = class Background {
if (this._settingsChangedSignalId != 0)
this._settings.disconnect(this._settingsChangedSignalId);
this._settingsChangedSignalId = 0;
}
},
updateResolution() {
if (this._animation)
this._refreshAnimation();
}
},
_refreshAnimation() {
if (!this._animation)
@@ -306,7 +311,7 @@ var Background = class Background {
this._removeAnimationTimeout();
this._updateAnimation();
}
},
_setLoaded() {
if (this.isLoaded)
@@ -319,7 +324,7 @@ var Background = class Background {
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(id, '[gnome-shell] this.emit');
}
},
_loadPattern() {
let colorString, res, color, secondColor;
@@ -335,7 +340,7 @@ var Background = class Background {
this.background.set_color(color);
else
this.background.set_gradient(shadingType, color, secondColor);
}
},
_watchFile(file) {
let key = file.hash();
@@ -352,14 +357,14 @@ var Background = class Background {
}
});
this._fileWatches[key] = signalId;
}
},
_removeAnimationTimeout() {
if (this._updateAnimationTimeoutId) {
GLib.source_remove(this._updateAnimationTimeoutId);
this._updateAnimationTimeoutId = 0;
}
}
},
_updateAnimation() {
this._updateAnimationTimeoutId = 0;
@@ -399,7 +404,7 @@ var Background = class Background {
});
}
}
}
},
_queueUpdateAnimation() {
if (this._updateAnimationTimeoutId != 0)
@@ -428,7 +433,7 @@ var Background = class Background {
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._updateAnimationTimeoutId, '[gnome-shell] this._updateAnimation');
}
},
_loadAnimation(file) {
this._cache.getAnimation({ file: file,
@@ -445,7 +450,7 @@ var Background = class Background {
this._watchFile(file);
}
});
}
},
_loadImage(file) {
this.background.set_file(file, this._style);
@@ -461,14 +466,14 @@ var Background = class Background {
image.disconnect(id);
});
}
}
},
_loadFile(file) {
if (file.get_basename().endsWith('.xml'))
this._loadAnimation(file);
else
this._loadImage(file);
}
},
_load() {
this._cache = getBackgroundCache();
@@ -481,14 +486,16 @@ var Background = class Background {
}
this._loadFile(this._file);
}
};
},
});
Signals.addSignalMethods(Background.prototype);
let _systemBackground;
var SystemBackground = class SystemBackground {
constructor() {
var SystemBackground = new Lang.Class({
Name: 'SystemBackground',
_init() {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png');
if (_systemBackground == null) {
@@ -517,12 +524,14 @@ var SystemBackground = class SystemBackground {
image = null;
});
}
}
};
},
});
Signals.addSignalMethods(SystemBackground.prototype);
var BackgroundSource = class BackgroundSource {
constructor(layoutManager, settingsSchema) {
var BackgroundSource = new Lang.Class({
Name: 'BackgroundSource',
_init(layoutManager, settingsSchema) {
// Allow override the background image setting for performance testing
this._layoutManager = layoutManager;
this._overrideImage = GLib.getenv('SHELL_BACKGROUND_IMAGE');
@@ -533,7 +542,7 @@ var BackgroundSource = class BackgroundSource {
this._monitorsChangedId =
monitorManager.connect('monitors-changed',
this._onMonitorsChanged.bind(this));
}
},
_onMonitorsChanged() {
for (let monitorIndex in this._backgrounds) {
@@ -547,7 +556,7 @@ var BackgroundSource = class BackgroundSource {
delete this._backgrounds[monitorIndex];
}
}
}
},
getBackground(monitorIndex) {
let file = null;
@@ -594,7 +603,7 @@ var BackgroundSource = class BackgroundSource {
}
return this._backgrounds[monitorIndex];
}
},
destroy() {
let monitorManager = Meta.MonitorManager.get();
@@ -608,10 +617,12 @@ var BackgroundSource = class BackgroundSource {
this._backgrounds = null;
}
};
});
var Animation = class Animation {
constructor(params) {
var Animation = new Lang.Class({
Name: 'Animation',
_init(params) {
params = Params.parse(params, { file: null });
this.file = params.file;
@@ -619,7 +630,7 @@ var Animation = class Animation {
this.transitionProgress = 0.0;
this.transitionDuration = 0.0;
this.loaded = false;
}
},
load(callback) {
this._show = new GnomeDesktop.BGSlideShow({ filename: this.file.get_path() });
@@ -629,7 +640,7 @@ var Animation = class Animation {
if (callback)
callback();
});
}
},
update(monitor) {
this.keyFrameFiles = [];
@@ -650,12 +661,14 @@ var Animation = class Animation {
if (filename2)
this.keyFrameFiles.push(Gio.File.new_for_path(filename2));
}
};
},
});
Signals.addSignalMethods(Animation.prototype);
var BackgroundManager = class BackgroundManager {
constructor(params) {
var BackgroundManager = new Lang.Class({
Name: 'BackgroundManager',
_init(params) {
params = Params.parse(params, { container: null,
layoutManager: Main.layoutManager,
monitorIndex: null,
@@ -675,7 +688,7 @@ var BackgroundManager = class BackgroundManager {
this.backgroundActor = this._createBackgroundActor();
this._newBackgroundActor = null;
}
},
destroy() {
let cache = getBackgroundCache();
@@ -691,7 +704,7 @@ var BackgroundManager = class BackgroundManager {
this.backgroundActor.destroy();
this.backgroundActor = null;
}
}
},
_swapBackgroundActor() {
let oldBackgroundActor = this.backgroundActor;
@@ -708,7 +721,7 @@ var BackgroundManager = class BackgroundManager {
oldBackgroundActor.destroy();
}
});
}
},
_updateBackgroundActor() {
if (this._newBackgroundActor) {
@@ -737,7 +750,7 @@ var BackgroundManager = class BackgroundManager {
this._swapBackgroundActor();
});
}
}
},
_createBackgroundActor() {
let background = this._backgroundSource.getBackground(this._monitorIndex);
@@ -774,6 +787,6 @@ var BackgroundManager = class BackgroundManager {
});
return backgroundActor;
}
};
},
});
Signals.addSignalMethods(BackgroundManager.prototype);

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
@@ -8,9 +9,12 @@ const BoxPointer = imports.ui.boxpointer;
const Main = imports.ui.main;
const PopupMenu = imports.ui.popupMenu;
var BackgroundMenu = class BackgroundMenu extends PopupMenu.PopupMenu {
constructor(layoutManager) {
super(layoutManager.dummyCursor, 0, St.Side.TOP);
var BackgroundMenu = new Lang.Class({
Name: 'BackgroundMenu',
Extends: PopupMenu.PopupMenu,
_init(layoutManager) {
this.parent(layoutManager.dummyCursor, 0, St.Side.TOP);
this.addSettingsAction(_("Change Background…"), 'gnome-background-panel.desktop');
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@@ -22,7 +26,7 @@ var BackgroundMenu = class BackgroundMenu extends PopupMenu.PopupMenu {
layoutManager.uiGroup.add_actor(this.actor);
this.actor.hide();
}
};
});
function addBackgroundMenu(actor, layoutManager) {
actor.reactive = true;

View File

@@ -3,11 +3,14 @@
const Atk = imports.gi.Atk;
const Cairo = imports.cairo;
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const St = imports.gi.St;
const Signals = imports.signals;
var BarLevel = class {
constructor(value, params) {
var BarLevel = new Lang.Class({
Name: "BarLevel",
_init(value, params) {
if (isNaN(value))
// Avoid spreading NaNs around
throw TypeError('The bar level value must be a number');
@@ -37,7 +40,7 @@ var BarLevel = class {
this._customAccessible.connect('set-current-value', this._setCurrentValue.bind(this));
this.connect('value-changed', this._valueChanged.bind(this));
}
},
setValue(value) {
if (isNaN(value))
@@ -45,7 +48,7 @@ var BarLevel = class {
this._value = Math.max(Math.min(value, this._maxValue), 0);
this.actor.queue_repaint();
}
},
setMaximumValue(value) {
if (isNaN(value))
@@ -54,7 +57,7 @@ var BarLevel = class {
this._maxValue = Math.max(value, 1);
this._overdriveStart = Math.min(this._overdriveStart, this._maxValue);
this.actor.queue_repaint();
}
},
setOverdriveStart(value) {
if (isNaN(value))
@@ -66,7 +69,7 @@ var BarLevel = class {
this._overdriveStart = value;
this._value = Math.max(Math.min(value, this._maxValue), 0);
this.actor.queue_repaint();
}
},
_barLevelRepaint(area) {
let cr = area.get_context();
@@ -173,34 +176,35 @@ var BarLevel = class {
}
cr.$dispose();
}
},
_getCurrentValue(actor) {
return this._value;
}
},
_getOverdriveStart(actor) {
return this._overdriveStart;
}
},
_getMinimumValue(actor) {
return 0;
}
},
_getMaximumValue(actor) {
return this._maxValue;
}
},
_setCurrentValue(actor, value) {
this._value = value;
}
},
_valueChanged(barLevel, value, property) {
this._customAccessible.notify("accessible-value");
}
},
get value() {
return this._value;
}
};
});
Signals.addSignalMethods(BarLevel.prototype);

View File

@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@@ -32,11 +32,13 @@ var POPUP_ANIMATION_TIME = 0.15;
* totally inside the monitor if possible.
*
*/
var BoxPointer = GObject.registerClass({
var BoxPointer = new Lang.Class({
Name: 'BoxPointer',
Extends: St.Widget,
Signals: { 'arrow-side-changed': {} },
}, class BoxPointer extends St.Widget {
_init(arrowSide, binProperties) {
super._init();
this.parent();
this.actor = this;
@@ -59,24 +61,24 @@ var BoxPointer = GObject.registerClass({
this._sourceAlignment = 0.5;
this._capturedEventId = 0;
this._muteInput();
}
},
get arrowSide() {
return this._arrowSide;
}
},
_muteInput() {
if (this._capturedEventId == 0)
this._capturedEventId = this.connect('captured-event',
() => Clutter.EVENT_STOP);
}
},
_unmuteInput() {
if (this._capturedEventId != 0) {
this.disconnect(this._capturedEventId);
this._capturedEventId = 0;
}
}
},
// BoxPointer.show() and BoxPointer.hide() are here for only compatibility
// purposes, and will be removed in 3.32.
@@ -92,7 +94,7 @@ var BoxPointer = GObject.registerClass({
}
this.visible = true;
}
},
hide(animate, onComplete) {
if (animate !== undefined) {
@@ -106,7 +108,7 @@ var BoxPointer = GObject.registerClass({
}
this.visible = false;
}
},
open(animate, onComplete) {
let themeNode = this.get_theme_node();
@@ -147,7 +149,7 @@ var BoxPointer = GObject.registerClass({
onComplete();
},
time: animationTime });
}
},
close(animate, onComplete) {
if (!this.visible)
@@ -194,7 +196,7 @@ var BoxPointer = GObject.registerClass({
onComplete();
}
});
}
},
_adjustAllocationForArrow(isWidth, minSize, natSize) {
let themeNode = this.get_theme_node();
@@ -209,7 +211,7 @@ var BoxPointer = GObject.registerClass({
}
return [minSize, natSize];
}
},
vfunc_get_preferred_width(forHeight) {
let themeNode = this.get_theme_node();
@@ -219,7 +221,7 @@ var BoxPointer = GObject.registerClass({
width = this._adjustAllocationForArrow(true, ...width);
return themeNode.adjust_preferred_width(...width);
}
},
vfunc_get_preferred_height(forWidth) {
let themeNode = this.get_theme_node();
@@ -230,7 +232,7 @@ var BoxPointer = GObject.registerClass({
height = this._adjustAllocationForArrow(false, ...height);
return themeNode.adjust_preferred_height(...height);
}
},
vfunc_allocate(box, flags) {
this.set_allocation(box, flags);
@@ -274,7 +276,7 @@ var BoxPointer = GObject.registerClass({
this._reposition();
this._updateFlip();
}
}
},
_drawBorder(area) {
let themeNode = this.get_theme_node();
@@ -456,7 +458,7 @@ var BoxPointer = GObject.registerClass({
}
cr.$dispose();
}
},
setPosition(sourceActor, alignment) {
// We need to show it now to force an allocation,
@@ -468,7 +470,7 @@ var BoxPointer = GObject.registerClass({
this._reposition();
this._updateFlip();
}
},
setSourceAlignment(alignment) {
this._sourceAlignment = alignment;
@@ -477,7 +479,7 @@ var BoxPointer = GObject.registerClass({
return;
this.setPosition(this._sourceActor, this._arrowAlignment);
}
},
_reposition() {
let sourceActor = this._sourceActor;
@@ -591,7 +593,7 @@ var BoxPointer = GObject.registerClass({
this._xPosition = Math.floor(x);
this._yPosition = Math.floor(y);
this._shiftActor();
}
},
// @origin: Coordinate specifying middle of the arrow, along
// the Y axis for St.Side.LEFT, St.Side.RIGHT from the top and X axis from
@@ -601,7 +603,7 @@ var BoxPointer = GObject.registerClass({
this._arrowOrigin = origin;
this._border.queue_repaint();
}
}
},
// @actor: an actor relative to which the arrow is positioned.
// Differently from setPosition, this will not move the boxpointer itself,
@@ -611,7 +613,7 @@ var BoxPointer = GObject.registerClass({
this._arrowActor = actor;
this._border.queue_repaint();
}
}
},
_shiftActor() {
// Since the position of the BoxPointer depends on the allocated size
@@ -622,7 +624,7 @@ var BoxPointer = GObject.registerClass({
// x == y == 0.
this.set_anchor_point(-(this._xPosition + this._xOffset),
-(this._yPosition + this._yOffset));
}
},
_calculateArrowSide(arrowSide) {
let sourceAllocation = Shell.util_get_transformed_allocation(this._sourceActor);
@@ -656,7 +658,7 @@ var BoxPointer = GObject.registerClass({
}
return arrowSide;
}
},
_updateFlip() {
let arrowSide = this._calculateArrowSide(this._userArrowSide);
@@ -670,36 +672,36 @@ var BoxPointer = GObject.registerClass({
this.emit('arrow-side-changed');
}
}
},
set xOffset(offset) {
this._xOffset = offset;
this._shiftActor();
}
},
get xOffset() {
return this._xOffset;
}
},
set yOffset(offset) {
this._yOffset = offset;
this._shiftActor();
}
},
get yOffset() {
return this._yOffset;
}
},
updateArrowSide(side) {
this._arrowSide = side;
this._border.queue_repaint();
this.emit('arrow-side-changed');
}
},
getPadding(side) {
return this.bin.get_theme_node().get_padding(side);
}
},
getArrowHeight() {
return this.get_theme_node().get_length('-arrow-rise');

View File

@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const St = imports.gi.St;
const Signals = imports.signals;
const Shell = imports.gi.Shell;
@@ -88,42 +89,49 @@ function _getCalendarDayAbbreviation(dayNumber) {
// Abstraction for an appointment/event in a calendar
var CalendarEvent = class CalendarEvent {
constructor(id, date, end, summary, allDay) {
var CalendarEvent = new Lang.Class({
Name: 'CalendarEvent',
_init(id, date, end, summary, allDay) {
this.id = id;
this.date = date;
this.end = end;
this.summary = summary;
this.allDay = allDay;
}
};
});
// Interface for appointments/events - e.g. the contents of a calendar
//
// First, an implementation with no events
var EmptyEventSource = class EmptyEventSource {
constructor() {
var EmptyEventSource = new Lang.Class({
Name: 'EmptyEventSource',
_init() {
this.isLoading = false;
this.isDummy = true;
this.hasCalendars = false;
}
},
destroy() {
}
},
ignoreEvent(event) {
},
requestRange(begin, end) {
}
},
getEvents(begin, end) {
let result = [];
return result;
}
},
hasEvents(day) {
return false;
}
};
});
Signals.addSignalMethods(EmptyEventSource.prototype);
const CalendarServerIface = `
@@ -169,12 +177,22 @@ function _dateIntervalsOverlap(a0, a1, b0, b1)
}
// an implementation that reads data from a session bus service
var DBusEventSource = class DBusEventSource {
constructor() {
var DBusEventSource = new Lang.Class({
Name: 'DBusEventSource',
_init() {
this._resetCache();
this.isLoading = false;
this.isDummy = false;
this._ignoredEvents = new Map();
let savedState = global.get_persistent_state('as', 'ignored_events');
if (savedState)
savedState.deep_unpack().forEach(eventId => {
this._ignoredEvents.set(eventId, true);
});
this._initialized = false;
this._dbusProxy = new CalendarServer();
this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, (object, result) => {
@@ -217,39 +235,39 @@ var DBusEventSource = class DBusEventSource {
this._onNameAppeared();
}
});
}
},
destroy() {
this._dbusProxy.run_dispose();
}
},
get hasCalendars() {
if (this._initialized)
return this._dbusProxy.HasCalendars;
else
return false;
}
},
_resetCache() {
this._events = [];
this._lastRequestBegin = null;
this._lastRequestEnd = null;
}
},
_onNameAppeared(owner) {
this._initialized = true;
this._resetCache();
this._loadEvents(true);
}
},
_onNameVanished(oldOwner) {
this._resetCache();
this.emit('changed');
}
},
_onChanged() {
this._loadEvents(false);
}
},
_onEventsReceived(results, error) {
let newEvents = [];
@@ -271,7 +289,7 @@ var DBusEventSource = class DBusEventSource {
this._events = newEvents;
this.isLoading = false;
this.emit('changed');
}
},
_loadEvents(forceReload) {
// Ignore while loading
@@ -285,7 +303,17 @@ var DBusEventSource = class DBusEventSource {
this._onEventsReceived.bind(this),
Gio.DBusCallFlags.NONE);
}
}
},
ignoreEvent(event) {
if (this._ignoredEvents.get(event.id))
return;
this._ignoredEvents.set(event.id, true);
let savedState = new GLib.Variant('as', [...this._ignoredEvents.keys()]);
global.set_persistent_state('ignored_events', savedState);
this.emit('changed');
},
requestRange(begin, end) {
if (!(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
@@ -296,13 +324,16 @@ var DBusEventSource = class DBusEventSource {
this._curRequestEnd = end;
this._loadEvents(false);
}
}
},
getEvents(begin, end) {
let result = [];
for(let n = 0; n < this._events.length; n++) {
let event = this._events[n];
if (this._ignoredEvents.has(event.id))
continue;
if (_dateIntervalsOverlap (event.date, event.end, begin, end)) {
result.push(event);
}
@@ -314,7 +345,7 @@ var DBusEventSource = class DBusEventSource {
return d1.getTime() - d2.getTime();
});
return result;
}
},
hasEvents(day) {
let dayBegin = _getBeginningOfDay(day);
@@ -327,11 +358,13 @@ var DBusEventSource = class DBusEventSource {
return true;
}
};
});
Signals.addSignalMethods(DBusEventSource.prototype);
var Calendar = class Calendar {
constructor() {
var Calendar = new Lang.Class({
Name: 'Calendar',
_init() {
this._weekStart = Shell.util_get_week_start();
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.calendar' });
@@ -369,7 +402,7 @@ var Calendar = class Calendar {
this._onScroll.bind(this));
this._buildHeader ();
}
},
// @eventSource: is an object implementing the EventSource API, e.g. the
// requestRange(), getEvents(), hasEvents() methods and the ::changed signal.
@@ -381,7 +414,7 @@ var Calendar = class Calendar {
});
this._rebuildCalendar();
this._update();
}
},
// Sets the calendar to show a specific date
setDate(date) {
@@ -391,14 +424,14 @@ var Calendar = class Calendar {
this._selectedDate = date;
this._update();
this.emit('selected-date-changed', new Date(this._selectedDate));
}
},
updateTimeZone() {
// The calendar need to be rebuilt after a time zone update because
// the date might have changed.
this._rebuildCalendar();
this._update();
}
},
_buildHeader() {
let layout = this.actor.layout_manager;
@@ -455,7 +488,7 @@ var Calendar = class Calendar {
// All the children after this are days, and get removed when we update the calendar
this._firstDayIndex = this.actor.get_n_children();
}
},
_onScroll(actor, event) {
switch (event.get_scroll_direction()) {
@@ -469,7 +502,7 @@ var Calendar = class Calendar {
break;
}
return Clutter.EVENT_PROPAGATE;
}
},
_onPrevMonthButtonClicked() {
let newDate = new Date(this._selectedDate);
@@ -493,7 +526,7 @@ var Calendar = class Calendar {
this._backButton.grab_key_focus();
this.setDate(newDate);
}
},
_onNextMonthButtonClicked() {
let newDate = new Date(this._selectedDate);
@@ -517,14 +550,14 @@ var Calendar = class Calendar {
this._forwardButton.grab_key_focus();
this.setDate(newDate);
}
},
_onSettingsChange() {
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
this._buildHeader();
this._rebuildCalendar();
this._update();
}
},
_rebuildCalendar() {
let now = new Date();
@@ -645,7 +678,7 @@ var Calendar = class Calendar {
// Signal to the event source that we are interested in events
// only from this date range
this._eventSource.requestRange(beginDate, iter);
}
},
_update() {
let now = new Date();
@@ -668,17 +701,18 @@ var Calendar = class Calendar {
button.remove_style_pseudo_class('selected');
});
}
};
});
Signals.addSignalMethods(Calendar.prototype);
var EventMessage = class EventMessage extends MessageList.Message {
constructor(event, date) {
super('', event.summary);
var EventMessage = new Lang.Class({
Name: 'EventMessage',
Extends: MessageList.Message,
_init(event, date) {
this._event = event;
this._date = date;
this.setTitle(this._formatEventTime());
this.parent(this._formatEventTime(), event.summary);
this._icon = new St.Icon({ icon_name: 'x-office-calendar-symbolic' });
this.setIcon(this._icon);
@@ -687,7 +721,7 @@ var EventMessage = class EventMessage extends MessageList.Message {
let iconVisible = this.actor.get_parent().has_style_pseudo_class('first-child');
this._icon.opacity = (iconVisible ? 255 : 0);
});
}
},
_formatEventTime() {
let periodBegin = _getBeginningOfDay(this._date);
@@ -720,17 +754,23 @@ var EventMessage = class EventMessage extends MessageList.Message {
title = title + ELLIPSIS_CHAR;
}
return title;
},
canClose() {
return isToday(this._date);
}
};
});
var NotificationMessage =
class NotificationMessage extends MessageList.Message {
constructor(notification) {
super(notification.title, notification.bannerBodyText);
this.setUseBodyMarkup(notification.bannerBodyMarkup);
var NotificationMessage = new Lang.Class({
Name: 'NotificationMessage',
Extends: MessageList.Message,
_init(notification) {
this.notification = notification;
this.parent(notification.title, notification.bannerBodyText);
this.setUseBodyMarkup(notification.bannerBodyMarkup);
this.setIcon(this._getIcon());
this.connect('close', () => {
@@ -739,14 +779,13 @@ class NotificationMessage extends MessageList.Message {
this.notification.destroy(MessageTray.NotificationDestroyedReason.DISMISSED);
});
this._destroyId = notification.connect('destroy', () => {
this._disconnectNotificationSignals();
this.notification = null;
if (!this._closed)
this.close();
});
this._updatedId = notification.connect('updated',
this._onUpdated.bind(this));
}
},
_getIcon() {
if (this.notification.gicon)
@@ -754,25 +793,22 @@ class NotificationMessage extends MessageList.Message {
icon_size: MESSAGE_ICON_SIZE });
else
return this.notification.source.createIcon(MESSAGE_ICON_SIZE);
}
},
_onUpdated(n, clear) {
this.setIcon(this._getIcon());
this.setTitle(n.title);
this.setBody(n.bannerBodyText);
this.setUseBodyMarkup(n.bannerBodyMarkup);
}
},
_onClicked() {
this.notification.activate();
}
},
_onDestroy() {
super._onDestroy();
this._disconnectNotificationSignals();
}
this.parent();
_disconnectNotificationSignals() {
if (this._updatedId)
this.notification.disconnect(this._updatedId);
this._updatedId = 0;
@@ -781,22 +817,21 @@ class NotificationMessage extends MessageList.Message {
this.notification.disconnect(this._destroyId);
this._destroyId = 0;
}
});
canClose() {
return true;
}
};
var EventsSection = class EventsSection extends MessageList.MessageListSection {
constructor() {
super();
var EventsSection = new Lang.Class({
Name: 'EventsSection',
Extends: MessageList.MessageListSection,
_init() {
this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
this._desktopSettings.connect('changed', this._reloadEvents.bind(this));
this._eventSource = new EmptyEventSource();
this._messageById = new Map();
this.parent();
this._title = new St.Button({ style_class: 'events-section-title',
label: '',
x_align: St.Align.START,
@@ -809,16 +844,20 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
Shell.AppSystem.get_default().connect('installed-changed',
this._appInstalledChanged.bind(this));
this._appInstalledChanged();
}
},
_ignoreEvent(event) {
this._eventSource.ignoreEvent(event);
},
setEventSource(eventSource) {
this._eventSource = eventSource;
this._eventSource.connect('changed', this._reloadEvents.bind(this));
}
},
get allowed() {
return Main.sessionMode.showCalendarEvents;
}
},
_updateTitle() {
this._title.visible = !isToday(this._date);
@@ -837,7 +876,7 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
dayFormat = Shell.util_translate_time_string(NC_("calendar heading",
"%A, %B %-d, %Y"));
this._title.label = this._date.toLocaleFormat(dayFormat);
}
},
_reloadEvents() {
if (this._eventSource.isLoading)
@@ -863,6 +902,9 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
let message = this._messageById.get(event.id);
if (!message) {
message = new EventMessage(event, this._date);
message.connect('close', () => {
this._ignoreEvent(event);
});
this._messageById.set(event.id, message);
this.addMessage(message, false);
} else {
@@ -872,12 +914,12 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
this._reloading = false;
this._sync();
}
},
_appInstalledChanged() {
this._calendarApp = undefined;
this._title.reactive = (this._getCalendarApp() != null);
}
},
_getCalendarApp() {
if (this._calendarApp !== undefined)
@@ -892,7 +934,7 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
this._calendarApp = null;
}
return this._calendarApp;
}
},
_onTitleClicked() {
Main.overview.hide();
@@ -902,30 +944,32 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
if (app.get_id() == 'evolution.desktop')
app = Gio.DesktopAppInfo.new('evolution-calendar.desktop');
app.launch([], global.create_app_launch_context(0, -1));
}
},
setDate(date) {
super.setDate(date);
this.parent(date);
this._updateTitle();
this._reloadEvents();
}
},
_shouldShow() {
return !this.empty || !isToday(this._date);
}
},
_sync() {
if (this._reloading)
return;
super._sync();
this.parent();
}
};
});
var NotificationSection =
class NotificationSection extends MessageList.MessageListSection {
constructor() {
super();
var NotificationSection = new Lang.Class({
Name: 'NotificationSection',
Extends: MessageList.MessageListSection,
_init() {
this.parent();
this._sources = new Map();
this._nUrgent = 0;
@@ -936,12 +980,12 @@ class NotificationSection extends MessageList.MessageListSection {
});
this.actor.connect('notify::mapped', this._onMapped.bind(this));
}
},
get allowed() {
return Main.sessionMode.hasNotifications &&
!Main.sessionMode.isGreeter;
}
},
_createTimeLabel(datetime) {
let label = new St.Label({ style_class: 'event-time',
@@ -952,7 +996,7 @@ class NotificationSection extends MessageList.MessageListSection {
label.text = Util.formatTimeSpan(datetime);
});
return label;
}
},
_sourceAdded(tray, source) {
let obj = {
@@ -967,7 +1011,7 @@ class NotificationSection extends MessageList.MessageListSection {
this._onNotificationAdded.bind(this));
this._sources.set(source, obj);
}
},
_onNotificationAdded(source, notification) {
let message = new NotificationMessage(notification);
@@ -998,14 +1042,14 @@ class NotificationSection extends MessageList.MessageListSection {
let index = isUrgent ? 0 : this._nUrgent;
this.addMessageAtIndex(message, index, this.actor.mapped);
}
},
_onSourceDestroy(source, obj) {
source.disconnect(obj.destroyId);
source.disconnect(obj.notificationAddedId);
this._sources.delete(source);
}
},
_onMapped() {
if (!this.actor.mapped)
@@ -1014,15 +1058,17 @@ class NotificationSection extends MessageList.MessageListSection {
for (let message of this._messages.keys())
if (message.notification.urgency != MessageTray.Urgency.CRITICAL)
message.notification.acknowledged = true;
}
},
_shouldShow() {
return !this.empty && isToday(this._date);
}
};
});
var Placeholder = class Placeholder {
constructor() {
var Placeholder = new Lang.Class({
Name: 'Placeholder',
_init() {
this.actor = new St.BoxLayout({ style_class: 'message-list-placeholder',
vertical: true });
@@ -1040,14 +1086,14 @@ var Placeholder = class Placeholder {
this.actor.add_actor(this._label);
this._sync();
}
},
setDate(date) {
if (sameDay(this._date, date))
return;
this._date = date;
this._sync();
}
},
_sync() {
let today = isToday(this._date);
@@ -1064,10 +1110,12 @@ var Placeholder = class Placeholder {
this._label.text = _("No Events");
}
}
};
});
var CalendarMessageList = class CalendarMessageList {
constructor() {
var CalendarMessageList = new Lang.Class({
Name: 'CalendarMessageList',
_init() {
this.actor = new St.Widget({ style_class: 'message-list',
layout_manager: new Clutter.BinLayout(),
x_expand: true, y_expand: true });
@@ -1087,7 +1135,7 @@ var CalendarMessageList = class CalendarMessageList {
box.add_actor(this._scrollView);
this._clearButton = new St.Button({ style_class: 'message-list-clear-button button',
label: _("Clear"),
label: _("Clear All"),
can_focus: true });
this._clearButton.set_x_align(Clutter.ActorAlign.END);
this._clearButton.connect('clicked', () => {
@@ -1113,7 +1161,7 @@ var CalendarMessageList = class CalendarMessageList {
this._addSection(this._eventsSection);
Main.sessionMode.connect('updated', this._sync.bind(this));
}
},
_addSection(section) {
let obj = {
@@ -1138,7 +1186,7 @@ var CalendarMessageList = class CalendarMessageList {
this._sections.set(section, obj);
this._sectionList.add_actor(section.actor);
this._sync();
}
},
_removeSection(section) {
let obj = this._sections.get(section);
@@ -1151,11 +1199,11 @@ var CalendarMessageList = class CalendarMessageList {
this._sections.delete(section);
this._sectionList.remove_actor(section.actor);
this._sync();
}
},
_onKeyFocusIn(section, actor) {
Util.ensureActorVisibleInScrollView(this._scrollView, actor);
}
},
_sync() {
let sections = [...this._sections.keys()];
@@ -1170,15 +1218,15 @@ var CalendarMessageList = class CalendarMessageList {
let canClear = sections.some(s => s.canClear && s.actor.visible);
this._clearButton.reactive = canClear;
}
},
setEventSource(eventSource) {
this._eventsSection.setEventSource(eventSource);
}
},
setDate(date) {
for (let section of this._sections.keys())
section.setDate(date);
this._placeholder.setDate(date);
}
};
});

View File

@@ -2,8 +2,12 @@ const Clutter = imports.gi.Clutter;
const Pango = imports.gi.Pango;
const St = imports.gi.St;
var CheckBox = class CheckBox {
constructor(label) {
const Lang = imports.lang;
var CheckBox = new Lang.Class({
Name: 'CheckBox',
_init(label) {
let container = new St.BoxLayout();
this.actor = new St.Button({ style_class: 'check-box',
child: container,
@@ -24,13 +28,13 @@ var CheckBox = class CheckBox {
if (label)
this.setLabel(label);
}
},
setLabel(label) {
this._label.set_text(label);
}
},
getLabelActor() {
return this._label;
}
};
});

View File

@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
@@ -15,29 +16,31 @@ var FROZEN_WINDOW_BRIGHTNESS = -0.3
var DIALOG_TRANSITION_TIME = 0.15
var ALIVE_TIMEOUT = 5000;
var CloseDialog = GObject.registerClass({
var CloseDialog = new Lang.Class({
Name: 'CloseDialog',
Extends: GObject.Object,
Implements: [ Meta.CloseDialog ],
Properties: {
'window': GObject.ParamSpec.override('window', Meta.CloseDialog)
},
}, class CloseDialog extends GObject.Object {
_init(window) {
super._init();
this.parent();
this._window = window;
this._dialog = null;
this._tracked = undefined;
this._timeoutId = 0;
this._windowFocusChangedId = 0;
this._keyFocusChangedId = 0;
}
},
get window() {
return this._window;
}
},
set window(window) {
this._window = window;
}
},
_createDialogContent() {
let tracker = Shell.WindowTracker.get_default();
@@ -49,7 +52,7 @@ var CloseDialog = GObject.registerClass({
"continue or force the application to quit entirely.");
let icon = new Gio.ThemedIcon({ name: 'dialog-warning-symbolic' });
return new Dialog.MessageDialogContent({ icon, title, subtitle });
}
},
_initDialog() {
if (this._dialog)
@@ -69,7 +72,7 @@ var CloseDialog = GObject.registerClass({
key: Clutter.Escape });
global.focus_manager.add_group(this._dialog);
}
},
_addWindowEffect() {
// We set the effect on the surface actor, so the dialog itself
@@ -80,21 +83,21 @@ var CloseDialog = GObject.registerClass({
let effect = new Clutter.BrightnessContrastEffect();
effect.set_brightness(FROZEN_WINDOW_BRIGHTNESS);
surfaceActor.add_effect_with_name("gnome-shell-frozen-window", effect);
}
},
_removeWindowEffect() {
let windowActor = this._window.get_compositor_private();
let surfaceActor = windowActor.get_first_child();
surfaceActor.remove_effect_by_name("gnome-shell-frozen-window");
}
},
_onWait() {
this.response(Meta.CloseDialogResponse.WAIT);
}
},
_onClose() {
this.response(Meta.CloseDialogResponse.FORCE_CLOSE);
}
},
_onFocusChanged() {
if (Meta.is_wayland_compositor())
@@ -125,7 +128,7 @@ var CloseDialog = GObject.registerClass({
});
this._tracked = shouldTrack;
}
},
vfunc_show() {
if (this._dialog != null)
@@ -159,7 +162,7 @@ var CloseDialog = GObject.registerClass({
time: DIALOG_TRANSITION_TIME,
onComplete: this._onFocusChanged.bind(this)
});
}
},
vfunc_hide() {
if (this._dialog == null)
@@ -188,7 +191,7 @@ var CloseDialog = GObject.registerClass({
dialog.destroy();
}
});
}
},
vfunc_focus() {
if (this._dialog)

View File

@@ -1,13 +1,17 @@
const Lang = imports.lang;
const Main = imports.ui.main;
var ComponentManager = class {
constructor() {
var ComponentManager = new Lang.Class({
Name: 'ComponentManager',
_init() {
this._allComponents = {};
this._enabledComponents = [];
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
this._sessionUpdated();
}
},
_sessionUpdated() {
let newEnabledComponents = Main.sessionMode.components;
@@ -25,12 +29,12 @@ var ComponentManager = class {
});
this._enabledComponents = newEnabledComponents;
}
},
_importComponent(name) {
let module = imports.ui.components[name];
return module.Component;
}
},
_ensureComponent(name) {
let component = this._allComponents[name];
@@ -44,13 +48,13 @@ var ComponentManager = class {
component = new constructor();
this._allComponents[name] = component;
return component;
}
},
_enableComponent(name) {
let component = this._ensureComponent(name);
if (component)
component.enable();
}
},
_disableComponent(name) {
let component = this._allComponents[name];
@@ -58,4 +62,4 @@ var ComponentManager = class {
return;
component.disable();
}
};
});

View File

@@ -1,5 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
@@ -18,8 +19,10 @@ const SETTING_ENABLE_AUTOMOUNT = 'automount';
var AUTORUN_EXPIRE_TIMEOUT_SECS = 10;
var AutomountManager = class {
constructor() {
var AutomountManager = new Lang.Class({
Name: 'AutomountManager',
_init() {
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
this._volumeQueue = [];
this._activeOperations = new Map();
@@ -31,7 +34,7 @@ var AutomountManager = class {
this._inhibited = false;
this._volumeMonitor = Gio.VolumeMonitor.get();
}
},
enable() {
this._volumeAddedId = this._volumeMonitor.connect('volume-added', this._onVolumeAdded.bind(this));
@@ -42,7 +45,7 @@ var AutomountManager = class {
this._mountAllId = Mainloop.idle_add(this._startupMountAll.bind(this));
GLib.Source.set_name_by_id(this._mountAllId, '[gnome-shell] this._startupMountAll');
}
},
disable() {
this._volumeMonitor.disconnect(this._volumeAddedId);
@@ -55,7 +58,7 @@ var AutomountManager = class {
Mainloop.source_remove(this._mountAllId);
this._mountAllId = 0;
}
}
},
_InhibitorsChanged(object, senderName, [inhibtor]) {
this._session.IsInhibitedRemote(GNOME_SESSION_AUTOMOUNT_INHIBIT,
@@ -64,7 +67,7 @@ var AutomountManager = class {
this._inhibited = result[0];
}
});
}
},
_startupMountAll() {
let volumes = this._volumeMonitor.get_volumes();
@@ -76,7 +79,7 @@ var AutomountManager = class {
this._mountAllId = 0;
return GLib.SOURCE_REMOVE;
}
},
_onDriveConnected() {
// if we're not in the current ConsoleKit session,
@@ -84,11 +87,10 @@ var AutomountManager = class {
if (!this._session.SessionIsActive)
return;
let player = global.display.get_sound_player();
player.play_from_theme('device-added-media',
_("External drive connected"),
null);
}
global.play_theme_sound(0, 'device-added-media',
_("External drive connected"),
null);
},
_onDriveDisconnected() {
// if we're not in the current ConsoleKit session,
@@ -96,11 +98,10 @@ var AutomountManager = class {
if (!this._session.SessionIsActive)
return;
let sound = global.display.get_sound();
sound.play_from_theme('device-removed-media',
_("External drive disconnected"),
null);
}
global.play_theme_sound(0, 'device-removed-media',
_("External drive disconnected"),
null);
},
_onDriveEjectButton(monitor, drive) {
// TODO: this code path is not tested, as the GVfs volume monitor
@@ -131,11 +132,11 @@ var AutomountManager = class {
}
});
}
}
},
_onVolumeAdded(monitor, volume) {
this._checkAndMountVolume(volume);
}
},
_checkAndMountVolume(volume, params) {
params = Params.parse(params, { checkSession: true,
@@ -175,7 +176,7 @@ var AutomountManager = class {
} else {
this._mountVolume(volume, null, params.allowAutorun);
}
}
},
_mountVolume(volume, operation, allowAutorun) {
if (allowAutorun)
@@ -186,7 +187,7 @@ var AutomountManager = class {
volume.mount(0, mountOp, null,
this._onVolumeMounted.bind(this));
}
},
_onVolumeMounted(volume, res) {
this._allowAutorunExpire(volume);
@@ -211,7 +212,7 @@ var AutomountManager = class {
this._closeOperation(volume);
}
}
}
},
_onVolumeRemoved(monitor, volume) {
if (volume._allowAutorunExpireId && volume._allowAutorunExpireId > 0) {
@@ -220,7 +221,7 @@ var AutomountManager = class {
}
this._volumeQueue =
this._volumeQueue.filter(element => (element != volume));
}
},
_reaskPassword(volume) {
let prevOperation = this._activeOperations.get(volume);
@@ -229,7 +230,7 @@ var AutomountManager = class {
new ShellMountOperation.ShellMountOperation(volume,
{ existingDialog: existingDialog });
this._mountVolume(volume, operation);
}
},
_closeOperation(volume) {
let operation = this._activeOperations.get(volume);
@@ -237,11 +238,11 @@ var AutomountManager = class {
return;
operation.close();
this._activeOperations.delete(volume);
}
},
_allowAutorun(volume) {
volume.allowAutorun = true;
}
},
_allowAutorunExpire(volume) {
let id = Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, () => {
@@ -252,5 +253,5 @@ var AutomountManager = class {
volume._allowAutorunExpireId = id;
GLib.Source.set_name_by_id(id, '[gnome-shell] volume.allowAutorun');
}
};
});
var Component = AutomountManager;

View File

@@ -1,5 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Gio = imports.gi.Gio;
const St = imports.gi.St;
@@ -83,11 +84,13 @@ function HotplugSniffer() {
'/org/gnome/Shell/HotplugSniffer');
}
var ContentTypeDiscoverer = class {
constructor(callback) {
var ContentTypeDiscoverer = new Lang.Class({
Name: 'ContentTypeDiscoverer',
_init(callback) {
this._callback = callback;
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
}
},
guessContentTypes(mount) {
let autorunEnabled = !this._settings.get_boolean(SETTING_DISABLE_AUTORUN);
@@ -100,7 +103,7 @@ var ContentTypeDiscoverer = class {
} else {
this._emitCallback(mount, []);
}
}
},
_onContentTypeGuessed(mount, res) {
let contentTypes = [];
@@ -123,7 +126,7 @@ var ContentTypeDiscoverer = class {
this._emitCallback(mount, contentTypes);
});
}
}
},
_emitCallback(mount, contentTypes) {
if (!contentTypes)
@@ -147,25 +150,27 @@ var ContentTypeDiscoverer = class {
this._callback(mount, apps, contentTypes);
}
};
});
var AutorunManager = class {
constructor() {
var AutorunManager = new Lang.Class({
Name: 'AutorunManager',
_init() {
this._session = new GnomeSession.SessionManager();
this._volumeMonitor = Gio.VolumeMonitor.get();
this._dispatcher = new AutorunDispatcher(this);
}
},
enable() {
this._mountAddedId = this._volumeMonitor.connect('mount-added', this._onMountAdded.bind(this));
this._mountRemovedId = this._volumeMonitor.connect('mount-removed', this._onMountRemoved.bind(this));
}
},
disable() {
this._volumeMonitor.disconnect(this._mountAddedId);
this._volumeMonitor.disconnect(this._mountRemovedId);
}
},
_onMountAdded(monitor, mount) {
// don't do anything if our session is not the currently
@@ -177,19 +182,21 @@ var AutorunManager = class {
this._dispatcher.addMount(mount, apps, contentTypes);
});
discoverer.guessContentTypes(mount);
}
},
_onMountRemoved(monitor, mount) {
this._dispatcher.removeMount(mount);
}
};
});
var AutorunDispatcher = class {
constructor(manager) {
var AutorunDispatcher = new Lang.Class({
Name: 'AutorunDispatcher',
_init(manager) {
this._manager = manager;
this._sources = [];
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
}
},
_getAutorunSettingForType(contentType) {
let runApp = this._settings.get_strv(SETTING_START_APP);
@@ -205,7 +212,7 @@ var AutorunDispatcher = class {
return AutorunSetting.FILES;
return AutorunSetting.ASK;
}
},
_getSourceForMount(mount) {
let filtered = this._sources.filter(source => (source.mount == mount));
@@ -217,7 +224,7 @@ var AutorunDispatcher = class {
return filtered[0];
return null;
}
},
_addSource(mount, apps) {
// if we already have a source showing for this
@@ -227,7 +234,7 @@ var AutorunDispatcher = class {
// add a new source
this._sources.push(new AutorunSource(this._manager, mount, apps));
}
},
addMount(mount, apps, contentTypes) {
// if autorun is disabled globally, return
@@ -265,7 +272,7 @@ var AutorunDispatcher = class {
// but we failed launching the default app or the default file manager
if (!success)
this._addSource(mount, apps);
}
},
removeMount(mount) {
let source = this._getSourceForMount(mount);
@@ -277,39 +284,45 @@ var AutorunDispatcher = class {
// destroy the notification source
source.destroy();
}
};
});
var AutorunSource = class extends MessageTray.Source {
constructor(manager, mount, apps) {
super(mount.get_name());
var AutorunSource = new Lang.Class({
Name: 'AutorunSource',
Extends: MessageTray.Source,
_init(manager, mount, apps) {
this._manager = manager;
this.mount = mount;
this.apps = apps;
this.parent(mount.get_name());
this._notification = new AutorunNotification(this._manager, this);
// add ourselves as a source, and popup the notification
Main.messageTray.add(this);
this.notify(this._notification);
}
},
getIcon() {
return this.mount.get_icon();
}
},
_createPolicy() {
return new MessageTray.NotificationApplicationPolicy('org.gnome.Nautilus');
}
};
});
var AutorunNotification = class extends MessageTray.Notification {
constructor(manager, source) {
super(source, source.title);
var AutorunNotification = new Lang.Class({
Name: 'AutorunNotification',
Extends: MessageTray.Notification,
_init(manager, source) {
this.parent(source, source.title);
this._manager = manager;
this._mount = source.mount;
}
},
createBanner() {
let banner = new MessageTray.NotificationBanner(this);
@@ -322,7 +335,7 @@ var AutorunNotification = class extends MessageTray.Notification {
});
return banner;
}
},
_buttonForApp(app) {
let box = new St.BoxLayout();
@@ -349,14 +362,14 @@ var AutorunNotification = class extends MessageTray.Notification {
});
return button;
}
},
activate() {
super.activate();
this.parent();
let app = Gio.app_info_get_default_for_type('inode/directory', false);
startAppForMount(app, this._mount);
}
};
});
var Component = AutorunManager;

View File

@@ -1,5 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
@@ -16,10 +17,15 @@ const CheckBox = imports.ui.checkBox;
const Tweener = imports.ui.tweener;
var WORK_SPINNER_ICON_SIZE = 16;
var WORK_SPINNER_ANIMATION_DELAY = 1.0;
var WORK_SPINNER_ANIMATION_TIME = 0.3;
var KeyringDialog = class extends ModalDialog.ModalDialog {
constructor() {
super({ styleClass: 'prompt-dialog' });
var KeyringDialog = new Lang.Class({
Name: 'KeyringDialog',
Extends: ModalDialog.ModalDialog,
_init() {
this.parent({ styleClass: 'prompt-dialog' });
this.prompt = new Shell.KeyringPrompt();
this.prompt.connect('show-password', this._onShowPassword.bind(this));
@@ -57,17 +63,34 @@ var KeyringDialog = class extends ModalDialog.ModalDialog {
this.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE);
}
},
_setWorking(working) {
if (!this._workSpinner)
return;
if (working)
Tweener.removeTweens(this._workSpinner.actor);
if (working) {
this._workSpinner.play();
else
this._workSpinner.stop();
}
Tweener.addTween(this._workSpinner.actor,
{ opacity: 255,
delay: WORK_SPINNER_ANIMATION_DELAY,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
Tweener.addTween(this._workSpinner.actor,
{ opacity: 0,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear',
onCompleteScope: this,
onComplete() {
if (this._workSpinner)
this._workSpinner.stop();
}
});
}
},
_buildControlTable() {
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
@@ -91,7 +114,9 @@ var KeyringDialog = class extends ModalDialog.ModalDialog {
ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true });
this._passwordEntry.clutter_text.connect('activate', this._onPasswordActivate.bind(this));
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true);
let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
if (rtl) {
layout.attach(this._workSpinner.actor, 0, row, 1, 1);
@@ -158,7 +183,7 @@ var KeyringDialog = class extends ModalDialog.ModalDialog {
this._controlTable = table;
this._content.messageBox.add(table, { x_fill: true, y_fill: true });
}
},
_updateSensitivity(sensitive) {
if (this._passwordEntry) {
@@ -174,7 +199,7 @@ var KeyringDialog = class extends ModalDialog.ModalDialog {
this._continueButton.can_focus = sensitive;
this._continueButton.reactive = sensitive;
this._setWorking(!sensitive);
}
},
_ensureOpen() {
// NOTE: ModalDialog.open() is safe to call if the dialog is
@@ -192,61 +217,65 @@ var KeyringDialog = class extends ModalDialog.ModalDialog {
' Dismissing prompt request');
this.prompt.cancel()
return false;
}
},
_onShowPassword(prompt) {
this._buildControlTable();
this._ensureOpen();
this._updateSensitivity(true);
this._passwordEntry.grab_key_focus();
}
},
_onShowConfirm(prompt) {
this._buildControlTable();
this._ensureOpen();
this._updateSensitivity(true);
this._continueButton.grab_key_focus();
}
},
_onHidePrompt(prompt) {
this.close();
}
},
_onPasswordActivate() {
if (this.prompt.confirm_visible)
this._confirmEntry.grab_key_focus();
else
this._onContinueButton();
}
},
_onConfirmActivate() {
this._onContinueButton();
}
},
_onContinueButton() {
this._updateSensitivity(false);
this.prompt.complete();
}
},
_onCancelButton() {
this.prompt.cancel();
}
};
},
});
var KeyringDummyDialog = class {
constructor() {
var KeyringDummyDialog = new Lang.Class({
Name: 'KeyringDummyDialog',
_init() {
this.prompt = new Shell.KeyringPrompt();
this.prompt.connect('show-password', this._cancelPrompt.bind(this));
this.prompt.connect('show-confirm', this._cancelPrompt.bind(this));
}
},
_cancelPrompt() {
this.prompt.cancel();
}
};
});
var KeyringPrompter = class {
constructor() {
var KeyringPrompter = new Lang.Class({
Name: 'KeyringPrompter',
_init() {
this._prompter = new Gcr.SystemPrompter();
this._prompter.connect('new-prompt', () => {
let dialog = this._enabled ? new KeyringDialog()
@@ -258,7 +287,7 @@ var KeyringPrompter = class {
this._registered = false;
this._enabled = false;
this._currentPrompt = null;
}
},
enable() {
if (!this._registered) {
@@ -268,7 +297,7 @@ var KeyringPrompter = class {
this._registered = true;
}
this._enabled = true;
}
},
disable() {
this._enabled = false;
@@ -277,6 +306,6 @@ var KeyringPrompter = class {
this._currentPrompt.cancel();
this._currentPrompt = null;
}
};
});
var Component = KeyringPrompter;

View File

@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const NM = imports.gi.NM;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
@@ -20,9 +21,12 @@ const ShellEntry = imports.ui.shellEntry;
const VPN_UI_GROUP = 'VPN Plugin UI';
var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
constructor(agent, requestId, connection, settingName, hints, flags, contentOverride) {
super({ styleClass: 'prompt-dialog' });
var NetworkSecretDialog = new Lang.Class({
Name: 'NetworkSecretDialog',
Extends: ModalDialog.ModalDialog,
_init(agent, requestId, connection, settingName, hints, contentOverride) {
this.parent({ styleClass: 'prompt-dialog' });
this._agent = agent;
this._requestId = requestId;
@@ -105,18 +109,6 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
contentBox.messageBox.add(secretTable);
if (flags & NM.SecretAgentGetSecretsFlags.WPS_PBC_ACTIVE) {
let descriptionLabel = new St.Label({ style_class: 'prompt-dialog-description',
text: _("Alternatively you can connect by pushing the “WPS” button on your router.") });
descriptionLabel.clutter_text.line_wrap = true;
descriptionLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
messageBox.add(descriptionLabel,
{ y_fill: true,
y_align: St.Align.START,
expand: true });
}
this._okButton = { label: _("Connect"),
action: this._onOk.bind(this),
default: true
@@ -129,7 +121,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
this._okButton]);
this._updateOkButton();
}
},
_updateOkButton() {
let valid = true;
@@ -140,7 +132,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
this._okButton.button.reactive = valid;
this._okButton.button.can_focus = valid;
}
},
_onOk() {
let valid = true;
@@ -156,12 +148,12 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
this.close(global.get_current_time());
}
// do nothing if not valid
}
},
cancel() {
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.USER_CANCELED);
this.close(global.get_current_time());
}
},
_validateWpaPsk(secret) {
let value = secret.value;
@@ -177,7 +169,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
}
return (value.length >= 8 && value.length <= 63);
}
},
_validateStaticWep(secret) {
let value = secret.value;
@@ -202,7 +194,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
return false;
}
return true;
}
},
_getWirelessSecrets(secrets, wirelessSetting) {
let wirelessSecuritySetting = this._connection.get_setting_wireless_security();
@@ -239,7 +231,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
default:
log('Invalid wireless key management: ' + wirelessSecuritySetting.key_mgmt);
}
}
},
_get8021xSecrets(secrets) {
let ieee8021xSetting = this._connection.get_setting_802_1x();
@@ -282,7 +274,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
default:
log('Invalid EAP/IEEE802.1x method: ' + ieee8021xSetting.get_eap_method(0));
}
}
},
_getPPPoESecrets(secrets) {
let pppoeSetting = this._connection.get_setting_pppoe();
@@ -292,7 +284,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
value: pppoeSetting.service || '', password: false });
secrets.push({ label: _("Password: "), key: 'password',
value: pppoeSetting.password || '', password: true });
}
},
_getMobileSecrets(secrets, connectionType) {
let setting;
@@ -302,7 +294,7 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
setting = this._connection.get_setting_by_name(connectionType);
secrets.push({ label: _("Password: "), key: 'password',
value: setting.value || '', password: true });
}
},
_getContent() {
let connectionSetting = this._connection.get_setting_connection();
@@ -355,14 +347,15 @@ var NetworkSecretDialog = class extends ModalDialog.ModalDialog {
return content;
}
};
});
var VPNRequestHandler = class {
constructor(agent, requestId, authHelper, serviceType, connection, hints, flags) {
var VPNRequestHandler = new Lang.Class({
Name: 'VPNRequestHandler',
_init(agent, requestId, authHelper, serviceType, connection, hints, flags) {
this._agent = agent;
this._requestId = requestId;
this._connection = connection;
this._flags = flags;
this._pluginOutBuffer = [];
this._title = null;
this._description = null;
@@ -419,7 +412,7 @@ var VPNRequestHandler = class {
this._agent.respond(requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
}
}
},
cancel(respond) {
if (respond)
@@ -435,7 +428,7 @@ var VPNRequestHandler = class {
}
this.destroy();
}
},
destroy() {
if (this._destroyed)
@@ -449,7 +442,7 @@ var VPNRequestHandler = class {
// Stdout is closed when we finish reading from it
this._destroyed = true;
}
},
_vpnChildFinished(pid, status, requestObj) {
this._childWatch = 0;
@@ -470,7 +463,7 @@ var VPNRequestHandler = class {
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
this.destroy();
}
},
_vpnChildProcessLineOldStyle(line) {
if (this._previousLine != undefined) {
@@ -488,7 +481,7 @@ var VPNRequestHandler = class {
} else {
this._previousLine = line;
}
}
},
_readStdoutOldStyle() {
this._dataStdout.read_line_async(GLib.PRIORITY_DEFAULT, null, (stream, result) => {
@@ -505,7 +498,7 @@ var VPNRequestHandler = class {
// try to read more!
this._readStdoutOldStyle();
});
}
},
_readStdoutNewStyle() {
this._dataStdout.fill_async(-1, GLib.PRIORITY_DEFAULT, null, (stream, result) => {
@@ -523,7 +516,7 @@ var VPNRequestHandler = class {
this._dataStdout.set_buffer_size(2 * this._dataStdout.get_buffer_size());
this._readStdoutNewStyle();
});
}
},
_showNewStyleDialog() {
let keyfile = new GLib.KeyFile();
@@ -581,13 +574,13 @@ var VPNRequestHandler = class {
if (contentOverride && contentOverride.secrets.length) {
// Only show the dialog if we actually have something to ask
this._shellDialog = new NetworkSecretDialog(this._agent, this._requestId, this._connection, 'vpn', [], this._flags, contentOverride);
this._shellDialog = new NetworkSecretDialog(this._agent, this._requestId, this._connection, 'vpn', [], contentOverride);
this._shellDialog.open(global.get_current_time());
} else {
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.CONFIRMED);
this.destroy();
}
}
},
_writeConnection() {
let vpnSetting = this._connection.get_setting_vpn();
@@ -608,12 +601,14 @@ var VPNRequestHandler = class {
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
this.destroy();
}
}
};
},
});
Signals.addSignalMethods(VPNRequestHandler.prototype);
var NetworkAgent = class {
constructor() {
var NetworkAgent = new Lang.Class({
Name: 'NetworkAgent',
_init() {
this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent',
capabilities: NM.SecretAgentCapabilities.VPN_HINTS,
auto_register: false
@@ -644,7 +639,7 @@ var NetworkAgent = class {
logError(e, 'error initializing the NetworkManager Agent');
}
});
}
},
enable() {
if (!this._native)
@@ -653,7 +648,7 @@ var NetworkAgent = class {
this._native.auto_register = true;
if (this._initialized && !this._native.registered)
this._native.register_async(null, null);
}
},
disable() {
let requestId;
@@ -676,7 +671,7 @@ var NetworkAgent = class {
this._native.auto_register = false;
if (this._initialized && this._native.registered)
this._native.unregister_async(null, null);
}
},
_showNotification(requestId, connection, settingName, hints, flags) {
let source = new MessageTray.Source(_("Network Manager"), 'network-transmit-receive');
@@ -736,14 +731,14 @@ var NetworkAgent = class {
Main.messageTray.add(source);
source.notify(notification);
}
},
_newRequest(agent, requestId, connection, settingName, hints, flags) {
if (!(flags & NM.SecretAgentGetSecretsFlags.USER_REQUESTED))
this._showNotification(requestId, connection, settingName, hints, flags);
else
this._handleRequest(requestId, connection, settingName, hints, flags);
}
},
_handleRequest(requestId, connection, settingName, hints, flags) {
if (settingName == 'vpn') {
@@ -751,13 +746,13 @@ var NetworkAgent = class {
return;
}
let dialog = new NetworkSecretDialog(this._native, requestId, connection, settingName, hints, flags);
let dialog = new NetworkSecretDialog(this._native, requestId, connection, settingName, hints);
dialog.connect('destroy', () => {
delete this._dialogs[requestId];
});
this._dialogs[requestId] = dialog;
dialog.open(global.get_current_time());
}
},
_cancelRequest(agent, requestId) {
if (this._dialogs[requestId]) {
@@ -768,7 +763,7 @@ var NetworkAgent = class {
this._vpnRequests[requestId].cancel(false);
delete this._vpnRequests[requestId];
}
}
},
_vpnRequest(requestId, connection, hints, flags) {
let vpnSetting = connection.get_setting_vpn();
@@ -790,7 +785,7 @@ var NetworkAgent = class {
delete this._vpnRequests[requestId];
});
this._vpnRequests[requestId] = vpnRequest;
}
},
_buildVPNServiceCache() {
if (this._vpnCacheBuilt)
@@ -823,5 +818,5 @@ var NetworkAgent = class {
}
});
}
};
});
var Component = NetworkAgent;

View File

@@ -1,5 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Signals = imports.signals;
const Shell = imports.gi.Shell;
const AccountsService = imports.gi.AccountsService;
@@ -24,10 +25,15 @@ const Tweener = imports.ui.tweener;
var DIALOG_ICON_SIZE = 48;
var WORK_SPINNER_ICON_SIZE = 16;
var WORK_SPINNER_ANIMATION_DELAY = 1.0;
var WORK_SPINNER_ANIMATION_TIME = 0.3;
var AuthenticationDialog = class extends ModalDialog.ModalDialog {
constructor(actionId, body, cookie, userNames) {
super({ styleClass: 'prompt-dialog' });
var AuthenticationDialog = new Lang.Class({
Name: 'AuthenticationDialog',
Extends: ModalDialog.ModalDialog,
_init(actionId, body, cookie, userNames) {
this.parent({ styleClass: 'prompt-dialog' });
this.actionId = actionId;
this.message = body;
@@ -38,8 +44,6 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._group.visible = !Main.sessionMode.isLocked;
});
this.connect('closed', this._onDialogClosed.bind(this));
let icon = new Gio.ThemedIcon({ name: 'dialog-password-symbolic' });
let title = _("Authentication Required");
@@ -113,7 +117,10 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._passwordBox.add(this._passwordEntry,
{ expand: true });
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, true);
let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
this._passwordBox.add(this._workSpinner.actor);
this.setInitialKeyFocus(this._passwordEntry);
@@ -154,25 +161,50 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._identityToAuth = Polkit.UnixUser.new_for_name(userName);
this._cookie = cookie;
}
},
_setWorking(working) {
if (working)
Tweener.removeTweens(this._workSpinner.actor);
if (working) {
this._workSpinner.play();
else
this._workSpinner.stop();
}
Tweener.addTween(this._workSpinner.actor,
{ opacity: 255,
delay: WORK_SPINNER_ANIMATION_DELAY,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
Tweener.addTween(this._workSpinner.actor,
{ opacity: 0,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear',
onCompleteScope: this,
onComplete() {
if (this._workSpinner)
this._workSpinner.stop();
}
});
}
},
performAuthentication() {
this._destroySession();
this.destroySession();
this._session = new PolkitAgent.Session({ identity: this._identityToAuth,
cookie: this._cookie });
this._sessionCompletedId = this._session.connect('completed', this._onSessionCompleted.bind(this));
this._sessionRequestId = this._session.connect('request', this._onSessionRequest.bind(this));
this._sessionShowErrorId = this._session.connect('show-error', this._onSessionShowError.bind(this));
this._sessionShowInfoId = this._session.connect('show-info', this._onSessionShowInfo.bind(this));
this._session.connect('completed', this._onSessionCompleted.bind(this));
this._session.connect('request', this._onSessionRequest.bind(this));
this._session.connect('show-error', this._onSessionShowError.bind(this));
this._session.connect('show-info', this._onSessionShowInfo.bind(this));
this._session.initiate();
}
},
close(timestamp) {
this.parent(timestamp);
if (this._sessionUpdatedId)
Main.sessionMode.disconnect(this._sessionUpdatedId);
this._sessionUpdatedId = 0;
},
_ensureOpen() {
// NOTE: ModalDialog.open() is safe to call if the dialog is
@@ -194,14 +226,14 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
' cookie ' + this._cookie);
this._emitDone(true);
}
}
},
_emitDone(dismissed) {
if (!this._doneEmitted) {
this._doneEmitted = true;
this.emit('done', dismissed);
}
}
},
_updateSensitivity(sensitive) {
this._passwordEntry.reactive = sensitive;
@@ -210,7 +242,7 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._okButton.can_focus = sensitive;
this._okButton.reactive = sensitive;
this._setWorking(!sensitive);
}
},
_onEntryActivate() {
let response = this._passwordEntry.get_text();
@@ -221,11 +253,11 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._errorMessageLabel.hide();
this._infoMessageLabel.hide();
this._nullMessageLabel.show();
}
},
_onAuthenticateButtonPressed() {
this._onEntryActivate();
}
},
_onSessionCompleted(session, gainedAuthorization) {
if (this._completed || this._doneEmitted)
@@ -257,7 +289,7 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
/* Try and authenticate again */
this.performAuthentication();
}
}
},
_onSessionRequest(session, request, echo_on) {
// Cheap localization trick
@@ -276,7 +308,7 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._passwordEntry.grab_key_focus();
this._updateSensitivity(true);
this._ensureOpen();
}
},
_onSessionShowError(session, text) {
this._passwordEntry.set_text('');
@@ -285,7 +317,7 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._infoMessageLabel.hide();
this._nullMessageLabel.hide();
this._ensureOpen();
}
},
_onSessionShowInfo(session, text) {
this._passwordEntry.set_text('');
@@ -294,60 +326,43 @@ var AuthenticationDialog = class extends ModalDialog.ModalDialog {
this._errorMessageLabel.hide();
this._nullMessageLabel.hide();
this._ensureOpen();
}
},
_destroySession() {
destroySession() {
if (this._session) {
if (!this._completed)
this._session.cancel();
this._completed = false;
this._session.disconnect(this._sessionCompletedId);
this._session.disconnect(this._sessionRequestId);
this._session.disconnect(this._sessionShowErrorId);
this._session.disconnect(this._sessionShowInfoId);
this._session = null;
}
}
},
_onUserChanged() {
if (this._user.is_loaded && this._userAvatar) {
this._userAvatar.update();
this._userAvatar.actor.show();
}
}
},
cancel() {
this._wasDismissed = true;
this.close(global.get_current_time());
this._emitDone(true);
}
_onDialogClosed() {
if (this._sessionUpdatedId)
Main.sessionMode.disconnect(this._sessionUpdatedId);
this._sessionUpdatedId = 0;
if (this._user) {
this._user.disconnect(this._userLoadedId);
this._user.disconnect(this._userChangedId);
this._user = null;
}
this._destroySession();
}
};
},
});
Signals.addSignalMethods(AuthenticationDialog.prototype);
var AuthenticationAgent = class {
constructor() {
var AuthenticationAgent = new Lang.Class({
Name: 'AuthenticationAgent',
_init() {
this._currentDialog = null;
this._handle = null;
this._native = new Shell.PolkitAuthenticationAgent();
this._native.connect('initiate', this._onInitiate.bind(this));
this._native.connect('cancel', this._onCancel.bind(this));
this._sessionUpdatedId = 0;
}
},
enable() {
try {
@@ -355,7 +370,7 @@ var AuthenticationAgent = class {
} catch(e) {
log('Failed to register AuthenticationAgent');
}
}
},
disable() {
try {
@@ -363,7 +378,7 @@ var AuthenticationAgent = class {
} catch(e) {
log('Failed to unregister AuthenticationAgent');
}
}
},
_onInitiate(nativeAgent, actionId, message, iconName, cookie, userNames) {
// Don't pop up a dialog while locked
@@ -391,18 +406,19 @@ var AuthenticationAgent = class {
this._currentDialog.connect('done', this._onDialogDone.bind(this));
this._currentDialog.performAuthentication();
}
},
_onCancel(nativeAgent) {
this._completeRequest(false);
}
},
_onDialogDone(dialog, dismissed) {
this._completeRequest(dismissed);
}
},
_completeRequest(dismissed) {
this._currentDialog.close();
this._currentDialog.destroySession();
this._currentDialog = null;
if (this._sessionUpdatedId)
@@ -410,7 +426,7 @@ var AuthenticationAgent = class {
this._sessionUpdatedId = 0;
this._native.complete(dismissed);
}
};
},
});
var Component = AuthenticationAgent;

View File

@@ -3,7 +3,6 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
@@ -80,15 +79,17 @@ function makeMessageFromTplEvent(event) {
};
}
var TelepathyComponent = class {
constructor() {
var TelepathyComponent = new Lang.Class({
Name: 'TelepathyComponent',
_init() {
this._client = null;
if (!HAVE_TP)
return; // Telepathy isn't available
this._client = new TelepathyClient();
}
},
enable() {
if (!this._client)
@@ -102,7 +103,7 @@ var TelepathyComponent = class {
if (!this._client.account_manager.is_prepared(Tp.AccountManager.get_feature_quark_core()))
this._client.account_manager.prepare_async(null, null);
}
},
disable() {
if (!this._client)
@@ -110,10 +111,12 @@ var TelepathyComponent = class {
this._client.unregister();
}
};
});
var TelepathyClient = HAVE_TP ? new Lang.Class({
Name: 'TelepathyClient',
Extends: Tp.BaseClient,
var TelepathyClient = HAVE_TP ? GObject.registerClass(
class TelepathyClient extends Tp.BaseClient {
_init() {
// channel path -> ChatSource
this._chatSources = {};
@@ -137,7 +140,7 @@ class TelepathyClient extends Tp.BaseClient {
// channel matching its filters is detected.
// The second argument, recover, means _observeChannels will be run
// for any existing channel as well.
super._init({ name: 'GnomeShell',
this.parent({ name: 'GnomeShell',
account_manager: this._accountManager,
uniquify_name: true });
@@ -155,7 +158,7 @@ class TelepathyClient extends Tp.BaseClient {
// needed
this.set_delegated_channels_callback(
this._delegatedChannelsCb.bind(this));
}
},
vfunc_observe_channels(account, conn, channels,
dispatchOp, requests, context) {
@@ -176,7 +179,7 @@ class TelepathyClient extends Tp.BaseClient {
}
context.accept();
}
},
_createChatSource(account, conn, channel, contact) {
if (this._chatSources[channel.get_object_path()])
@@ -188,13 +191,13 @@ class TelepathyClient extends Tp.BaseClient {
source.connect('destroy', () => {
delete this._chatSources[channel.get_object_path()];
});
}
},
vfunc_handle_channels(account, conn, channels, requests,
user_action_time, context) {
this._handlingChannels(account, conn, channels, true);
context.accept();
}
},
_handlingChannels(account, conn, channels, notify) {
let len = channels.length;
@@ -228,7 +231,7 @@ class TelepathyClient extends Tp.BaseClient {
source.notify();
}
}
}
},
vfunc_add_dispatch_operation(account, conn, channels,
dispatchOp, context) {
@@ -246,7 +249,7 @@ class TelepathyClient extends Tp.BaseClient {
else
context.fail(new Tp.Error({ code: Tp.Error.INVALID_ARGUMENT,
message: 'Unsupported channel type' }));
}
},
_approveTextChannel(account, conn, channel, dispatchOp, context) {
let [targetHandle, targetHandleType] = channel.get_handle();
@@ -268,22 +271,25 @@ class TelepathyClient extends Tp.BaseClient {
});
context.accept();
}
},
_delegatedChannelsCb(client, channels) {
// Nothing to do as we don't make a distinction between observed and
// handled channels.
}
},
}) : null;
var ChatSource = class extends MessageTray.Source {
constructor(account, conn, channel, contact, client) {
super(contact.get_alias());
var ChatSource = new Lang.Class({
Name: 'ChatSource',
Extends: MessageTray.Source,
_init(account, conn, channel, contact, client) {
this._account = account;
this._contact = contact;
this._client = client;
this.parent(contact.get_alias());
this.isChat = true;
this._pendingMessages = [];
@@ -307,7 +313,7 @@ var ChatSource = class extends MessageTray.Source {
Main.messageTray.add(this);
this._getLogMessages();
}
},
_ensureNotification() {
if (this._notification)
@@ -323,13 +329,13 @@ var ChatSource = class extends MessageTray.Source {
this._notification = null;
});
this.pushNotification(this._notification);
}
},
_createPolicy() {
if (this._account.protocol_name == 'irc')
return new MessageTray.NotificationApplicationPolicy('org.gnome.Polari');
return new MessageTray.NotificationApplicationPolicy('empathy');
}
},
createBanner() {
this._banner = new ChatNotificationBanner(this._notification);
@@ -342,7 +348,7 @@ var ChatSource = class extends MessageTray.Source {
});
return this._banner;
}
},
_updateAlias() {
let oldAlias = this.title;
@@ -354,7 +360,7 @@ var ChatSource = class extends MessageTray.Source {
this.setTitle(newAlias);
if (this._notification)
this._notification.appendAliasChange(oldAlias, newAlias);
}
},
getIcon() {
let file = this._contact.get_avatar_file();
@@ -363,7 +369,7 @@ var ChatSource = class extends MessageTray.Source {
} else {
return new Gio.ThemedIcon({ name: 'avatar-default' });
}
}
},
getSecondaryIcon() {
let iconName;
@@ -392,7 +398,7 @@ var ChatSource = class extends MessageTray.Source {
iconName = 'user-offline';
}
return new Gio.ThemedIcon({ name: iconName });
}
},
_updateAvatarIcon() {
this.iconUpdated();
@@ -400,7 +406,7 @@ var ChatSource = class extends MessageTray.Source {
this._notification.update(this._notification.title,
this._notification.bannerBodyText,
{ gicon: this.getIcon() });
}
},
open() {
Main.overview.hide();
@@ -425,7 +431,7 @@ var ChatSource = class extends MessageTray.Source {
cd.present_channel_async(this._channel, global.get_current_time(), null);
}
}
},
_getLogMessages() {
let logManager = Tpl.LogManager.dup_singleton();
@@ -434,7 +440,7 @@ var ChatSource = class extends MessageTray.Source {
logManager.get_filtered_events_async(this._account, entity,
Tpl.EventTypeMask.TEXT, SCROLLBACK_HISTORY_LINES,
null, this._displayPendingMessages.bind(this));
}
},
_displayPendingMessages(logManager, result) {
let [success, events] = logManager.get_filtered_events_finish(result);
@@ -487,7 +493,7 @@ var ChatSource = class extends MessageTray.Source {
if (pendingMessages.length > 0)
this.notify();
}
},
destroy(reason) {
if (this._client.is_handling_channel(this._channel)) {
@@ -521,25 +527,25 @@ var ChatSource = class extends MessageTray.Source {
this._contact.disconnect(this._notifyAvatarId);
this._contact.disconnect(this._presenceChangedId);
super.destroy(reason);
}
this.parent(reason);
},
_channelClosed() {
this.destroy(MessageTray.NotificationDestroyedReason.SOURCE_CLOSED);
}
},
/* All messages are new messages for Telepathy sources */
get count() {
return this._pendingMessages.length;
}
},
get unseenCount() {
return this.count;
}
},
get countVisible() {
return this.count > 0;
}
},
_messageReceived(channel, message) {
if (message.get_message_type() == Tp.ChannelTextMessageType.DELIVERY_REPORT)
@@ -559,7 +565,7 @@ var ChatSource = class extends MessageTray.Source {
this._notifyTimeoutId = Mainloop.timeout_add(500,
this._notifyTimeout.bind(this));
GLib.Source.set_name_by_id(this._notifyTimeoutId, '[gnome-shell] this._notifyTimeout');
}
},
_notifyTimeout() {
if (this._pendingMessages.length != 0)
@@ -568,7 +574,7 @@ var ChatSource = class extends MessageTray.Source {
this._notifyTimeoutId = 0;
return GLib.SOURCE_REMOVE;
}
},
// This is called for both messages we send from
// our client and other clients as well.
@@ -576,11 +582,11 @@ var ChatSource = class extends MessageTray.Source {
this._ensureNotification();
message = makeMessageFromTpMessage(message, NotificationDirection.SENT);
this._notification.appendMessage(message);
}
},
notify() {
super.notify(this._notification);
}
this.parent(this._notification);
},
respond(text) {
let type;
@@ -595,7 +601,7 @@ var ChatSource = class extends MessageTray.Source {
this._channel.send_message_async(msg, 0, (src, result) => {
this._channel.send_message_finish(result);
});
}
},
setChatState(state) {
// We don't want to send COMPOSING every time a letter is typed into
@@ -608,14 +614,14 @@ var ChatSource = class extends MessageTray.Source {
this._chatState = state;
this._channel.set_chat_state_async(state, null);
}
}
},
_presenceChanged(contact, presence, status, message) {
if (this._notification)
this._notification.update(this._notification.title,
this._notification.bannerBodyText,
{ secondaryGIcon: this.getSecondaryIcon() });
}
},
_pendingRemoved(channel, message) {
let idx = this._pendingMessages.indexOf(message);
@@ -628,32 +634,35 @@ var ChatSource = class extends MessageTray.Source {
if (this._pendingMessages.length == 0 &&
this._banner && !this._banner.expanded)
this._banner.hide();
}
},
_ackMessages() {
// Don't clear our messages here, tp-glib will send a
// 'pending-message-removed' for each one.
this._channel.ack_all_pending_messages_async(null);
}
};
});
var ChatNotification = class extends MessageTray.Notification {
constructor(source) {
super(source, source.title, null,
{ secondaryGIcon: source.getSecondaryIcon() });
var ChatNotification = new Lang.Class({
Name: 'ChatNotification',
Extends: MessageTray.Notification,
_init(source) {
this.parent(source, source.title, null,
{ secondaryGIcon: source.getSecondaryIcon() });
this.setUrgency(MessageTray.Urgency.HIGH);
this.setResident(true);
this.messages = [];
this._timestampTimeoutId = 0;
}
},
destroy(reason) {
if (this._timestampTimeoutId)
Mainloop.source_remove(this._timestampTimeoutId);
this._timestampTimeoutId = 0;
super.destroy(reason);
}
this.parent(reason);
},
/**
* appendMessage:
@@ -691,7 +700,7 @@ var ChatNotification = class extends MessageTray.Notification {
styles: styles,
timestamp: message.timestamp,
noTimestamp: noTimestamp });
}
},
_filterMessages() {
if (this.messages.length < 1)
@@ -716,7 +725,7 @@ var ChatNotification = class extends MessageTray.Notification {
for (let i = 0; i < expired.length; i++)
this.emit('message-removed', expired[i]);
}
}
},
/**
* _append:
@@ -764,7 +773,7 @@ var ChatNotification = class extends MessageTray.Notification {
}
this._filterMessages();
}
},
appendTimestamp() {
this._timestampTimeoutId = 0;
@@ -775,7 +784,7 @@ var ChatNotification = class extends MessageTray.Notification {
this._filterMessages();
return GLib.SOURCE_REMOVE;
}
},
appendAliasChange(oldAlias, newAlias) {
oldAlias = GLib.markup_escape_text(oldAlias, -1);
@@ -791,19 +800,24 @@ var ChatNotification = class extends MessageTray.Notification {
this._filterMessages();
}
};
});
var ChatLineBox = new Lang.Class({
Name: 'ChatLineBox',
Extends: St.BoxLayout,
var ChatLineBox = GObject.registerClass(
class ChatLineBox extends St.BoxLayout {
vfunc_get_preferred_height(forWidth) {
let [, natHeight] = super.vfunc_get_preferred_height(forWidth);
let [, natHeight] = this.parent(forWidth);
return [natHeight, natHeight];
}
});
var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
constructor(notification) {
super(notification);
var ChatNotificationBanner = new Lang.Class({
Name: 'ChatNotificationBanner',
Extends: MessageTray.NotificationBanner,
_init(notification) {
this.parent(notification);
this._responseEntry = new St.Entry({ style_class: 'chat-response',
x_expand: true,
@@ -866,14 +880,14 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
for (let i = this.notification.messages.length - 1; i >= 0; i--)
this._addMessage(this.notification.messages[i]);
}
},
_onDestroy() {
super._onDestroy();
this.parent();
this.notification.disconnect(this._messageAddedId);
this.notification.disconnect(this._messageRemovedId);
this.notification.disconnect(this._timestampChangedId);
}
},
scrollTo(side) {
let adjustment = this._scrollArea.vscroll.adjustment;
@@ -881,11 +895,11 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
adjustment.value = adjustment.lower;
else if (side == St.Side.BOTTOM)
adjustment.value = adjustment.upper;
}
},
hide() {
this.emit('done-displaying');
}
},
_addMessage(message) {
let highlighter = new MessageList.URLHighlighter(message.body, true, true);
@@ -907,7 +921,7 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
this._messageActors.set(message, lineBox);
this._updateTimestamp(message);
}
},
_updateTimestamp(message) {
let actor = this._messageActors.get(message);
@@ -928,7 +942,7 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
actor.add_actor(timeLabel);
}
}
},
_onEntryActivated() {
let text = this._responseEntry.get_text();
@@ -941,7 +955,7 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
// see Source._messageSent
this._responseEntry.set_text('');
this.notification.source.respond(text);
}
},
_composingStopTimeout() {
this._composingTimeoutId = 0;
@@ -949,7 +963,7 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
this.notification.source.setChatState(Tp.ChannelChatState.PAUSED);
return GLib.SOURCE_REMOVE;
}
},
_onEntryChanged() {
let text = this._responseEntry.get_text();
@@ -976,6 +990,6 @@ var ChatNotificationBanner = class extends MessageTray.NotificationBanner {
this.notification.source.setChatState(Tp.ChannelChatState.ACTIVE);
}
}
};
});
var Component = TelepathyComponent;

View File

@@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@@ -20,13 +21,15 @@ var SortGroup = {
BOTTOM: 2
};
var CtrlAltTabManager = class CtrlAltTabManager {
constructor() {
var CtrlAltTabManager = new Lang.Class({
Name: 'CtrlAltTabManager',
_init() {
this._items = [];
this.addGroup(global.window_group, _("Windows"),
'focus-windows-symbolic', { sortGroup: SortGroup.TOP,
focusCallback: this._focusWindows.bind(this) });
}
},
addGroup(root, name, icon, params) {
let item = Params.parse(params, { sortGroup: SortGroup.MIDDLE,
@@ -41,7 +44,7 @@ var CtrlAltTabManager = class CtrlAltTabManager {
root.connect('destroy', () => { this.removeGroup(root); });
if (root instanceof St.Widget)
global.focus_manager.add_group(root);
}
},
removeGroup(root) {
if (root instanceof St.Widget)
@@ -52,14 +55,14 @@ var CtrlAltTabManager = class CtrlAltTabManager {
return;
}
}
}
},
focusGroup(item, timestamp) {
if (item.focusCallback)
item.focusCallback(timestamp);
else
item.root.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
}
},
// Sort the items into a consistent order; panel first, tray last,
// and everything else in between, sorted by X coordinate, so that
@@ -74,7 +77,7 @@ var CtrlAltTabManager = class CtrlAltTabManager {
[bx, y] = b.proxy.get_transformed_position();
return ax - bx;
}
},
popup(backward, binding, mask) {
// Start with the set of focus groups that are currently mapped
@@ -127,20 +130,22 @@ var CtrlAltTabManager = class CtrlAltTabManager {
this._popup = null;
});
}
}
},
_focusWindows(timestamp) {
global.display.focus_default_window(timestamp);
}
};
});
var CtrlAltTabPopup =
class CtrlAltTabPopup extends SwitcherPopup.SwitcherPopup {
constructor(items) {
super(items);
var CtrlAltTabPopup = new Lang.Class({
Name: 'CtrlAltTabPopup',
Extends: SwitcherPopup.SwitcherPopup,
_init(items) {
this.parent(items);
this._switcherList = new CtrlAltTabSwitcher(this._items);
}
},
_keyPressHandler(keysym, action) {
if (action == Meta.KeyBindingAction.SWITCH_PANELS)
@@ -155,22 +160,24 @@ class CtrlAltTabPopup extends SwitcherPopup.SwitcherPopup {
return Clutter.EVENT_PROPAGATE;
return Clutter.EVENT_STOP;
}
},
_finish(time) {
super._finish(time);
this.parent(time);
Main.ctrlAltTabManager.focusGroup(this._items[this._selectedIndex], time);
}
};
},
});
var CtrlAltTabSwitcher =
class CtrlAltTabSwitcher extends SwitcherPopup.SwitcherList {
constructor(items) {
super(true);
var CtrlAltTabSwitcher = new Lang.Class({
Name: 'CtrlAltTabSwitcher',
Extends: SwitcherPopup.SwitcherList,
_init(items) {
this.parent(true);
for (let i = 0; i < items.length; i++)
this._addIcon(items[i]);
}
},
_addIcon(item) {
let box = new St.BoxLayout({ style_class: 'alt-tab-app',
@@ -188,4 +195,4 @@ class CtrlAltTabSwitcher extends SwitcherPopup.SwitcherList {
this.addItem(box, text);
}
};
});

View File

@@ -3,8 +3,8 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Signals = imports.signals;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@@ -33,10 +33,12 @@ function getAppFromSource(source) {
// A container like StBin, but taking the child's scale into account
// when requesting a size
var DashItemContainer = GObject.registerClass(
class DashItemContainer extends St.Widget {
var DashItemContainer = new Lang.Class({
Name: 'DashItemContainer',
Extends: St.Widget,
_init() {
super._init({ style_class: 'dash-item-container',
this.parent({ style_class: 'dash-item-container',
pivot_point: new Clutter.Point({ x: .5, y: .5 }),
x_expand: true,
x_align: Clutter.ActorAlign.CENTER });
@@ -57,23 +59,23 @@ class DashItemContainer extends St.Widget {
this.child.destroy();
this.label.destroy();
});
}
},
vfunc_get_preferred_height(forWidth) {
let themeNode = this.get_theme_node();
forWidth = themeNode.adjust_for_width(forWidth);
let [minHeight, natHeight] = super.vfunc_get_preferred_height(forWidth);
let [minHeight, natHeight] = this.parent(forWidth);
return themeNode.adjust_preferred_height(minHeight * this.scale_y,
natHeight * this.scale_y);
}
},
vfunc_get_preferred_width(forHeight) {
let themeNode = this.get_theme_node();
forHeight = themeNode.adjust_for_height(forHeight);
let [minWidth, natWidth] = super.vfunc_get_preferred_width(forHeight);
let [minWidth, natWidth] = this.parent(forHeight);
return themeNode.adjust_preferred_width(minWidth * this.scale_x,
natWidth * this.scale_x);
}
},
showLabel() {
if (!this._labelText)
@@ -107,12 +109,12 @@ class DashItemContainer extends St.Widget {
time: DASH_ITEM_LABEL_SHOW_TIME,
transition: 'easeOutQuad',
});
}
},
setLabelText(text) {
this._labelText = text;
this.child.accessible_name = text;
}
},
hideLabel() {
Tweener.addTween(this.label,
@@ -123,7 +125,7 @@ class DashItemContainer extends St.Widget {
this.label.hide();
}
});
}
},
setChild(actor) {
if (this.child == actor)
@@ -136,7 +138,7 @@ class DashItemContainer extends St.Widget {
this.set_scale(this._childScale, this._childScale);
this.set_opacity(this._childOpacity);
}
},
show(animate) {
if (this.child == null)
@@ -149,7 +151,7 @@ class DashItemContainer extends St.Widget {
time: time,
transition: 'easeOutQuad'
});
}
},
animateOutAndDestroy() {
this.label.hide();
@@ -169,35 +171,37 @@ class DashItemContainer extends St.Widget {
this.destroy();
}
});
}
},
set childScale(scale) {
this._childScale = scale;
this.set_scale(scale, scale);
this.queue_relayout();
}
},
get childScale() {
return this._childScale;
}
},
set childOpacity(opacity) {
this._childOpacity = opacity;
this.set_opacity(opacity);
this.queue_redraw();
}
},
get childOpacity() {
return this._childOpacity;
}
});
var ShowAppsIcon = GObject.registerClass(
class ShowAppsIcon extends DashItemContainer {
var ShowAppsIcon = new Lang.Class({
Name: 'ShowAppsIcon',
Extends: DashItemContainer,
_init() {
super._init();
this.parent();
this.toggleButton = new St.Button({ style_class: 'show-apps',
track_hover: true,
@@ -213,7 +217,7 @@ class ShowAppsIcon extends DashItemContainer {
this.setChild(this.toggleButton);
this.setDragApp(null);
}
},
_createIcon(size) {
this._iconActor = new St.Icon({ icon_name: 'view-app-grid-symbolic',
@@ -221,7 +225,7 @@ class ShowAppsIcon extends DashItemContainer {
style_class: 'show-apps-icon',
track_hover: true });
return this._iconActor;
}
},
_canRemoveApp(app) {
if (app == null)
@@ -233,7 +237,7 @@ class ShowAppsIcon extends DashItemContainer {
let id = app.get_id();
let isFavorite = AppFavorites.getAppFavorites().isFavorite(id);
return isFavorite;
}
},
setDragApp(app) {
let canRemove = this._canRemoveApp(app);
@@ -246,14 +250,14 @@ class ShowAppsIcon extends DashItemContainer {
this.setLabelText(_("Remove from Favorites"));
else
this.setLabelText(_("Show Applications"));
}
},
handleDragOver(source, actor, x, y, time) {
if (!this._canRemoveApp(getAppFromSource(source)))
return DND.DragMotionResult.NO_DROP;
return DND.DragMotionResult.MOVE_DROP;
}
},
acceptDrop(source, actor, x, y, time) {
let app = getAppFromSource(source);
@@ -271,30 +275,36 @@ class ShowAppsIcon extends DashItemContainer {
}
});
var DragPlaceholderItem = GObject.registerClass(
class DragPlaceholderItem extends DashItemContainer {
var DragPlaceholderItem = new Lang.Class({
Name: 'DragPlaceholderItem',
Extends: DashItemContainer,
_init() {
super._init();
this.parent();
this.setChild(new St.Bin({ style_class: 'placeholder' }));
}
});
var EmptyDropTargetItem = GObject.registerClass(
class EmptyDropTargetItem extends DashItemContainer {
var EmptyDropTargetItem = new Lang.Class({
Name: 'EmptyDropTargetItem',
Extends: DashItemContainer,
_init() {
super._init();
this.parent();
this.setChild(new St.Bin({ style_class: 'empty-dash-drop-target' }));
}
});
var DashActor = GObject.registerClass(
class DashActor extends St.Widget {
var DashActor = new Lang.Class({
Name: 'DashActor',
Extends: St.Widget,
_init() {
let layout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.VERTICAL });
super._init({ name: 'dash',
this.parent({ name: 'dash',
layout_manager: layout,
clip_to_allocation: true });
}
},
vfunc_allocate(box, flags) {
let contentBox = this.get_theme_node().get_content_box(box);
@@ -315,7 +325,7 @@ class DashActor extends St.Widget {
childBox.y1 = contentBox.y2 - showAppsNatHeight;
childBox.y2 = contentBox.y2;
showAppsButton.allocate(childBox, flags);
}
},
vfunc_get_preferred_height(forWidth) {
// We want to request the natural height of all our children
@@ -323,7 +333,7 @@ class DashActor extends St.Widget {
// then calls BoxLayout), but we only request the showApps
// button as the minimum size
let [, natHeight] = super.vfunc_get_preferred_height(forWidth);
let [, natHeight] = this.parent(forWidth);
let themeNode = this.get_theme_node();
let adjustedForWidth = themeNode.adjust_for_width(forWidth);
@@ -337,8 +347,10 @@ class DashActor extends St.Widget {
const baseIconSizes = [ 16, 22, 24, 32, 48, 64 ];
var Dash = class Dash {
constructor() {
var Dash = new Lang.Class({
Name: 'Dash',
_init() {
this._maxHeight = -1;
this.iconSize = 64;
this._shownInitially = false;
@@ -395,7 +407,7 @@ var Dash = class Dash {
// Translators: this is the name of the dock/favorites area on
// the left of the overview
Main.ctrlAltTabManager.addGroup(this.actor, _("Dash"), 'user-bookmarks-symbolic');
}
},
_onDragBegin() {
this._dragCancelled = false;
@@ -409,26 +421,26 @@ var Dash = class Dash {
this._box.insert_child_at_index(this._emptyDropTarget, 0);
this._emptyDropTarget.show(true);
}
}
},
_onDragCancelled() {
this._dragCancelled = true;
this._endDrag();
}
},
_onDragEnd() {
if (this._dragCancelled)
return;
this._endDrag();
}
},
_endDrag() {
this._clearDragPlaceholder();
this._clearEmptyDropTarget();
this._showAppsIcon.setDragApp(null);
DND.removeDragMonitor(this._dragMonitor);
}
},
_onDragMotion(dragEvent) {
let app = getAppFromSource(dragEvent.source);
@@ -447,18 +459,18 @@ var Dash = class Dash {
this._showAppsIcon.setDragApp(null);
return DND.DragMotionResult.CONTINUE;
}
},
_appIdListToHash(apps) {
let ids = {};
for (let i = 0; i < apps.length; i++)
ids[apps[i].get_id()] = apps[i];
return ids;
}
},
_queueRedisplay() {
Main.queueDeferredWork(this._workId);
}
},
_hookUpLabel(item, appIcon) {
item.child.connect('notify::hover', () => {
@@ -478,7 +490,7 @@ var Dash = class Dash {
this._syncLabel(item, appIcon);
});
}
}
},
_createAppItem(app) {
let appIcon = new AppDisplay.AppIcon(app,
@@ -512,7 +524,7 @@ var Dash = class Dash {
this._hookUpLabel(item, appIcon);
return item;
}
},
_itemMenuStateChanged(item, opened) {
// When the menu closes, it calls sync_hover, which means
@@ -525,7 +537,7 @@ var Dash = class Dash {
item.hideLabel();
}
}
},
_syncLabel(item, appIcon) {
let shouldShow = appIcon ? appIcon.shouldShowTooltip() : item.child.get_hover();
@@ -561,7 +573,7 @@ var Dash = class Dash {
GLib.Source.set_name_by_id(this._resetHoverTimeoutId, '[gnome-shell] this._labelShowing');
}
}
}
},
_adjustIconSize() {
// For the icon size, we only consider children which are "proper"
@@ -651,7 +663,7 @@ var Dash = class Dash {
transition: 'easeOutQuad',
});
}
}
},
_redisplay() {
let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
@@ -780,7 +792,7 @@ var Dash = class Dash {
// Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=692744
// Without it, StBoxLayout may use a stale size cache
this._box.queue_relayout();
}
},
_clearDragPlaceholder() {
if (this._dragPlaceholder) {
@@ -792,14 +804,14 @@ var Dash = class Dash {
this._dragPlaceholder = null;
}
this._dragPlaceholderPos = -1;
}
},
_clearEmptyDropTarget() {
if (this._emptyDropTarget) {
this._emptyDropTarget.animateOutAndDestroy();
this._emptyDropTarget = null;
}
}
},
handleDragOver(source, actor, x, y, time) {
let app = getAppFromSource(source);
@@ -876,7 +888,7 @@ var Dash = class Dash {
return DND.DragMotionResult.MOVE_DROP;
return DND.DragMotionResult.COPY_DROP;
}
},
// Draggable target interface
acceptDrop(source, actor, x, y, time) {
@@ -926,5 +938,6 @@ var Dash = class Dash {
return true;
}
};
});
Signals.addSignalMethods(Dash.prototype);

View File

@@ -6,6 +6,7 @@ const GnomeDesktop = imports.gi.GnomeDesktop;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const GWeather = imports.gi.GWeather;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Pango = imports.gi.Pango;
const Cairo = imports.cairo;
@@ -30,8 +31,10 @@ function _isToday(date) {
now.getDate() == date.getDate();
}
var TodayButton = class TodayButton {
constructor(calendar) {
var TodayButton = new Lang.Class({
Name: 'TodayButton',
_init(calendar) {
// Having the ability to go to the current date if the user is already
// on the current date can be confusing. So don't make the button reactive
// until the selected date changes.
@@ -60,7 +63,7 @@ var TodayButton = class TodayButton {
// current date.
this.actor.reactive = !_isToday(date)
});
}
},
setDate(date) {
this._dayLabel.set_text(date.toLocaleFormat('%A'));
@@ -80,10 +83,12 @@ var TodayButton = class TodayButton {
dateFormat = Shell.util_translate_time_string (N_("%A %B %e %Y"));
this.actor.accessible_name = date.toLocaleFormat(dateFormat);
}
};
});
var WorldClocksSection = class WorldClocksSection {
constructor() {
var WorldClocksSection = new Lang.Class({
Name: 'WorldClocksSection',
_init() {
this._clock = new GnomeDesktop.WallClock();
this._clockNotifyId = 0;
@@ -113,11 +118,11 @@ var WorldClocksSection = class WorldClocksSection {
this._clockAppMon.watchSetting('world-clocks',
this._clocksChanged.bind(this));
this._sync();
}
},
_sync() {
this.actor.visible = this._clockAppMon.available;
}
},
_clocksChanged(settings) {
this._grid.destroy_all_children();
@@ -182,7 +187,7 @@ var WorldClocksSection = class WorldClocksSection {
this._clock.disconnect(this._clockNotifyId);
this._clockNotifyId = 0;
}
}
},
_updateLabels() {
for (let i = 0; i < this._locations.length; i++) {
@@ -192,10 +197,12 @@ var WorldClocksSection = class WorldClocksSection {
l.actor.text = Util.formatTime(now, { timeOnly: true });
}
}
};
});
var WeatherSection = class WeatherSection {
constructor() {
var WeatherSection = new Lang.Class({
Name: 'WeatherSection',
_init() {
this._weatherClient = new Weather.WeatherClient();
this.actor = new St.Button({ style_class: 'weather-button',
@@ -229,7 +236,7 @@ var WeatherSection = class WeatherSection {
this._weatherClient.connect('changed', this._sync.bind(this));
this._sync();
}
},
_getSummary(info, capitalize=false) {
let options = capitalize ? GWeather.FormatOptions.SENTENCE_CAPITALIZATION
@@ -243,7 +250,7 @@ var WeatherSection = class WeatherSection {
let [, sky] = info.get_value_sky();
return GWeather.Sky.to_string_full(sky, options);
}
},
_sameSummary(info1, info2) {
let [ok1, phenom1, qualifier1] = info1.get_value_conditions();
@@ -254,7 +261,7 @@ var WeatherSection = class WeatherSection {
let [, sky1] = info1.get_value_sky();
let [, sky2] = info2.get_value_sky();
return sky1 == sky2;
}
},
_getSummaryText() {
let info = this._weatherClient.info;
@@ -302,7 +309,7 @@ var WeatherSection = class WeatherSection {
return this._getSummary(info, capitalize);
});
return String.prototype.format.apply(fmt, summaries);
}
},
_getLabelText() {
if (!this._weatherClient.hasLocation)
@@ -321,7 +328,7 @@ var WeatherSection = class WeatherSection {
return _("Go online for weather information");
return _("Weather information is currently unavailable");
}
},
_sync() {
this.actor.visible = this._weatherClient.available;
@@ -331,10 +338,12 @@ var WeatherSection = class WeatherSection {
this._conditionsLabel.text = this._getLabelText();
}
};
});
var MessagesIndicator = class MessagesIndicator {
constructor() {
var MessagesIndicator = new Lang.Class({
Name: 'MessagesIndicator',
_init() {
this.actor = new St.Icon({ icon_name: 'message-indicator-symbolic',
icon_size: 16,
visible: false, y_expand: true,
@@ -348,18 +357,18 @@ var MessagesIndicator = class MessagesIndicator {
let sources = Main.messageTray.getSources();
sources.forEach(source => { this._onSourceAdded(null, source); });
}
},
_onSourceAdded(tray, source) {
source.connect('count-updated', this._updateCount.bind(this));
this._sources.push(source);
this._updateCount();
}
},
_onSourceRemoved(tray, source) {
this._sources.splice(this._sources.indexOf(source), 1);
this._updateCount();
}
},
_updateCount() {
let count = 0;
@@ -368,21 +377,23 @@ var MessagesIndicator = class MessagesIndicator {
this.actor.visible = (count > 0);
}
};
});
var IndicatorPad = new Lang.Class({
Name: 'IndicatorPad',
Extends: St.Widget,
var IndicatorPad = GObject.registerClass(
class IndicatorPad extends St.Widget {
_init(actor) {
this._source = actor;
this._source.connect('notify::visible', () => { this.queue_relayout(); });
super._init();
}
this.parent();
},
vfunc_get_preferred_width(container, forHeight) {
if (this._source.visible)
return this._source.get_preferred_width(forHeight);
return [0, 0];
}
},
vfunc_get_preferred_height(container, forWidth) {
if (this._source.visible)
@@ -391,15 +402,17 @@ class IndicatorPad extends St.Widget {
}
});
var FreezableBinLayout = GObject.registerClass(
class FreezableBinLayout extends Clutter.BinLayout {
var FreezableBinLayout = new Lang.Class({
Name: 'FreezableBinLayout',
Extends: Clutter.BinLayout,
_init() {
super._init();
this.parent();
this._frozen = false;
this._savedWidth = [NaN, NaN];
this._savedHeight = [NaN, NaN];
}
},
set frozen(v) {
if (this._frozen == v)
@@ -408,22 +421,22 @@ class FreezableBinLayout extends Clutter.BinLayout {
this._frozen = v;
if (!this._frozen)
this.layout_changed();
}
},
vfunc_get_preferred_width(container, forHeight) {
if (!this._frozen || this._savedWidth.some(isNaN))
return super.vfunc_get_preferred_width(container, forHeight);
return this.parent(container, forHeight);
return this._savedWidth;
}
},
vfunc_get_preferred_height(container, forWidth) {
if (!this._frozen || this._savedHeight.some(isNaN))
return super.vfunc_get_preferred_height(container, forWidth);
return this.parent(container, forWidth);
return this._savedHeight;
}
},
vfunc_allocate(container, allocation, flags) {
super.vfunc_allocate(container, allocation, flags);
this.parent(container, allocation, flags);
let [width, height] = allocation.get_size();
this._savedWidth = [width, width];
@@ -431,22 +444,26 @@ class FreezableBinLayout extends Clutter.BinLayout {
}
});
var CalendarColumnLayout = GObject.registerClass(
class CalendarColumnLayout extends Clutter.BoxLayout {
var CalendarColumnLayout = new Lang.Class({
Name: 'CalendarColumnLayout',
Extends: Clutter.BoxLayout,
_init(actor) {
super._init({ orientation: Clutter.Orientation.VERTICAL });
this.parent({ orientation: Clutter.Orientation.VERTICAL });
this._calActor = actor;
}
},
vfunc_get_preferred_width(container, forHeight) {
if (!this._calActor || this._calActor.get_parent() != container)
return super.vfunc_get_preferred_width(container, forHeight);
return this.parent(container, forHeight);
return this._calActor.get_preferred_width(forHeight);
}
});
var DateMenuButton = GObject.registerClass(
class DateMenuButton extends PanelMenu.Button {
var DateMenuButton = new Lang.Class({
Name: 'DateMenuButton',
Extends: PanelMenu.Button,
_init() {
let item;
let hbox;
@@ -455,7 +472,7 @@ class DateMenuButton extends PanelMenu.Button {
let menuAlignment = 0.5;
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
menuAlignment = 1.0 - menuAlignment;
super._init(menuAlignment);
this.parent(menuAlignment);
this._clockDisplay = new St.Label({ y_align: Clutter.ActorAlign.CENTER });
this._indicator = new MessagesIndicator();
@@ -536,11 +553,11 @@ class DateMenuButton extends PanelMenu.Button {
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
this._sessionUpdated();
}
},
_getEventSource() {
return new Calendar.DBusEventSource();
}
},
_setEventSource(eventSource) {
if (this._eventSource)
@@ -550,7 +567,7 @@ class DateMenuButton extends PanelMenu.Button {
this._messageList.setEventSource(eventSource);
this._eventSource = eventSource;
}
},
_updateTimeZone() {
// SpiderMonkey caches the time zone so we must explicitly clear it
@@ -559,7 +576,7 @@ class DateMenuButton extends PanelMenu.Button {
System.clearDateCaches();
this._calendar.updateTimeZone();
}
},
_sessionUpdated() {
let eventSource;

View File

@@ -5,11 +5,14 @@ const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Pango = imports.gi.Pango;
const St = imports.gi.St;
const Lang = imports.lang;
var Dialog = new Lang.Class({
Name: 'Dialog',
Extends: St.Widget,
var Dialog = GObject.registerClass(
class Dialog extends St.Widget {
_init(parentActor, styleClass) {
super._init({ layout_manager: new Clutter.BinLayout() });
this.parent({ layout_manager: new Clutter.BinLayout() });
this.connect('destroy', this._onDestroy.bind(this));
this._initialKeyFocus = null;
@@ -25,7 +28,7 @@ class Dialog extends St.Widget {
this._parentActor = parentActor;
this._eventId = this._parentActor.connect('event', this._modalEventHandler.bind(this));
this._parentActor.add_child(this);
}
},
_createDialog() {
this._dialog = new St.BoxLayout({ style_class: 'modal-dialog',
@@ -52,13 +55,13 @@ class Dialog extends St.Widget {
this._dialog.add(this.buttonLayout,
{ x_align: St.Align.MIDDLE,
y_align: St.Align.START });
}
},
_onDestroy() {
if (this._eventId != 0)
this._parentActor.disconnect(this._eventId);
this._eventId = 0;
}
},
_modalEventHandler(actor, event) {
if (event.type() == Clutter.EventType.KEY_PRESS) {
@@ -84,7 +87,7 @@ class Dialog extends St.Widget {
}
return Clutter.EVENT_PROPAGATE;
}
},
_setInitialKeyFocus(actor) {
if (this._initialKeyFocus)
@@ -96,15 +99,15 @@ class Dialog extends St.Widget {
this._initialKeyFocus = null;
this._initialKeyFocusDestroyId = 0;
});
}
},
get initialKeyFocus() {
return this._initialKeyFocus || this;
}
},
addContent(actor) {
this.contentLayout.add (actor, { expand: true });
}
},
addButton(buttonInfo) {
let { label, action, key } = buttonInfo;
@@ -141,15 +144,17 @@ class Dialog extends St.Widget {
this.buttonLayout.add_actor(button);
return button;
}
},
clearButtons() {
this.buttonLayout.destroy_all_children();
this._buttonKeys = {};
}
},
});
var MessageDialogContent = GObject.registerClass({
var MessageDialogContent = new Lang.Class({
Name: 'MessageDialogContent',
Extends: St.BoxLayout,
Properties: {
'icon': GObject.ParamSpec.object('icon', 'icon', 'icon',
GObject.ParamFlags.READWRITE |
@@ -167,8 +172,8 @@ var MessageDialogContent = GObject.registerClass({
GObject.ParamFlags.READWRITE |
GObject.ParamFlags.CONSTRUCT,
null)
}
}, class MessageDialogContent extends St.BoxLayout {
},
_init(params) {
this._icon = new St.Icon({ y_align: Clutter.ActorAlign.START });
this._title = new St.Label({ style_class: 'headline' });
@@ -187,7 +192,7 @@ var MessageDialogContent = GObject.registerClass({
if (!params.hasOwnProperty('style_class'))
params.style_class = 'message-dialog-main-layout';
super._init(params);
this.parent(params);
this.messageBox = new St.BoxLayout({ style_class: 'message-dialog-content',
x_expand: true,
@@ -199,45 +204,45 @@ var MessageDialogContent = GObject.registerClass({
this.add_actor(this._icon);
this.add_actor(this.messageBox);
}
},
get icon() {
return this._icon.gicon;
}
},
get title() {
return this._title.text;
}
},
get subtitle() {
return this._subtitle.text;
}
},
get body() {
return this._body.text;
}
},
set icon(icon) {
Object.assign(this._icon, { gicon: icon, visible: icon != null });
this.notify('icon');
}
},
set title(title) {
this._setLabel(this._title, 'title', title);
}
},
set subtitle(subtitle) {
this._setLabel(this._subtitle, 'subtitle', subtitle);
}
},
set body(body) {
this._setLabel(this._body, 'body', body);
}
},
_setLabel(label, prop, value) {
Object.assign(label, { text: value || '', visible: value != null });
this.notify(prop);
}
},
insertBeforeBody(actor) {
this.messageBox.insert_child_below(actor, this._body);

View File

@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const St = imports.gi.St;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@@ -73,8 +74,10 @@ function removeDragMonitor(monitor) {
}
}
var _Draggable = class _Draggable {
constructor(actor, params) {
var _Draggable = new Lang.Class({
Name: 'Draggable',
_init(actor, params) {
params = Params.parse(params, { manualMode: false,
restoreOnSuccess: false,
dragActorMaxSize: undefined,
@@ -109,7 +112,7 @@ var _Draggable = class _Draggable {
this._dragCancellable = true;
this._eventsGrabbed = false;
}
},
_onButtonPress(actor, event) {
if (event.get_button() != 1)
@@ -126,7 +129,7 @@ var _Draggable = class _Draggable {
this._dragStartY = stageY;
return Clutter.EVENT_PROPAGATE;
}
},
_onTouchEvent(actor, event) {
if (event.type() != Clutter.EventType.TOUCH_BEGIN ||
@@ -146,7 +149,7 @@ var _Draggable = class _Draggable {
this._dragStartY = stageY;
return Clutter.EVENT_PROPAGATE;
}
},
_grabDevice(actor) {
let manager = Clutter.DeviceManager.get_default();
@@ -158,7 +161,7 @@ var _Draggable = class _Draggable {
pointer.grab (actor);
this._grabbedDevice = pointer;
}
},
_ungrabDevice() {
if (this._touchSequence)
@@ -168,13 +171,13 @@ var _Draggable = class _Draggable {
this._touchSequence = null;
this._grabbedDevice = null;
}
},
_grabActor() {
this._grabDevice(this.actor);
this._onEventId = this.actor.connect('event',
this._onEvent.bind(this));
}
},
_ungrabActor() {
if (!this._onEventId)
@@ -183,7 +186,7 @@ var _Draggable = class _Draggable {
this._ungrabDevice();
this.actor.disconnect(this._onEventId);
this._onEventId = null;
}
},
_grabEvents() {
if (!this._eventsGrabbed) {
@@ -191,7 +194,7 @@ var _Draggable = class _Draggable {
if (this._eventsGrabbed)
this._grabDevice(_getEventHandlerActor());
}
}
},
_ungrabEvents() {
if (this._eventsGrabbed) {
@@ -199,7 +202,7 @@ var _Draggable = class _Draggable {
Main.popModal(_getEventHandlerActor());
this._eventsGrabbed = false;
}
}
},
_onEvent(actor, event) {
// We intercept BUTTON_RELEASE event to know that the button was released in case we
@@ -243,7 +246,7 @@ var _Draggable = class _Draggable {
}
return Clutter.EVENT_PROPAGATE;
}
},
/**
* fakeRelease:
@@ -256,7 +259,7 @@ var _Draggable = class _Draggable {
fakeRelease() {
this._buttonDown = false;
this._ungrabActor();
}
},
/**
* startDrag:
@@ -392,7 +395,7 @@ var _Draggable = class _Draggable {
onUpdateScope: this });
}
}
}
},
_maybeStartDrag(event) {
let [stageX, stageY] = event.get_coords();
@@ -406,17 +409,12 @@ var _Draggable = class _Draggable {
}
return true;
}
_pickTargetActor() {
return this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
this._dragX, this._dragY);
}
},
_updateDragHover() {
this._updateHoverId = 0;
let target = this._pickTargetActor();
let target = this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
this._dragX, this._dragY);
let dragEvent = {
x: this._dragX,
y: this._dragY,
@@ -424,18 +422,6 @@ var _Draggable = class _Draggable {
source: this.actor._delegate,
targetActor: target
};
let targetActorDestroyHandlerId;
let handleTargetActorDestroyClosure;
handleTargetActorDestroyClosure = () => {
target = this._pickTargetActor();
dragEvent.targetActor = target;
targetActorDestroyHandlerId =
target.connect('destroy', handleTargetActorDestroyClosure);
};
targetActorDestroyHandlerId =
target.connect('destroy', handleTargetActorDestroyClosure);
for (let i = 0; i < dragMonitors.length; i++) {
let motionFunc = dragMonitors[i].dragMotion;
if (motionFunc) {
@@ -446,7 +432,6 @@ var _Draggable = class _Draggable {
}
}
}
dragEvent.targetActor.disconnect(targetActorDestroyHandlerId);
while (target) {
if (target._delegate && target._delegate.handleDragOver) {
@@ -468,7 +453,7 @@ var _Draggable = class _Draggable {
}
global.display.set_cursor(Meta.Cursor.DND_IN_DRAG);
return GLib.SOURCE_REMOVE;
}
},
_queueUpdateDragHover() {
if (this._updateHoverId)
@@ -477,7 +462,7 @@ var _Draggable = class _Draggable {
this._updateHoverId = GLib.idle_add(GLib.PRIORITY_DEFAULT,
this._updateDragHover.bind(this));
GLib.Source.set_name_by_id(this._updateHoverId, '[gnome-shell] this._updateDragHover');
}
},
_updateDragPosition(event) {
let [stageX, stageY] = event.get_coords();
@@ -488,7 +473,7 @@ var _Draggable = class _Draggable {
this._queueUpdateDragHover();
return true;
}
},
_dragActorDropped(event) {
let [dropX, dropY] = event.get_coords();
@@ -551,7 +536,7 @@ var _Draggable = class _Draggable {
this._cancelDrag(event.get_time());
return true;
}
},
_getRestoreLocation() {
let x, y, scale;
@@ -583,7 +568,7 @@ var _Draggable = class _Draggable {
}
return [x, y, scale];
}
},
_cancelDrag(eventTime) {
this.emit('drag-cancelled', eventTime);
@@ -610,7 +595,7 @@ var _Draggable = class _Draggable {
scale_y: snapBackScale,
time: SNAP_BACK_ANIMATION_TIME,
});
}
},
_restoreDragActor(eventTime) {
this._dragState = DragState.INIT;
@@ -623,7 +608,7 @@ var _Draggable = class _Draggable {
this._animateDragEnd(eventTime,
{ time: REVERT_ANIMATION_TIME });
}
},
_animateDragEnd(eventTime, params) {
this._animationInProgress = true;
@@ -636,7 +621,7 @@ var _Draggable = class _Draggable {
// start the animation
Tweener.addTween(this._dragActor, params)
}
},
_finishAnimation() {
if (!this._animationInProgress)
@@ -647,7 +632,7 @@ var _Draggable = class _Draggable {
this._dragComplete();
global.display.set_cursor(Meta.Cursor.DEFAULT);
}
},
_onAnimationComplete(dragActor, eventTime) {
if (this._dragOrigParent) {
@@ -661,7 +646,7 @@ var _Draggable = class _Draggable {
this.emit('drag-end', eventTime, false);
this._finishAnimation();
}
},
_dragComplete() {
if (!this._actorDestroyed && this._dragActor)
@@ -683,7 +668,8 @@ var _Draggable = class _Draggable {
this._dragState = DragState.INIT;
currentDraggable = null;
}
};
});
Signals.addSignalMethods(_Draggable.prototype);
/**

View File

@@ -1,6 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Signals = imports.signals;
const Meta = imports.gi.Meta;
const Clutter = imports.gi.Clutter;
@@ -11,24 +11,26 @@ const Main = imports.ui.main;
var EDGE_THRESHOLD = 20;
var DRAG_DISTANCE = 80;
var EdgeDragAction = GObject.registerClass({
var EdgeDragAction = new Lang.Class({
Name: 'EdgeDragAction',
Extends: Clutter.GestureAction,
Signals: { 'activated': {} },
}, class EdgeDragAction extends Clutter.GestureAction {
_init(side, allowedModes) {
super._init();
this.parent();
this._side = side;
this._allowedModes = allowedModes;
this.set_n_touch_points(1);
global.display.connect('grab-op-begin', () => { this.cancel(); });
}
},
_getMonitorRect(x, y) {
let rect = new Meta.Rectangle({ x: x - 1, y: y - 1, width: 1, height: 1 });
let monitorIndex = global.display.get_monitor_index_for_rect(rect);
return global.display.get_monitor_geometry(monitorIndex);
}
},
vfunc_gesture_prepare(action, actor) {
if (this.get_n_current_points() == 0)
@@ -44,7 +46,7 @@ var EdgeDragAction = GObject.registerClass({
(this._side == St.Side.RIGHT && x > monitorRect.x + monitorRect.width - EDGE_THRESHOLD) ||
(this._side == St.Side.TOP && y < monitorRect.y + EDGE_THRESHOLD) ||
(this._side == St.Side.BOTTOM && y > monitorRect.y + monitorRect.height - EDGE_THRESHOLD));
}
},
vfunc_gesture_progress(action, actor) {
let [startX, startY] = this.get_press_coords(0);
@@ -64,7 +66,7 @@ var EdgeDragAction = GObject.registerClass({
}
return true;
}
},
vfunc_gesture_end(action, actor) {
let [startX, startY] = this.get_press_coords(0);

View File

@@ -16,6 +16,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const AccountsService = imports.gi.AccountsService;
@@ -234,10 +235,13 @@ function init() {
_endSessionDialog = new EndSessionDialog();
}
var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
constructor() {
super({ styleClass: 'end-session-dialog',
destroyOnClose: false });
var EndSessionDialog = new Lang.Class({
Name: 'EndSessionDialog',
Extends: ModalDialog.ModalDialog,
_init() {
this.parent({ styleClass: 'end-session-dialog',
destroyOnClose: false });
this._loginManager = LoginManager.getLoginManager();
this._userManager = AccountsService.UserManager.get_default();
@@ -352,12 +356,12 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(EndSessionDialogIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
}
},
_onDestroy() {
this._user.disconnect(this._userLoadedId);
this._user.disconnect(this._userChangedId);
}
},
_sync() {
let open = (this.state == ModalDialog.State.OPENING || this.state == ModalDialog.State.OPENED);
@@ -430,7 +434,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
this._scrollView.visible = hasApplications || hasSessions;
this._applicationHeader.visible = hasApplications;
this._sessionHeader.visible = hasSessions;
}
},
_updateButtons() {
let dialogContent = DialogContent[this._type];
@@ -452,20 +456,20 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
}
this.setButtons(buttons);
}
},
close(skipSignal) {
super.close();
this.parent();
if (!skipSignal)
this._dbusImpl.emit_signal('Closed', null);
}
},
cancel() {
this._stopTimer();
this._dbusImpl.emit_signal('Canceled', null);
this.close();
}
},
_confirm(signal) {
let callback = () => {
@@ -500,11 +504,11 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
} else {
this._triggerOfflineUpdateCancel(callback);
}
}
},
_onOpened() {
this._sync();
}
},
_triggerOfflineUpdateReboot(callback) {
this._pkOfflineProxy.TriggerRemote('reboot', (result, error) => {
@@ -513,7 +517,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
callback();
});
}
},
_triggerOfflineUpdateShutdown(callback) {
this._pkOfflineProxy.TriggerRemote('power-off', (result, error) => {
@@ -522,7 +526,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
callback();
});
}
},
_triggerOfflineUpdateCancel(callback) {
this._pkOfflineProxy.CancelRemote((result, error) => {
@@ -531,7 +535,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
callback();
});
}
},
_startTimer() {
let startTime = GLib.get_monotonic_time();
@@ -555,7 +559,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._timerId, '[gnome-shell] this._confirm');
}
},
_stopTimer() {
if (this._timerId > 0) {
@@ -564,7 +568,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
}
this._secondsLeft = 0;
}
},
_constructListItemForApp(inhibitor, app) {
let actor = new St.BoxLayout({ style_class: 'end-session-dialog-app-list-item',
@@ -589,7 +593,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
}
return actor;
}
},
_onInhibitorLoaded(inhibitor) {
if (this._applications.indexOf(inhibitor) < 0) {
@@ -608,7 +612,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
}
this._sync();
}
},
_constructListItemForSession(session) {
let avatar = new UserWidget.Avatar(session.user, { iconSize: _ITEM_ICON_SIZE });
@@ -638,7 +642,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
actor.label_actor = nameLabel;
return actor;
}
},
_loadSessions() {
this._loginManager.listSessions(result => {
@@ -680,7 +684,7 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
this._sync();
});
}
},
OpenAsync(parameters, invocation) {
let [type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths] = parameters;
@@ -750,9 +754,9 @@ var EndSessionDialog = class EndSessionDialog extends ModalDialog.ModalDialog {
invocation.return_value(null);
this.disconnect(signalId);
});
}
},
Close(parameters, invocation) {
this.close();
}
};
});

View File

@@ -14,6 +14,7 @@ const Clutter = imports.gi.Clutter;
const Gettext = imports.gettext;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const St = imports.gi.St;

View File

@@ -1,5 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
@@ -181,10 +183,12 @@ function checkForUpdates() {
});
}
var InstallExtensionDialog =
class InstallExtensionDialog extends ModalDialog.ModalDialog {
constructor(uuid, info, invocation) {
super({ styleClass: 'extension-dialog' });
var InstallExtensionDialog = new Lang.Class({
Name: 'InstallExtensionDialog',
Extends: ModalDialog.ModalDialog,
_init(uuid, info, invocation) {
this.parent({ styleClass: 'extension-dialog' });
this._uuid = uuid;
this._info = info;
@@ -212,12 +216,12 @@ class InstallExtensionDialog extends ModalDialog.ModalDialog {
let label = new St.Label({ style_class: 'message-dialog-title headline',
text: message });
box.add(label);
}
},
_onCancelButtonPressed(button, event) {
this.close();
this._invocation.return_value(GLib.Variant.new('(s)', ['cancelled']));
}
},
_onInstallButtonPressed(button, event) {
let params = { shell_version: Config.PACKAGE_VERSION };
@@ -260,7 +264,7 @@ class InstallExtensionDialog extends ModalDialog.ModalDialog {
this.close();
}
};
});
function init() {
_httpSession = new Soup.SessionAsync({ ssl_use_system_ca_file: true });

View File

@@ -1,5 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Signals = imports.signals;
const GLib = imports.gi.GLib;

View File

@@ -22,26 +22,29 @@
*/
const Atspi = imports.gi.Atspi;
const Lang = imports.lang;
const Signals = imports.signals;
const CARETMOVED = 'object:text-caret-moved';
const STATECHANGED = 'object:state-changed';
var FocusCaretTracker = class FocusCaretTracker {
constructor() {
var FocusCaretTracker = new Lang.Class({
Name: 'FocusCaretTracker',
_init() {
this._atspiListener = Atspi.EventListener.new(this._onChanged.bind(this));
this._atspiInited = false;
this._focusListenerRegistered = false;
this._caretListenerRegistered = false;
}
},
_onChanged(event) {
if (event.type.indexOf(STATECHANGED) == 0)
this.emit('focus-changed', event);
else if (event.type == CARETMOVED)
this.emit('caret-moved', event);
}
},
_initAtspi() {
if (!this._atspiInited && Atspi.init() == 0) {
@@ -50,7 +53,7 @@ var FocusCaretTracker = class FocusCaretTracker {
}
return this._atspiInited;
}
},
registerFocusListener() {
if (!this._initAtspi() || this._focusListenerRegistered)
@@ -59,7 +62,7 @@ var FocusCaretTracker = class FocusCaretTracker {
this._atspiListener.register(STATECHANGED + ':focused');
this._atspiListener.register(STATECHANGED + ':selected');
this._focusListenerRegistered = true;
}
},
registerCaretListener() {
if (!this._initAtspi() || this._caretListenerRegistered)
@@ -67,7 +70,7 @@ var FocusCaretTracker = class FocusCaretTracker {
this._atspiListener.register(CARETMOVED);
this._caretListenerRegistered = true;
}
},
deregisterFocusListener() {
if (!this._focusListenerRegistered)
@@ -76,7 +79,7 @@ var FocusCaretTracker = class FocusCaretTracker {
this._atspiListener.deregister(STATECHANGED + ':focused');
this._atspiListener.deregister(STATECHANGED + ':selected');
this._focusListenerRegistered = false;
}
},
deregisterCaretListener() {
if (!this._caretListenerRegistered)
@@ -85,5 +88,5 @@ var FocusCaretTracker = class FocusCaretTracker {
this._atspiListener.deregister(CARETMOVED);
this._caretListenerRegistered = false;
}
};
});
Signals.addSignalMethods(FocusCaretTracker.prototype);

View File

@@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@@ -45,8 +46,10 @@ function _popGrabHelper(grabHelper) {
// your code just needs to deal with it; you shouldn't adjust behavior directly
// after you call ungrab(), but instead pass an 'onUngrab' callback when you
// call grab().
var GrabHelper = class GrabHelper {
constructor(owner, params) {
var GrabHelper = new Lang.Class({
Name: 'GrabHelper',
_init(owner, params) {
this._owner = owner;
this._modalParams = params;
@@ -56,7 +59,7 @@ var GrabHelper = class GrabHelper {
this._ignoreUntilRelease = false;
this._modalCount = 0;
}
},
// addActor:
// @actor: an actor
@@ -68,7 +71,7 @@ var GrabHelper = class GrabHelper {
this.removeActor(actor);
});
this._actors.push(actor);
}
},
// removeActor:
// @actor: an actor
@@ -83,7 +86,7 @@ var GrabHelper = class GrabHelper {
actor.disconnect(actor.__grabHelperDestroyId);
delete actor.__grabHelperDestroyId;
}
}
},
_isWithinGrabbedActor(actor) {
let currentActor = this.currentGrab.actor;
@@ -95,19 +98,19 @@ var GrabHelper = class GrabHelper {
actor = actor.get_parent();
}
return false;
}
},
get currentGrab() {
return this._grabStack[this._grabStack.length - 1] || {};
}
},
get grabbed() {
return this._grabStack.length > 0;
}
},
get grabStack() {
return this._grabStack;
}
},
_findStackIndex(actor) {
if (!actor)
@@ -118,7 +121,7 @@ var GrabHelper = class GrabHelper {
return i;
}
return -1;
}
},
_actorInGrabStack(actor) {
while (actor) {
@@ -128,11 +131,11 @@ var GrabHelper = class GrabHelper {
actor = actor.get_parent();
}
return -1;
}
},
isActorGrabbed(actor) {
return this._findStackIndex(actor) >= 0;
}
},
// grab:
// @params: A bunch of parameters, see below
@@ -192,7 +195,7 @@ var GrabHelper = class GrabHelper {
}
return true;
}
},
_takeModalGrab() {
let firstGrab = (this._modalCount == 0);
@@ -205,7 +208,7 @@ var GrabHelper = class GrabHelper {
this._modalCount++;
return true;
}
},
_releaseModalGrab() {
this._modalCount--;
@@ -218,7 +221,7 @@ var GrabHelper = class GrabHelper {
Main.popModal(this._owner);
global.sync_pointer();
}
},
// ignoreRelease:
//
@@ -228,7 +231,7 @@ var GrabHelper = class GrabHelper {
// the next release event.
ignoreRelease() {
this._ignoreUntilRelease = true;
}
},
// ungrab:
// @params: The parameters for the grab; see below.
@@ -271,7 +274,7 @@ var GrabHelper = class GrabHelper {
if (poppedGrab.savedFocus)
poppedGrab.savedFocus.grab_key_focus();
}
}
},
onCapturedEvent(event) {
let type = event.type();
@@ -319,5 +322,5 @@ var GrabHelper = class GrabHelper {
}
return Clutter.EVENT_STOP;
}
};
},
});

View File

@@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter;
const IBus = imports.gi.IBus;
const Lang = imports.lang;
const Signals = imports.signals;
const St = imports.gi.St;
@@ -13,8 +14,10 @@ var MAX_CANDIDATES_PER_PAGE = 16;
var DEFAULT_INDEX_LABELS = [ '1', '2', '3', '4', '5', '6', '7', '8',
'9', '0', 'a', 'b', 'c', 'd', 'e', 'f' ];
var CandidateArea = class CandidateArea {
constructor() {
var CandidateArea = new Lang.Class({
Name: 'CandidateArea',
_init() {
this.actor = new St.BoxLayout({ vertical: true,
reactive: true,
visible: false });
@@ -71,7 +74,7 @@ var CandidateArea = class CandidateArea {
this._orientation = -1;
this._cursorPosition = 0;
}
},
setOrientation(orientation) {
if (this._orientation == orientation)
@@ -92,7 +95,7 @@ var CandidateArea = class CandidateArea {
this._previousButton.child.icon_name = 'go-up-symbolic';
this._nextButton.child.icon_name = 'go-down-symbolic';
}
}
},
setCandidates(indexes, candidates, cursorPosition, cursorVisible) {
for (let i = 0; i < MAX_CANDIDATES_PER_PAGE; ++i) {
@@ -111,7 +114,7 @@ var CandidateArea = class CandidateArea {
this._cursorPosition = cursorPosition;
if (cursorVisible)
this._candidateBoxes[cursorPosition].add_style_pseudo_class('selected');
}
},
updateButtons(wrapsAround, page, nPages) {
if (nPages < 2) {
@@ -121,12 +124,14 @@ var CandidateArea = class CandidateArea {
this._buttonBox.show();
this._previousButton.reactive = wrapsAround || page > 0;
this._nextButton.reactive = wrapsAround || page < nPages - 1;
}
};
},
});
Signals.addSignalMethods(CandidateArea.prototype);
var CandidatePopup = class CandidatePopup {
constructor() {
var CandidatePopup = new Lang.Class({
Name: 'CandidatePopup',
_init() {
this._boxPointer = new BoxPointer.BoxPointer(St.Side.TOP);
this._boxPointer.visible = false;
this._boxPointer.style_class = 'candidate-popup-boxpointer';
@@ -166,7 +171,7 @@ var CandidatePopup = class CandidatePopup {
});
this._panelService = null;
}
},
setPanelService(panelService) {
this._panelService = panelService;
@@ -270,13 +275,13 @@ var CandidatePopup = class CandidatePopup {
this._boxPointer.close(BoxPointer.PopupAnimation.NONE);
Main.keyboard.resetSuggestions();
});
}
},
_setDummyCursorGeometry(x, y, w, h) {
Main.layoutManager.setDummyCursorGeometry(x, y, w, h);
if (this._boxPointer.actor.visible)
this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
}
},
_updateVisibility() {
let isVisible = (!Main.keyboard.visible &&
@@ -291,7 +296,7 @@ var CandidatePopup = class CandidatePopup {
} else {
this._boxPointer.close(BoxPointer.PopupAnimation.NONE);
}
}
},
_setTextAttributes(clutterText, ibusAttrList) {
let attr;
@@ -299,4 +304,4 @@ var CandidatePopup = class CandidatePopup {
if (attr.get_attr_type() == IBus.AttrType.BACKGROUND)
clutterText.set_selection(attr.get_start_index(), attr.get_end_index());
}
};
});

View File

@@ -1,13 +1,13 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const Lang = imports.lang;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const Main = imports.ui.main;
@@ -34,8 +34,10 @@ var AnimationDirection = {
var APPICON_ANIMATION_OUT_SCALE = 3;
var APPICON_ANIMATION_OUT_TIME = 0.25;
var BaseIcon = GObject.registerClass(
class BaseIcon extends St.Bin {
var BaseIcon = new Lang.Class({
Name: 'BaseIcon',
Extends: St.Bin,
_init(label, params) {
params = Params.parse(params, { createIcon: null,
setSizeManually: false,
@@ -45,7 +47,7 @@ class BaseIcon extends St.Bin {
if (params.showLabel)
styleClass += ' overview-icon-with-label';
super._init({ style_class: styleClass,
this.parent({ style_class: styleClass,
x_fill: true,
y_fill: true });
@@ -77,18 +79,18 @@ class BaseIcon extends St.Bin {
let cache = St.TextureCache.get_default();
this._iconThemeChangedId = cache.connect('icon-theme-changed', this._onIconThemeChanged.bind(this));
}
},
vfunc_get_preferred_width(forHeight) {
// Return the actual height to keep the squared aspect
return this.get_preferred_height(-1);
}
},
// This can be overridden by a subclass, or by the createIcon
// parameter to _init()
createIcon(size) {
throw new Error('no implementation of createIcon in ' + this);
}
},
setIconSize(size) {
if (!this._setSizeManually)
@@ -98,7 +100,7 @@ class BaseIcon extends St.Bin {
return;
this._createIconTexture(size);
}
},
_createIconTexture(size) {
if (this.icon)
@@ -107,7 +109,7 @@ class BaseIcon extends St.Bin {
this.icon = this.createIcon(this.iconSize);
this._iconBin.child = this.icon;
}
},
vfunc_style_changed() {
let node = this.get_theme_node();
@@ -124,7 +126,7 @@ class BaseIcon extends St.Bin {
return;
this._createIconTexture(size);
}
},
_onDestroy() {
if (this._iconThemeChangedId > 0) {
@@ -132,11 +134,11 @@ class BaseIcon extends St.Bin {
cache.disconnect(this._iconThemeChangedId);
this._iconThemeChangedId = 0;
}
}
},
_onIconThemeChanged() {
this._createIconTexture(this.iconSize);
}
},
animateZoomOut() {
// Animate only the child instead of the entire actor, so the
@@ -185,12 +187,14 @@ function zoomOutActor(actor) {
});
}
var IconGrid = GObject.registerClass({
var IconGrid = new Lang.Class({
Name: 'IconGrid',
Extends: St.Widget,
Signals: {'animation-done': {},
'child-focused': { param_types: [Clutter.Actor.$gtype]} },
}, class IconGrid extends St.Widget {
_init(params) {
super._init({ style_class: 'icon-grid',
this.parent({ style_class: 'icon-grid',
y_align: Clutter.ActorAlign.START });
this.actor = this;
@@ -232,19 +236,19 @@ var IconGrid = GObject.registerClass({
this.connect('actor-added', this._childAdded.bind(this));
this.connect('actor-removed', this._childRemoved.bind(this));
}
},
_keyFocusIn(actor) {
this.emit('child-focused', actor);
}
},
_childAdded(grid, child) {
child._iconGridKeyFocusInId = child.connect('key-focus-in', this._keyFocusIn.bind(this));
}
},
_childRemoved(grid, child) {
child.disconnect(child._iconGridKeyFocusInId);
}
},
vfunc_get_preferred_width(forHeight) {
if (this._fillParent)
@@ -264,11 +268,11 @@ var IconGrid = GObject.registerClass({
let natSize = nColumns * this._getHItemSize() + totalSpacing + this.leftPadding + this.rightPadding;
return this.get_theme_node().adjust_preferred_width(minSize, natSize);
}
},
_getVisibleChildren() {
return this.get_children().filter(actor => actor.visible);
}
},
vfunc_get_preferred_height(forWidth) {
if (this._fillParent)
@@ -298,7 +302,7 @@ var IconGrid = GObject.registerClass({
let height = nRows * this._getVItemSize() + totalSpacing + this.topPadding + this.bottomPadding;
return themeNode.adjust_preferred_height(height, height);
}
},
vfunc_allocate(box, flags) {
this.set_allocation(box, flags);
@@ -359,7 +363,7 @@ var IconGrid = GObject.registerClass({
x += this._getHItemSize() + spacing;
}
}
}
},
vfunc_get_paint_volume(paintVolume) {
// Setting the paint volume does not make sense when we don't have
@@ -398,7 +402,7 @@ var IconGrid = GObject.registerClass({
}
return true;
}
},
/**
* Intended to be override by subclasses if they need a different
@@ -406,12 +410,12 @@ var IconGrid = GObject.registerClass({
*/
_getChildrenToAnimate() {
return this._getVisibleChildren();
}
},
_cancelAnimation() {
this._clonesAnimating.forEach(clone => { clone.destroy(); });
this._clonesAnimating = [];
}
},
_animationDone() {
this._clonesAnimating.forEach(clone => {
@@ -421,7 +425,7 @@ var IconGrid = GObject.registerClass({
});
this._clonesAnimating = [];
this.emit('animation-done');
}
},
animatePulse(animationDirection) {
if (animationDirection != AnimationDirection.IN)
@@ -470,7 +474,7 @@ var IconGrid = GObject.registerClass({
}
});
}
}
},
animateSpring(animationDirection, sourceActor) {
this._cancelAnimation();
@@ -570,7 +574,7 @@ var IconGrid = GObject.registerClass({
Tweener.addTween(actorClone, movementParams);
Tweener.addTween(actorClone, fadeParams);
}
}
},
_getAllocatedChildSizeAndSpacing(child) {
let [,, natWidth, natHeight] = child.get_preferred_size();
@@ -579,7 +583,7 @@ var IconGrid = GObject.registerClass({
let height = Math.min(this._getVItemSize(), natHeight);
let ySpacing = Math.max(0, height - natHeight) / 2;
return [width, height, xSpacing, ySpacing];
}
},
_calculateChildBox(child, x, y, box) {
/* Center the item in its allocation horizontally */
@@ -597,15 +601,15 @@ var IconGrid = GObject.registerClass({
childBox.x2 = childBox.x1 + width;
childBox.y2 = childBox.y1 + height;
return childBox;
}
},
columnsForWidth(rowWidth) {
return this._computeLayout(rowWidth)[0];
}
},
getRowLimit() {
return this._rowLimit;
}
},
_computeLayout(forWidth) {
let nColumns = 0;
@@ -622,7 +626,7 @@ var IconGrid = GObject.registerClass({
usedWidth -= spacing;
return [nColumns, usedWidth];
}
},
_onStyleChanged() {
let themeNode = this.get_theme_node();
@@ -630,7 +634,7 @@ var IconGrid = GObject.registerClass({
this._hItemSize = themeNode.get_length('-shell-grid-horizontal-item-size') || ICON_SIZE;
this._vItemSize = themeNode.get_length('-shell-grid-vertical-item-size') || ICON_SIZE;
this.queue_relayout();
}
},
nRows(forWidth) {
let children = this._getVisibleChildren();
@@ -639,35 +643,35 @@ var IconGrid = GObject.registerClass({
if (this._rowLimit)
nRows = Math.min(nRows, this._rowLimit);
return nRows;
}
},
rowsForHeight(forHeight) {
return Math.floor((forHeight - (this.topPadding + this.bottomPadding) + this._getSpacing()) / (this._getVItemSize() + this._getSpacing()));
}
},
usedHeightForNRows(nRows) {
return (this._getVItemSize() + this._getSpacing()) * nRows - this._getSpacing() + this.topPadding + this.bottomPadding;
}
},
usedWidth(forWidth) {
return this.usedWidthForNColumns(this.columnsForWidth(forWidth));
}
},
usedWidthForNColumns(columns) {
let usedWidth = columns * (this._getHItemSize() + this._getSpacing());
usedWidth -= this._getSpacing();
return usedWidth + this.leftPadding + this.rightPadding;
}
},
removeAll() {
this._items = [];
this.remove_all_children();
}
},
destroyAll() {
this._items = [];
this.destroy_all_children();
}
},
addItem(item, index) {
if (!item.icon instanceof BaseIcon)
@@ -678,35 +682,35 @@ var IconGrid = GObject.registerClass({
this.insert_child_at_index(item.actor, index);
else
this.add_actor(item.actor);
}
},
removeItem(item) {
this.remove_child(item.actor);
}
},
getItemAtIndex(index) {
return this.get_child_at_index(index);
}
},
visibleItemsCount() {
return this.get_children().filter(c => c.is_visible()).length;
}
},
setSpacing(spacing) {
this._fixedSpacing = spacing;
}
},
_getSpacing() {
return this._fixedSpacing ? this._fixedSpacing : this._spacing;
}
},
_getHItemSize() {
return this._fixedHItemSize ? this._fixedHItemSize : this._hItemSize;
}
},
_getVItemSize() {
return this._fixedVItemSize ? this._fixedVItemSize : this._vItemSize;
}
},
_updateSpacingForSize(availWidth, availHeight) {
let maxEmptyVArea = availHeight - this._minRows * this._getVItemSize();
@@ -739,7 +743,7 @@ var IconGrid = GObject.registerClass({
this.setSpacing(spacing);
if (this._padWithSpacing)
this.topPadding = this.rightPadding = this.bottomPadding = this.leftPadding = spacing;
}
},
/**
* This function must to be called before iconGrid allocation,
@@ -764,7 +768,7 @@ var IconGrid = GObject.registerClass({
}
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
this._updateIconSizes.bind(this));
}
},
// Note that this is ICON_SIZE as used by BaseIcon, not elsewhere in IconGrid; it's a bit messed up
_updateIconSizes() {
@@ -776,23 +780,25 @@ var IconGrid = GObject.registerClass({
}
});
var PaginatedIconGrid = GObject.registerClass({
var PaginatedIconGrid = new Lang.Class({
Name: 'PaginatedIconGrid',
Extends: IconGrid,
Signals: {'space-opened': {},
'space-closed': {} },
}, class PaginatedIconGrid extends IconGrid {
_init(params) {
super._init(params);
this.parent(params);
this._nPages = 0;
this.currentPage = 0;
this._rowsPerPage = 0;
this._spaceBetweenPages = 0;
this._childrenPerPage = 0;
}
},
vfunc_get_preferred_height(forWidth) {
let height = (this._availableHeightPerPageForItems() + this.bottomPadding + this.topPadding) * this._nPages + this._spaceBetweenPages * this._nPages;
return [height, height];
}
},
vfunc_allocate(box, flags) {
if (this._childrenPerPage == 0)
@@ -847,7 +853,7 @@ var PaginatedIconGrid = GObject.registerClass({
} else
x += this._getHItemSize() + spacing;
}
}
},
// Overriden from IconGrid
_getChildrenToAnimate() {
@@ -856,7 +862,7 @@ var PaginatedIconGrid = GObject.registerClass({
let lastIndex = firstIndex + this._childrenPerPage;
return children.slice(firstIndex, lastIndex);
}
},
_computePages(availWidthPerPage, availHeightPerPage) {
let [nColumns, usedWidth] = this._computeLayout(availWidthPerPage);
@@ -875,24 +881,24 @@ var PaginatedIconGrid = GObject.registerClass({
this._nPages = Math.ceil(nRows / this._rowsPerPage);
this._spaceBetweenPages = availHeightPerPage - (this.topPadding + this.bottomPadding) - this._availableHeightPerPageForItems();
this._childrenPerPage = nColumns * this._rowsPerPage;
}
},
adaptToSize(availWidth, availHeight) {
super.adaptToSize(availWidth, availHeight);
this.parent(availWidth, availHeight);
this._computePages(availWidth, availHeight);
}
},
_availableHeightPerPageForItems() {
return this.usedHeightForNRows(this._rowsPerPage) - (this.topPadding + this.bottomPadding);
}
},
nPages() {
return this._nPages;
}
},
getPageHeight() {
return this._availableHeightPerPageForItems();
}
},
getPageY(pageNumber) {
if (!this._nPages)
@@ -901,7 +907,7 @@ var PaginatedIconGrid = GObject.registerClass({
let firstPageItem = pageNumber * this._childrenPerPage
let childBox = this._getVisibleChildren()[firstPageItem].get_allocation_box();
return childBox.y1 - this.topPadding;
}
},
getItemPage(item) {
let children = this._getVisibleChildren();
@@ -911,7 +917,7 @@ var PaginatedIconGrid = GObject.registerClass({
return 0;
}
return Math.floor(index / this._childrenPerPage);
}
},
/**
* openExtraSpace:
@@ -963,7 +969,7 @@ var PaginatedIconGrid = GObject.registerClass({
this._translateChildren(childrenDown, Gtk.DirectionType.DOWN, nRowsDown);
this._translatedChildren = childrenUp.concat(childrenDown);
}
}
},
_translateChildren(children, direction, nRows) {
let translationY = nRows * (this._getVItemSize() + this._getSpacing());
@@ -983,7 +989,7 @@ var PaginatedIconGrid = GObject.registerClass({
params.onComplete = () => { this.emit('space-opened'); };
Tweener.addTween(children[i], params);
}
}
},
closeExtraSpace() {
if (!this._translatedChildren || !this._translatedChildren.length) {

View File

@@ -2,6 +2,7 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@@ -15,39 +16,41 @@ const APP_WHITELIST = ['gnome-control-center.desktop'];
var DialogResponse = Meta.InhibitShortcutsDialogResponse;
var InhibitShortcutsDialog = GObject.registerClass({
var InhibitShortcutsDialog = new Lang.Class({
Name: 'InhibitShortcutsDialog',
Extends: GObject.Object,
Implements: [Meta.InhibitShortcutsDialog],
Properties: {
'window': GObject.ParamSpec.override('window', Meta.InhibitShortcutsDialog)
}
}, class InhibitShortcutsDialog extends GObject.Object {
},
_init(window) {
super._init();
this.parent();
this._window = window;
this._dialog = new ModalDialog.ModalDialog();
this._buildLayout();
}
},
get window() {
return this._window;
}
},
set window(window) {
this._window = window;
}
},
get _app() {
let windowTracker = Shell.WindowTracker.get_default();
return windowTracker.get_window_app(this._window);
}
},
_getRestoreAccel() {
let settings = new Gio.Settings({ schema_id: WAYLAND_KEYBINDINGS_SCHEMA });
let accel = settings.get_strv('restore-shortcuts')[0] || '';
return Gtk.accelerator_get_label.apply(null,
Gtk.accelerator_parse(accel));
}
},
_buildLayout() {
let name = this._app ? this._app.get_name() : this._window.title;
@@ -79,19 +82,19 @@ var InhibitShortcutsDialog = GObject.registerClass({
this._emitResponse(DialogResponse.ALLOW);
},
default: true });
}
},
_emitResponse(response) {
this.emit('response', response);
this._dialog.close();
}
},
vfunc_show() {
if (this._app && APP_WHITELIST.indexOf(this._app.get_id()) != -1)
this._emitResponse(DialogResponse.ALLOW);
else
this._dialog.open();
}
},
vfunc_hide() {
this._dialog.close();

View File

@@ -1,6 +1,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Dialog = imports.ui.dialog;
const ModalDialog = imports.ui.modalDialog;
@@ -8,17 +9,17 @@ const KEYBOARD_A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard';
const KEY_STICKY_KEYS_ENABLED = 'stickykeys-enable';
const KEY_SLOW_KEYS_ENABLED = 'slowkeys-enable';
var KbdA11yDialog = new GObject.registerClass(
class KbdA11yDialog extends GObject.Object {
_init() {
super._init();
var KbdA11yDialog = new Lang.Class({
Name: 'KbdA11yDialog',
Extends: GObject.Object,
_init() {
this._a11ySettings = new Gio.Settings({ schema_id: KEYBOARD_A11Y_SCHEMA });
let deviceManager = Clutter.DeviceManager.get_default();
deviceManager.connect('kbd-a11y-flags-changed',
this._showKbdA11yDialog.bind(this));
}
},
_showKbdA11yDialog(deviceManager, newFlags, whatChanged) {
let dialog = new ModalDialog.ModalDialog();

View File

@@ -5,7 +5,7 @@ const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@@ -55,13 +55,15 @@ const defaultKeysPost = [
[{ width: 1.5, action: 'languageMenu', extraClassName: 'layout-key' }, { width: 1.5, action: 'hide', extraClassName: 'hide-key' }] ],
];
var KeyContainer = new GObject.registerClass(
class KeyContainer extends St.Widget {
var KeyContainer = new Lang.Class({
Name: 'KeyContainer',
Extends: St.Widget,
_init() {
let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL,
column_homogeneous: true,
row_homogeneous: true });
super._init({ layout_manager: gridLayout });
this.parent({ layout_manager: gridLayout });
this._gridLayout = gridLayout;
this._currentRow = 0;
this._currentCol = 0;
@@ -69,7 +71,7 @@ class KeyContainer extends St.Widget {
this._currentRow = null;
this._rows = [];
}
},
appendRow(length) {
this._currentRow++;
@@ -79,7 +81,7 @@ class KeyContainer extends St.Widget {
row.keys = [];
row.width = 0;
this._rows.push(row);
}
},
appendKey(key, width = 1, height = 1) {
let keyInfo = {
@@ -96,7 +98,7 @@ class KeyContainer extends St.Widget {
this._currentCol += width;
this._maxCols = Math.max(this._currentCol, this._maxCols);
}
},
vfunc_allocate(box, flags) {
if (box.get_width() > 0 && box.get_height() > 0 && this._maxCols > 0) {
@@ -120,8 +122,8 @@ class KeyContainer extends St.Widget {
}
}
super.vfunc_allocate(box, flags);
}
this.parent (box, flags);
},
layoutButtons() {
let nCol = 0, nRow = 0;
@@ -153,28 +155,33 @@ class KeyContainer extends St.Widget {
}
});
var Suggestions = class {
constructor() {
var Suggestions = new Lang.Class({
Name: 'Suggestions',
_init() {
this.actor = new St.BoxLayout({ style_class: 'word-suggestions',
vertical: false });
this.actor.show();
}
},
add(word, callback) {
let button = new St.Button({ label: word });
button.connect('clicked', callback);
this.actor.add(button);
}
},
clear() {
this.actor.remove_all_children();
}
};
},
});
Signals.addSignalMethods(Suggestions.prototype);
var LanguageSelectionPopup = class extends PopupMenu.PopupMenu {
constructor(actor) {
super(actor, 0.5, St.Side.BOTTOM);
var LanguageSelectionPopup = new Lang.Class({
Name: 'LanguageSelectionPopup',
Extends: PopupMenu.PopupMenu,
_init(actor) {
this.parent(actor, 0.5, St.Side.BOTTOM);
let inputSourceManager = InputSourceManager.getInputSourceManager();
let inputSources = inputSourceManager.inputSources;
@@ -188,14 +195,19 @@ var LanguageSelectionPopup = class extends PopupMenu.PopupMenu {
}
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.addSettingsAction(_("Region & Language Settings"), 'gnome-region-panel.desktop');
this.addAction(_("Region & Language Settings"), this._launchSettings.bind(this));
this._capturedEventId = 0;
this._unmapId = actor.connect('notify::mapped', () => {
if (!actor.is_mapped())
this.close(true);
});
}
},
_launchSettings() {
Util.spawn(['gnome-control-center', 'region']);
this.close(true);
},
_onCapturedEvent(actor, event) {
if (event.get_source() == this.actor ||
@@ -206,33 +218,35 @@ var LanguageSelectionPopup = class extends PopupMenu.PopupMenu {
this.close(true);
return Clutter.EVENT_STOP;
}
},
open(animate) {
super.open(animate);
this.parent(animate);
this._capturedEventId = global.stage.connect('captured-event',
this._onCapturedEvent.bind(this));
}
},
close(animate) {
super.close(animate);
this.parent(animate);
if (this._capturedEventId != 0) {
global.stage.disconnect(this._capturedEventId);
this._capturedEventId = 0;
}
}
},
destroy() {
if (this._capturedEventId != 0)
global.stage.disconnect(this._capturedEventId);
if (this._unmapId != 0)
this.sourceActor.disconnect(this._unmapId);
super.destroy();
}
};
this.parent();
},
});
var Key = class Key {
constructor(key) {
var Key = new Lang.Class({
Name: 'Key',
_init(key, extendedKeys) {
this.key = key || "";
this.keyButton = this._makeKey(this.key);
@@ -251,14 +265,14 @@ var Key = class Key {
this._capturedEventId = 0;
this._unmapId = 0;
this._longPress = false;
}
},
_onDestroy() {
if (this._boxPointer) {
this._boxPointer.destroy();
this._boxPointer = null;
}
}
},
_ensureExtendedKeysPopup() {
if (this._extended_keys.length == 0)
@@ -276,12 +290,12 @@ var Key = class Key {
this._boxPointer.actor.add_style_class_name('keyboard-subkeys');
this._getExtendedKeys();
this.keyButton._extended_keys = this._extended_keyboard;
}
},
_getKeyval(key) {
let unicode = String.charCodeAt(key, 0);
return Gdk.unicode_to_keyval(unicode);
}
},
_press(key) {
if (key != this.key || this._extended_keys.length == 0) {
@@ -308,7 +322,7 @@ var Key = class Key {
return GLib.SOURCE_REMOVE;
});
}
}
},
_release(key) {
if (this._pressTimeoutId != 0) {
@@ -322,7 +336,7 @@ var Key = class Key {
this.emit('released', this._getKeyval(key), key);
this._hideSubkeys();
this._longPress = false;
}
},
_onCapturedEvent(actor, event) {
let type = event.type();
@@ -339,7 +353,7 @@ var Key = class Key {
this._hideSubkeys();
return Clutter.EVENT_STOP;
}
},
_showSubkeys() {
this._boxPointer.open(BoxPointer.PopupAnimation.FULL);
@@ -349,7 +363,7 @@ var Key = class Key {
if (!this.keyButton.is_mapped())
this._hideSubkeys();
});
}
},
_hideSubkeys() {
if (this._boxPointer)
@@ -363,7 +377,7 @@ var Key = class Key {
this._unmapId = 0;
}
this._capturedPress = false;
}
},
_makeKey(key) {
let label = GLib.markup_escape_text(key, -1);
@@ -409,7 +423,7 @@ var Key = class Key {
});
return button;
}
},
_getExtendedKeys() {
this._extended_keyboard = new St.BoxLayout({ style_class: 'key-container',
@@ -425,33 +439,35 @@ var Key = class Key {
key.height = this.keyButton.height;
}
this._boxPointer.bin.add_actor(this._extended_keyboard);
}
},
get subkeys() {
return this._boxPointer;
}
},
setWidth(width) {
this.keyButton.keyWidth = width;
}
},
setLatched(latched) {
if (latched)
this.keyButton.add_style_pseudo_class('latched');
else
this.keyButton.remove_style_pseudo_class('latched');
}
};
},
});
Signals.addSignalMethods(Key.prototype);
var KeyboardModel = class {
constructor(groupName) {
var KeyboardModel = new Lang.Class({
Name: 'KeyboardModel',
_init(groupName) {
try {
this._model = this._loadModel(groupName);
} catch (e) {
this._model = this._loadModel('us');
}
}
},
_loadModel(groupName) {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/osk-layouts/%s.json'.format(groupName));
@@ -460,19 +476,21 @@ var KeyboardModel = class {
contents = imports.byteArray.toString(contents);
return JSON.parse(contents);
}
},
getLevels() {
return this._model.levels;
}
},
getKeysForLevel(levelName) {
return this._model.levels.find(level => level == levelName);
}
};
});
var FocusTracker = class {
constructor() {
var FocusTracker = new Lang.Class({
Name: 'FocusTracker',
_init() {
this._currentWindow = null;
this._rect = null;
@@ -507,15 +525,15 @@ var FocusTracker = class {
this._ibusManager.connect('focus-out', () => {
this.emit('focus-changed', false);
});
}
},
get currentWindow() {
return this._currentWindow;
}
},
_setCurrentWindow(window) {
this._currentWindow = window;
}
},
_setCurrentRect(rect) {
if (this._currentWindow) {
@@ -533,7 +551,7 @@ var FocusTracker = class {
this._rect = rect;
this.emit('position-changed');
}
},
getCurrentRect() {
let rect = { x: this._rect.x, y: this._rect.y,
@@ -547,11 +565,13 @@ var FocusTracker = class {
return rect;
}
};
});
Signals.addSignalMethods(FocusTracker.prototype);
var Keyboard = class Keyboard {
constructor() {
var Keyboard = new Lang.Class({
Name: 'Keyboard',
_init() {
this.actor = null;
this._focusInExtendedKeys = false;
@@ -609,16 +629,16 @@ var Keyboard = class Keyboard {
this._keyboardRestingId = 0;
Main.layoutManager.connect('monitors-changed', this._relayout.bind(this));
}
},
get visible() {
return this._keyboardVisible;
}
},
_onFocusPositionChanged(focusTracker) {
let rect = focusTracker.getCurrentRect();
this.setCursorLocation(focusTracker.currentWindow, rect.x, rect.y, rect.width, rect.height);
}
},
_lastDeviceIsTouchscreen() {
if (!this._lastDeviceId)
@@ -631,7 +651,7 @@ var Keyboard = class Keyboard {
return false;
return device.get_device_type() == Clutter.InputDeviceType.TOUCHSCREEN_DEVICE;
}
},
_syncEnabled() {
let wasEnabled = this._enabled;
@@ -647,7 +667,7 @@ var Keyboard = class Keyboard {
if (!this._enabled && wasEnabled)
Main.layoutManager.hideKeyboard(true);
}
},
_destroyKeyboard() {
if (this._keyboardNotifyId)
@@ -666,7 +686,7 @@ var Keyboard = class Keyboard {
this._languagePopup.destroy();
this._languagePopup = null;
}
}
},
_setupKeyboard() {
this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true });
@@ -700,7 +720,7 @@ var Keyboard = class Keyboard {
this._focusNotifyId = global.stage.connect('notify::key-focus', this._onKeyFocusChanged.bind(this));
this._relayout();
}
},
_onKeyFocusChanged() {
let focus = global.stage.key_focus;
@@ -724,7 +744,7 @@ var Keyboard = class Keyboard {
});
GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.show');
}
}
},
_createLayersForGroup(groupName) {
let keyboardModel = new KeyboardModel(groupName);
@@ -749,12 +769,12 @@ var Keyboard = class Keyboard {
layout.hide();
}
return layers;
}
},
_ensureKeysForGroup(group) {
if (!this._groups[group])
this._groups[group] = this._createLayersForGroup(group);
}
},
_addRowKeys(keys, layout) {
for (let i = 0; i < keys.length; ++i) {
@@ -787,7 +807,7 @@ var Keyboard = class Keyboard {
layout.appendKey(button.actor, button.keyButton.keyWidth);
}
}
},
_popupLanguageMenu(keyActor) {
if (this._languagePopup)
@@ -796,7 +816,7 @@ var Keyboard = class Keyboard {
this._languagePopup = new LanguageSelectionPopup(keyActor);
Main.layoutManager.addChrome(this._languagePopup.actor);
this._languagePopup.open(true);
}
},
_loadDefaultKeys(keys, layout, numLevels, numKeys) {
let extraButton;
@@ -861,14 +881,14 @@ var Keyboard = class Keyboard {
layout.appendKey(extraButton.actor, extraButton.keyButton.keyWidth);
}
}
},
_setCurrentLevelLatched(layout, latched) {
for (let i = 0; layout.shiftKeys[i]; i++) {
let key = layout.shiftKeys[i];
key.setLatched(latched);
}
}
},
_getDefaultKeysForRow(row, numRows, level) {
let pre, post;
@@ -886,7 +906,7 @@ var Keyboard = class Keyboard {
} else {
return [null, null];
}
}
},
_mergeRowKeys(layout, pre, row, post, numLevels) {
if (pre != null)
@@ -896,7 +916,7 @@ var Keyboard = class Keyboard {
if (post != null)
this._loadDefaultKeys(post, layout, numLevels, row.length);
}
},
_loadRows(model, level, numLevels, layout) {
let rows = model.rows;
@@ -905,7 +925,7 @@ var Keyboard = class Keyboard {
let [pre, post] = this._getDefaultKeysForRow(i, rows.length, level);
this._mergeRowKeys (layout, pre, rows[i], post, numLevels);
}
}
},
_getGridSlots() {
let numOfHorizSlots = 0, numOfVertSlots;
@@ -920,7 +940,7 @@ var Keyboard = class Keyboard {
}
return [numOfHorizSlots, numOfVertSlots];
}
},
_relayout() {
let monitor = Main.layoutManager.keyboardMonitor;
@@ -931,17 +951,17 @@ var Keyboard = class Keyboard {
let maxHeight = monitor.height / 3;
this.actor.width = monitor.width;
this.actor.height = maxHeight;
}
},
_onGroupChanged() {
this._ensureKeysForGroup(this._keyboardController.getCurrentGroup());
this._setActiveLayer(0);
}
},
_onKeyboardGroupsChanged(keyboard) {
this._groups = [];
this._onGroupChanged();
}
},
_onKeyboardStateChanged(controller, state) {
let enabled;
@@ -958,7 +978,7 @@ var Keyboard = class Keyboard {
this.show(Main.layoutManager.focusIndex);
else
this.hide();
}
},
_setActiveLayer(activeLevel) {
let activeGroupName = this._keyboardController.getCurrentGroup();
@@ -971,20 +991,20 @@ var Keyboard = class Keyboard {
this._current_page = layers[activeLevel];
this._current_page.show();
}
},
shouldTakeEvent(event) {
let actor = event.get_source();
return Main.layoutManager.keyboardBox.contains(actor) ||
!!actor._extended_keys || !!actor.extended_key;
}
},
_clearKeyboardRestTimer() {
if (!this._keyboardRestingId)
return;
GLib.source_remove(this._keyboardRestingId);
this._keyboardRestingId = 0;
}
},
show(monitor) {
if (!this._enabled)
@@ -1010,7 +1030,7 @@ var Keyboard = class Keyboard {
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._keyboardRestingId, '[gnome-shell] this._clearKeyboardRestTimer');
}
},
_show(monitor) {
if (!this._keyboardRequested)
@@ -1024,7 +1044,7 @@ var Keyboard = class Keyboard {
this._setAnimationWindow(this._delayedAnimFocusWindow);
this._delayedAnimFocusWindow = null;
}
}
},
hide() {
if (!this._enabled)
@@ -1045,7 +1065,7 @@ var Keyboard = class Keyboard {
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._keyboardRestingId, '[gnome-shell] this._clearKeyboardRestTimer');
}
},
_hide() {
if (this._keyboardRequested)
@@ -1053,7 +1073,7 @@ var Keyboard = class Keyboard {
Main.layoutManager.hideKeyboard();
this.setCursorLocation(null);
}
},
_hideSubkeys() {
if (this._subkeysBoxPointer) {
@@ -1065,26 +1085,26 @@ var Keyboard = class Keyboard {
this._capturedEventId = 0;
}
this._capturedPress = false;
}
},
resetSuggestions() {
if (this._suggestions)
this._suggestions.clear();
}
},
addSuggestion(text, callback) {
if (!this._suggestions)
return;
this._suggestions.add(text, callback);
this._suggestions.actor.show();
}
},
_clearShowIdle() {
if (!this._showIdleId)
return;
GLib.source_remove(this._showIdleId);
this._showIdleId = 0;
}
},
_windowSlideAnimationComplete(window, delta) {
// Synchronize window and actor positions again.
@@ -1092,7 +1112,7 @@ var Keyboard = class Keyboard {
let frameRect = window.get_frame_rect();
frameRect.y += delta;
window.move_frame(true, frameRect.x, frameRect.y);
}
},
_animateWindow(window, show) {
let windowActor = window.get_compositor_private();
@@ -1115,7 +1135,7 @@ var Keyboard = class Keyboard {
onComplete: this._windowSlideAnimationComplete,
onCompleteParams: [window, deltaY] });
}
}
},
_setAnimationWindow(window) {
if (this._animFocusedWindow == window)
@@ -1127,7 +1147,7 @@ var Keyboard = class Keyboard {
this._animateWindow(window, true);
this._animFocusedWindow = window;
}
},
setCursorLocation(window, x, y , w, h) {
let monitor = Main.layoutManager.keyboardMonitor;
@@ -1150,11 +1170,14 @@ var Keyboard = class Keyboard {
}
this._oskFocusWindow = window;
}
};
},
});
var KeyboardController = class {
constructor() {
var KeyboardController = new Lang.Class({
Name: 'KeyboardController',
_init() {
this.parent();
let deviceManager = Clutter.DeviceManager.get_default();
this._virtualDevice = deviceManager.create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);
@@ -1172,24 +1195,24 @@ var KeyboardController = class {
Main.inputMethod.connect('input-panel-state', (o, state) => {
this.emit('panel-state', state);
});
}
},
_onSourcesModified() {
this.emit('groups-changed');
}
},
_onSourceChanged(inputSourceManager, oldSource) {
let source = inputSourceManager.currentSource;
this._currentSource = source;
this.emit('active-group', source.id);
}
},
_onContentPurposeHintsChanged(method) {
let hints = method.content_hints;
let purpose = method.content_purpose;
// XXX: hook numeric/emoji/etc special keyboards
}
},
getGroups() {
let inputSources = this._inputSourceManager.inputSources;
@@ -1201,11 +1224,11 @@ var KeyboardController = class {
}
return groups;
}
},
getCurrentGroup() {
return this._currentSource.xkbId;
}
},
commitString(string, fromKey) {
if (string == null)
@@ -1216,16 +1239,16 @@ var KeyboardController = class {
Main.inputMethod.commit(string);
return true;
}
},
keyvalPress(keyval) {
this._virtualDevice.notify_keyval(Clutter.get_current_event_time(),
keyval, Clutter.KeyState.PRESSED);
}
},
keyvalRelease(keyval) {
this._virtualDevice.notify_keyval(Clutter.get_current_event_time(),
keyval, Clutter.KeyState.RELEASED);
}
};
},
});
Signals.addSignalMethods(KeyboardController.prototype);

View File

@@ -3,6 +3,7 @@
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@@ -35,7 +36,9 @@ function isPopupMetaWindow(actor) {
}
}
var MonitorConstraint = GObject.registerClass({
var MonitorConstraint = new Lang.Class({
Name: 'MonitorConstraint',
Extends: Clutter.Constraint,
Properties: {'primary': GObject.ParamSpec.boolean('primary',
'Primary', 'Track primary monitor',
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE,
@@ -48,18 +51,18 @@ var MonitorConstraint = GObject.registerClass({
'Work-area', 'Track monitor\'s work-area',
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE,
false)},
}, class MonitorConstraint extends Clutter.Constraint {
_init(props) {
this._primary = false;
this._index = -1;
this._workArea = false;
super._init(props);
}
this.parent(props);
},
get primary() {
return this._primary;
}
},
set primary(v) {
if (v)
@@ -68,11 +71,11 @@ var MonitorConstraint = GObject.registerClass({
if (this.actor)
this.actor.queue_relayout();
this.notify('primary');
}
},
get index() {
return this._index;
}
},
set index(v) {
this._primary = false;
@@ -80,11 +83,11 @@ var MonitorConstraint = GObject.registerClass({
if (this.actor)
this.actor.queue_relayout();
this.notify('index');
}
},
get work_area() {
return this._workArea;
}
},
set work_area(v) {
if (v == this._workArea)
@@ -93,7 +96,7 @@ var MonitorConstraint = GObject.registerClass({
if (this.actor)
this.actor.queue_relayout();
this.notify('work-area');
}
},
vfunc_set_actor(actor) {
if (actor) {
@@ -121,8 +124,8 @@ var MonitorConstraint = GObject.registerClass({
this._workareasChangedId = 0;
}
super.vfunc_set_actor(actor);
}
this.parent(actor);
},
vfunc_update_allocation(actor, actorBox) {
if (!this._primary && this._index < 0)
@@ -150,19 +153,21 @@ var MonitorConstraint = GObject.registerClass({
}
});
var Monitor = class Monitor {
constructor(index, geometry) {
var Monitor = new Lang.Class({
Name: 'Monitor',
_init(index, geometry) {
this.index = index;
this.x = geometry.x;
this.y = geometry.y;
this.width = geometry.width;
this.height = geometry.height;
}
},
get inFullscreen() {
return global.display.get_monitor_in_fullscreen(this.index);
}
};
})
const defaultParams = {
trackFullscreen: false,
@@ -170,15 +175,17 @@ const defaultParams = {
affectsInputRegion: true
};
var LayoutManager = GObject.registerClass({
var LayoutManager = new Lang.Class({
Name: 'LayoutManager',
Extends: GObject.Object,
Signals: { 'hot-corners-changed': {},
'startup-complete': {},
'startup-prepared': {},
'monitors-changed': {},
'keyboard-visible-changed': { param_types: [GObject.TYPE_BOOLEAN] } },
}, class LayoutManager extends GObject.Object {
_init() {
super._init();
this.parent();
this._rtl = (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL);
this.monitors = [];
@@ -289,33 +296,33 @@ var LayoutManager = GObject.registerClass({
Meta.Background.refresh_all();
});
}
}
},
// This is called by Main after everything else is constructed
init() {
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
this._loadBackground();
}
},
showOverview() {
this.overviewGroup.show();
this._inOverview = true;
this._updateVisibility();
}
},
hideOverview() {
this.overviewGroup.hide();
this._inOverview = false;
this._updateVisibility();
}
},
_sessionUpdated() {
this._updateVisibility();
this._queueUpdateRegions();
}
},
_updateMonitors() {
let display = global.display;
@@ -353,7 +360,7 @@ var LayoutManager = GObject.registerClass({
this.primaryMonitor = null;
this.bottomMonitor = null;
}
}
},
_updateHotCorners() {
// destroy old hot corners
@@ -412,11 +419,11 @@ var LayoutManager = GObject.registerClass({
}
this.emit('hot-corners-changed');
}
},
_addBackgroundMenu(bgManager) {
BackgroundMenu.addBackgroundMenu(bgManager.backgroundActor, this);
}
},
_createBackgroundManager(monitorIndex) {
let bgManager = new Background.BackgroundManager({ container: this._backgroundGroup,
@@ -427,7 +434,7 @@ var LayoutManager = GObject.registerClass({
this._addBackgroundMenu(bgManager);
return bgManager;
}
},
_showSecondaryBackgrounds() {
for (let i = 0; i < this.monitors.length; i++) {
@@ -441,7 +448,7 @@ var LayoutManager = GObject.registerClass({
transition: 'easeOutQuad' });
}
}
}
},
_updateBackgrounds() {
let i;
@@ -460,13 +467,13 @@ var LayoutManager = GObject.registerClass({
if (i != this.primaryIndex && this._startingUp)
bgManager.backgroundActor.hide();
}
}
},
_updateKeyboardBox() {
this.keyboardBox.set_position(this.keyboardMonitor.x,
this.keyboardMonitor.y + this.keyboardMonitor.height);
this.keyboardBox.set_size(this.keyboardMonitor.width, -1);
}
},
_updateBoxes() {
this.screenShieldGroup.set_position(0, 0);
@@ -479,7 +486,7 @@ var LayoutManager = GObject.registerClass({
this.panelBox.set_size(this.primaryMonitor.width, -1);
this.keyboardIndex = this.primaryIndex;
}
},
_panelBoxChanged() {
this._updatePanelBarrier();
@@ -489,7 +496,7 @@ var LayoutManager = GObject.registerClass({
if (corner)
corner.setBarrierSize(size);
});
}
},
_updatePanelBarrier() {
if (this._rightPanelBarrier) {
@@ -508,7 +515,7 @@ var LayoutManager = GObject.registerClass({
x2: primary.x + primary.width, y2: primary.y + this.panelBox.height,
directions: Meta.BarrierDirection.NEGATIVE_X });
}
}
},
_monitorsChanged() {
this._updateMonitors();
@@ -520,7 +527,7 @@ var LayoutManager = GObject.registerClass({
this._queueUpdateRegions();
this.emit('monitors-changed');
}
},
_isAboveOrBelowPrimary(monitor) {
let primary = this.monitors[this.primaryIndex];
@@ -534,16 +541,16 @@ var LayoutManager = GObject.registerClass({
return true;
return false;
}
},
get currentMonitor() {
let index = global.display.get_current_monitor();
return this.monitors[index];
}
},
get keyboardMonitor() {
return this.monitors[this.keyboardIndex];
}
},
get focusIndex() {
let i = Main.layoutManager.primaryIndex;
@@ -553,22 +560,22 @@ var LayoutManager = GObject.registerClass({
else if (global.display.focus_window != null)
i = global.display.focus_window.get_monitor();
return i;
}
},
get focusMonitor() {
if (this.focusIndex < 0)
return null;
return this.monitors[this.focusIndex];
}
},
set keyboardIndex(v) {
this._keyboardIndex = v;
this._updateKeyboardBox();
}
},
get keyboardIndex() {
return this._keyboardIndex;
}
},
_loadBackground() {
if (!this.primaryMonitor) {
@@ -591,7 +598,7 @@ var LayoutManager = GObject.registerClass({
this._prepareStartupAnimation();
});
}
},
// Startup Animations
//
@@ -657,7 +664,7 @@ var LayoutManager = GObject.registerClass({
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(id, '[gnome-shell] this._startupAnimation');
}
},
_startupAnimation() {
if (Meta.is_restart())
@@ -666,7 +673,7 @@ var LayoutManager = GObject.registerClass({
this._startupAnimationGreeter();
else
this._startupAnimationSession();
}
},
_startupAnimationGreeter() {
Tweener.addTween(this.panelBox,
@@ -675,7 +682,7 @@ var LayoutManager = GObject.registerClass({
transition: 'easeOutQuad',
onComplete: this._startupAnimationComplete,
onCompleteScope: this });
}
},
_startupAnimationSession() {
Tweener.addTween(this.uiGroup,
@@ -686,7 +693,7 @@ var LayoutManager = GObject.registerClass({
transition: 'easeOutQuad',
onComplete: this._startupAnimationComplete,
onCompleteScope: this });
}
},
_startupAnimationComplete() {
this._coverPane.destroy();
@@ -707,7 +714,7 @@ var LayoutManager = GObject.registerClass({
this._queueUpdateRegions();
this.emit('startup-complete');
}
},
showKeyboard() {
this.keyboardBox.show();
@@ -720,7 +727,7 @@ var LayoutManager = GObject.registerClass({
onCompleteScope: this
});
this.emit('keyboard-visible-changed', true);
}
},
_showKeyboardComplete() {
// Poke Chrome to update the input shape; it doesn't notice
@@ -730,7 +737,7 @@ var LayoutManager = GObject.registerClass({
this._keyboardHeightNotifyId = this.keyboardBox.connect('notify::height', () => {
this.keyboardBox.anchor_y = this.keyboardBox.height;
});
}
},
hideKeyboard(immediate) {
if (this._keyboardHeightNotifyId) {
@@ -747,12 +754,12 @@ var LayoutManager = GObject.registerClass({
});
this.emit('keyboard-visible-changed', false);
}
},
_hideKeyboardComplete() {
this.keyboardBox.hide();
this._updateRegions();
}
},
// setDummyCursorGeometry:
//
@@ -767,7 +774,7 @@ var LayoutManager = GObject.registerClass({
setDummyCursorGeometry(x, y, w, h) {
this.dummyCursor.set_position(Math.round(x), Math.round(y));
this.dummyCursor.set_size(Math.round(w), Math.round(h));
}
},
// addChrome:
// @actor: an actor to add to the chrome
@@ -793,7 +800,7 @@ var LayoutManager = GObject.registerClass({
if (this.uiGroup.contains(global.top_window_group))
this.uiGroup.set_child_below_sibling(actor, global.top_window_group);
this._trackActor(actor, params);
}
},
// trackChrome:
// @actor: a descendant of the chrome to begin tracking
@@ -825,7 +832,7 @@ var LayoutManager = GObject.registerClass({
}
this._trackActor(actor, params);
}
},
// untrackChrome:
// @actor: an actor previously tracked via trackChrome()
@@ -833,7 +840,7 @@ var LayoutManager = GObject.registerClass({
// Undoes the effect of trackChrome()
untrackChrome(actor) {
this._untrackActor(actor);
}
},
// removeChrome:
// @actor: a chrome actor
@@ -842,7 +849,7 @@ var LayoutManager = GObject.registerClass({
removeChrome(actor) {
this.uiGroup.remove_actor(actor);
this._untrackActor(actor);
}
},
_findActor(actor) {
for (let i = 0; i < this._trackedActors.length; i++) {
@@ -851,7 +858,7 @@ var LayoutManager = GObject.registerClass({
return i;
}
return -1;
}
},
_trackActor(actor, params) {
if (this._findActor(actor) != -1)
@@ -871,7 +878,7 @@ var LayoutManager = GObject.registerClass({
this._trackedActors.push(actorData);
this._updateActorVisibility(actorData);
this._queueUpdateRegions();
}
},
_untrackActor(actor) {
let i = this._findActor(actor);
@@ -886,7 +893,7 @@ var LayoutManager = GObject.registerClass({
actor.disconnect(actorData.destroyId);
this._queueUpdateRegions();
}
},
_updateActorVisibility(actorData) {
if (!actorData.trackFullscreen)
@@ -896,7 +903,7 @@ var LayoutManager = GObject.registerClass({
actorData.actor.visible = !(global.window_group.visible &&
monitor &&
monitor.inFullscreen);
}
},
_updateVisibility() {
let windowsVisible = Main.sessionMode.hasWindows && !this._inOverview;
@@ -905,7 +912,7 @@ var LayoutManager = GObject.registerClass({
global.top_window_group.visible = windowsVisible;
this._trackedActors.forEach(this._updateActorVisibility.bind(this));
}
},
getWorkAreaForMonitor(monitorIndex) {
// Assume that all workspaces will have the same
@@ -913,7 +920,7 @@ var LayoutManager = GObject.registerClass({
let workspaceManager = global.workspace_manager;
let ws = workspaceManager.get_workspace_by_index(0);
return ws.get_work_area_for_monitor(monitorIndex);
}
},
// This call guarantees that we return some monitor to simplify usage of it
// In practice all tracked actors should be visible on some monitor anyway
@@ -922,14 +929,14 @@ var LayoutManager = GObject.registerClass({
let [w, h] = actor.get_transformed_size();
let rect = new Meta.Rectangle({ x: x, y: y, width: w, height: h });
return global.display.get_monitor_index_for_rect(rect);
}
},
findMonitorForActor(actor) {
let index = this.findIndexForActor(actor);
if (index >= 0 && index < this.monitors.length)
return this.monitors[index];
return null;
}
},
_queueUpdateRegions() {
if (this._startingUp)
@@ -938,19 +945,19 @@ var LayoutManager = GObject.registerClass({
if (!this._updateRegionIdle)
this._updateRegionIdle = Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
this._updateRegions.bind(this));
}
},
_getWindowActorsForWorkspace(workspace) {
return global.get_window_actors().filter(actor => {
let win = actor.meta_window;
return win.located_on_workspace(workspace);
});
}
},
_updateFullscreen() {
this._updateVisibility();
this._queueUpdateRegions();
}
},
_windowsRestacked() {
let changed = false;
@@ -962,7 +969,7 @@ var LayoutManager = GObject.registerClass({
this._updateVisibility();
this._queueUpdateRegions();
}
}
},
_updateRegions() {
if (this._updateRegionIdle) {
@@ -1062,13 +1069,13 @@ var LayoutManager = GObject.registerClass({
}
return GLib.SOURCE_REMOVE;
}
},
modalEnded() {
// We don't update the stage input region while in a modal,
// so queue an update now.
this._queueUpdateRegions();
}
},
});
@@ -1076,8 +1083,10 @@ var LayoutManager = GObject.registerClass({
//
// This class manages a "hot corner" that can toggle switching to
// overview.
var HotCorner = class HotCorner {
constructor(layoutManager, monitor, x, y) {
var HotCorner = new Lang.Class({
Name: 'HotCorner',
_init(layoutManager, monitor, x, y) {
// We use this flag to mark the case where the user has entered the
// hot corner and has not left both the hot corner and a surrounding
// guard area (the "environs"). This avoids triggering the hot corner
@@ -1105,7 +1114,7 @@ var HotCorner = class HotCorner {
layoutManager.uiGroup.add_actor(this._ripple1);
layoutManager.uiGroup.add_actor(this._ripple2);
layoutManager.uiGroup.add_actor(this._ripple3);
}
},
setBarrierSize(size) {
if (this._verticalBarrier) {
@@ -1140,7 +1149,7 @@ var HotCorner = class HotCorner {
this._pressureBarrier.addBarrier(this._verticalBarrier);
this._pressureBarrier.addBarrier(this._horizontalBarrier);
}
}
},
_setupFallbackCornerIfNeeded(layoutManager) {
if (!global.display.supports_extended_barriers()) {
@@ -1175,7 +1184,7 @@ var HotCorner = class HotCorner {
this._corner.connect('leave-event',
this._onCornerLeft.bind(this));
}
}
},
destroy() {
this.setBarrierSize(0);
@@ -1184,7 +1193,7 @@ var HotCorner = class HotCorner {
if (this.actor)
this.actor.destroy();
}
},
_animRipple(ripple, delay, time, startScale, startOpacity, finalScale) {
// We draw a ripple by using a source image and animating it scaling
@@ -1214,7 +1223,7 @@ var HotCorner = class HotCorner {
transition: 'linear',
onUpdate() { ripple.opacity = 255 * Math.sqrt(ripple._opacity); },
onComplete() { ripple.visible = false; } });
}
},
_rippleAnimation() {
// Show three concentric ripples expanding outwards; the exact
@@ -1225,17 +1234,17 @@ var HotCorner = class HotCorner {
this._animRipple(this._ripple1, 0.0, 0.83, 0.25, 1.0, 1.5);
this._animRipple(this._ripple2, 0.05, 1.0, 0.0, 0.7, 1.25);
this._animRipple(this._ripple3, 0.35, 1.0, 0.0, 0.3, 1);
}
},
_toggleOverview() {
if (this._monitor.inFullscreen && !Main.overview.visible)
if (this._monitor.inFullscreen)
return;
if (Main.overview.shouldToggleByCornerOrButton()) {
this._rippleAnimation();
Main.overview.toggle();
}
}
},
handleDragOver(source, actor, x, y, time) {
if (source != Main.xdndHandler)
@@ -1244,7 +1253,7 @@ var HotCorner = class HotCorner {
this._toggleOverview();
return DND.DragMotionResult.CONTINUE;
}
},
_onCornerEntered() {
if (!this._entered) {
@@ -1252,24 +1261,26 @@ var HotCorner = class HotCorner {
this._toggleOverview();
}
return Clutter.EVENT_PROPAGATE;
}
},
_onCornerLeft(actor, event) {
if (event.get_related() != this.actor)
this._entered = false;
// Consume event, otherwise this will confuse onEnvironsLeft
return Clutter.EVENT_STOP;
}
},
_onEnvironsLeft(actor, event) {
if (event.get_related() != this._corner)
this._entered = false;
return Clutter.EVENT_PROPAGATE;
}
};
});
var PressureBarrier = class PressureBarrier {
constructor(threshold, timeout, actionMode) {
var PressureBarrier = new Lang.Class({
Name: 'PressureBarrier',
_init(threshold, timeout, actionMode) {
this._threshold = threshold;
this._timeout = timeout;
this._actionMode = actionMode;
@@ -1278,57 +1289,57 @@ var PressureBarrier = class PressureBarrier {
this._isTriggered = false;
this._reset();
}
},
addBarrier(barrier) {
barrier._pressureHitId = barrier.connect('hit', this._onBarrierHit.bind(this));
barrier._pressureLeftId = barrier.connect('left', this._onBarrierLeft.bind(this));
this._barriers.push(barrier);
}
},
_disconnectBarrier(barrier) {
barrier.disconnect(barrier._pressureHitId);
barrier.disconnect(barrier._pressureLeftId);
}
},
removeBarrier(barrier) {
this._disconnectBarrier(barrier);
this._barriers.splice(this._barriers.indexOf(barrier), 1);
}
},
destroy() {
this._barriers.forEach(this._disconnectBarrier.bind(this));
this._barriers = [];
}
},
setEventFilter(filter) {
this._eventFilter = filter;
}
},
_reset() {
this._barrierEvents = [];
this._currentPressure = 0;
this._lastTime = 0;
}
},
_isHorizontal(barrier) {
return barrier.y1 == barrier.y2;
}
},
_getDistanceAcrossBarrier(barrier, event) {
if (this._isHorizontal(barrier))
return Math.abs(event.dy);
else
return Math.abs(event.dx);
}
},
_getDistanceAlongBarrier(barrier, event) {
if (this._isHorizontal(barrier))
return Math.abs(event.dx);
else
return Math.abs(event.dy);
}
},
_trimBarrierEvents() {
// Events are guaranteed to be sorted in time order from
@@ -1352,7 +1363,7 @@ var PressureBarrier = class PressureBarrier {
}
this._barrierEvents = this._barrierEvents.slice(firstNewEvent);
}
},
_onBarrierLeft(barrier, event) {
barrier._isHit = false;
@@ -1360,13 +1371,13 @@ var PressureBarrier = class PressureBarrier {
this._reset();
this._isTriggered = false;
}
}
},
_trigger() {
this._isTriggered = true;
this.emit('trigger');
this._reset();
}
},
_onBarrierHit(barrier, event) {
barrier._isHit = true;
@@ -1408,5 +1419,5 @@ var PressureBarrier = class PressureBarrier {
if (this._currentPressure >= this._threshold)
this._trigger();
}
};
});
Signals.addSignalMethods(PressureBarrier.prototype);

View File

@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Signals = imports.signals;
const St = imports.gi.St;
@@ -27,36 +27,38 @@ t = clamp(t, 0.0, 1.0);\n\
float pixel_brightness = mix(1.0, 1.0 - vignette_sharpness, t);\n\
cogl_color_out.a = cogl_color_out.a * (1 - pixel_brightness * brightness);';
var RadialShaderQuad = GObject.registerClass(
class RadialShaderQuad extends Shell.GLSLQuad {
var RadialShaderQuad = new Lang.Class({
Name: 'RadialShaderQuad',
Extends: Shell.GLSLQuad,
_init(params) {
super._init(params);
this.parent(params);
this._brightnessLocation = this.get_uniform_location('brightness');
this._sharpnessLocation = this.get_uniform_location('vignette_sharpness');
this.brightness = 1.0;
this.vignetteSharpness = 0.0;
}
},
vfunc_build_pipeline() {
this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT,
VIGNETTE_DECLARATIONS, VIGNETTE_CODE, true);
}
},
get brightness() {
return this._brightness;
}
},
set brightness(v) {
this._brightness = v;
this.set_uniform_float(this._brightnessLocation,
1, [this._brightness]);
}
},
get vignetteSharpness() {
return this._sharpness;
}
},
set vignetteSharpness(v) {
this._sharpness = v;
@@ -89,8 +91,10 @@ class RadialShaderQuad extends Shell.GLSLQuad {
* @container and will track any changes in its size. You can override
* this by passing an explicit width and height in @params.
*/
var Lightbox = class Lightbox {
constructor(container, params) {
var Lightbox = new Lang.Class({
Name: 'Lightbox',
_init(container, params) {
params = Params.parse(params, { inhibitEvents: false,
width: null,
height: null,
@@ -133,7 +137,7 @@ var Lightbox = class Lightbox {
this._actorRemovedSignalId = container.connect('actor-removed', this._actorRemoved.bind(this));
this._highlighted = null;
}
},
_actorAdded(container, newChild) {
let children = this._container.get_children();
@@ -155,7 +159,7 @@ var Lightbox = class Lightbox {
if (prevChild != -1) // paranoia
this._children.splice(prevChild + 1, 0, newChild);
}
}
},
show(fadeInTime) {
fadeInTime = fadeInTime || 0;
@@ -185,7 +189,7 @@ var Lightbox = class Lightbox {
}
this.actor.show();
}
},
hide(fadeOutTime) {
fadeOutTime = fadeOutTime || 0;
@@ -213,7 +217,7 @@ var Lightbox = class Lightbox {
}
});
}
}
},
_actorRemoved(container, child) {
let index = this._children.indexOf(child);
@@ -222,7 +226,7 @@ var Lightbox = class Lightbox {
if (child == this._highlighted)
this._highlighted = null;
}
},
/**
* highlight:
@@ -253,7 +257,7 @@ var Lightbox = class Lightbox {
}
this._highlighted = window;
}
},
/**
* destroy:
@@ -262,7 +266,7 @@ var Lightbox = class Lightbox {
*/
destroy() {
this.actor.destroy();
}
},
/**
* _onDestroy:
@@ -276,5 +280,5 @@ var Lightbox = class Lightbox {
this.highlight(null);
}
};
});
Signals.addSignalMethods(Lightbox.prototype);

View File

@@ -11,6 +11,7 @@ const Pango = imports.gi.Pango;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const System = imports.system;
@@ -34,6 +35,7 @@ var commandHeader = 'const Clutter = imports.gi.Clutter; ' +
'const Meta = imports.gi.Meta; ' +
'const Shell = imports.gi.Shell; ' +
'const Main = imports.ui.main; ' +
'const Lang = imports.lang; ' +
'const Tweener = imports.ui.tweener; ' +
/* Utility functions...we should probably be able to use these
* in the shell core code too. */
@@ -60,12 +62,14 @@ function _getAutoCompleteGlobalKeywords() {
return keywords.concat(windowProperties).concat(headerProperties);
}
var AutoComplete = class AutoComplete {
constructor(entry) {
var AutoComplete = new Lang.Class({
Name: 'AutoComplete',
_init(entry) {
this._entry = entry;
this._entry.connect('key-press-event', this._entryKeyPressEvent.bind(this));
this._lastTabTime = global.get_current_time();
}
},
_processCompletionRequest(event) {
if (event.completions.length == 0) {
@@ -87,7 +91,7 @@ var AutoComplete = class AutoComplete {
} else if (event.completions.length > 1 && event.tabType === 'double') {
this.emit('suggest', { completions: event.completions});
}
}
},
_entryKeyPressEvent(actor, event) {
let cursorPos = this._entry.clutter_text.get_cursor_position();
@@ -110,7 +114,7 @@ var AutoComplete = class AutoComplete {
this._lastTabTime = currTime;
}
return Clutter.EVENT_PROPAGATE;
}
},
// Insert characters of text not already included in head at cursor position. i.e., if text="abc" and head="a",
// the string "bc" will be appended to this._entry
@@ -120,19 +124,21 @@ var AutoComplete = class AutoComplete {
this._entry.clutter_text.insert_text(additionalCompletionText, cursorPos);
}
};
});
Signals.addSignalMethods(AutoComplete.prototype);
var Notebook = class Notebook {
constructor() {
var Notebook = new Lang.Class({
Name: 'Notebook',
_init() {
this.actor = new St.BoxLayout({ vertical: true });
this.tabControls = new St.BoxLayout({ style_class: 'labels' });
this._selectedIndex = -1;
this._tabs = [];
}
},
appendPage(name, child) {
let labelBox = new St.BoxLayout({ style_class: 'notebook-tab',
@@ -165,7 +171,7 @@ var Notebook = class Notebook {
if (this._selectedIndex == -1)
this.selectIndex(0);
}
},
_unselect() {
if (this._selectedIndex < 0)
@@ -174,7 +180,7 @@ var Notebook = class Notebook {
tabData.labelBox.remove_style_pseudo_class('selected');
tabData.scrollView.hide();
this._selectedIndex = -1;
}
},
selectIndex(index) {
if (index == this._selectedIndex)
@@ -196,7 +202,7 @@ var Notebook = class Notebook {
tabData.scrollView.show();
this._selectedIndex = index;
this.emit('selection', tabData.child);
}
},
selectChild(child) {
if (child == null)
@@ -210,26 +216,26 @@ var Notebook = class Notebook {
}
}
}
}
},
scrollToBottom(index) {
let tabData = this._tabs[index];
tabData._scrollToBottom = true;
}
},
_onAdjustValueChanged(tabData) {
let vAdjust = tabData.scrollView.vscroll.adjustment;
if (vAdjust.value < (vAdjust.upper - vAdjust.lower - 0.5))
tabData._scrolltoBottom = false;
}
},
_onAdjustScopeChanged(tabData) {
if (!tabData._scrollToBottom)
return;
let vAdjust = tabData.scrollView.vscroll.adjustment;
vAdjust.value = vAdjust.upper - vAdjust.page_size;
}
},
nextTab() {
let nextIndex = this._selectedIndex;
@@ -238,7 +244,7 @@ var Notebook = class Notebook {
}
this.selectIndex(nextIndex);
}
},
prevTab() {
let prevIndex = this._selectedIndex;
@@ -248,7 +254,7 @@ var Notebook = class Notebook {
this.selectIndex(prevIndex);
}
};
});
Signals.addSignalMethods(Notebook.prototype);
function objectToString(o) {
@@ -260,8 +266,10 @@ function objectToString(o) {
}
}
var ObjLink = class ObjLink {
constructor(lookingGlass, o, title) {
var ObjLink = new Lang.Class({
Name: 'ObjLink',
_init(lookingGlass, o, title) {
let text;
if (title)
text = title;
@@ -278,15 +286,17 @@ var ObjLink = class ObjLink {
this.actor.connect('clicked', this._onClicked.bind(this));
this._lookingGlass = lookingGlass;
}
},
_onClicked(link) {
this._lookingGlass.inspectObject(this._obj, this.actor);
}
};
});
var Result = class Result {
constructor(lookingGlass, command, o, index) {
var Result = new Lang.Class({
Name: 'Result',
_init(lookingGlass, command, o, index) {
this.index = index;
this.o = o;
@@ -304,10 +314,12 @@ var Result = class Result {
let objLink = new ObjLink(this._lookingGlass, o);
box.add(objLink.actor);
}
};
});
var WindowList = class WindowList {
constructor(lookingGlass) {
var WindowList = new Lang.Class({
Name: 'WindowList',
_init(lookingGlass) {
this.actor = new St.BoxLayout({ name: 'Windows', vertical: true, style: 'spacing: 8px' });
let tracker = Shell.WindowTracker.get_default();
this._updateId = Main.initializeDeferredWork(this.actor, this._updateWindowList.bind(this));
@@ -315,7 +327,7 @@ var WindowList = class WindowList {
tracker.connect('tracked-windows-changed', this._updateWindowList.bind(this));
this._lookingGlass = lookingGlass;
}
},
_updateWindowList() {
this.actor.destroy_all_children();
@@ -349,11 +361,13 @@ var WindowList = class WindowList {
}
}
}
};
});
Signals.addSignalMethods(WindowList.prototype);
var ObjInspector = class ObjInspector {
constructor(lookingGlass) {
var ObjInspector = new Lang.Class({
Name: 'ObjInspector',
_init(lookingGlass) {
this._obj = null;
this._previousObj = null;
@@ -368,7 +382,7 @@ var ObjInspector = class ObjInspector {
this.actor.add_actor(this._container);
this._lookingGlass = lookingGlass;
}
},
selectObject(obj, skipPrevious) {
if (!skipPrevious)
@@ -422,7 +436,7 @@ var ObjInspector = class ObjInspector {
this._container.add_actor(hbox);
}
}
}
},
open(sourceActor) {
if (this._open)
@@ -438,7 +452,7 @@ var ObjInspector = class ObjInspector {
} else {
this.actor.set_scale(1, 1);
}
}
},
close() {
if (!this._open)
@@ -447,21 +461,23 @@ var ObjInspector = class ObjInspector {
this.actor.hide();
this._previousObj = null;
this._obj = null;
}
},
_onInsert() {
let obj = this._obj;
this.close();
this._lookingGlass.insertObject(obj);
}
},
_onBack() {
this.selectObject(this._previousObj, true);
}
};
});
var RedBorderEffect = new Lang.Class({
Name: 'RedBorderEffect',
Extends: Clutter.Effect,
var RedBorderEffect = GObject.registerClass(
class RedBorderEffect extends Clutter.Effect {
vfunc_paint() {
let actor = this.get_actor();
actor.continue_paint();
@@ -481,15 +497,17 @@ class RedBorderEffect extends Clutter.Effect {
geom.width - width, geom.height - width);
Cogl.rectangle(0, geom.height - width,
width, width);
}
},
});
var Inspector = GObject.registerClass({
var Inspector = new Lang.Class({
Name: 'Inspector',
Extends: Clutter.Actor,
Signals: { 'closed': {},
'target': { param_types: [Clutter.Actor.$gtype, GObject.TYPE_DOUBLE, GObject.TYPE_DOUBLE] } },
}, class Inspector extends Clutter.Actor {
_init(lookingGlass) {
super._init({ width: 0,
this.parent({ width: 0,
height: 0 });
Main.uiGroup.add_actor(this);
@@ -518,7 +536,7 @@ var Inspector = GObject.registerClass({
this._pointerTarget = null;
this._lookingGlass = lookingGlass;
}
},
vfunc_allocate(box, flags) {
this.set_allocation(box, flags);
@@ -537,7 +555,7 @@ var Inspector = GObject.registerClass({
childBox.y1 = primary.y + Math.floor((primary.height - natHeight) / 2);
childBox.y2 = childBox.y1 + natHeight;
this._eventHandler.allocate(childBox, flags);
}
},
_close() {
Clutter.ungrab_pointer();
@@ -545,13 +563,13 @@ var Inspector = GObject.registerClass({
this._eventHandler.destroy();
this._eventHandler = null;
this.emit('closed');
}
},
_onKeyPressEvent(actor, event) {
if (event.get_key_symbol() == Clutter.Escape)
this._close();
return Clutter.EVENT_STOP;
}
},
_onButtonPressEvent(actor, event) {
if (this._target) {
@@ -560,7 +578,7 @@ var Inspector = GObject.registerClass({
}
this._close();
return Clutter.EVENT_STOP;
}
},
_onScrollEvent(actor, event) {
switch (event.get_scroll_direction()) {
@@ -594,12 +612,12 @@ var Inspector = GObject.registerClass({
break;
}
return Clutter.EVENT_STOP;
}
},
_onMotionEvent(actor, event) {
this._update(event);
return Clutter.EVENT_STOP;
}
},
_update(event) {
let [stageX, stageY] = event.get_coords();
@@ -619,8 +637,10 @@ var Inspector = GObject.registerClass({
}
});
var Extensions = class Extensions {
constructor(lookingGlass) {
var Extensions = new Lang.Class({
Name: 'Extensions',
_init(lookingGlass) {
this._lookingGlass = lookingGlass;
this.actor = new St.BoxLayout({ vertical: true,
name: 'lookingGlassExtensions' });
@@ -637,7 +657,7 @@ var Extensions = class Extensions {
ExtensionSystem.connect('extension-loaded',
this._loadExtension.bind(this));
}
},
_loadExtension(o, uuid) {
let extension = ExtensionUtils.extensions[uuid];
@@ -652,20 +672,20 @@ var Extensions = class Extensions {
this._numExtensions ++;
this._extensionsList.add(extensionDisplay);
}
},
_onViewSource(actor) {
let extension = actor._extension;
let uri = extension.dir.get_uri();
Gio.app_info_launch_default_for_uri(uri, global.create_app_launch_context(0, -1));
this._lookingGlass.close();
}
},
_onWebPage(actor) {
let extension = actor._extension;
Gio.app_info_launch_default_for_uri(extension.metadata.url, global.create_app_launch_context(0, -1));
this._lookingGlass.close();
}
},
_onViewErrors(actor) {
let extension = actor._extension;
@@ -693,7 +713,7 @@ var Extensions = class Extensions {
}
actor._isShowing = shouldShow;
}
},
_stateToString(extensionState) {
switch (extensionState) {
@@ -710,7 +730,7 @@ var Extensions = class Extensions {
return _("Downloading");
}
return 'Unknown'; // Not translated, shouldn't appear
}
},
_createExtensionDisplay(extension) {
let box = new St.BoxLayout({ style_class: 'lg-extension', vertical: true });
@@ -758,10 +778,12 @@ var Extensions = class Extensions {
return box;
}
};
});
var LookingGlass = class LookingGlass {
constructor() {
var LookingGlass = new Lang.Class({
Name: 'LookingGlass',
_init() {
this._borderPaintTarget = null;
this._redBorderEffect = new RedBorderEffect();
@@ -895,7 +917,7 @@ var LookingGlass = class LookingGlass {
});
this._resize();
}
},
_updateFont() {
let fontName = this._interfaceSettings.get_string('monospace-font-name');
@@ -905,7 +927,7 @@ var LookingGlass = class LookingGlass {
this.actor.style =
'font-size: ' + fontDesc.get_size() / 1024. + (fontDesc.get_size_is_absolute() ? 'px' : 'pt') + ';'
+ 'font-family: "' + fontDesc.get_family() + '";';
}
},
setBorderPaintTarget(obj) {
if (this._borderPaintTarget != null)
@@ -913,7 +935,7 @@ var LookingGlass = class LookingGlass {
this._borderPaintTarget = obj;
if (this._borderPaintTarget != null)
this._borderPaintTarget.add_effect(this._redBorderEffect);
}
},
_pushResult(command, obj) {
let index = this._results.length + this._offset;
@@ -933,7 +955,7 @@ var LookingGlass = class LookingGlass {
// Scroll to bottom
this._notebook.scrollToBottom(0);
}
},
_showCompletions(completions) {
if (!this._completionActor) {
@@ -962,7 +984,7 @@ var LookingGlass = class LookingGlass {
opacity: 255
});
}
}
},
_hideCompletions() {
if (this._completionActor) {
@@ -976,49 +998,46 @@ var LookingGlass = class LookingGlass {
}
});
}
}
},
_evaluate(command) {
this._history.addItem(command);
let lines = command.split(';');
lines.push(`return ${lines.pop()}`);
let fullCmd = commandHeader + lines.join(';');
let fullCmd = commandHeader + command;
let resultObj;
try {
resultObj = Function(fullCmd)();
resultObj = eval(fullCmd);
} catch (e) {
resultObj = '<exception ' + e + '>';
}
this._pushResult(command, resultObj);
this._entry.text = '';
}
},
inspect(x, y) {
return global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
}
},
getIt() {
return this._it;
}
},
getResult(idx) {
return this._results[idx - this._offset].o;
}
},
toggle() {
if (this._open)
this.close();
else
this.open();
}
},
_queueResize() {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { this._resize(); });
}
},
_resize() {
let primary = Main.layoutManager.primaryMonitor;
@@ -1034,16 +1053,16 @@ var LookingGlass = class LookingGlass {
this._objInspector.actor.set_size(Math.floor(myWidth * 0.8), Math.floor(myHeight * 0.8));
this._objInspector.actor.set_position(this.actor.x + Math.floor(myWidth * 0.1),
this._targetY + Math.floor(myHeight * 0.1));
}
},
insertObject(obj) {
this._pushResult('<insert>', obj);
}
},
inspectObject(obj, sourceActor) {
this._objInspector.open(sourceActor);
this._objInspector.selectObject(obj);
}
},
// Handle key events which are relevant for all tabs of the LookingGlass
_globalKeyPressEvent(actor, event) {
@@ -1066,7 +1085,7 @@ var LookingGlass = class LookingGlass {
}
}
return Clutter.EVENT_PROPAGATE;
}
},
open() {
if (this._open)
@@ -1088,7 +1107,7 @@ var LookingGlass = class LookingGlass {
transition: 'easeOutQuad',
y: this._targetY
});
}
},
close() {
if (!this._open)
@@ -1111,5 +1130,5 @@ var LookingGlass = class LookingGlass {
}
});
}
};
});
Signals.addSignalMethods(LookingGlass.prototype);

View File

@@ -7,6 +7,7 @@ const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Signals = imports.signals;
@@ -52,8 +53,10 @@ const CROSS_HAIRS_CLIP_KEY = 'cross-hairs-clip';
let magDBusService = null;
var Magnifier = class Magnifier {
constructor() {
var Magnifier = new Lang.Class({
Name: 'Magnifier',
_init() {
// Magnifier is a manager of ZoomRegions.
this._zoomRegions = [];
@@ -81,7 +84,7 @@ var Magnifier = class Magnifier {
// Export to dbus.
magDBusService = new MagnifierDBus.ShellMagnifier();
this.setActive(showAtLaunch);
}
},
/**
* showSystemCursor:
@@ -89,7 +92,7 @@ var Magnifier = class Magnifier {
*/
showSystemCursor() {
this._cursorTracker.set_pointer_visible(true);
}
},
/**
* hideSystemCursor:
@@ -97,7 +100,7 @@ var Magnifier = class Magnifier {
*/
hideSystemCursor() {
this._cursorTracker.set_pointer_visible(false);
}
},
/**
* setActive:
@@ -128,7 +131,7 @@ var Magnifier = class Magnifier {
// Notify interested parties of this change
this.emit('active-changed', activate);
}
},
/**
* isActive:
@@ -141,7 +144,7 @@ var Magnifier = class Magnifier {
return false;
else
return this._zoomRegions[0].isActive();
}
},
/**
* startTrackingMouse:
@@ -152,7 +155,7 @@ var Magnifier = class Magnifier {
let interval = 1000 / Clutter.get_default_frame_rate();
this._pointerWatch = PointerWatcher.getPointerWatcher().addWatch(interval, this.scrollToMousePos.bind(this));
}
}
},
/**
* stopTrackingMouse:
@@ -163,7 +166,7 @@ var Magnifier = class Magnifier {
this._pointerWatch.remove();
this._pointerWatch = null;
}
},
/**
* isTrackingMouse:
@@ -171,7 +174,7 @@ var Magnifier = class Magnifier {
*/
isTrackingMouse() {
return !!this._mouseTrackingId;
}
},
/**
* scrollToMousePos:
@@ -197,7 +200,7 @@ var Magnifier = class Magnifier {
this.showSystemCursor();
}
return true;
}
},
/**
* createZoomRegion:
@@ -226,7 +229,7 @@ var Magnifier = class Magnifier {
zoomRegion.addCrosshairs(this._crossHairs);
return zoomRegion;
}
},
/**
* addZoomRegion:
@@ -240,7 +243,7 @@ var Magnifier = class Magnifier {
if (!this.isTrackingMouse())
this.startTrackingMouse();
}
}
},
/**
* getZoomRegions:
@@ -249,7 +252,7 @@ var Magnifier = class Magnifier {
*/
getZoomRegions() {
return this._zoomRegions;
}
},
/**
* clearAllZoomRegions:
@@ -262,7 +265,7 @@ var Magnifier = class Magnifier {
this._zoomRegions.length = 0;
this.stopTrackingMouse();
this.showSystemCursor();
}
},
/**
* addCrosshairs:
@@ -288,7 +291,7 @@ var Magnifier = class Magnifier {
this._zoomRegions.forEach ((zoomRegion, index, array) => {
zoomRegion.addCrosshairs(theCrossHairs);
});
}
},
/**
* setCrosshairsVisible:
@@ -305,7 +308,7 @@ var Magnifier = class Magnifier {
if (this._crossHairs)
this._crossHairs.hide();
}
}
},
/**
* setCrosshairsColor:
@@ -317,7 +320,7 @@ var Magnifier = class Magnifier {
let [res, clutterColor] = Clutter.Color.from_string(color);
this._crossHairs.setColor(clutterColor);
}
}
},
/**
* getCrosshairsColor:
@@ -331,7 +334,7 @@ var Magnifier = class Magnifier {
}
else
return '#00000000';
}
},
/**
* setCrosshairsThickness:
@@ -342,7 +345,7 @@ var Magnifier = class Magnifier {
setCrosshairsThickness(thickness) {
if (this._crossHairs)
this._crossHairs.setThickness(thickness);
}
},
/**
* getCrosshairsThickness:
@@ -355,7 +358,7 @@ var Magnifier = class Magnifier {
return this._crossHairs.getThickness();
else
return 0;
}
},
/**
* setCrosshairsOpacity:
@@ -364,7 +367,7 @@ var Magnifier = class Magnifier {
setCrosshairsOpacity(opacity) {
if (this._crossHairs)
this._crossHairs.setOpacity(opacity * 255);
}
},
/**
* getCrosshairsOpacity:
@@ -375,7 +378,7 @@ var Magnifier = class Magnifier {
return this._crossHairs.getOpacity() / 255.0;
else
return 0.0;
}
},
/**
* setCrosshairsLength:
@@ -386,7 +389,7 @@ var Magnifier = class Magnifier {
setCrosshairsLength(length) {
if (this._crossHairs)
this._crossHairs.setLength(length);
}
},
/**
* getCrosshairsLength:
@@ -399,7 +402,7 @@ var Magnifier = class Magnifier {
return this._crossHairs.getLength();
else
return 0;
}
},
/**
* setCrosshairsClip:
@@ -417,7 +420,7 @@ var Magnifier = class Magnifier {
if (this._crossHairs)
this._crossHairs.setClip([0, 0]);
}
}
},
/**
* getCrosshairsClip:
@@ -431,7 +434,7 @@ var Magnifier = class Magnifier {
}
else
return false;
}
},
//// Private methods ////
@@ -439,7 +442,7 @@ var Magnifier = class Magnifier {
Shell.util_cursor_tracker_to_clutter(this._cursorTracker, this._mouseSprite);
let [xHot, yHot] = this._cursorTracker.get_hot();
this._mouseSprite.set_anchor_point(xHot, yHot);
}
},
_settingsInit(zoomRegion) {
this._appSettings = new Gio.Settings({ schema_id: APPLICATIONS_SCHEMA });
@@ -557,7 +560,7 @@ var Magnifier = class Magnifier {
this.setCrosshairsVisible(showCrosshairs);
return this._appSettings.get_boolean(SHOW_KEY);
}
},
_updateScreenPosition() {
// Applies only to the first zoom region.
@@ -567,7 +570,7 @@ var Magnifier = class Magnifier {
if (position != GDesktopEnums.MagnifierScreenPosition.FULL_SCREEN)
this._updateLensMode();
}
}
},
_updateMagFactor() {
// Applies only to the first zoom region.
@@ -576,14 +579,14 @@ var Magnifier = class Magnifier {
let magFactor = parseFloat(this._settings.get_double(MAG_FACTOR_KEY).toFixed(2));
this._zoomRegions[0].setMagFactor(magFactor, magFactor);
}
}
},
_updateLensMode() {
// Applies only to the first zoom region.
if (this._zoomRegions.length) {
this._zoomRegions[0].setLensMode(this._settings.get_boolean(LENS_MODE_KEY));
}
}
},
_updateClampMode() {
// Applies only to the first zoom region.
@@ -592,7 +595,7 @@ var Magnifier = class Magnifier {
!this._settings.get_boolean(CLAMP_MODE_KEY)
);
}
}
},
_updateMouseTrackingMode() {
// Applies only to the first zoom region.
@@ -601,7 +604,7 @@ var Magnifier = class Magnifier {
this._settings.get_enum(MOUSE_TRACKING_KEY)
);
}
}
},
_updateFocusTrackingMode() {
// Applies only to the first zoom region.
@@ -610,7 +613,7 @@ var Magnifier = class Magnifier {
this._settings.get_enum(FOCUS_TRACKING_KEY)
);
}
}
},
_updateCaretTrackingMode() {
// Applies only to the first zoom region.
@@ -619,7 +622,7 @@ var Magnifier = class Magnifier {
this._settings.get_enum(CARET_TRACKING_KEY)
);
}
}
},
_updateInvertLightness() {
// Applies only to the first zoom region.
@@ -628,7 +631,7 @@ var Magnifier = class Magnifier {
this._settings.get_boolean(INVERT_LIGHTNESS_KEY)
);
}
}
},
_updateColorSaturation() {
// Applies only to the first zoom region.
@@ -637,7 +640,7 @@ var Magnifier = class Magnifier {
this._settings.get_double(COLOR_SATURATION_KEY)
);
}
}
},
_updateBrightness() {
// Applies only to the first zoom region.
@@ -648,7 +651,7 @@ var Magnifier = class Magnifier {
brightness.b = this._settings.get_double(BRIGHT_BLUE_KEY);
this._zoomRegions[0].setBrightness(brightness);
}
}
},
_updateContrast() {
// Applies only to the first zoom region.
@@ -660,11 +663,13 @@ var Magnifier = class Magnifier {
this._zoomRegions[0].setContrast(contrast);
}
}
};
});
Signals.addSignalMethods(Magnifier.prototype);
var ZoomRegion = class ZoomRegion {
constructor(magnifier, mouseSourceActor) {
var ZoomRegion = new Lang.Class({
Name: 'ZoomRegion',
_init(magnifier, mouseSourceActor) {
this._magnifier = magnifier;
this._focusCaretTracker = new FocusCaretTracker.FocusCaretTracker();
@@ -710,7 +715,7 @@ var ZoomRegion = class ZoomRegion {
this._updateCaret.bind(this));
this._focusCaretTracker.connect('focus-changed',
this._updateFocus.bind(this));
}
},
_updateFocus(caller, event) {
let component = event.source.get_component_iface();
@@ -727,7 +732,7 @@ var ZoomRegion = class ZoomRegion {
[this._xFocus, this._yFocus] = [extents.x + (extents.width / 2),
extents.y + (extents.height / 2)];
this._centerFromFocusPosition();
}
},
_updateCaret(caller, event) {
let text = event.source.get_text_iface();
@@ -743,7 +748,7 @@ var ZoomRegion = class ZoomRegion {
[this._xCaret, this._yCaret] = [extents.x, extents.y];
this._centerFromCaretPosition();
}
},
/**
* setActive:
@@ -766,7 +771,7 @@ var ZoomRegion = class ZoomRegion {
this._syncCaretTracking();
this._syncFocusTracking();
}
},
/**
* isActive:
@@ -774,7 +779,7 @@ var ZoomRegion = class ZoomRegion {
*/
isActive() {
return this._magView != null;
}
},
/**
* setMagFactor:
@@ -788,7 +793,7 @@ var ZoomRegion = class ZoomRegion {
this._changeROI({ xMagFactor: xMagFactor,
yMagFactor: yMagFactor,
redoCursorTracking: this._followingCursor });
}
},
/**
* getMagFactor:
@@ -799,7 +804,7 @@ var ZoomRegion = class ZoomRegion {
*/
getMagFactor() {
return [this._xMagFactor, this._yMagFactor];
}
},
/**
* setMouseTrackingMode
@@ -809,7 +814,7 @@ var ZoomRegion = class ZoomRegion {
if (mode >= GDesktopEnums.MagnifierMouseTrackingMode.NONE &&
mode <= GDesktopEnums.MagnifierMouseTrackingMode.PUSH)
this._mouseTrackingMode = mode;
}
},
/**
* getMouseTrackingMode
@@ -817,7 +822,7 @@ var ZoomRegion = class ZoomRegion {
*/
getMouseTrackingMode() {
return this._mouseTrackingMode;
}
},
/**
* setFocusTrackingMode
@@ -826,7 +831,7 @@ var ZoomRegion = class ZoomRegion {
setFocusTrackingMode(mode) {
this._focusTrackingMode = mode;
this._syncFocusTracking();
}
},
/**
* setCaretTrackingMode
@@ -835,7 +840,7 @@ var ZoomRegion = class ZoomRegion {
setCaretTrackingMode(mode) {
this._caretTrackingMode = mode;
this._syncCaretTracking();
}
},
_syncFocusTracking() {
let enabled = this._focusTrackingMode != GDesktopEnums.MagnifierFocusTrackingMode.NONE &&
@@ -845,7 +850,7 @@ var ZoomRegion = class ZoomRegion {
this._focusCaretTracker.registerFocusListener();
else
this._focusCaretTracker.deregisterFocusListener();
}
},
_syncCaretTracking() {
let enabled = this._caretTrackingMode != GDesktopEnums.MagnifierCaretTrackingMode.NONE &&
@@ -855,7 +860,7 @@ var ZoomRegion = class ZoomRegion {
this._focusCaretTracker.registerCaretListener();
else
this._focusCaretTracker.deregisterCaretListener();
}
},
/**
* setViewPort
@@ -867,7 +872,7 @@ var ZoomRegion = class ZoomRegion {
setViewPort(viewPort) {
this._setViewPort(viewPort);
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.NONE;
}
},
/**
* setROI
@@ -885,7 +890,7 @@ var ZoomRegion = class ZoomRegion {
yMagFactor: this._viewPortHeight / roi.height,
xCenter: roi.x + roi.width / 2,
yCenter: roi.y + roi.height / 2 });
}
},
/**
* getROI:
@@ -902,7 +907,7 @@ var ZoomRegion = class ZoomRegion {
return [this._xCenter - roiWidth / 2,
this._yCenter - roiHeight / 2,
roiWidth, roiHeight];
}
},
/**
* setLensMode:
@@ -914,7 +919,7 @@ var ZoomRegion = class ZoomRegion {
this._lensMode = lensMode;
if (!this._lensMode)
this.setScreenPosition (this._screenPosition);
}
},
/**
* isLensMode:
@@ -923,7 +928,7 @@ var ZoomRegion = class ZoomRegion {
*/
isLensMode() {
return this._lensMode;
}
},
/**
* setClampScrollingAtEdges:
@@ -935,7 +940,7 @@ var ZoomRegion = class ZoomRegion {
this._clampScrollingAtEdges = clamp;
if (clamp)
this._changeROI();
}
},
/**
* setTopHalf:
@@ -949,7 +954,7 @@ var ZoomRegion = class ZoomRegion {
viewPort.height = global.screen_height/2;
this._setViewPort(viewPort);
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.TOP_HALF;
}
},
/**
* setBottomHalf:
@@ -963,7 +968,7 @@ var ZoomRegion = class ZoomRegion {
viewPort.height = global.screen_height/2;
this._setViewPort(viewPort);
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.BOTTOM_HALF;
}
},
/**
* setLeftHalf:
@@ -977,7 +982,7 @@ var ZoomRegion = class ZoomRegion {
viewPort.height = global.screen_height;
this._setViewPort(viewPort);
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.LEFT_HALF;
}
},
/**
* setRightHalf:
@@ -991,7 +996,7 @@ var ZoomRegion = class ZoomRegion {
viewPort.height = global.screen_height;
this._setViewPort(viewPort);
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.RIGHT_HALF;
}
},
/**
* setFullScreenMode:
@@ -1007,7 +1012,7 @@ var ZoomRegion = class ZoomRegion {
this.setViewPort(viewPort);
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.FULL_SCREEN;
}
},
/**
* setScreenPosition:
@@ -1035,7 +1040,7 @@ var ZoomRegion = class ZoomRegion {
this.setRightHalf();
break;
}
}
},
/**
* getScreenPosition:
@@ -1045,7 +1050,7 @@ var ZoomRegion = class ZoomRegion {
*/
getScreenPosition() {
return this._screenPosition;
}
},
/**
* scrollToMousePos:
@@ -1061,14 +1066,14 @@ var ZoomRegion = class ZoomRegion {
// Determine whether the system mouse pointer is over this zoom region.
return this._isMouseOverRegion();
}
},
_clearScrollContentsTimer() {
if (this._scrollContentsTimerId != 0) {
Mainloop.source_remove(this._scrollContentsTimerId);
this._scrollContentsTimerId = 0;
}
}
},
_scrollContentsToDelayed(x, y) {
if (this._pointerIdleMonitor.get_idletime() >= POINTER_REST_TIME) {
@@ -1081,7 +1086,7 @@ var ZoomRegion = class ZoomRegion {
this._scrollContentsToDelayed(x, y);
return GLib.SOURCE_REMOVE;
});
}
},
/**
* scrollContentsTo:
@@ -1096,7 +1101,7 @@ var ZoomRegion = class ZoomRegion {
this._followingCursor = false;
this._changeROI({ xCenter: x,
yCenter: y });
}
},
/**
* addCrosshairs:
@@ -1111,7 +1116,7 @@ var ZoomRegion = class ZoomRegion {
if (crossHairs && this.isActive()) {
this._crossHairsActor = crossHairs.addToZoomRegion(this, this._mouseActor);
}
}
},
/**
* setInvertLightness:
@@ -1122,7 +1127,7 @@ var ZoomRegion = class ZoomRegion {
this._invertLightness = flag;
if (this._magShaderEffects)
this._magShaderEffects.setInvertLightness(this._invertLightness);
}
},
/**
* getInvertLightness:
@@ -1131,7 +1136,7 @@ var ZoomRegion = class ZoomRegion {
*/
getInvertLightness() {
return this._invertLightness;
}
},
/**
* setColorSaturation:
@@ -1144,7 +1149,7 @@ var ZoomRegion = class ZoomRegion {
this._colorSaturation = saturation;
if (this._magShaderEffects)
this._magShaderEffects.setColorSaturation(this._colorSaturation);
}
},
/**
* getColorSaturation:
@@ -1152,7 +1157,7 @@ var ZoomRegion = class ZoomRegion {
*/
getColorSaturation() {
return this._colorSaturation;
}
},
/**
* setBrightness:
@@ -1168,7 +1173,7 @@ var ZoomRegion = class ZoomRegion {
this._brightness.b = brightness.b;
if (this._magShaderEffects)
this._magShaderEffects.setBrightness(this._brightness);
}
},
/**
* setContrast:
@@ -1184,7 +1189,7 @@ var ZoomRegion = class ZoomRegion {
this._contrast.b = contrast.b;
if (this._magShaderEffects)
this._magShaderEffects.setContrast(this._contrast);
}
},
/**
* getContrast:
@@ -1198,7 +1203,7 @@ var ZoomRegion = class ZoomRegion {
contrast.g = this._contrast.g;
contrast.b = this._contrast.b;
return contrast;
}
},
//// Private methods ////
@@ -1244,7 +1249,7 @@ var ZoomRegion = class ZoomRegion {
this._magShaderEffects.setInvertLightness(this._invertLightness);
this._magShaderEffects.setBrightness(this._brightness);
this._magShaderEffects.setContrast(this._contrast);
}
},
_destroyActors() {
if (this._mouseActor == this._mouseSourceActor)
@@ -1260,7 +1265,7 @@ var ZoomRegion = class ZoomRegion {
this._uiGroupClone = null;
this._mouseActor = null;
this._crossHairsActor = null;
}
},
_setViewPort(viewPort, fromROIUpdate) {
// Sets the position of the zoom region on the screen
@@ -1285,7 +1290,7 @@ var ZoomRegion = class ZoomRegion {
if (this.isActive() && this._isMouseOverRegion())
this._magnifier.hideSystemCursor();
}
},
_changeROI(params) {
// Updates the area we are viewing; the magnification factors
@@ -1336,7 +1341,7 @@ var ZoomRegion = class ZoomRegion {
this._updateCloneGeometry();
this._updateMousePosition();
}
},
_isMouseOverRegion() {
// Return whether the system mouse sprite is over this ZoomRegion. If the
@@ -1352,7 +1357,7 @@ var ZoomRegion = class ZoomRegion {
);
}
return mouseIsOver;
}
},
_isFullScreen() {
// Does the magnified view occupy the whole screen? Note that this
@@ -1365,7 +1370,7 @@ var ZoomRegion = class ZoomRegion {
this._viewPortHeight != global.screen_height)
return false;
return true;
}
},
_centerFromMousePosition() {
// Determines where the center should be given the current cursor
@@ -1385,7 +1390,7 @@ var ZoomRegion = class ZoomRegion {
}
return null; // Should never be hit
}
},
_centerFromCaretPosition() {
let xCaret = this._xCaret;
@@ -1399,7 +1404,7 @@ var ZoomRegion = class ZoomRegion {
[xCaret, yCaret] = this._centerFromPointCentered(xCaret, yCaret);
this._scrollContentsToDelayed(xCaret, yCaret);
}
},
_centerFromFocusPosition() {
let xFocus = this._xFocus;
@@ -1413,7 +1418,7 @@ var ZoomRegion = class ZoomRegion {
[xFocus, yFocus] = this._centerFromPointCentered(xFocus, yFocus);
this._scrollContentsToDelayed(xFocus, yFocus);
}
},
_centerFromPointPush(xPoint, yPoint) {
let [xRoi, yRoi, widthRoi, heightRoi] = this.getROI();
@@ -1434,7 +1439,7 @@ var ZoomRegion = class ZoomRegion {
yPos += (yPoint - yRoiBottom);
return [xPos, yPos];
}
},
_centerFromPointProportional(xPoint, yPoint) {
let [xRoi, yRoi, widthRoi, heightRoi] = this.getROI();
@@ -1451,18 +1456,18 @@ var ZoomRegion = class ZoomRegion {
let yPos = yPoint - yProportion * (heightRoi /2 - yPadding);
return [xPos, yPos];
}
},
_centerFromPointCentered(xPoint, yPoint) {
return [xPoint, yPoint];
}
},
_screenToViewPort(screenX, screenY) {
// Converts coordinates relative to the (unmagnified) screen to coordinates
// relative to the origin of this._magView
return [this._viewPortWidth / 2 + (screenX - this._xCenter) * this._xMagFactor,
this._viewPortHeight / 2 + (screenY - this._yCenter) * this._yMagFactor];
}
},
_updateMagViewGeometry() {
if (!this.isActive())
@@ -1475,7 +1480,7 @@ var ZoomRegion = class ZoomRegion {
this._magView.set_size(this._viewPortWidth, this._viewPortHeight);
this._magView.set_position(this._viewPortX, this._viewPortY);
}
},
_updateCloneGeometry() {
if (!this.isActive())
@@ -1488,7 +1493,7 @@ var ZoomRegion = class ZoomRegion {
this._uiGroupClone.set_position(Math.round(x), Math.round(y));
this._updateMousePosition();
}
},
_updateMousePosition() {
if (!this.isActive())
@@ -1507,7 +1512,7 @@ var ZoomRegion = class ZoomRegion {
this._crossHairsActor.set_position(xMagMouse - groupWidth / 2,
yMagMouse - groupHeight / 2);
}
}
},
_monitorsChanged() {
if (!this.isActive())
@@ -1523,10 +1528,12 @@ var ZoomRegion = class ZoomRegion {
else
this.setScreenPosition(this._screenPosition);
}
};
});
var Crosshairs = class Crosshairs {
constructor() {
var Crosshairs = new Lang.Class({
Name: 'Crosshairs',
_init() {
// Set the group containing the crosshairs to three times the desktop
// size in case the crosshairs need to appear to be infinite in
@@ -1553,12 +1560,12 @@ var Crosshairs = class Crosshairs {
Main.layoutManager.connect('monitors-changed',
this._monitorsChanged.bind(this));
}
},
_monitorsChanged() {
this._actor.set_size(global.screen_width * 3, global.screen_height * 3);
this.reCenter();
}
},
/**
* addToZoomRegion
@@ -1592,7 +1599,7 @@ var Crosshairs = class Crosshairs {
}
}
return crosshairsActor;
}
},
/**
* removeFromParent:
@@ -1605,7 +1612,7 @@ var Crosshairs = class Crosshairs {
childActor.get_parent().remove_actor(childActor);
else
childActor.destroy();
}
},
/**
* setColor:
@@ -1617,7 +1624,7 @@ var Crosshairs = class Crosshairs {
this._horizRightHair.background_color = clutterColor;
this._vertTopHair.background_color = clutterColor;
this._vertBottomHair.background_color = clutterColor;
}
},
/**
* getColor:
@@ -1626,7 +1633,7 @@ var Crosshairs = class Crosshairs {
*/
getColor() {
return this._horizLeftHair.get_color();
}
},
/**
* setThickness:
@@ -1639,7 +1646,7 @@ var Crosshairs = class Crosshairs {
this._vertTopHair.set_width(thickness);
this._vertBottomHair.set_width(thickness);
this.reCenter();
}
},
/**
* getThickness:
@@ -1648,7 +1655,7 @@ var Crosshairs = class Crosshairs {
*/
getThickness() {
return this._horizLeftHair.get_height();
}
},
/**
* setOpacity:
@@ -1667,7 +1674,7 @@ var Crosshairs = class Crosshairs {
this._horizRightHair.set_opacity(opacity);
this._vertTopHair.set_opacity(opacity);
this._vertBottomHair.set_opacity(opacity);
}
},
/**
* setLength:
@@ -1680,7 +1687,7 @@ var Crosshairs = class Crosshairs {
this._vertTopHair.set_height(length);
this._vertBottomHair.set_height(length);
this.reCenter();
}
},
/**
* getLength:
@@ -1689,7 +1696,7 @@ var Crosshairs = class Crosshairs {
*/
getLength() {
return this._horizLeftHair.get_width();
}
},
/**
* setClip:
@@ -1710,7 +1717,7 @@ var Crosshairs = class Crosshairs {
this._clipSize = [0, 0];
this.reCenter();
}
}
},
/**
* show:
@@ -1721,7 +1728,7 @@ var Crosshairs = class Crosshairs {
// Clones don't share visibility.
for (let i = 0; i < this._clones.length; i++)
this._clones[i].show();
}
},
/**
* hide:
@@ -1732,7 +1739,7 @@ var Crosshairs = class Crosshairs {
// Clones don't share visibility.
for (let i = 0; i < this._clones.length; i++)
this._clones[i].hide();
}
},
/**
* reCenter:
@@ -1766,10 +1773,12 @@ var Crosshairs = class Crosshairs {
this._vertTopHair.set_position((groupWidth - thickness) / 2, top);
this._vertBottomHair.set_position((groupWidth - thickness) / 2, bottom);
}
};
});
var MagShaderEffects = class MagShaderEffects {
constructor(uiGroupClone) {
var MagShaderEffects = new Lang.Class({
Name: 'MagShaderEffects',
_init(uiGroupClone) {
this._inverse = new Shell.InvertLightnessEffect();
this._brightnessContrast = new Clutter.BrightnessContrastEffect();
this._colorDesaturation = new Clutter.DesaturateEffect();
@@ -1780,7 +1789,7 @@ var MagShaderEffects = class MagShaderEffects {
this._magView.add_effect(this._inverse);
this._magView.add_effect(this._brightnessContrast);
this._magView.add_effect(this._colorDesaturation);
}
},
/**
* destroyEffects:
@@ -1794,7 +1803,7 @@ var MagShaderEffects = class MagShaderEffects {
this._brightnessContrast = null;
this._inverse = null;
this._magView = null;
}
},
/**
* setInvertLightness:
@@ -1803,11 +1812,11 @@ var MagShaderEffects = class MagShaderEffects {
*/
setInvertLightness(invertFlag) {
this._inverse.set_enabled(invertFlag);
}
},
setColorSaturation(factor) {
this._colorDesaturation.set_factor(1.0 - factor);
}
},
/**
* setBrightness:
@@ -1831,7 +1840,7 @@ var MagShaderEffects = class MagShaderEffects {
(bRed != NO_CHANGE || bGreen != NO_CHANGE || bBlue != NO_CHANGE ||
cRed != NO_CHANGE || cGreen != NO_CHANGE || cBlue != NO_CHANGE)
);
}
},
/**
* Set the contrast of the magnified view.
@@ -1856,5 +1865,5 @@ var MagShaderEffects = class MagShaderEffects {
cRed != NO_CHANGE || cGreen != NO_CHANGE || cBlue != NO_CHANGE ||
bRed != NO_CHANGE || bGreen != NO_CHANGE || bBlue != NO_CHANGE
);
}
};
},
});

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Main = imports.ui.main;
const { loadInterfaceXML } = imports.misc.fileUtils;
@@ -21,13 +22,15 @@ const ZoomRegionIface = loadInterfaceXML('org.gnome.Magnifier.ZoomRegion');
// '/org/gnome/Magnifier/ZoomRegion/zoomer1', etc.
let _zoomRegionInstanceCount = 0;
var ShellMagnifier = class ShellMagnifier {
constructor() {
var ShellMagnifier = new Lang.Class({
Name: 'ShellMagnifier',
_init() {
this._zoomers = {};
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(MagnifierIface, this);
this._dbusImpl.export(Gio.DBus.session, MAG_SERVICE_PATH);
}
},
/**
* setActive:
@@ -35,7 +38,7 @@ var ShellMagnifier = class ShellMagnifier {
*/
setActive(activate) {
Main.magnifier.setActive(activate);
}
},
/**
* isActive:
@@ -43,7 +46,7 @@ var ShellMagnifier = class ShellMagnifier {
*/
isActive() {
return Main.magnifier.isActive();
}
},
/**
* showCursor:
@@ -51,7 +54,7 @@ var ShellMagnifier = class ShellMagnifier {
*/
showCursor() {
Main.magnifier.showSystemCursor();
}
},
/**
* hideCursor:
@@ -59,7 +62,7 @@ var ShellMagnifier = class ShellMagnifier {
*/
hideCursor() {
Main.magnifier.hideSystemCursor();
}
},
/**
* createZoomRegion:
@@ -94,7 +97,7 @@ var ShellMagnifier = class ShellMagnifier {
proxyAndZoomRegion.zoomRegion = realZoomRegion;
this._zoomers[objectPath] = proxyAndZoomRegion;
return objectPath;
}
},
/**
* addZoomRegion:
@@ -109,7 +112,7 @@ var ShellMagnifier = class ShellMagnifier {
}
else
return false;
}
},
/**
* getZoomRegions:
@@ -147,7 +150,7 @@ var ShellMagnifier = class ShellMagnifier {
}
});
return objectPaths;
}
},
/**
* clearAllZoomRegions:
@@ -163,7 +166,7 @@ var ShellMagnifier = class ShellMagnifier {
delete this._zoomers[objectPath];
}
this._zoomers = {};
}
},
/**
* fullScreenCapable:
@@ -172,7 +175,7 @@ var ShellMagnifier = class ShellMagnifier {
*/
fullScreenCapable() {
return true;
}
},
/**
* setCrosswireSize:
@@ -181,7 +184,7 @@ var ShellMagnifier = class ShellMagnifier {
*/
setCrosswireSize(size) {
Main.magnifier.setCrosshairsThickness(size);
}
},
/**
* getCrosswireSize:
@@ -190,7 +193,7 @@ var ShellMagnifier = class ShellMagnifier {
*/
getCrosswireSize() {
return Main.magnifier.getCrosshairsThickness();
}
},
/**
* setCrosswireLength:
@@ -199,7 +202,7 @@ var ShellMagnifier = class ShellMagnifier {
*/
setCrosswireLength(length) {
Main.magnifier.setCrosshairsLength(length);
}
},
/**
* setCrosswireSize:
@@ -208,7 +211,7 @@ var ShellMagnifier = class ShellMagnifier {
*/
getCrosswireLength() {
return Main.magnifier.getCrosshairsLength();
}
},
/**
* setCrosswireClip:
@@ -217,7 +220,7 @@ var ShellMagnifier = class ShellMagnifier {
*/
setCrosswireClip(clip) {
Main.magnifier.setCrosshairsClip(clip);
}
},
/**
* getCrosswireClip:
@@ -226,7 +229,7 @@ var ShellMagnifier = class ShellMagnifier {
*/
getCrosswireClip() {
return Main.magnifier.getCrosshairsClip();
}
},
/**
* setCrosswireColor:
@@ -235,7 +238,7 @@ var ShellMagnifier = class ShellMagnifier {
*/
setCrosswireColor(color) {
Main.magnifier.setCrosshairsColor('#%08x'.format(color));
}
},
/**
* getCrosswireClip:
@@ -247,7 +250,7 @@ var ShellMagnifier = class ShellMagnifier {
// Drop the leading '#'.
return parseInt(colorString.slice(1), 16);
}
};
});
/**
* ShellMagnifierZoomRegion:
@@ -255,13 +258,15 @@ var ShellMagnifier = class ShellMagnifier {
* @zoomerObjectPath: String that is the path to a DBus ZoomRegion.
* @zoomRegion: The actual zoom region associated with the object path.
*/
var ShellMagnifierZoomRegion = class ShellMagnifierZoomRegion {
constructor(zoomerObjectPath, zoomRegion) {
var ShellMagnifierZoomRegion = new Lang.Class({
Name: 'ShellMagnifierZoomRegion',
_init(zoomerObjectPath, zoomRegion) {
this._zoomRegion = zoomRegion;
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ZoomRegionIface, this);
this._dbusImpl.export(Gio.DBus.session, zoomerObjectPath);
}
},
/**
* setMagFactor:
@@ -273,7 +278,7 @@ var ShellMagnifierZoomRegion = class ShellMagnifierZoomRegion {
*/
setMagFactor(xMagFactor, yMagFactor) {
this._zoomRegion.setMagFactor(xMagFactor, yMagFactor);
}
},
/**
* getMagFactor:
@@ -284,7 +289,7 @@ var ShellMagnifierZoomRegion = class ShellMagnifierZoomRegion {
*/
getMagFactor() {
return this._zoomRegion.getMagFactor();
}
},
/**
* setRoi:
@@ -296,7 +301,7 @@ var ShellMagnifierZoomRegion = class ShellMagnifierZoomRegion {
setRoi(roi) {
let roiObject = { x: roi[0], y: roi[1], width: roi[2] - roi[0], height: roi[3] - roi[1] };
this._zoomRegion.setROI(roiObject);
}
},
/**
* getRoi:
@@ -311,7 +316,7 @@ var ShellMagnifierZoomRegion = class ShellMagnifierZoomRegion {
roi[2] += roi[0];
roi[3] += roi[1];
return roi;
}
},
/**
* Set the "region of interest" by centering the given screen coordinate
@@ -324,7 +329,7 @@ var ShellMagnifierZoomRegion = class ShellMagnifierZoomRegion {
shiftContentsTo(x, y) {
this._zoomRegion.scrollContentsTo(x, y);
return true;
}
},
/**
* moveResize
@@ -335,9 +340,9 @@ var ShellMagnifierZoomRegion = class ShellMagnifierZoomRegion {
moveResize(viewPort) {
let viewRect = { x: viewPort[0], y: viewPort[1], width: viewPort[2] - viewPort[0], height: viewPort[3] - viewPort[1] };
this._zoomRegion.setViewPort(viewRect);
}
},
destroy() {
this._dbusImpl.unexport();
}
};
});

View File

@@ -5,6 +5,7 @@ const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
@@ -19,7 +20,6 @@ const Environment = imports.ui.environment;
const ExtensionSystem = imports.ui.extensionSystem;
const ExtensionDownloader = imports.ui.extensionDownloader;
const InputMethod = imports.misc.inputMethod;
const Introspect = imports.misc.introspect;
const Keyboard = imports.ui.keyboard;
const MessageTray = imports.ui.messageTray;
const ModalDialog = imports.ui.modalDialog;
@@ -82,7 +82,6 @@ var keyboard = null;
var layoutManager = null;
var kbdA11yDialog = null;
var inputMethod = null;
var introspectService = null;
let _startDate;
let _defaultCssStylesheet = null;
let _cssStylesheet = null;
@@ -188,8 +187,6 @@ function _initializeUI() {
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
componentManager = new Components.ComponentManager();
introspectService = new Introspect.IntrospectService();
layoutManager.init();
overview.init();
@@ -699,12 +696,15 @@ function queueDeferredWork(workId) {
}
}
var RestartMessage = class extends ModalDialog.ModalDialog {
constructor(message) {
super({ shellReactive: true,
styleClass: 'restart-message headline',
shouldFadeIn: false,
destroyOnClose: true });
var RestartMessage = new Lang.Class({
Name: 'RestartMessage',
Extends: ModalDialog.ModalDialog,
_init(message) {
this.parent({ shellReactive: true,
styleClass: 'restart-message headline',
shouldFadeIn: false,
destroyOnClose: true });
let label = new St.Label({ text: message });
@@ -714,7 +714,7 @@ var RestartMessage = class extends ModalDialog.ModalDialog {
y_align: St.Align.MIDDLE });
this.buttonLayout.hide();
}
};
});
function showRestartMessage(message) {
let restartMessage = new RestartMessage(message);

View File

@@ -3,6 +3,7 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const Meta = imports.gi.Meta;
@@ -39,8 +40,10 @@ function _fixMarkup(text, allowMarkup) {
return GLib.markup_escape_text(text, -1);
}
var URLHighlighter = class URLHighlighter {
constructor(text, lineWrap, allowMarkup) {
var URLHighlighter = new Lang.Class({
Name: 'URLHighlighter',
_init(text, lineWrap, allowMarkup) {
if (!text)
text = '';
this.actor = new St.Label({ reactive: true, style_class: 'url-highlighter',
@@ -111,7 +114,7 @@ var URLHighlighter = class URLHighlighter {
}
return Clutter.EVENT_PROPAGATE;
});
}
},
setMarkup(text, allowMarkup) {
text = text ? _fixMarkup(text, allowMarkup) : '';
@@ -121,7 +124,7 @@ var URLHighlighter = class URLHighlighter {
/* clutter_text.text contain text without markup */
this._urls = Util.findUrls(this.actor.clutter_text.text);
this._highlightUrls();
}
},
_highlightUrls() {
// text here contain markup
@@ -136,7 +139,7 @@ var URLHighlighter = class URLHighlighter {
}
markup += this._text.substr(pos);
this.actor.clutter_text.set_markup(markup);
}
},
_findUrlAtPos(event) {
let success;
@@ -157,14 +160,16 @@ var URLHighlighter = class URLHighlighter {
}
return -1;
}
};
});
var ScaleLayout = new Lang.Class({
Name: 'ScaleLayout',
Extends: Clutter.BinLayout,
var ScaleLayout = new GObject.registerClass(
class ScaleLayout extends Clutter.BinLayout {
_init(params) {
this._container = null;
super._init(params);
}
this.parent(params);
},
_connectContainer(container) {
if (this._container == container)
@@ -184,43 +189,45 @@ class ScaleLayout extends Clutter.BinLayout {
});
this._signals.push(id);
}
}
},
vfunc_get_preferred_width(container, forHeight) {
this._connectContainer(container);
let [min, nat] = super.vfunc_get_preferred_width(container, forHeight);
let [min, nat] = this.parent(container, forHeight);
return [Math.floor(min * container.scale_x),
Math.floor(nat * container.scale_x)];
}
},
vfunc_get_preferred_height(container, forWidth) {
this._connectContainer(container);
let [min, nat] = super.vfunc_get_preferred_height(container, forWidth);
let [min, nat] = this.parent(container, forWidth);
return [Math.floor(min * container.scale_y),
Math.floor(nat * container.scale_y)];
}
});
var LabelExpanderLayout = GObject.registerClass({
var LabelExpanderLayout = new Lang.Class({
Name: 'LabelExpanderLayout',
Extends: Clutter.LayoutManager,
Properties: { 'expansion': GObject.ParamSpec.double('expansion',
'Expansion',
'Expansion of the layout, between 0 (collapsed) ' +
'and 1 (fully expanded',
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE,
0, 1, 0)},
}, class LabelExpanderLayout extends Clutter.LayoutManager {
_init(params) {
this._expansion = 0;
this._expandLines = DEFAULT_EXPAND_LINES;
super._init(params);
}
this.parent(params);
},
get expansion() {
return this._expansion;
}
},
set expansion(v) {
if (v == this._expansion)
@@ -233,7 +240,7 @@ var LabelExpanderLayout = GObject.registerClass({
this._container.get_child_at_index(i).visible = (i == visibleIndex);
this.layout_changed();
}
},
set expandLines(v) {
if (v == this._expandLines)
@@ -241,11 +248,11 @@ var LabelExpanderLayout = GObject.registerClass({
this._expandLines = v;
if (this._expansion > 0)
this.layout_changed();
}
},
vfunc_set_container(container) {
this._container = container;
}
},
vfunc_get_preferred_width(container, forHeight) {
let [min, nat] = [0, 0];
@@ -260,7 +267,7 @@ var LabelExpanderLayout = GObject.registerClass({
}
return [min, nat];
}
},
vfunc_get_preferred_height(container, forWidth) {
let [min, nat] = [0, 0];
@@ -278,7 +285,7 @@ var LabelExpanderLayout = GObject.registerClass({
}
return [min, nat];
}
},
vfunc_allocate(container, box, flags) {
for (let i = 0; i < container.get_n_children(); i++) {
@@ -291,8 +298,10 @@ var LabelExpanderLayout = GObject.registerClass({
}
});
var Message = class Message {
constructor(title, body) {
var Message = new Lang.Class({
Name: 'Message',
_init(title, body) {
this.expanded = false;
this._useBodyMarkup = false;
@@ -359,25 +368,25 @@ var Message = class Message {
this.actor.connect('clicked', this._onClicked.bind(this));
this.actor.connect('destroy', this._onDestroy.bind(this));
this._sync();
}
},
close() {
this.emit('close');
}
},
setIcon(actor) {
this._iconBin.child = actor;
this._iconBin.visible = (actor != null);
}
},
setSecondaryActor(actor) {
this._secondaryBin.child = actor;
}
},
setTitle(text) {
let title = text ? _fixMarkup(text.replace(/\n/g, ' '), false) : '';
this.titleLabel.clutter_text.set_markup(title);
}
},
setBody(text) {
this._bodyText = text;
@@ -385,7 +394,7 @@ var Message = class Message {
this._useBodyMarkup);
if (this._expandedLabel)
this._expandedLabel.setMarkup(text, this._useBodyMarkup);
}
},
setUseBodyMarkup(enable) {
if (this._useBodyMarkup === enable)
@@ -393,7 +402,7 @@ var Message = class Message {
this._useBodyMarkup = enable;
if (this.bodyLabel)
this.setBody(this._bodyText);
}
},
setActionArea(actor) {
if (actor == null) {
@@ -407,7 +416,7 @@ var Message = class Message {
this._actionBin.add_actor(actor);
this._actionBin.visible = this.expanded;
}
},
addMediaControl(iconName, callback) {
let icon = new St.Icon({ icon_name: iconName, icon_size: 16 });
@@ -416,7 +425,7 @@ var Message = class Message {
button.connect('clicked', callback);
this._mediaControls.add_actor(button);
return button;
}
},
setExpandedBody(actor) {
if (actor == null) {
@@ -429,11 +438,11 @@ var Message = class Message {
throw new Error('Message already has an expanded body actor');
this._bodyStack.insert_child_at_index(actor, 1);
}
},
setExpandedLines(nLines) {
this._bodyStack.layout_manager.expandLines = nLines;
}
},
expand(animate) {
this.expanded = true;
@@ -462,7 +471,7 @@ var Message = class Message {
}
this.emit('expanded');
}
},
unexpand(animate) {
if (animate) {
@@ -486,23 +495,23 @@ var Message = class Message {
}
this.emit('unexpanded');
}
},
canClose() {
return false;
}
return this._mediaControls.get_n_children() == 0;
},
_sync() {
let visible = this.actor.hover && this.canClose();
this._closeButton.opacity = visible ? 255 : 0;
this._closeButton.reactive = visible;
}
},
_onClicked() {
}
},
_onDestroy() {
}
},
_onKeyPressed(a, event) {
let keysym = event.get_key_symbol();
@@ -514,11 +523,13 @@ var Message = class Message {
}
return Clutter.EVENT_PROPAGATE;
}
};
});
Signals.addSignalMethods(Message.prototype);
var MessageListSection = class MessageListSection {
constructor() {
var MessageListSection = new Lang.Class({
Name: 'MessageListSection',
_init() {
this.actor = new St.BoxLayout({ style_class: 'message-list-section',
clip_to_allocation: true,
x_expand: true, vertical: true });
@@ -541,26 +552,26 @@ var MessageListSection = class MessageListSection {
this.empty = true;
this.canClear = false;
this._sync();
}
},
_onKeyFocusIn(actor) {
this.emit('key-focus-in', actor);
}
},
get allowed() {
return true;
}
},
setDate(date) {
if (Calendar.sameDay(date, this._date))
return;
this._date = date;
this._sync();
}
},
addMessage(message, animate) {
this.addMessageAtIndex(message, -1, animate);
}
},
addMessageAtIndex(message, index, animate) {
let obj = {
@@ -593,7 +604,7 @@ var MessageListSection = class MessageListSection {
scale_y: 1,
time: MESSAGE_ANIMATION_TIME,
transition: 'easeOutQuad' });
}
},
moveMessage(message, index, animate) {
let obj = this._messages.get(message);
@@ -615,7 +626,7 @@ var MessageListSection = class MessageListSection {
time: MESSAGE_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: onComplete });
}
},
removeMessage(message, animate) {
let obj = this._messages.get(message);
@@ -638,7 +649,7 @@ var MessageListSection = class MessageListSection {
obj.container.destroy();
global.sync_pointer();
}
}
},
clear() {
let messages = [...this._messages.keys()].filter(msg => msg.canClose());
@@ -666,18 +677,18 @@ var MessageListSection = class MessageListSection {
}});
}
}
}
},
_canClear() {
for (let message of this._messages.keys())
if (message.canClose())
return true;
return false;
}
},
_shouldShow() {
return !this.empty;
}
},
_sync() {
let empty = this._list.get_n_children() == 0;
@@ -696,5 +707,5 @@ var MessageListSection = class MessageListSection {
this.actor.visible = this.allowed && this._shouldShow();
}
};
});
Signals.addSignalMethods(MessageListSection.prototype);

View File

@@ -6,6 +6,7 @@ const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Atk = imports.gi.Atk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
@@ -71,13 +72,15 @@ var Urgency = {
CRITICAL: 3
};
var FocusGrabber = class FocusGrabber {
constructor(actor) {
var FocusGrabber = new Lang.Class({
Name: 'FocusGrabber',
_init(actor) {
this._actor = actor;
this._prevKeyFocusActor = null;
this._focusActorChangedId = 0;
this._focused = false;
}
},
grabFocus() {
if (this._focused)
@@ -91,7 +94,7 @@ var FocusGrabber = class FocusGrabber {
this._actor.grab_key_focus();
this._focused = true;
}
},
_focusUngrabbed() {
if (!this._focused)
@@ -104,13 +107,13 @@ var FocusGrabber = class FocusGrabber {
this._focused = false;
return true;
}
},
_focusActorChanged() {
let focusedActor = global.stage.get_key_focus();
if (!focusedActor || !this._actor.contains(focusedActor))
this._focusUngrabbed();
}
},
ungrabFocus() {
if (!this._focusUngrabbed())
@@ -125,15 +128,17 @@ var FocusGrabber = class FocusGrabber {
global.stage.set_key_focus(null);
}
}
};
});
// NotificationPolicy:
// An object that holds all bits of configurable policy related to a notification
// source, such as whether to play sound or honour the critical bit.
//
// A notification without a policy object will inherit the default one.
var NotificationPolicy = class NotificationPolicy {
constructor(params) {
var NotificationPolicy = new Lang.Class({
Name: 'NotificationPolicy',
_init(params) {
params = Params.parse(params, { enable: true,
enableSound: true,
showBanners: true,
@@ -141,76 +146,72 @@ var NotificationPolicy = class NotificationPolicy {
showInLockScreen: true,
detailsInLockScreen: false
});
Object.getOwnPropertyNames(params).forEach(key => {
let desc = Object.getOwnPropertyDescriptor(params, key);
Object.defineProperty(this, `_${key}`, desc);
});
}
Lang.copyProperties(params, this);
},
// Do nothing for the default policy. These methods are only useful for the
// GSettings policy.
store() { }
store() { },
destroy() { }
get enable() {
return this._enable;
}
get enableSound() {
return this._enableSound;
}
get showBanners() {
return this._showBanners;
}
get forceExpanded() {
return this._forceExpanded;
}
get showInLockScreen() {
return this._showInLockScreen;
}
get detailsInLockScreen() {
return this._detailsInLockScreen;
}
};
});
Signals.addSignalMethods(NotificationPolicy.prototype);
var NotificationGenericPolicy =
class NotificationGenericPolicy extends NotificationPolicy {
constructor() {
super();
var NotificationGenericPolicy = new Lang.Class({
Name: 'NotificationGenericPolicy',
Extends: NotificationPolicy,
_init() {
// Don't chain to parent, it would try setting
// our properties to the defaults
this.id = 'generic';
this._masterSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.notifications' });
this._masterSettings.connect('changed', this._changed.bind(this));
}
},
store() { }
store() { },
destroy() {
this._masterSettings.run_dispose();
}
},
_changed(settings, key) {
this.emit('policy-changed', key);
}
},
get enable() {
return true;
},
get enableSound() {
return true;
},
get showBanners() {
return this._masterSettings.get_boolean('show-banners');
}
},
get forceExpanded() {
return false;
},
get showInLockScreen() {
return this._masterSettings.get_boolean('show-in-lock-screen');
}
};
},
var NotificationApplicationPolicy =
class NotificationApplicationPolicy extends NotificationPolicy {
constructor(id) {
super();
get detailsInLockScreen() {
return false;
}
});
var NotificationApplicationPolicy = new Lang.Class({
Name: 'NotificationApplicationPolicy',
Extends: NotificationPolicy,
_init(id) {
// Don't chain to parent, it would try setting
// our properties to the defaults
this.id = id;
this._canonicalId = this._canonicalizeId(id);
@@ -221,7 +222,7 @@ class NotificationApplicationPolicy extends NotificationPolicy {
this._masterSettings.connect('changed', this._changed.bind(this));
this._settings.connect('changed', this._changed.bind(this));
}
},
store() {
this._settings.set_string('application-id', this.id + '.desktop');
@@ -231,51 +232,51 @@ class NotificationApplicationPolicy extends NotificationPolicy {
apps.push(this._canonicalId);
this._masterSettings.set_strv('application-children', apps);
}
}
},
destroy() {
this._masterSettings.run_dispose();
this._settings.run_dispose();
}
},
_changed(settings, key) {
this.emit('policy-changed', key);
if (key == 'enable')
this.emit('enable-changed');
}
},
_canonicalizeId(id) {
// Keys are restricted to lowercase alphanumeric characters and dash,
// and two dashes cannot be in succession
return id.toLowerCase().replace(/[^a-z0-9\-]/g, '-').replace(/--+/g, '-');
}
},
get enable() {
return this._settings.get_boolean('enable');
}
},
get enableSound() {
return this._settings.get_boolean('enable-sound-alerts');
}
},
get showBanners() {
return this._masterSettings.get_boolean('show-banners') &&
this._settings.get_boolean('show-banners');
}
},
get forceExpanded() {
return this._settings.get_boolean('force-expanded');
}
},
get showInLockScreen() {
return this._masterSettings.get_boolean('show-in-lock-screen') &&
this._settings.get_boolean('show-in-lock-screen');
}
},
get detailsInLockScreen() {
return this._settings.get_boolean('details-in-lock-screen');
}
};
});
// Notification:
// @source: the notification's Source
@@ -332,8 +333,10 @@ class NotificationApplicationPolicy extends NotificationPolicy {
// @source allows playing sounds).
//
// [1] https://developer.gnome.org/notification-spec/#markup
var Notification = class Notification {
constructor(source, title, banner, params) {
var Notification = new Lang.Class({
Name: 'Notification',
_init(source, title, banner, params) {
this.source = source;
this.title = title;
this.urgency = Urgency.NORMAL;
@@ -355,7 +358,7 @@ var Notification = class Notification {
// for new and updated notifications
if (arguments.length != 1)
this.update(title, banner, params);
}
},
// update:
// @title: the new title
@@ -400,41 +403,41 @@ var Notification = class Notification {
}
this.emit('updated', params.clear);
}
},
// addAction:
// @label: the label for the action's button
// @callback: the callback for the action
addAction(label, callback) {
this.actions.push({ label: label, callback: callback });
}
},
get acknowledged() {
return this._acknowledged;
}
},
set acknowledged(v) {
if (this._acknowledged == v)
return;
this._acknowledged = v;
this.emit('acknowledged-changed');
}
},
setUrgency(urgency) {
this.urgency = urgency;
}
},
setResident(resident) {
this.resident = resident;
}
},
setTransient(isTransient) {
this.isTransient = isTransient;
}
},
setForFeedback(forFeedback) {
this.forFeedback = forFeedback;
}
},
playSound() {
if (this._soundPlayed)
@@ -445,12 +448,28 @@ var Notification = class Notification {
return;
}
let player = global.display.get_sound_player();
if (this._soundName)
player.play_from_theme(this._soundName, this.title, null);
else if (this._soundFile)
player.play_from_file(this._soundFile, this.title, null);
}
if (this._soundName) {
if (this.source.app) {
let app = this.source.app;
global.play_theme_sound_full(0, this._soundName,
this.title, null,
app.get_id(), app.get_name());
} else {
global.play_theme_sound(0, this._soundName, this.title, null);
}
} else if (this._soundFile) {
if (this.source.app) {
let app = this.source.app;
global.play_sound_file_full(0, this._soundFile,
this.title, null,
app.get_id(), app.get_name());
} else {
global.play_sound_file(0, this._soundFile, this.title, null);
}
}
},
// Allow customizing the banner UI:
// the default implementation defers the creation to
@@ -459,26 +478,28 @@ var Notification = class Notification {
// Notification or Source
createBanner() {
return this.source.createBanner(this);
}
},
activate() {
this.emit('activated');
if (!this.resident)
this.destroy();
}
},
destroy(reason) {
if (!reason)
reason = NotificationDestroyedReason.DISMISSED;
this.emit('destroy', reason);
}
};
});
Signals.addSignalMethods(Notification.prototype);
var NotificationBanner =
class NotificationBanner extends Calendar.NotificationMessage {
constructor(notification) {
super(notification);
var NotificationBanner = new Lang.Class({
Name: 'NotificationBanner',
Extends: Calendar.NotificationMessage,
_init(notification) {
this.parent(notification);
this.actor.can_focus = false;
this.actor.add_style_class_name('notification-banner');
@@ -495,15 +516,15 @@ class NotificationBanner extends Calendar.NotificationMessage {
// attention switching to the window.
this.emit('done-displaying');
});
}
},
_onDestroy() {
super._onDestroy();
this.parent();
this.notification.disconnect(this._activatedId);
}
},
_onUpdated(n, clear) {
super._onUpdated(n, clear);
this.parent(n, clear);
if (clear) {
this.setSecondaryActor(null);
@@ -513,13 +534,13 @@ class NotificationBanner extends Calendar.NotificationMessage {
this._addActions();
this._addSecondaryIcon();
}
},
_addActions() {
this.notification.actions.forEach(action => {
this.addAction(action.label, action.callback);
});
}
},
_addSecondaryIcon() {
if (this.notification.secondaryGIcon) {
@@ -527,7 +548,7 @@ class NotificationBanner extends Calendar.NotificationMessage {
x_align: Clutter.ActorAlign.END });
this.setSecondaryActor(icon);
}
}
},
addButton(button, callback) {
if (!this._buttonBox) {
@@ -555,7 +576,7 @@ class NotificationBanner extends Calendar.NotificationMessage {
});
return button;
}
},
addAction(label, callback) {
let button = new St.Button({ style_class: 'notification-button',
@@ -565,12 +586,14 @@ class NotificationBanner extends Calendar.NotificationMessage {
return this.addButton(button, callback);
}
};
});
var SourceActor = new Lang.Class({
Name: 'SourceActor',
Extends: St.Widget,
var SourceActor = GObject.registerClass(
class SourceActor extends St.Widget {
_init(source, size) {
super._init();
this.parent();
this._source = source;
this._size = size;
@@ -592,12 +615,12 @@ class SourceActor extends St.Widget {
this._iconUpdatedId = this._source.connect('icon-updated', this._updateIcon.bind(this));
this._updateIcon();
}
},
setIcon(icon) {
this._iconBin.child = icon;
this._iconSet = true;
}
},
_updateIcon() {
if (this._actorDestroyed)
@@ -608,10 +631,12 @@ class SourceActor extends St.Widget {
}
});
var SourceActorWithLabel = GObject.registerClass(
class SourceActorWithLabel extends SourceActor {
var SourceActorWithLabel = new Lang.Class({
Name: 'SourceActorWithLabel',
Extends: SourceActor,
_init(source, size) {
super._init(source, size);
this.parent(source, size);
this._counterLabel = new St.Label({ x_align: Clutter.ActorAlign.CENTER,
x_expand: true,
@@ -637,10 +662,10 @@ class SourceActorWithLabel extends SourceActor {
this.connect('destroy', () => {
this._source.disconnect(this._countUpdatedId);
});
}
},
vfunc_allocate(box, flags) {
super.vfunc_allocate(box, flags);
this.parent(box, flags);
let childBox = new Clutter.ActorBox();
@@ -661,7 +686,7 @@ class SourceActorWithLabel extends SourceActor {
childBox.y2 = box.y2;
this._counterBin.allocate(childBox, flags);
}
},
_updateCount() {
if (this._actorDestroyed)
@@ -679,10 +704,12 @@ class SourceActorWithLabel extends SourceActor {
}
});
var Source = class Source {
constructor(title, iconName) {
this.SOURCE_ICON_SIZE = 48;
var Source = new Lang.Class({
Name: 'MessageTraySource',
SOURCE_ICON_SIZE: 48,
_init(title, iconName) {
this.title = title;
this.iconName = iconName;
@@ -690,43 +717,37 @@ var Source = class Source {
this.notifications = [];
this._policy = null;
}
get policy() {
if (!this._policy)
this._policy = this._createPolicy();
return this._policy;
}
this.policy = this._createPolicy();
},
get count() {
return this.notifications.length;
}
},
get unseenCount() {
return this.notifications.filter(n => !n.acknowledged).length;
}
},
get countVisible() {
return this.count > 1;
}
},
countUpdated() {
this.emit('count-updated');
}
},
_createPolicy() {
return new NotificationPolicy();
}
},
setTitle(newTitle) {
this.title = newTitle;
this.emit('title-changed');
}
},
createBanner(notification) {
return new NotificationBanner(notification);
}
},
// Called to create a new icon actor.
// Provides a sane default implementation, override if you need
@@ -734,11 +755,11 @@ var Source = class Source {
createIcon(size) {
return new St.Icon({ gicon: this.getIcon(),
icon_size: size });
}
},
getIcon() {
return new Gio.ThemedIcon({ name: this.iconName });
}
},
_onNotificationDestroy(notification) {
let index = this.notifications.indexOf(notification);
@@ -750,7 +771,7 @@ var Source = class Source {
this.destroy();
this.countUpdated();
}
},
pushNotification(notification) {
if (this.notifications.indexOf(notification) >= 0)
@@ -765,7 +786,7 @@ var Source = class Source {
this.emit('notification-added', notification);
this.countUpdated();
}
},
notify(notification) {
notification.acknowledged = false;
@@ -776,7 +797,7 @@ var Source = class Source {
} else {
notification.playSound();
}
}
},
destroy(reason) {
this.policy.destroy();
@@ -788,15 +809,15 @@ var Source = class Source {
notifications[i].destroy(reason);
this.emit('destroy', reason);
}
},
iconUpdated() {
this.emit('icon-updated');
}
},
// To be overridden by subclasses
open() {
}
},
destroyNonResidentNotifications() {
for (let i = this.notifications.length - 1; i >= 0; i--)
@@ -805,11 +826,13 @@ var Source = class Source {
this.countUpdated();
}
};
});
Signals.addSignalMethods(Source.prototype);
var MessageTray = class MessageTray {
constructor() {
var MessageTray = new Lang.Class({
Name: 'MessageTray',
_init() {
this._presence = new GnomeSession.Presence((proxy, error) => {
this._onStatusChanged(proxy.status);
});
@@ -916,27 +939,27 @@ var MessageTray = class MessageTray {
this._sources = new Map();
this._sessionUpdated();
}
},
_sessionUpdated() {
this._updateState();
}
},
_onDragBegin() {
Shell.util_set_hidden_from_pick(this.actor, true);
}
},
_onDragEnd() {
Shell.util_set_hidden_from_pick(this.actor, false);
}
},
get bannerAlignment() {
return this._bannerBin.get_x_align();
}
},
set bannerAlignment(align) {
this._bannerBin.set_x_align(align);
}
},
_onNotificationKeyRelease(actor, event) {
if (event.get_key_symbol() == Clutter.KEY_Escape && event.get_state() == 0) {
@@ -945,27 +968,27 @@ var MessageTray = class MessageTray {
}
return Clutter.EVENT_PROPAGATE;
}
},
_expireNotification() {
this._notificationExpired = true;
this._updateState();
}
},
get queueCount() {
return this._notificationQueue.length;
}
},
set bannerBlocked(v) {
if (this._bannerBlocked == v)
return;
this._bannerBlocked = v;
this._updateState();
}
},
contains(source) {
return this._sources.has(source);
}
},
add(source) {
if (this.contains(source)) {
@@ -981,7 +1004,7 @@ var MessageTray = class MessageTray {
});
source.policy.connect('policy-changed', this._updateState.bind(this));
this._onSourceEnableChanged(source.policy, source);
}
},
_addSource(source) {
let obj = {
@@ -996,7 +1019,7 @@ var MessageTray = class MessageTray {
obj.destroyId = source.connect('destroy', this._onSourceDestroy.bind(this));
this.emit('source-added', source);
}
},
_removeSource(source) {
let obj = this._sources.get(source);
@@ -1006,11 +1029,11 @@ var MessageTray = class MessageTray {
source.disconnect(obj.destroyId);
this.emit('source-removed', source);
}
},
getSources() {
return [...this._sources.keys()];
}
},
_onSourceEnableChanged(policy, source) {
let wasEnabled = this.contains(source);
@@ -1022,11 +1045,11 @@ var MessageTray = class MessageTray {
else
this._removeSource(source);
}
}
},
_onSourceDestroy(source) {
this._removeSource(source);
}
},
_onNotificationDestroy(notification) {
if (this._notification == notification && (this._notificationState == State.SHOWN || this._notificationState == State.SHOWING)) {
@@ -1041,7 +1064,7 @@ var MessageTray = class MessageTray {
this._notificationQueue.splice(index, 1);
this.emit('queue-changed');
}
}
},
_onNotify(source, notification) {
if (this._notification == notification) {
@@ -1067,7 +1090,7 @@ var MessageTray = class MessageTray {
}
}
this._updateState();
}
},
_resetNotificationLeftTimeout() {
this._useLongerNotificationLeftTimeout = false;
@@ -1077,7 +1100,7 @@ var MessageTray = class MessageTray {
this._notificationLeftMouseX = -1;
this._notificationLeftMouseY = -1;
}
}
},
_onNotificationHoverChanged() {
if (this._bannerBin.hover == this._notificationHovered)
@@ -1121,7 +1144,7 @@ var MessageTray = class MessageTray {
this._notificationLeftTimeoutId = Mainloop.timeout_add(timeout, this._onNotificationLeftTimeout.bind(this));
GLib.Source.set_name_by_id(this._notificationLeftTimeoutId, '[gnome-shell] this._onNotificationLeftTimeout');
}
}
},
_onStatusChanged(status) {
if (status == GnomeSession.PresenceStatus.BUSY) {
@@ -1136,7 +1159,7 @@ var MessageTray = class MessageTray {
}
this._updateState();
}
},
_onNotificationLeftTimeout() {
let [x, y, mods] = global.get_pointer();
@@ -1158,13 +1181,13 @@ var MessageTray = class MessageTray {
this._updateState();
}
return GLib.SOURCE_REMOVE;
}
},
_escapeTray() {
this._pointerInNotification = false;
this._updateNotificationTimeout(0);
this._updateState();
}
},
// All of the logic for what happens when occurs here; the various
// event handlers merely update variables such as
@@ -1227,7 +1250,7 @@ var MessageTray = class MessageTray {
// Clean transient variables that are used to communicate actions
// to updateState()
this._notificationExpired = false;
}
},
_tween(actor, statevar, value, params) {
let onComplete = params.onComplete;
@@ -1244,24 +1267,24 @@ var MessageTray = class MessageTray {
let valuing = (value == State.SHOWN) ? State.SHOWING : State.HIDING;
this[statevar] = valuing;
}
},
_tweenComplete(statevar, value, onComplete, onCompleteScope, onCompleteParams) {
this[statevar] = value;
if (onComplete)
onComplete.apply(onCompleteScope, onCompleteParams);
this._updateState();
}
},
_clampOpacity() {
this._bannerBin.opacity = Math.max(0, Math.min(this._bannerBin._opacity, 255));
}
},
_onIdleMonitorBecameActive() {
this._userActiveWhileNotificationShown = true;
this._updateNotificationTimeout(2000);
this._updateState();
}
},
_showNotification() {
this._notification = this._notificationQueue.shift();
@@ -1306,7 +1329,7 @@ var MessageTray = class MessageTray {
this._lastSeenMouseY = y;
this._resetNotificationLeftTimeout();
}
},
_updateShowingNotification() {
this._notification.acknowledged = true;
@@ -1340,12 +1363,12 @@ var MessageTray = class MessageTray {
};
this._tween(this._bannerBin, '_notificationState', State.SHOWN, tweenParams);
}
},
_showNotificationCompleted() {
if (this._notification.urgency != Urgency.CRITICAL)
this._updateNotificationTimeout(NOTIFICATION_TIMEOUT * 1000);
}
},
_updateNotificationTimeout(timeout) {
if (this._notificationTimeoutId) {
@@ -1358,7 +1381,7 @@ var MessageTray = class MessageTray {
this._notificationTimeout.bind(this));
GLib.Source.set_name_by_id(this._notificationTimeoutId, '[gnome-shell] this._notificationTimeout');
}
}
},
_notificationTimeout() {
let [x, y, mods] = global.get_pointer();
@@ -1382,7 +1405,7 @@ var MessageTray = class MessageTray {
this._lastSeenMouseX = x;
this._lastSeenMouseY = y;
return GLib.SOURCE_REMOVE;
}
},
_hideNotification(animate) {
this._notificationFocusGrabber.ungrabFocus();
@@ -1416,7 +1439,7 @@ var MessageTray = class MessageTray {
this._notificationState = State.HIDDEN;
this._hideNotificationCompleted();
}
}
},
_hideNotificationCompleted() {
let notification = this._notification;
@@ -1431,14 +1454,14 @@ var MessageTray = class MessageTray {
this._banner.actor.destroy();
this._banner = null;
this.actor.hide();
}
},
_expandActiveNotification() {
if (!this._banner)
return;
this._expandBanner(false);
}
},
_expandBanner(autoExpanding) {
// Don't animate changes in notifications that are auto-expanding.
@@ -1447,20 +1470,23 @@ var MessageTray = class MessageTray {
// Don't focus notifications that are auto-expanding.
if (!autoExpanding)
this._ensureBannerFocused();
}
},
_ensureBannerFocused() {
this._notificationFocusGrabber.grabFocus();
}
};
});
Signals.addSignalMethods(MessageTray.prototype);
var SystemNotificationSource = class SystemNotificationSource extends Source {
constructor() {
super(_("System Information"), 'dialog-information-symbolic');
}
var SystemNotificationSource = new Lang.Class({
Name: 'SystemNotificationSource',
Extends: Source,
_init() {
this.parent(_("System Information"), 'dialog-information-symbolic');
},
open() {
this.destroy();
}
};
});

View File

@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
const St = imports.gi.St;
@@ -30,8 +31,10 @@ var State = {
FADED_OUT: 4
};
var ModalDialog = class {
constructor(params) {
var ModalDialog = new Lang.Class({
Name: 'ModalDialog',
_init(params) {
params = Params.parse(params, { shellReactive: false,
styleClass: null,
actionMode: Shell.ActionMode.SYSTEM_MODAL,
@@ -84,30 +87,30 @@ var ModalDialog = class {
this._initialKeyFocus = null;
this._initialKeyFocusDestroyId = 0;
this._savedKeyFocus = null;
}
},
destroy() {
this._group.destroy();
}
},
clearButtons() {
this.dialogLayout.clearButtons();
}
},
setButtons(buttons) {
this.clearButtons();
for (let buttonInfo of buttons)
this.addButton(buttonInfo);
}
},
addButton(buttonInfo) {
return this.dialogLayout.addButton(buttonInfo);
}
},
_onGroupDestroy() {
this.emit('destroy');
}
},
_fadeOpen(onPrimary) {
if (onPrimary)
@@ -131,7 +134,7 @@ var ModalDialog = class {
this.emit('opened');
}
});
}
},
setInitialKeyFocus(actor) {
if (this._initialKeyFocusDestroyId)
@@ -143,7 +146,7 @@ var ModalDialog = class {
this._initialKeyFocus = null;
this._initialKeyFocusDestroyId = 0;
});
}
},
open(timestamp, onPrimary) {
if (this.state == State.OPENED || this.state == State.OPENING)
@@ -154,7 +157,7 @@ var ModalDialog = class {
this._fadeOpen(onPrimary);
return true;
}
},
_closeComplete() {
this.state = State.CLOSED;
@@ -163,7 +166,7 @@ var ModalDialog = class {
if (this._destroyOnClose)
this.destroy();
}
},
close(timestamp) {
if (this.state == State.CLOSED || this.state == State.CLOSING)
@@ -182,7 +185,7 @@ var ModalDialog = class {
})
else
this._closeComplete();
}
},
// Drop modal status without closing the dialog; this makes the
// dialog insensitive as well, so it needs to be followed shortly
@@ -202,7 +205,7 @@ var ModalDialog = class {
if (!this._shellReactive)
this._eventBlocker.raise_top();
}
},
pushModal(timestamp) {
if (this._hasModal)
@@ -226,7 +229,7 @@ var ModalDialog = class {
if (!this._shellReactive)
this._eventBlocker.lower_bottom();
return true;
}
},
// This method is like close, but fades the dialog out much slower,
// and leaves the lightbox in place. Once in the faded out state,
@@ -256,5 +259,5 @@ var ModalDialog = class {
}
});
}
};
});
Signals.addSignalMethods(ModalDialog.prototype);

View File

@@ -1,4 +1,5 @@
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Signals = imports.signals;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
@@ -20,12 +21,15 @@ const MprisPlayerProxy = Gio.DBusProxy.makeProxyWrapper(MprisPlayerIface);
const MPRIS_PLAYER_PREFIX = 'org.mpris.MediaPlayer2.';
var MediaMessage = class MediaMessage extends MessageList.Message {
constructor(player) {
super('', '');
var MediaMessage = new Lang.Class({
Name: 'MediaMessage',
Extends: MessageList.Message,
_init(player) {
this._player = player;
this.parent('', '');
this._icon = new St.Icon({ style_class: 'media-message-cover-icon' });
this.setIcon(this._icon);
@@ -47,16 +51,16 @@ var MediaMessage = class MediaMessage extends MessageList.Message {
this._player.connect('changed', this._update.bind(this));
this._player.connect('closed', this.close.bind(this));
this._update();
}
},
_onClicked() {
this._player.raise();
Main.panel.closeCalendar();
}
},
_updateNavButton(button, sensitive) {
button.reactive = sensitive;
}
},
_update() {
this.setTitle(this._player.trackArtists.join(', '));
@@ -79,10 +83,12 @@ var MediaMessage = class MediaMessage extends MessageList.Message {
this._updateNavButton(this._prevButton, this._player.canGoPrevious);
this._updateNavButton(this._nextButton, this._player.canGoNext);
}
};
});
var MprisPlayer = class MprisPlayer {
constructor(busName) {
var MprisPlayer = new Lang.Class({
Name: 'MprisPlayer',
_init(busName) {
this._mprisProxy = new MprisProxy(Gio.DBus.session, busName,
'/org/mpris/MediaPlayer2',
this._onMprisProxyReady.bind(this));
@@ -94,43 +100,43 @@ var MprisPlayer = class MprisPlayer {
this._trackArtists = [];
this._trackTitle = '';
this._trackCoverUrl = '';
}
},
get status() {
return this._playerProxy.PlaybackStatus;
}
},
get trackArtists() {
return this._trackArtists;
}
},
get trackTitle() {
return this._trackTitle;
}
},
get trackCoverUrl() {
return this._trackCoverUrl;
}
},
playPause() {
this._playerProxy.PlayPauseRemote();
}
},
get canGoNext() {
return this._playerProxy.CanGoNext;
}
},
next() {
this._playerProxy.NextRemote();
}
},
get canGoPrevious() {
return this._playerProxy.CanGoPrevious;
}
},
previous() {
this._playerProxy.PreviousRemote();
}
},
raise() {
// The remote Raise() method may run into focus stealing prevention,
@@ -145,7 +151,7 @@ var MprisPlayer = class MprisPlayer {
app.activate();
else if (this._mprisProxy.CanRaise)
this._mprisProxy.RaiseRemote();
}
},
_close() {
this._mprisProxy.disconnect(this._ownerNotifyId);
@@ -155,7 +161,7 @@ var MprisPlayer = class MprisPlayer {
this._playerProxy = null;
this.emit('closed');
}
},
_onMprisProxyReady() {
this._ownerNotifyId = this._mprisProxy.connect('notify::g-name-owner',
@@ -163,13 +169,13 @@ var MprisPlayer = class MprisPlayer {
if (!this._mprisProxy.g_name_owner)
this._close();
});
}
},
_onPlayerProxyReady() {
this._propsChangedId = this._playerProxy.connect('g-properties-changed',
this._updateState.bind(this));
this._updateState();
}
},
_updateState() {
let metadata = {};
@@ -191,12 +197,15 @@ var MprisPlayer = class MprisPlayer {
this._close();
}
}
};
});
Signals.addSignalMethods(MprisPlayer.prototype);
var MediaSection = class MediaSection extends MessageList.MessageListSection {
constructor() {
super();
var MediaSection = new Lang.Class({
Name: 'MediaSection',
Extends: MessageList.MessageListSection,
_init() {
this.parent();
this._players = new Map();
@@ -204,11 +213,11 @@ var MediaSection = class MediaSection extends MessageList.MessageListSection {
'org.freedesktop.DBus',
'/org/freedesktop/DBus',
this._onProxyReady.bind(this));
}
},
_shouldShow() {
return !this.empty && Calendar.isToday(this._date);
}
},
_addPlayer(busName) {
if (this._players.get(busName))
@@ -225,7 +234,7 @@ var MediaSection = class MediaSection extends MessageList.MessageListSection {
this.addMessage(message, true);
});
this._players.set(busName, player);
}
},
_onProxyReady() {
this._proxy.ListNamesRemote(([names]) => {
@@ -238,7 +247,7 @@ var MediaSection = class MediaSection extends MessageList.MessageListSection {
});
this._proxy.connectSignal('NameOwnerChanged',
this._onNameOwnerChanged.bind(this));
}
},
_onNameOwnerChanged(proxy, sender, [name, oldOwner, newOwner]) {
if (!name.startsWith(MPRIS_PLAYER_PREFIX))
@@ -247,4 +256,4 @@ var MediaSection = class MediaSection extends MessageList.MessageListSection {
if (newOwner && !oldOwner)
this._addPlayer(name);
}
};
});

View File

@@ -5,6 +5,7 @@ const GdkPixbuf = imports.gi.GdkPixbuf;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Mainloop = imports.mainloop;
const St = imports.gi.St;
@@ -50,8 +51,10 @@ const rewriteRules = {
]
};
var FdoNotificationDaemon = class FdoNotificationDaemon {
constructor() {
var FdoNotificationDaemon = new Lang.Class({
Name: 'FdoNotificationDaemon',
_init() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(FdoNotificationsIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/Notifications');
@@ -66,7 +69,7 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
this._onFocusAppChanged.bind(this));
Main.overview.connect('hidden',
this._onFocusAppChanged.bind(this));
}
},
_imageForNotificationData(hints) {
if (hints['image-data']) {
@@ -74,11 +77,9 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
bitsPerSample, nChannels, data] = hints['image-data'];
return Shell.util_create_pixbuf_from_data(data, GdkPixbuf.Colorspace.RGB, hasAlpha,
bitsPerSample, width, height, rowStride);
} else if (hints['image-path']) {
return this._iconForNotificationData(hints['image-path']);
}
return null;
}
return this._iconForNotificationData(hints['image-path']);
},
_fallbackIconForNotificationData(hints) {
let stockIcon;
@@ -92,7 +93,7 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
break;
}
return new Gio.ThemedIcon({ name: stockIcon });
}
},
_iconForNotificationData(icon) {
if (icon) {
@@ -104,7 +105,7 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
return new Gio.ThemedIcon({ name: icon });
}
return null;
}
},
_lookupSource(title, pid) {
for (let i = 0; i < this._sources.length; i++) {
@@ -113,7 +114,7 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
return source;
}
return null;
}
},
// Returns the source associated with ndata.notification if it is set.
// If the existing or requested source is associated with a tray icon
@@ -155,7 +156,7 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
Main.messageTray.add(source);
return source;
}
},
NotifyAsync(params, invocation) {
let [appName, replacesId, icon, summary, body, actions, hints, timeout] = params;
@@ -263,7 +264,7 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
});
return invocation.return_value(GLib.Variant.new('(u)', [id]));
}
},
_notifyForSource(source, ndata) {
let [id, icon, summary, body, actions, hints, notification] =
@@ -354,7 +355,7 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
let sourceGIcon = source.useNotificationIcon ? gicon : null;
source.processNotification(notification, sourceGIcon);
}
},
CloseNotification(id) {
let ndata = this._notifications[id];
@@ -363,7 +364,7 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
ndata.notification.destroy(MessageTray.NotificationDestroyedReason.SOURCE_CLOSED);
delete this._notifications[id];
}
}
},
GetCapabilities() {
return [
@@ -378,7 +379,7 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
'persistence',
'sound',
];
}
},
GetServerInformation() {
return [
@@ -387,7 +388,7 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
Config.PACKAGE_VERSION,
'1.2'
];
}
},
_onFocusAppChanged() {
let tracker = Shell.WindowTracker.get_default();
@@ -401,27 +402,31 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
return;
}
}
}
},
_emitNotificationClosed(id, reason) {
this._dbusImpl.emit_signal('NotificationClosed',
GLib.Variant.new('(uu)', [id, reason]));
}
},
_emitActionInvoked(id, action) {
this._dbusImpl.emit_signal('ActionInvoked',
GLib.Variant.new('(us)', [id, action]));
}
};
});
var FdoNotificationDaemonSource =
class FdoNotificationDaemonSource extends MessageTray.Source {
constructor(title, pid, sender, appId) {
super(title);
var FdoNotificationDaemonSource = new Lang.Class({
Name: 'FdoNotificationDaemonSource',
Extends: MessageTray.Source,
_init(title, pid, sender, appId) {
// Need to set the app before chaining up, so
// methods called from the parent constructor can find it
this.pid = pid;
this.app = this._getApp(appId);
this.parent(title);
this.initialTitle = title;
if (this.app)
@@ -436,7 +441,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
this._onNameVanished.bind(this));
else
this._nameWatcherId = 0;
}
},
_createPolicy() {
if (this.app && this.app.get_app_info()) {
@@ -445,7 +450,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
} else {
return new MessageTray.NotificationGenericPolicy();
}
}
},
_onNameVanished() {
// Destroy the notification source when its sender is removed from DBus.
@@ -455,7 +460,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
// so allow the code path that handles the tray icon being removed to handle that case.
if (this.app)
this.destroy();
}
},
processNotification(notification, gicon) {
if (gicon)
@@ -467,7 +472,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
this.pushNotification(notification);
else
this.notify(notification);
}
},
_getApp(appId) {
let app;
@@ -483,7 +488,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
}
return null;
}
},
setTitle(title) {
// Do nothing if .app is set, we don't want to override the
@@ -492,13 +497,13 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
if (this.app)
return;
super.setTitle(title);
}
this.parent(title);
},
open() {
this.openApp();
this.destroyNonResidentNotifications();
}
},
openApp() {
if (this.app == null)
@@ -507,7 +512,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
this.app.activate();
Main.overview.hide();
Main.panel.closeCalendar();
}
},
destroy() {
if (this._nameWatcherId) {
@@ -515,8 +520,8 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
this._nameWatcherId = 0;
}
super.destroy();
}
this.parent();
},
createIcon(size) {
if (this.app) {
@@ -528,7 +533,7 @@ class FdoNotificationDaemonSource extends MessageTray.Source {
return null;
}
}
};
});
const PRIORITY_URGENCY_MAP = {
low: MessageTray.Urgency.LOW,
@@ -537,10 +542,12 @@ const PRIORITY_URGENCY_MAP = {
urgent: MessageTray.Urgency.CRITICAL
};
var GtkNotificationDaemonNotification =
class GtkNotificationDaemonNotification extends MessageTray.Notification {
constructor(source, notification) {
super(source);
var GtkNotificationDaemonNotification = new Lang.Class({
Name: 'GtkNotificationDaemonNotification',
Extends: MessageTray.Notification,
_init(source, notification) {
this.parent(source);
this._serialized = GLib.Variant.new('a{sv}', notification);
let { "title": title,
@@ -577,7 +584,7 @@ class GtkNotificationDaemonNotification extends MessageTray.Notification {
this.update(title.unpack(), body ? body.unpack() : null,
{ gicon: gicon ? Gio.icon_deserialize(gicon) : null,
datetime : time ? GLib.DateTime.new_from_unix_local(time.unpack()) : null });
}
},
_activateAction(namespacedActionId, target) {
if (namespacedActionId) {
@@ -588,22 +595,22 @@ class GtkNotificationDaemonNotification extends MessageTray.Notification {
} else {
this.source.open();
}
}
},
_onButtonClicked(button) {
let { 'action': action, 'target': actionTarget } = button;
this._activateAction(action.unpack(), actionTarget);
}
},
activate() {
this._activateAction(this._defaultAction, this._defaultActionTarget);
super.activate();
}
this.parent();
},
serialize() {
return this._serialized;
}
};
},
});
const FdoApplicationIface = loadInterfaceXML('org.freedesktop.Application');
const FdoApplicationProxy = Gio.DBusProxy.makeProxyWrapper(FdoApplicationIface);
@@ -619,42 +626,41 @@ function getPlatformData() {
function InvalidAppError() {}
var GtkNotificationDaemonAppSource =
class GtkNotificationDaemonAppSource extends MessageTray.Source {
constructor(appId) {
let objectPath = objectPathFromAppId(appId);
if (!GLib.Variant.is_object_path(objectPath))
throw new InvalidAppError();
let app = Shell.AppSystem.get_default().lookup_app(appId + '.desktop');
if (!app)
throw new InvalidAppError();
super(app.get_name());
var GtkNotificationDaemonAppSource = new Lang.Class({
Name: 'GtkNotificationDaemonAppSource',
Extends: MessageTray.Source,
_init(appId) {
this._appId = appId;
this._app = app;
this._objectPath = objectPath;
this._objectPath = objectPathFromAppId(appId);
if (!GLib.Variant.is_object_path(this._objectPath))
throw new InvalidAppError();
this._app = Shell.AppSystem.get_default().lookup_app(appId + '.desktop');
if (!this._app)
throw new InvalidAppError();
this._notifications = {};
this._notificationPending = false;
}
this.parent(this._app.get_name());
},
createIcon(size) {
return this._app.create_icon_texture(size);
}
},
_createPolicy() {
return new MessageTray.NotificationApplicationPolicy(this._appId);
}
},
_createApp(callback) {
return new FdoApplicationProxy(Gio.DBus.session, this._appId, this._objectPath, callback);
}
},
_createNotification(params) {
return new GtkNotificationDaemonNotification(this, params);
}
},
activateAction(actionId, target) {
this._createApp((app, error) => {
@@ -665,7 +671,7 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
});
Main.overview.hide();
Main.panel.closeCalendar();
}
},
open() {
this._createApp((app, error) => {
@@ -676,7 +682,7 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
});
Main.overview.hide();
Main.panel.closeCalendar();
}
},
addNotification(notificationId, notificationParams, showBanner) {
this._notificationPending = true;
@@ -696,18 +702,18 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
this.pushNotification(notification);
this._notificationPending = false;
}
},
destroy(reason) {
if (this._notificationPending)
return;
super.destroy(reason);
}
this.parent(reason);
},
removeNotification(notificationId) {
if (this._notifications[notificationId])
this._notifications[notificationId].destroy(MessageTray.NotificationDestroyedReason.SOURCE_CLOSED);
}
},
serialize() {
let notifications = [];
@@ -716,13 +722,15 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
notifications.push([notificationId, notification.serialize()]);
}
return [this._appId, notifications];
}
};
},
});
const GtkNotificationsIface = loadInterfaceXML('org.gtk.Notifications');
var GtkNotificationDaemon = class GtkNotificationDaemon {
constructor() {
var GtkNotificationDaemon = new Lang.Class({
Name: 'GtkNotificationDaemon',
_init() {
this._sources = {};
this._loadNotifications();
@@ -731,7 +739,7 @@ var GtkNotificationDaemon = class GtkNotificationDaemon {
this._dbusImpl.export(Gio.DBus.session, '/org/gtk/Notifications');
Gio.DBus.session.own_name('org.gtk.Notifications', Gio.BusNameOwnerFlags.REPLACE, null, null);
}
},
_ensureAppSource(appId) {
if (this._sources[appId])
@@ -747,7 +755,7 @@ var GtkNotificationDaemon = class GtkNotificationDaemon {
Main.messageTray.add(source);
this._sources[appId] = source;
return source;
}
},
_loadNotifications() {
this._isLoading = true;
@@ -775,7 +783,7 @@ var GtkNotificationDaemon = class GtkNotificationDaemon {
}
this._isLoading = false;
}
},
_saveNotifications() {
if (this._isLoading)
@@ -788,7 +796,7 @@ var GtkNotificationDaemon = class GtkNotificationDaemon {
}
global.set_persistent_state('notifications', new GLib.Variant('a(sa(sv))', sources));
}
},
AddNotificationAsync(params, invocation) {
let [appId, notificationId, notification] = params;
@@ -810,7 +818,7 @@ var GtkNotificationDaemon = class GtkNotificationDaemon {
source.addNotification(notificationId, notification, true);
invocation.return_value(null);
}
},
RemoveNotificationAsync(params, invocation) {
let [appId, notificationId] = params;
@@ -819,12 +827,14 @@ var GtkNotificationDaemon = class GtkNotificationDaemon {
source.removeNotification(notificationId);
invocation.return_value(null);
}
};
},
});
var NotificationDaemon = class NotificationDaemon {
constructor() {
var NotificationDaemon = new Lang.Class({
Name: 'NotificationDaemon',
_init() {
this._fdoNotificationDaemon = new FdoNotificationDaemon();
this._gtkNotificationDaemon = new GtkNotificationDaemon();
}
};
},
});

View File

@@ -4,14 +4,17 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const St = imports.gi.St;
const Lang = imports.lang;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
const Meta = imports.gi.Meta;
var FADE_TIME = 0.1;
var OsdMonitorLabel = class {
constructor(monitor, label) {
var OsdMonitorLabel = new Lang.Class({
Name: 'OsdMonitorLabel',
_init(monitor, label) {
this._actor = new St.Widget({ x_expand: true,
y_expand: true });
@@ -30,7 +33,7 @@ var OsdMonitorLabel = class {
this._position();
Meta.disable_unredirect_for_display(global.display);
}
},
_position() {
let workArea = Main.layoutManager.getWorkAreaForMonitor(this._monitor);
@@ -41,16 +44,18 @@ var OsdMonitorLabel = class {
this._box.x = workArea.x;
this._box.y = workArea.y;
}
},
destroy() {
this._actor.destroy();
Meta.enable_unredirect_for_display(global.display);
}
};
});
var OsdMonitorLabeler = class {
constructor() {
var OsdMonitorLabeler = new Lang.Class({
Name: 'OsdMonitorLabeler',
_init() {
this._monitorManager = Meta.MonitorManager.get();
this._client = null;
this._clientWatchId = 0;
@@ -59,7 +64,7 @@ var OsdMonitorLabeler = class {
Main.layoutManager.connect('monitors-changed',
this._reset.bind(this));
this._reset();
}
},
_reset() {
for (let i in this._osdLabels)
@@ -69,7 +74,7 @@ var OsdMonitorLabeler = class {
let monitors = Main.layoutManager.monitors;
for (let i in monitors)
this._monitorLabels.set(monitors[i].index, []);
}
},
_trackClient(client) {
if (this._client)
@@ -81,7 +86,7 @@ var OsdMonitorLabeler = class {
this.hide(name);
});
return true;
}
},
_untrackClient(client) {
if (!this._client || this._client != client)
@@ -91,7 +96,7 @@ var OsdMonitorLabeler = class {
this._clientWatchId = 0;
this._client = null;
return true;
}
},
show(client, params) {
if (!this._trackClient(client))
@@ -113,7 +118,7 @@ var OsdMonitorLabeler = class {
labels.sort();
this._osdLabels.push(new OsdMonitorLabel(monitor, labels.join(' ')));
}
}
},
show2(client, params) {
if (!this._trackClient(client))
@@ -132,7 +137,7 @@ var OsdMonitorLabeler = class {
labels.sort();
this._osdLabels.push(new OsdMonitorLabel(monitor, labels.join(' ')));
}
}
},
hide(client) {
if (!this._untrackClient(client))
@@ -140,4 +145,4 @@ var OsdMonitorLabeler = class {
this._reset();
}
};
});

View File

@@ -2,10 +2,10 @@
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const St = imports.gi.St;
const BarLevel = imports.ui.barLevel;
const Lang = imports.lang;
const Layout = imports.ui.layout;
const Main = imports.ui.main;
const Mainloop = imports.mainloop;
@@ -16,51 +16,59 @@ var HIDE_TIMEOUT = 1500;
var FADE_TIME = 0.1;
var LEVEL_ANIMATION_TIME = 0.1;
var LevelBar = class extends BarLevel.BarLevel {
constructor() {
super(0, { styleClass: 'level' });
var LevelBar = new Lang.Class({
Name: 'LevelBar',
Extends: BarLevel.BarLevel,
_init() {
this._level = 0;
this._maxLevel = 100;
let params = {
styleClass: 'level',
}
this.parent(this._level, params);
this.actor.accessible_name = _("Volume");
this.actor.connect('notify::width', () => { this.level = this.level; });
}
},
get level() {
return this._level;
}
},
set level(value) {
this._level = Math.max(0, Math.min(value, this._maxLevel));
this.setValue(this._level / 100);
}
},
get maxLevel() {
return this._maxLevel;
}
},
set maxLevel(value) {
this._maxLevel = Math.max(100, value);
this.setMaximumValue(this._maxLevel / 100);
}
};
});
var OsdWindowConstraint = new Lang.Class({
Name: 'OsdWindowConstraint',
Extends: Clutter.Constraint,
var OsdWindowConstraint = GObject.registerClass(
class OsdWindowConstraint extends Clutter.Constraint {
_init(props) {
this._minSize = 0;
super._init(props);
}
this.parent(props);
},
set minSize(v) {
this._minSize = v;
if (this.actor)
this.actor.queue_relayout();
}
},
vfunc_update_allocation(actor, actorBox) {
// Clutter will adjust the allocation for margins,
@@ -79,8 +87,10 @@ class OsdWindowConstraint extends Clutter.Constraint {
}
});
var OsdWindow = class {
constructor(monitorIndex) {
var OsdWindow = new Lang.Class({
Name: 'OsdWindow',
_init(monitorIndex) {
this.actor = new St.Widget({ x_expand: true,
y_expand: true,
x_align: Clutter.ActorAlign.CENTER,
@@ -119,7 +129,7 @@ var OsdWindow = class {
this._relayout.bind(this));
this._relayout();
Main.uiGroup.add_child(this.actor);
}
},
_onDestroy() {
if (this._monitorsChangedId)
@@ -130,17 +140,17 @@ var OsdWindow = class {
if (this._scaleChangedId)
themeContext.disconnect(this._scaleChangedId);
this._scaleChangedId = 0;
}
},
setIcon(icon) {
this._icon.gicon = icon;
}
},
setLabel(label) {
this._label.visible = (label != undefined);
if (label)
this._label.text = label;
}
},
setLevel(level) {
this._level.actor.visible = (level != undefined);
@@ -153,13 +163,13 @@ var OsdWindow = class {
else
this._level.level = level;
}
}
},
setMaxLevel(maxLevel) {
if (maxLevel === undefined)
maxLevel = 100;
this._level.maxLevel = maxLevel;
}
},
show() {
if (!this._icon.gicon)
@@ -182,7 +192,7 @@ var OsdWindow = class {
this._hideTimeoutId = Mainloop.timeout_add(HIDE_TIMEOUT,
this._hide.bind(this));
GLib.Source.set_name_by_id(this._hideTimeoutId, '[gnome-shell] this._hide');
}
},
cancel() {
if (!this._hideTimeoutId)
@@ -190,7 +200,7 @@ var OsdWindow = class {
Mainloop.source_remove(this._hideTimeoutId);
this._hide();
}
},
_hide() {
this._hideTimeoutId = 0;
@@ -204,14 +214,14 @@ var OsdWindow = class {
}
});
return GLib.SOURCE_REMOVE;
}
},
_reset() {
this.actor.hide();
this.setLabel(null);
this.setMaxLevel(null);
this.setLevel(null);
}
},
_relayout() {
/* assume 110x110 on a 640x480 display and scale from there */
@@ -229,15 +239,17 @@ var OsdWindow = class {
this._box.translation_y = Math.round(monitor.height / 4);
this._boxConstraint.minSize = popupSize;
}
};
});
var OsdWindowManager = class {
constructor() {
var OsdWindowManager = new Lang.Class({
Name: 'OsdWindowManager',
_init() {
this._osdWindows = [];
Main.layoutManager.connect('monitors-changed',
this._monitorsChanged.bind(this));
this._monitorsChanged();
}
},
_monitorsChanged() {
for (let i = 0; i < Main.layoutManager.monitors.length; i++) {
@@ -251,7 +263,7 @@ var OsdWindowManager = class {
}
this._osdWindows.length = Main.layoutManager.monitors.length;
}
},
_showOsdWindow(monitorIndex, icon, label, level, maxLevel) {
this._osdWindows[monitorIndex].setIcon(icon);
@@ -259,7 +271,7 @@ var OsdWindowManager = class {
this._osdWindows[monitorIndex].setMaxLevel(maxLevel);
this._osdWindows[monitorIndex].setLevel(level);
this._osdWindows[monitorIndex].show();
}
},
show(monitorIndex, icon, label, level, maxLevel) {
if (monitorIndex != -1) {
@@ -273,10 +285,10 @@ var OsdWindowManager = class {
for (let i = 0; i < this._osdWindows.length; i++)
this._showOsdWindow(i, icon, label, level, maxLevel);
}
}
},
hideAll() {
for (let i = 0; i < this._osdWindows.length; i++)
this._osdWindows[i].cancel();
}
};
});

View File

@@ -6,6 +6,7 @@ const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
const Lang = imports.lang;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
const Gdk = imports.gi.Gdk;
@@ -34,11 +35,13 @@ var DND_WINDOW_SWITCH_TIMEOUT = 750;
var OVERVIEW_ACTIVATION_TIMEOUT = 0.5;
var ShellInfo = class {
constructor() {
var ShellInfo = new Lang.Class({
Name: 'ShellInfo',
_init() {
this._source = null;
this._undoCallback = null;
}
},
_onUndoClicked() {
if (this._undoCallback)
@@ -47,7 +50,7 @@ var ShellInfo = class {
if (this._source)
this._source.destroy();
}
},
setMessage(text, options) {
options = Params.parse(options, { undoCallback: null,
@@ -81,16 +84,18 @@ var ShellInfo = class {
this._source.notify(notification);
}
};
});
var Overview = class {
constructor() {
var Overview = new Lang.Class({
Name: 'Overview',
_init() {
this._overviewCreated = false;
this._initCalled = false;
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
this._sessionUpdated();
}
},
_createOverview() {
if (this._overviewCreated)
@@ -162,7 +167,7 @@ var Overview = class {
if (this._initCalled)
this.init();
}
},
_updateBackgrounds() {
for (let i = 0; i < this._bgManagers.length; i++)
@@ -176,7 +181,7 @@ var Overview = class {
vignette: true });
this._bgManagers.push(bgManager);
}
}
},
_unshadeBackgrounds() {
let backgrounds = this._backgroundGroup.get_children();
@@ -188,7 +193,7 @@ var Overview = class {
transition: 'easeOutQuad'
});
}
}
},
_shadeBackgrounds() {
let backgrounds = this._backgroundGroup.get_children();
@@ -200,12 +205,12 @@ var Overview = class {
transition: 'easeOutQuad'
});
}
}
},
_sessionUpdated() {
this.isDummy = !Main.sessionMode.hasOverview;
this._createOverview();
}
},
// The members we construct that are implemented in JS might
// want to access the overview as Main.overview to connect
@@ -254,15 +259,15 @@ var Overview = class {
Main.layoutManager.connect('monitors-changed', this._relayout.bind(this));
this._relayout();
}
},
addSearchProvider(provider) {
this.viewSelector.addSearchProvider(provider);
}
},
removeSearchProvider(provider) {
this.viewSelector.removeSearchProvider(provider);
}
},
//
// options:
@@ -274,7 +279,7 @@ var Overview = class {
return;
this._shellInfo.setMessage(text, options);
}
},
_onDragBegin() {
this._inXdndDrag = true;
@@ -283,7 +288,7 @@ var Overview = class {
// Remember the workspace we started from
let workspaceManager = global.workspace_manager;
this._lastActiveWorkspaceIndex = workspaceManager.get_active_workspace_index();
}
},
_onDragEnd(time) {
this._inXdndDrag = false;
@@ -300,7 +305,7 @@ var Overview = class {
this._lastHoveredWindow = null;
DND.removeDragMonitor(this._dragMonitor);
this.endItemDrag();
}
},
_resetWindowSwitchTimeout() {
if (this._windowSwitchTimeoutId != 0) {
@@ -308,7 +313,7 @@ var Overview = class {
this._windowSwitchTimeoutId = 0;
this._needsFakePointerEvent = false;
}
}
},
_fakePointerEvent() {
let display = Gdk.Display.get_default();
@@ -317,7 +322,7 @@ var Overview = class {
let [gdkScreen, pointerX, pointerY] = pointer.get_position();
pointer.warp(gdkScreen, pointerX, pointerY);
}
},
_onDragMotion(dragEvent) {
let targetIsWindow = dragEvent.targetActor &&
@@ -351,19 +356,19 @@ var Overview = class {
}
return DND.DragMotionResult.CONTINUE;
}
},
_onScrollEvent(actor, event) {
this.emit('scroll-event', event);
return Clutter.EVENT_PROPAGATE;
}
},
addAction(action) {
if (this.isDummy)
return;
this._backgroundGroup.add_action(action);
}
},
_getDesktopClone() {
let windows = global.get_window_actors().filter(
@@ -379,7 +384,7 @@ var Overview = class {
clone.destroy();
});
return clone;
}
},
_relayout() {
// To avoid updating the position and size of the workspaces
@@ -394,7 +399,7 @@ var Overview = class {
this._coverPane.set_size(global.screen_width, global.screen_height);
this._updateBackgrounds();
}
},
_onRestacked() {
let stack = global.get_window_actors();
@@ -406,44 +411,44 @@ var Overview = class {
}
this.emit('windows-restacked', stackIndices);
}
},
beginItemDrag(source) {
this.emit('item-drag-begin');
this._inItemDrag = true;
}
},
cancelledItemDrag(source) {
this.emit('item-drag-cancelled');
}
},
endItemDrag(source) {
if (!this._inItemDrag)
return;
this.emit('item-drag-end');
this._inItemDrag = false;
}
},
beginWindowDrag(window) {
this.emit('window-drag-begin', window);
this._inWindowDrag = true;
}
},
cancelledWindowDrag(window) {
this.emit('window-drag-cancelled', window);
}
},
endWindowDrag(window) {
if (!this._inWindowDrag)
return;
this.emit('window-drag-end', window);
this._inWindowDrag = false;
}
},
focusSearch() {
this.show();
this._searchEntry.grab_key_focus();
}
},
fadeInDesktop() {
this._desktopFade.opacity = 0;
@@ -452,7 +457,7 @@ var Overview = class {
{ opacity: 255,
time: ANIMATION_TIME,
transition: 'easeOutQuad' });
}
},
fadeOutDesktop() {
if (!this._desktopFade.get_n_children()) {
@@ -470,7 +475,7 @@ var Overview = class {
time: ANIMATION_TIME,
transition: 'easeOutQuad'
});
}
},
// Checks if the Activities button is currently sensitive to
// clicks. The first call to this function within the
@@ -487,7 +492,7 @@ var Overview = class {
GLib.get_monotonic_time() / GLib.USEC_PER_SEC - this._activationTime > OVERVIEW_ACTIVATION_TIMEOUT)
return true;
return false;
}
},
_syncGrab() {
// We delay grab changes during animation so that when removing the
@@ -516,7 +521,7 @@ var Overview = class {
}
}
return true;
}
},
// show:
//
@@ -533,7 +538,7 @@ var Overview = class {
Main.layoutManager.showOverview();
this._animateVisible();
}
},
_animateVisible() {
@@ -561,7 +566,7 @@ var Overview = class {
this._coverPane.raise_top();
this._coverPane.show();
this.emit('showing');
}
},
_showDone() {
this.animationInProgress = false;
@@ -575,7 +580,7 @@ var Overview = class {
this._syncGrab();
global.sync_pointer();
}
},
// hide:
//
@@ -601,7 +606,8 @@ var Overview = class {
this._animateNotVisible();
this._syncGrab();
}
},
_animateNotVisible() {
if (!this.visible || this.animationInProgress)
@@ -625,7 +631,7 @@ var Overview = class {
this._coverPane.raise_top();
this._coverPane.show();
this.emit('hiding');
}
},
_hideDone() {
// Re-enable unredirection
@@ -652,7 +658,7 @@ var Overview = class {
this._fakePointerEvent();
this._needsFakePointerEvent = false;
}
}
},
toggle() {
if (this.isDummy)
@@ -662,10 +668,10 @@ var Overview = class {
this.hide();
else
this.show();
}
},
getShowAppsButton() {
return this._dash.showAppsButton;
}
};
});
Signals.addSignalMethods(Overview.prototype);

View File

@@ -2,6 +2,7 @@
const GObject = imports.gi.GObject;
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
@@ -29,15 +30,17 @@ var SlideDirection = {
RIGHT: 1
};
var SlideLayout = GObject.registerClass(
class SlideLayout extends Clutter.FixedLayout {
var SlideLayout = new Lang.Class({
Name: 'SlideLayout',
Extends: Clutter.FixedLayout,
_init(params) {
this._slideX = 1;
this._translationX = undefined;
this._direction = SlideDirection.LEFT;
super._init(params);
}
this.parent(params);
},
vfunc_get_preferred_width(container, forHeight) {
let child = container.get_first_child();
@@ -48,7 +51,7 @@ class SlideLayout extends Clutter.FixedLayout {
natWidth *= this._slideX;
return [minWidth, natWidth];
}
},
vfunc_allocate(container, box, flags) {
let child = container.get_first_child();
@@ -71,38 +74,40 @@ class SlideLayout extends Clutter.FixedLayout {
actorBox.y2 = actorBox.y1 + availHeight;
child.allocate(actorBox, flags);
}
},
set slideX(value) {
this._slideX = value;
this.layout_changed();
}
},
get slideX() {
return this._slideX;
}
},
set slideDirection(direction) {
this._direction = direction;
this.layout_changed();
}
},
get slideDirection() {
return this._direction;
}
},
set translationX(value) {
this._translationX = value;
this.layout_changed();
}
},
get translationX() {
return this._translationX;
}
},
});
var SlidingControl = class {
constructor(params) {
var SlidingControl = new Lang.Class({
Name: 'SlidingControl',
_init(params) {
params = Params.parse(params, { slideDirection: SlideDirection.LEFT });
this._visible = true;
@@ -123,23 +128,23 @@ var SlidingControl = class {
Main.overview.connect('window-drag-begin', this._onWindowDragBegin.bind(this));
Main.overview.connect('window-drag-cancelled', this._onWindowDragEnd.bind(this));
Main.overview.connect('window-drag-end', this._onWindowDragEnd.bind(this));
}
},
_getSlide() {
throw new Error('getSlide() must be overridden');
}
},
_updateSlide() {
Tweener.addTween(this.layout, { slideX: this._getSlide(),
time: SIDE_CONTROLS_ANIMATION_TIME,
transition: 'easeOutQuad' });
}
},
getVisibleWidth() {
let child = this.actor.get_first_child();
let [, , natWidth, ] = child.get_preferred_size();
return natWidth;
}
},
_getTranslation() {
let child = this.actor.get_first_child();
@@ -150,7 +155,7 @@ var SlidingControl = class {
return - visibleWidth;
else
return visibleWidth;
}
},
_updateTranslation() {
let translationStart = 0;
@@ -171,57 +176,57 @@ var SlidingControl = class {
Tweener.addTween(this.layout, { translationX: translationEnd,
time: SIDE_CONTROLS_ANIMATION_TIME,
transition: 'easeOutQuad' });
}
},
_onOverviewHiding() {
// We need to explicitly slideOut since showing pages
// doesn't imply sliding out, instead, hiding the overview does.
this.slideOut();
}
},
_onWindowDragBegin() {
this._onDragBegin();
}
},
_onWindowDragEnd() {
this._onDragEnd();
}
},
_onDragBegin() {
this._inDrag = true;
this._updateTranslation();
this._updateSlide();
}
},
_onDragEnd() {
this._inDrag = false;
this._updateSlide();
}
},
fadeIn() {
Tweener.addTween(this.actor, { opacity: 255,
time: SIDE_CONTROLS_ANIMATION_TIME / 2,
transition: 'easeInQuad'
});
}
},
fadeHalf() {
Tweener.addTween(this.actor, { opacity: 128,
time: SIDE_CONTROLS_ANIMATION_TIME / 2,
transition: 'easeOutQuad'
});
}
},
slideIn() {
this._visible = true;
// we will update slideX and the translation from pageEmpty
}
},
slideOut() {
this._visible = false;
this._updateTranslation();
// we will update slideX from pageEmpty
}
},
pageEmpty() {
// When pageEmpty is received, there's no visible view in the
@@ -231,11 +236,14 @@ var SlidingControl = class {
this.layout.slideX = this._getSlide();
this._updateTranslation();
}
};
});
var ThumbnailsSlider = class extends SlidingControl {
constructor(thumbnailsBox) {
super({ slideDirection: SlideDirection.RIGHT });
var ThumbnailsSlider = new Lang.Class({
Name: 'ThumbnailsSlider',
Extends: SlidingControl,
_init(thumbnailsBox) {
this.parent({ slideDirection: SlideDirection.RIGHT });
this._thumbnailsBox = thumbnailsBox;
@@ -251,7 +259,7 @@ var ThumbnailsSlider = class extends SlidingControl {
this._updateSlide.bind(this));
this.actor.connect('notify::hover', this._updateSlide.bind(this));
this._thumbnailsBox.bind_property('visible', this.actor, 'visible', GObject.BindingFlags.SYNC_CREATE);
}
},
_getAlwaysZoomOut() {
// Always show the pager on hover, during a drag, or if workspaces are
@@ -279,17 +287,17 @@ var ThumbnailsSlider = class extends SlidingControl {
}
return alwaysZoomOut;
}
},
getNonExpandedWidth() {
let child = this.actor.get_first_child();
return child.get_theme_node().get_length('visible-width');
}
},
_onDragEnd() {
this.actor.sync_hover();
super._onDragEnd();
}
this.parent();
},
_getSlide() {
if (!this._visible)
@@ -304,20 +312,23 @@ var ThumbnailsSlider = class extends SlidingControl {
let expandedWidth = child.get_preferred_width(preferredHeight)[1];
return this.getNonExpandedWidth() / expandedWidth;
}
},
getVisibleWidth() {
let alwaysZoomOut = this._getAlwaysZoomOut();
if (alwaysZoomOut)
return super.getVisibleWidth();
return this.parent();
else
return this.getNonExpandedWidth();
}
};
});
var DashSlider = class extends SlidingControl {
constructor(dash) {
super({ slideDirection: SlideDirection.LEFT });
var DashSlider = new Lang.Class({
Name: 'DashSlider',
Extends: SlidingControl,
_init(dash) {
this.parent({ slideDirection: SlideDirection.LEFT });
this._dash = dash;
@@ -333,31 +344,33 @@ var DashSlider = class extends SlidingControl {
this.actor.add_actor(this._dash.actor);
this._dash.connect('icon-size-changed', this._updateSlide.bind(this));
}
},
_getSlide() {
if (this._visible || this._inDrag)
return 1;
else
return 0;
}
},
_onWindowDragBegin() {
this.fadeHalf();
}
},
_onWindowDragEnd() {
this.fadeIn();
}
};
});
var DashSpacer = new Lang.Class({
Name: 'DashSpacer',
Extends: St.Widget,
var DashSpacer = GObject.registerClass(
class DashSpacer extends St.Widget {
_init(params) {
super._init(params);
this.parent(params);
this._bindConstraint = null;
}
},
setDashActor(dashActor) {
if (this._bindConstraint) {
@@ -370,34 +383,38 @@ class DashSpacer extends St.Widget {
coordinate: Clutter.BindCoordinate.SIZE });
this.add_constraint(this._bindConstraint);
}
}
},
vfunc_get_preferred_width(forHeight) {
let box = this.get_allocation_box();
let minWidth = super.vfunc_get_preferred_width(forHeight)[0];
let minWidth = this.parent(forHeight)[0];
let natWidth = box.x2 - box.x1;
return [minWidth, natWidth];
}
},
vfunc_get_preferred_height(forWidth) {
let box = this.get_allocation_box();
let minHeight = super.vfunc_get_preferred_height(forWidth)[0];
let minHeight = this.parent(forWidth)[0];
let natHeight = box.y2 - box.y1;
return [minHeight, natHeight];
}
});
var ControlsLayout = GObject.registerClass({
var ControlsLayout = new Lang.Class({
Name: 'ControlsLayout',
Extends: Clutter.BinLayout,
Signals: { 'allocation-changed': { flags: GObject.SignalFlags.RUN_LAST } },
}, class ControlsLayout extends Clutter.BinLayout {
vfunc_allocate(container, box, flags) {
super.vfunc_allocate(container, box, flags);
this.parent(container, box, flags);
this.emit('allocation-changed');
}
});
var ControlsManager = class {
constructor(searchEntry) {
var ControlsManager = new Lang.Class({
Name: 'ControlsManager',
_init(searchEntry) {
this.dash = new Dash.Dash();
this._dashSlider = new DashSlider(this.dash);
this._dashSpacer = new DashSpacer();
@@ -440,7 +457,7 @@ var ControlsManager = class {
Main.overview.connect('item-drag-cancelled', () => {
this.viewSelector.fadeIn();
});
}
},
_updateWorkspacesGeometry() {
let [x, y] = this.actor.get_transformed_position();
@@ -460,7 +477,7 @@ var ControlsManager = class {
geometry.x += thumbnailsWidth;
this.viewSelector.setWorkspacesFullGeometry(geometry);
}
},
_setVisibility() {
// Ignore the case when we're leaving the overview, since
@@ -485,7 +502,7 @@ var ControlsManager = class {
this._thumbnailsSlider.slideIn();
else
this._thumbnailsSlider.slideOut();
}
},
_updateSpacerVisibility() {
if (Main.overview.animationInProgress && !Main.overview.visibleTarget)
@@ -493,7 +510,7 @@ var ControlsManager = class {
let activePage = this.viewSelector.getActivePage();
this._dashSpacer.visible = (activePage == ViewSelector.ViewPage.WINDOWS);
}
},
_onPageEmpty() {
this._dashSlider.pageEmpty();
@@ -501,4 +518,4 @@ var ControlsManager = class {
this._updateSpacerVisibility();
}
};
});

View File

@@ -1,5 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Clutter = imports.gi.Clutter;
@@ -31,8 +32,10 @@ const CCW = 1;
const UP = 0;
const DOWN = 1;
var PadChooser = class {
constructor(device, groupDevices) {
var PadChooser = new Lang.Class({
Name: 'PadChooser',
_init(device, groupDevices) {
this.actor = new St.Button({ style_class: 'pad-chooser-button',
toggle_mode: true,
x_fill: false,
@@ -59,7 +62,7 @@ var PadChooser = class {
this._padChooserMenu.close(true);
}
});
}
},
_ensureMenu(devices) {
this._padChooserMenu = new PopupMenu.PopupMenu(this.actor, 0.5, St.Side.TOP);
@@ -78,31 +81,33 @@ var PadChooser = class {
this.emit('pad-selected', device);
});
}
}
},
_onDestroy() {
this._padChooserMenu.destroy();
}
},
update(devices) {
if (this._padChooserMenu)
this._padChooserMenu.actor.destroy();
this.actor.set_checked(false);
this._ensureMenu(devices);
}
},
destroy() {
this.actor.destroy();
}
};
},
});
Signals.addSignalMethods(PadChooser.prototype);
var KeybindingEntry = class {
constructor() {
var KeybindingEntry = new Lang.Class({
Name: 'KeybindingEntry',
_init() {
this.actor = new St.Entry({ hint_text: _("New shortcut…"),
style: 'width: 10em' });
this.actor.connect('captured-event', this._onCapturedEvent.bind(this));
}
},
_onCapturedEvent(actor, event) {
if (event.type() != Clutter.EventType.KEY_PRESS)
@@ -116,11 +121,13 @@ var KeybindingEntry = class {
this.emit('keybinding-edited', str);
return Clutter.EVENT_STOP;
}
};
});
Signals.addSignalMethods(KeybindingEntry.prototype);
var ActionComboBox = class {
constructor() {
var ActionComboBox = new Lang.Class({
Name: 'ActionComboBox',
_init() {
this.actor = new St.Button({ style_class: 'button' });
this.actor.connect('clicked', this._onButtonClicked.bind(this));
this.actor.set_toggle_mode(true);
@@ -168,41 +175,43 @@ var ActionComboBox = class {
}
this.setAction(GDesktopEnums.PadButtonAction.NONE);
}
},
_onActionSelected(action) {
this.setAction(action);
this.popdown();
this.emit('action-selected', action);
}
},
setAction(action) {
this._label.set_text(this._actionLabels.get(action));
}
},
popup() {
this._editMenu.open(true);
}
},
popdown() {
this._editMenu.close(true);
}
},
_onButtonClicked() {
if (this.actor.get_checked())
this.popup();
else
this.popdown();
}
},
setButtonActionsActive(active) {
this._buttonItems.forEach(item => { item.setSensitive(active); });
}
};
});
Signals.addSignalMethods(ActionComboBox.prototype);
var ActionEditor = class {
constructor() {
var ActionEditor = new Lang.Class({
Name: 'ActionEditor',
_init() {
let boxLayout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.HORIZONTAL,
spacing: 12 });
@@ -221,7 +230,7 @@ var ActionEditor = class {
x_expand: false});
this._doneButton.connect('clicked', this._onEditingDone.bind(this));
this.actor.add_actor(this._doneButton);
}
},
_updateKeybindingEntryState() {
if (this._currentAction == GDesktopEnums.PadButtonAction.KEYBINDING) {
@@ -231,7 +240,7 @@ var ActionEditor = class {
} else {
this._keybindingEdit.actor.hide();
}
}
},
setSettings(settings, action) {
this._buttonSettings = settings;
@@ -243,21 +252,21 @@ var ActionEditor = class {
let isButton = (action == Meta.PadActionType.BUTTON);
this._actionComboBox.setButtonActionsActive(isButton);
}
},
close() {
this._actionComboBox.popdown();
this.actor.hide();
}
},
_onKeybindingEdited(entry, keybinding) {
this._currentKeybinding = keybinding;
}
},
_onActionSelected(menu, action) {
this._currentAction = action;
this._updateKeybindingEntryState();
}
},
_storeSettings() {
if (!this._buttonSettings)
@@ -274,17 +283,19 @@ var ActionEditor = class {
this._buttonSettings.set_string('keybinding', keybinding);
else
this._buttonSettings.reset('keybinding');
}
},
_onEditingDone() {
this._storeSettings();
this.close();
this.emit('done');
}
};
});
Signals.addSignalMethods(ActionEditor.prototype);
var PadDiagram = GObject.registerClass({
var PadDiagram = new Lang.Class({
Name: 'PadDiagram',
Extends: St.DrawingArea,
Properties: { 'left-handed': GObject.ParamSpec.boolean('left-handed',
'left-handed', 'Left handed',
GObject.ParamFlags.READWRITE |
@@ -300,7 +311,7 @@ var PadDiagram = GObject.registerClass({
GObject.ParamFlags.READWRITE |
GObject.ParamFlags.CONSTRUCT_ONLY,
Clutter.Actor.$gtype) },
}, class PadDiagram extends St.DrawingArea {
_init(params) {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/pad-osd.css');
let [success, css, etag] = file.load_contents(null);
@@ -311,20 +322,20 @@ var PadDiagram = GObject.registerClass({
this._css = css;
this._labels = [];
this._activeButtons = [];
super._init(params);
}
this.parent(params);
},
get left_handed() {
return this._leftHanded;
}
},
set left_handed(leftHanded) {
this._leftHanded = leftHanded;
}
},
get image() {
return this._imagePath;
}
},
set image(imagePath) {
let originalHandle = Rsvg.Handle.new_from_file(imagePath);
@@ -334,17 +345,17 @@ var PadDiagram = GObject.registerClass({
this._imagePath = imagePath;
this._handle = this._composeStyledDiagram();
}
},
get editor_actor() {
return this._editorActor;
}
},
set editor_actor(actor) {
actor.hide();
this._editorActor = actor;
this.add_actor(actor);
}
},
_wrappingSvgHeader() {
return ('<?xml version="1.0" encoding="UTF-8" standalone="no"?>' +
@@ -352,13 +363,13 @@ var PadDiagram = GObject.registerClass({
'xmlns:xi="http://www.w3.org/2001/XInclude" ' +
'width="' + this._imageWidth + '" height="' + this._imageHeight + '"> ' +
'<style type="text/css">');
}
},
_wrappingSvgFooter() {
return ('</style>' +
'<xi:include href="' + this._imagePath + '" />' +
'</svg>');
}
},
_cssString() {
let css = this._css;
@@ -372,7 +383,7 @@ var PadDiagram = GObject.registerClass({
}
return css;
}
},
_composeStyledDiagram() {
let svgData = '';
@@ -390,7 +401,7 @@ var PadDiagram = GObject.registerClass({
handle.close();
return handle;
}
},
_updateDiagramScale() {
if (this._handle == null)
@@ -401,7 +412,7 @@ var PadDiagram = GObject.registerClass({
let scaleX = this._actorWidth / dimensions.width;
let scaleY = this._actorHeight / dimensions.height;
this._scale = Math.min(scaleX, scaleY);
}
},
_allocateChild(child, x, y, direction) {
let [prefHeight, natHeight] = child.get_preferred_height(-1);
@@ -419,10 +430,10 @@ var PadDiagram = GObject.registerClass({
childBox.y1 = y - natHeight / 2;
childBox.y2 = y + natHeight / 2;
child.allocate(childBox, 0);
}
},
vfunc_allocate(box, flags) {
super.vfunc_allocate(box, flags);
this.parent(box, flags);
this._updateDiagramScale();
for (let i = 0; i < this._labels.length; i++) {
@@ -436,7 +447,7 @@ var PadDiagram = GObject.registerClass({
let [found, x, y, arrangement] = this.getLabelCoords(action, idx, dir);
this._allocateChild(this._editorActor, x, y, arrangement);
}
}
},
vfunc_repaint() {
if (this._handle == null)
@@ -458,7 +469,7 @@ var PadDiagram = GObject.registerClass({
this._handle.render_cairo(cr);
cr.restore();
cr.$dispose();
}
},
_transformPoint(x, y) {
if (this._handle == null || this._scale == null)
@@ -469,7 +480,7 @@ var PadDiagram = GObject.registerClass({
x = x * this._scale + this._actorWidth / 2 - dimensions.width / 2 * this._scale;
y = y * this._scale + this._actorHeight / 2 - dimensions.height / 2 * this._scale;;
return [Math.round(x), Math.round(y)];
}
},
_getItemLabelCoords(labelName, leaderName) {
if (this._handle == null)
@@ -501,7 +512,7 @@ var PadDiagram = GObject.registerClass({
let [x, y] = this._transformPoint(pos.x, pos.y)
return [true, x, y, direction];
}
},
getButtonLabelCoords(button) {
let ch = String.fromCharCode('A'.charCodeAt() + button);
@@ -509,7 +520,7 @@ var PadDiagram = GObject.registerClass({
let leaderName = 'Leader' + ch;
return this._getItemLabelCoords(labelName, leaderName);
}
},
getRingLabelCoords(number, dir) {
let numStr = number > 0 ? (number + 1).toString() : '';
@@ -518,7 +529,7 @@ var PadDiagram = GObject.registerClass({
let leaderName = 'LeaderRing' + numStr + dirStr;
return this._getItemLabelCoords(labelName, leaderName);
}
},
getStripLabelCoords(number, dir) {
let numStr = number > 0 ? (number + 1).toString() : '';
@@ -527,7 +538,7 @@ var PadDiagram = GObject.registerClass({
let leaderName = 'LeaderStrip' + numStr + dirStr;
return this._getItemLabelCoords(labelName, leaderName);
}
},
getLabelCoords(action, idx, dir) {
if (action == Meta.PadActionType.BUTTON)
@@ -538,19 +549,19 @@ var PadDiagram = GObject.registerClass({
return this.getStripLabelCoords(idx, dir);
return [false];
}
},
_invalidateSvg() {
if (this._handle == null)
return;
this._handle = this._composeStyledDiagram();
this.queue_repaint();
}
},
activateButton(button) {
this._activeButtons.push(button);
this._invalidateSvg();
}
},
deactivateButton(button) {
for (let i = 0; i < this._activeButtons.length; i++) {
@@ -558,12 +569,12 @@ var PadDiagram = GObject.registerClass({
this._activeButtons.splice(i, 1);
}
this._invalidateSvg();
}
},
addLabel(label, type, idx, dir) {
this._labels.push([label, type, idx, dir]);
this.add_actor(label);
}
},
_applyLabel(label, action, idx, dir, str) {
if (str != null) {
@@ -573,7 +584,7 @@ var PadDiagram = GObject.registerClass({
this._allocateChild(label, x, y, arrangement);
}
label.show();
}
},
stopEdition(continues, str) {
this._editorActor.hide();
@@ -591,7 +602,7 @@ var PadDiagram = GObject.registerClass({
this._prevEdited = this._curEdited;
this._curEdited = null;
}
}
},
startEdition(action, idx, dir) {
let editedLabel;
@@ -618,8 +629,10 @@ var PadDiagram = GObject.registerClass({
}
});
var PadOsd = class {
constructor(padDevice, settings, imagePath, editionMode, monitorIndex) {
var PadOsd = new Lang.Class({
Name: 'PadOsd',
_init(padDevice, settings, imagePath, editionMode, monitorIndex) {
this.padDevice = padDevice;
this._groupPads = [ padDevice ];
this._settings = settings;
@@ -739,7 +752,7 @@ var PadOsd = class {
this._syncEditionMode();
Main.pushModal(this.actor);
}
},
_updatePadChooser() {
if (this._groupPads.length > 1) {
@@ -756,7 +769,7 @@ var PadOsd = class {
this._padChooser.destroy();
this._padChooser = null;
}
}
},
_requestForOtherPad(pad) {
if (pad == this.padDevice ||
@@ -766,13 +779,13 @@ var PadOsd = class {
let editionMode = this._editionMode;
this.destroy();
global.display.request_pad_osd(pad, editionMode);
}
},
_createLabel(type, number, dir) {
let str = global.display.get_pad_action_label(this.padDevice, type, number);
let label = new St.Label({ text: str ? str : _("None") });
this._padDiagram.addLabel(label, type, number, dir);
}
},
_onCapturedEvent(actor, event) {
if (event.type() == Clutter.EventType.PAD_BUTTON_PRESS &&
@@ -817,7 +830,7 @@ var PadOsd = class {
}
return Clutter.EVENT_PROPAGATE;
}
},
_syncEditionMode() {
this._editButton.set_reactive(!this._editionMode);
@@ -837,7 +850,7 @@ var PadOsd = class {
}
this._titleLabel.clutter_text.set_markup('<span size="larger"><b>' + title + '</b></span>');
}
},
_isEditedAction(type, number, dir) {
if (!this._editedAction)
@@ -846,7 +859,7 @@ var PadOsd = class {
return (this._editedAction.type == type &&
this._editedAction.number == number &&
this._editedAction.dir == dir);
}
},
_followUpActionEdition(str) {
let { type, dir, number, mode } = this._editedAction;
@@ -863,7 +876,7 @@ var PadOsd = class {
this._startStripActionEdition(number, DOWN, mode);
return true;
}
},
_endActionEdition() {
this._actionEditor.close();
@@ -880,7 +893,7 @@ var PadOsd = class {
}
this._editedActionSettings = null;
}
},
_startActionEdition(key, type, number, dir, mode) {
if (this._isEditedAction(type, number, dir))
@@ -894,25 +907,25 @@ var PadOsd = class {
settingsPath);
this._actionEditor.setSettings(this._editedActionSettings, type);
this._padDiagram.startEdition(type, number, dir);
}
},
_startButtonActionEdition(button) {
let ch = String.fromCharCode('A'.charCodeAt() + button);
let key = 'button' + ch;
this._startActionEdition(key, Meta.PadActionType.BUTTON, button);
}
},
_startRingActionEdition(ring, dir, mode) {
let ch = String.fromCharCode('A'.charCodeAt() + ring);
let key = 'ring%s-%s-mode-%d'.format(ch, dir == CCW ? 'ccw' : 'cw', mode);
this._startActionEdition(key, Meta.PadActionType.RING, ring, dir, mode);
}
},
_startStripActionEdition(strip, dir, mode) {
let ch = String.fromCharCode('A'.charCodeAt() + strip);
let key = 'strip%s-%s-mode-%d'.format(ch, dir == UP ? 'up' : 'down', mode);
this._startActionEdition(key, Meta.PadActionType.STRIP, strip, dir, mode);
}
},
setEditionMode(editionMode) {
if (this._editionMode == editionMode)
@@ -920,11 +933,11 @@ var PadOsd = class {
this._editionMode = editionMode;
this._syncEditionMode();
}
},
destroy() {
this.actor.destroy();
}
},
_onDestroy() {
Main.popModal(this.actor);
@@ -948,17 +961,19 @@ var PadOsd = class {
this.actor = null;
this.emit('closed');
}
};
});
Signals.addSignalMethods(PadOsd.prototype);
const PadOsdIface = loadInterfaceXML('org.gnome.Shell.Wacom.PadOsd');
var PadOsdService = class {
constructor() {
var PadOsdService = new Lang.Class({
Name: 'PadOsdService',
_init() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(PadOsdIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Wacom');
Gio.DBus.session.own_name('org.gnome.Shell.Wacom.PadOsd', Gio.BusNameOwnerFlags.REPLACE, null, null);
}
},
ShowAsync(params, invocation) {
let [deviceNode, editionMode] = params;
@@ -982,5 +997,5 @@ var PadOsdService = class {
global.display.request_pad_osd(padDevice, editionMode);
invocation.return_value(null);
}
};
});
Signals.addSignalMethods(PadOsdService.prototype);

View File

@@ -2,25 +2,36 @@
const Cairo = imports.cairo;
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Signals = imports.signals;
const Atk = imports.gi.Atk;
const Animation = imports.ui.animation;
const Config = imports.misc.config;
const CtrlAltTab = imports.ui.ctrlAltTab;
const DND = imports.ui.dnd;
const Overview = imports.ui.overview;
const PopupMenu = imports.ui.popupMenu;
const PanelMenu = imports.ui.panelMenu;
const RemoteMenu = imports.ui.remoteMenu;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
var PANEL_ICON_SIZE = 16;
var APP_MENU_ICON_MARGIN = 0;
var BUTTON_DND_ACTIVATION_TIMEOUT = 250;
var SPINNER_ANIMATION_TIME = 1.0;
// To make sure the panel corners blend nicely with the panel,
// we draw background and borders the same way, e.g. drawing
// them as filled shapes from the outside inwards instead of
@@ -64,10 +75,336 @@ function _unpremultiply(color) {
blue: blue, alpha: color.alpha });
};
var ActivitiesButton = GObject.registerClass(
class ActivitiesButton extends PanelMenu.Button {
/**
* AppMenuButton:
*
* This class manages the "application menu" component. It tracks the
* currently focused application. However, when an app is launched,
* this menu also handles startup notification for it. So when we
* have an active startup notification, we switch modes to display that.
*/
var AppMenuButton = new Lang.Class({
Name: 'AppMenuButton',
Extends: PanelMenu.Button,
Signals: {'changed': {}},
_init(panel) {
this.parent(0.0, null, true);
this.actor.accessible_role = Atk.Role.MENU;
this._startingApps = [];
this._menuManager = panel.menuManager;
this._gtkSettings = Gtk.Settings.get_default();
this._targetApp = null;
this._appMenuNotifyId = 0;
this._actionGroupNotifyId = 0;
this._busyNotifyId = 0;
let bin = new St.Bin({ name: 'appMenu' });
bin.connect('style-changed', this._onStyleChanged.bind(this));
this.actor.add_actor(bin);
this.actor.bind_property("reactive", this.actor, "can-focus", 0);
this.actor.reactive = false;
this._container = new St.BoxLayout({ style_class: 'panel-status-menu-box' });
bin.set_child(this._container);
let textureCache = St.TextureCache.get_default();
textureCache.connect('icon-theme-changed',
this._onIconThemeChanged.bind(this));
this._iconBox = new St.Bin({ style_class: 'app-menu-icon' });
this._container.add_actor(this._iconBox);
this._label = new St.Label({ y_expand: true,
y_align: Clutter.ActorAlign.CENTER });
this._container.add_actor(this._label);
this._arrow = PopupMenu.arrowIcon(St.Side.BOTTOM);
this._container.add_actor(this._arrow);
this._visible = this._gtkSettings.gtk_shell_shows_app_menu &&
!Main.overview.visible;
if (!this._visible)
this.hide();
this._overviewHidingId = Main.overview.connect('hiding', this._sync.bind(this));
this._overviewShowingId = Main.overview.connect('showing', this._sync.bind(this));
this._showsAppMenuId = this._gtkSettings.connect('notify::gtk-shell-shows-app-menu',
this._sync.bind(this));
this._stop = true;
this._spinner = null;
let tracker = Shell.WindowTracker.get_default();
let appSys = Shell.AppSystem.get_default();
this._focusAppNotifyId =
tracker.connect('notify::focus-app', this._focusAppChanged.bind(this));
this._appStateChangedSignalId =
appSys.connect('app-state-changed', this._onAppStateChanged.bind(this));
this._switchWorkspaceNotifyId =
global.window_manager.connect('switch-workspace', this._sync.bind(this));
this._sync();
},
fadeIn() {
if (this._visible)
return;
this._visible = true;
this.actor.reactive = true;
this.show();
Tweener.removeTweens(this.actor);
Tweener.addTween(this.actor,
{ opacity: 255,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad' });
},
fadeOut() {
if (!this._visible)
return;
this._visible = false;
this.actor.reactive = false;
Tweener.removeTweens(this.actor);
Tweener.addTween(this.actor,
{ opacity: 0,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete() {
this.hide();
},
onCompleteScope: this });
},
_onStyleChanged(actor) {
let node = actor.get_theme_node();
let [success, icon] = node.lookup_url('spinner-image', false);
if (!success || (this._spinnerIcon && this._spinnerIcon.equal(icon)))
return;
this._spinnerIcon = icon;
this._spinner = new Animation.AnimatedIcon(this._spinnerIcon, PANEL_ICON_SIZE);
this._container.add_actor(this._spinner.actor);
this._spinner.actor.hide();
},
_syncIcon() {
if (!this._targetApp)
return;
let icon = this._targetApp.create_icon_texture(PANEL_ICON_SIZE - APP_MENU_ICON_MARGIN);
this._iconBox.set_child(icon);
},
_onIconThemeChanged() {
if (this._iconBox.child == null)
return;
this._syncIcon();
},
stopAnimation() {
if (this._stop)
return;
this._stop = true;
if (this._spinner == null)
return;
Tweener.addTween(this._spinner.actor,
{ opacity: 0,
time: SPINNER_ANIMATION_TIME,
transition: "easeOutQuad",
onCompleteScope: this,
onComplete() {
this._spinner.stop();
this._spinner.actor.opacity = 255;
this._spinner.actor.hide();
}
});
},
startAnimation() {
this._stop = false;
if (this._spinner == null)
return;
this._spinner.play();
this._spinner.actor.show();
},
_onAppStateChanged(appSys, app) {
let state = app.state;
if (state != Shell.AppState.STARTING)
this._startingApps = this._startingApps.filter(a => a != app);
else if (state == Shell.AppState.STARTING)
this._startingApps.push(app);
// For now just resync on all running state changes; this is mainly to handle
// cases where the focused window's application changes without the focus
// changing. An example case is how we map OpenOffice.org based on the window
// title which is a dynamic property.
this._sync();
},
_focusAppChanged() {
let tracker = Shell.WindowTracker.get_default();
let focusedApp = tracker.focus_app;
if (!focusedApp) {
// If the app has just lost focus to the panel, pretend
// nothing happened; otherwise you can't keynav to the
// app menu.
if (global.stage.key_focus != null)
return;
}
this._sync();
},
_findTargetApp() {
let workspaceManager = global.workspace_manager;
let workspace = workspaceManager.get_active_workspace();
let tracker = Shell.WindowTracker.get_default();
let focusedApp = tracker.focus_app;
if (focusedApp && focusedApp.is_on_workspace(workspace))
return focusedApp;
for (let i = 0; i < this._startingApps.length; i++)
if (this._startingApps[i].is_on_workspace(workspace))
return this._startingApps[i];
return null;
},
_sync() {
let targetApp = this._findTargetApp();
if (this._targetApp != targetApp) {
if (this._appMenuNotifyId) {
this._targetApp.disconnect(this._appMenuNotifyId);
this._appMenuNotifyId = 0;
}
if (this._actionGroupNotifyId) {
this._targetApp.disconnect(this._actionGroupNotifyId);
this._actionGroupNotifyId = 0;
}
if (this._busyNotifyId) {
this._targetApp.disconnect(this._busyNotifyId);
this._busyNotifyId = 0;
}
this._targetApp = targetApp;
if (this._targetApp) {
this._appMenuNotifyId = this._targetApp.connect('notify::menu', this._sync.bind(this));
this._actionGroupNotifyId = this._targetApp.connect('notify::action-group', this._sync.bind(this));
this._busyNotifyId = this._targetApp.connect('notify::busy', this._sync.bind(this));
this._label.set_text(this._targetApp.get_name());
this.actor.set_accessible_name(this._targetApp.get_name());
}
}
let shellShowsAppMenu = this._gtkSettings.gtk_shell_shows_app_menu;
Meta.prefs_set_show_fallback_app_menu(!shellShowsAppMenu);
let visible = (this._targetApp != null &&
shellShowsAppMenu &&
!Main.overview.visibleTarget);
if (visible)
this.fadeIn();
else
this.fadeOut();
let isBusy = (this._targetApp != null &&
(this._targetApp.get_state() == Shell.AppState.STARTING ||
this._targetApp.get_busy()));
if (isBusy)
this.startAnimation();
else
this.stopAnimation();
this.actor.reactive = (visible && !isBusy);
this._syncIcon();
this._maybeSetMenu();
this.emit('changed');
},
_maybeSetMenu() {
let menu;
if (this._targetApp == null) {
menu = null;
} else if (this._targetApp.action_group && this._targetApp.menu) {
if (this.menu instanceof RemoteMenu.RemoteMenu &&
this.menu.actionGroup == this._targetApp.action_group)
return;
menu = new RemoteMenu.RemoteMenu(this.actor, this._targetApp.menu, this._targetApp.action_group);
menu.connect('activate', () => {
let win = this._targetApp.get_windows()[0];
win.check_alive(global.get_current_time());
});
} else {
if (this.menu && this.menu.isDummyQuitMenu)
return;
// fallback to older menu
menu = new PopupMenu.PopupMenu(this.actor, 0.0, St.Side.TOP, 0);
menu.isDummyQuitMenu = true;
menu.addAction(_("Quit"), () => {
this._targetApp.request_quit();
});
}
this.setMenu(menu);
if (menu)
this._menuManager.addMenu(menu);
},
_onDestroy() {
if (this._appStateChangedSignalId > 0) {
let appSys = Shell.AppSystem.get_default();
appSys.disconnect(this._appStateChangedSignalId);
this._appStateChangedSignalId = 0;
}
if (this._focusAppNotifyId > 0) {
let tracker = Shell.WindowTracker.get_default();
tracker.disconnect(this._focusAppNotifyId);
this._focusAppNotifyId = 0;
}
if (this._overviewHidingId > 0) {
Main.overview.disconnect(this._overviewHidingId);
this._overviewHidingId = 0;
}
if (this._overviewShowingId > 0) {
Main.overview.disconnect(this._overviewShowingId);
this._overviewShowingId = 0;
}
if (this._showsAppMenuId > 0) {
this._gtkSettings.disconnect(this._showsAppMenuId);
this._showsAppMenuId = 0;
}
if (this._switchWorkspaceNotifyId > 0) {
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
this._switchWorkspaceNotifyId = 0;
}
this.parent();
}
});
var ActivitiesButton = new Lang.Class({
Name: 'ActivitiesButton',
Extends: PanelMenu.Button,
_init() {
super._init(0.0, null, true);
this.parent(0.0, null, true);
this.actor.accessible_role = Atk.Role.TOGGLE_BUTTON;
this.actor.name = 'panelActivities';
@@ -93,7 +430,7 @@ class ActivitiesButton extends PanelMenu.Button {
});
this._xdndTimeOut = 0;
}
},
handleDragOver(source, actor, x, y, time) {
if (source != Main.xdndHandler)
@@ -107,7 +444,7 @@ class ActivitiesButton extends PanelMenu.Button {
GLib.Source.set_name_by_id(this._xdndTimeOut, '[gnome-shell] this._xdndToggleOverview');
return DND.DragMotionResult.CONTINUE;
}
},
_onCapturedEvent(actor, event) {
if (event.type() == Clutter.EventType.BUTTON_PRESS ||
@@ -116,10 +453,10 @@ class ActivitiesButton extends PanelMenu.Button {
return Clutter.EVENT_STOP;
}
return Clutter.EVENT_PROPAGATE;
}
},
_onEvent(actor, event) {
super._onEvent(actor, event);
this.parent(actor, event);
if (event.type() == Clutter.EventType.TOUCH_END ||
event.type() == Clutter.EventType.BUTTON_RELEASE)
@@ -127,7 +464,7 @@ class ActivitiesButton extends PanelMenu.Button {
Main.overview.toggle();
return Clutter.EVENT_PROPAGATE;
}
},
_onKeyRelease(actor, event) {
let symbol = event.get_key_symbol();
@@ -136,7 +473,7 @@ class ActivitiesButton extends PanelMenu.Button {
Main.overview.toggle();
}
return Clutter.EVENT_PROPAGATE;
}
},
_xdndToggleOverview(actor) {
let [x, y, mask] = global.get_pointer();
@@ -151,14 +488,16 @@ class ActivitiesButton extends PanelMenu.Button {
}
});
var PanelCorner = class {
constructor(side) {
var PanelCorner = new Lang.Class({
Name: 'PanelCorner',
_init(side) {
this._side = side;
this.actor = new St.DrawingArea({ style_class: 'panel-corner' });
this.actor.connect('style-changed', this._styleChanged.bind(this));
this.actor.connect('repaint', this._repaint.bind(this));
}
},
_findRightmostButton(container) {
if (!container.get_children)
@@ -183,7 +522,7 @@ var PanelCorner = class {
return this._findRightmostButton(children[index]);
return children[index];
}
},
_findLeftmostButton(container) {
if (!container.get_children)
@@ -208,7 +547,7 @@ var PanelCorner = class {
return this._findLeftmostButton(children[index]);
return children[index];
}
},
setStyleParent(box) {
let side = this._side;
@@ -254,7 +593,7 @@ var PanelCorner = class {
// the .panel-button default
button.style = 'transition-duration: 0ms';
}
}
},
_repaint() {
let node = this.actor.get_theme_node();
@@ -302,7 +641,7 @@ var PanelCorner = class {
}
cr.$dispose();
}
},
_styleChanged() {
let node = this.actor.get_theme_node();
@@ -313,23 +652,25 @@ var PanelCorner = class {
this.actor.set_size(cornerRadius, borderWidth + cornerRadius);
this.actor.set_anchor_point(0, borderWidth);
}
};
});
var AggregateLayout = new Lang.Class({
Name: 'AggregateLayout',
Extends: Clutter.BoxLayout,
var AggregateLayout = GObject.registerClass(
class AggregateLayout extends Clutter.BoxLayout {
_init(params) {
if (!params)
params = {};
params['orientation'] = Clutter.Orientation.VERTICAL;
super._init(params);
this.parent(params);
this._sizeChildren = [];
}
},
addSizeChild(actor) {
this._sizeChildren.push(actor);
this.layout_changed();
}
},
vfunc_get_preferred_width(container, forHeight) {
let themeNode = container.get_theme_node();
@@ -346,10 +687,12 @@ class AggregateLayout extends Clutter.BoxLayout {
}
});
var AggregateMenu = GObject.registerClass(
class AggregateMenu extends PanelMenu.Button {
var AggregateMenu = new Lang.Class({
Name: 'AggregateMenu',
Extends: PanelMenu.Button,
_init() {
super._init(0.0, C_("System menu in the top bar", "System"), false);
this.parent(0.0, C_("System menu in the top bar", "System"), false);
this.menu.actor.add_style_class_name('aggregate-menu');
let menuLayout = new AggregateLayout();
@@ -416,21 +759,24 @@ class AggregateMenu extends PanelMenu.Button {
menuLayout.addSizeChild(this._rfkill.menu.actor);
menuLayout.addSizeChild(this._power.menu.actor);
menuLayout.addSizeChild(this._system.menu.actor);
}
},
});
const PANEL_ITEM_IMPLEMENTATIONS = {
'activities': ActivitiesButton,
'aggregateMenu': AggregateMenu,
'appMenu': AppMenuButton,
'dateMenu': imports.ui.dateMenu.DateMenuButton,
'a11y': imports.ui.status.accessibility.ATIndicator,
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
};
var Panel = GObject.registerClass(
class Panel extends St.Widget {
var Panel = new Lang.Class({
Name: 'Panel',
Extends: St.Widget,
_init() {
super._init({ name: 'panel',
this.parent({ name: 'panel',
reactive: true });
// For compatibility with extensions that still use the
@@ -440,8 +786,6 @@ class Panel extends St.Widget {
this._sessionStyle = null;
Meta.prefs_set_show_fallback_app_menu(true);
this.statusArea = {};
this.menuManager = new PopupMenu.PopupMenuManager(this);
@@ -485,7 +829,7 @@ class Panel extends St.Widget {
global.display.connect('workareas-changed', () => { this.queue_relayout(); });
this._updatePanel();
}
},
_onWindowActorAdded(container, metaWindowActor) {
let signalIds = [];
@@ -493,7 +837,7 @@ class Panel extends St.Widget {
signalIds.push(metaWindowActor.connect(s, this._updateSolidStyle.bind(this)));
});
this._trackedWindows.set(metaWindowActor, signalIds);
}
},
_onWindowActorRemoved(container, metaWindowActor) {
this._trackedWindows.get(metaWindowActor).forEach(id => {
@@ -501,7 +845,7 @@ class Panel extends St.Widget {
});
this._trackedWindows.delete(metaWindowActor);
this._updateSolidStyle();
}
},
vfunc_get_preferred_width(actor, forHeight) {
let primaryMonitor = Main.layoutManager.primaryMonitor;
@@ -510,10 +854,10 @@ class Panel extends St.Widget {
return [0, primaryMonitor.width];
return [0, 0];
}
},
vfunc_allocate(box, flags) {
super.vfunc_allocate(box, flags);
this.parent(box, flags);
let allocWidth = box.x2 - box.x1;
let allocHeight = box.y2 - box.y1;
@@ -589,7 +933,7 @@ class Panel extends St.Widget {
childBox.y1 = allocHeight;
childBox.y2 = allocHeight + cornerHeight;
this._rightCorner.actor.allocate(childBox, flags);
}
},
_onButtonPress(actor, event) {
if (Main.modalCount > 0)
@@ -635,7 +979,7 @@ class Panel extends St.Widget {
stageX, stageY);
return Clutter.EVENT_STOP;
}
},
_onKeyPress(actor, event) {
let symbol = event.get_key_symbol();
@@ -645,7 +989,7 @@ class Panel extends St.Widget {
}
return Clutter.EVENT_PROPAGATE;
}
},
_toggleMenu(indicator) {
if (!indicator) // menu not supported by current session mode
@@ -658,11 +1002,15 @@ class Panel extends St.Widget {
menu.toggle();
if (menu.isOpen)
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
}
},
toggleAppMenu() {
this._toggleMenu(this.statusArea.appMenu);
},
toggleCalendar() {
this._toggleMenu(this.statusArea.dateMenu);
}
},
closeCalendar() {
let indicator = this.statusArea.dateMenu;
@@ -674,7 +1022,7 @@ class Panel extends St.Widget {
return;
menu.close();
}
},
set boxOpacity(value) {
let isReactive = value > 0;
@@ -685,11 +1033,11 @@ class Panel extends St.Widget {
this._centerBox.reactive = isReactive;
this._rightBox.opacity = value;
this._rightBox.reactive = isReactive;
}
},
get boxOpacity() {
return this._leftBox.opacity;
}
},
_updatePanel() {
let panel = Main.sessionMode.panel;
@@ -722,7 +1070,7 @@ class Panel extends St.Widget {
this._leftCorner.setStyleParent(this._leftBox);
this._rightCorner.setStyleParent(this._rightBox);
}
}
},
_updateSolidStyle() {
if (this.has_style_pseudo_class('overview') || !Main.sessionMode.hasWindows) {
@@ -757,7 +1105,7 @@ class Panel extends St.Widget {
else
this._removeStyleClassName('solid');
}
},
_hideIndicators() {
for (let role in PANEL_ITEM_IMPLEMENTATIONS) {
@@ -766,7 +1114,7 @@ class Panel extends St.Widget {
continue;
indicator.container.hide();
}
}
},
_ensureIndicator(role) {
let indicator = this.statusArea[role];
@@ -780,7 +1128,7 @@ class Panel extends St.Widget {
this.statusArea[role] = indicator;
}
return indicator;
}
},
_updateBox(elements, box) {
let nChildren = box.get_n_children();
@@ -793,7 +1141,7 @@ class Panel extends St.Widget {
this._addToPanelBox(role, indicator, i + nChildren, box);
}
}
},
_addToPanelBox(role, indicator, position, box) {
let container = indicator.container;
@@ -814,7 +1162,7 @@ class Panel extends St.Widget {
});
indicator.connect('menu-set', this._onMenuSet.bind(this));
this._onMenuSet(indicator);
}
},
addToStatusArea(role, indicator, position, box) {
if (this.statusArea[role])
@@ -833,19 +1181,19 @@ class Panel extends St.Widget {
this.statusArea[role] = indicator;
this._addToPanelBox(role, indicator, position, boxContainer);
return indicator;
}
},
_addStyleClassName(className) {
this.add_style_class_name(className);
this._rightCorner.actor.add_style_class_name(className);
this._leftCorner.actor.add_style_class_name(className);
}
},
_removeStyleClassName(className) {
this.remove_style_class_name(className);
this._rightCorner.actor.remove_style_class_name(className);
this._leftCorner.actor.remove_style_class_name(className);
}
},
_onMenuSet(indicator) {
if (!indicator.menu || indicator.menu.hasOwnProperty('_openChangedId'))

View File

@@ -2,8 +2,8 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
@@ -13,12 +13,14 @@ const Main = imports.ui.main;
const Params = imports.misc.params;
const PopupMenu = imports.ui.popupMenu;
var ButtonBox = GObject.registerClass(
class ButtonBox extends St.Widget {
var ButtonBox = new Lang.Class({
Name: 'ButtonBox',
Extends: St.Widget,
_init(params) {
params = Params.parse(params, { style_class: 'panel-button' }, true);
super._init(params);
this.parent(params);
this.actor = this;
this._delegate = this;
@@ -31,14 +33,14 @@ class ButtonBox extends St.Widget {
this.connect('destroy', this._onDestroy.bind(this));
this._minHPadding = this._natHPadding = 0.0;
}
},
_onStyleChanged(actor) {
let themeNode = actor.get_theme_node();
this._minHPadding = themeNode.get_length('-minimum-hpadding');
this._natHPadding = themeNode.get_length('-natural-hpadding');
}
},
vfunc_get_preferred_width(forHeight) {
let child = this.get_first_child();
@@ -53,7 +55,7 @@ class ButtonBox extends St.Widget {
naturalSize += 2 * this._natHPadding;
return [minimumSize, naturalSize];
}
},
vfunc_get_preferred_height(forWidth) {
let child = this.get_first_child();
@@ -62,7 +64,7 @@ class ButtonBox extends St.Widget {
return child.get_preferred_height(-1);
return [0, 0];
}
},
vfunc_allocate(box, flags) {
this.set_allocation(box, flags);
@@ -89,19 +91,21 @@ class ButtonBox extends St.Widget {
childBox.y2 = availHeight;
child.allocate(childBox, flags);
}
},
_onDestroy() {
this.container.child = null;
this.container.destroy();
}
},
});
var Button = GObject.registerClass({
var Button = new Lang.Class({
Name: 'PanelMenuButton',
Extends: ButtonBox,
Signals: {'menu-set': {} },
}, class PanelMenuButton extends ButtonBox {
_init(menuAlignment, nameText, dontCreateMenu) {
super._init({ reactive: true,
this.parent({ reactive: true,
can_focus: true,
track_hover: true,
accessible_name: nameText ? nameText : "",
@@ -114,13 +118,13 @@ var Button = GObject.registerClass({
this.menu = new PopupMenu.PopupDummyMenu(this.actor);
else
this.setMenu(new PopupMenu.PopupMenu(this.actor, menuAlignment, St.Side.TOP, 0));
}
},
setSensitive(sensitive) {
this.reactive = sensitive;
this.can_focus = sensitive;
this.track_hover = sensitive;
}
},
setMenu(menu) {
if (this.menu)
@@ -136,7 +140,7 @@ var Button = GObject.registerClass({
this.menu.actor.hide();
}
this.emit('menu-set');
}
},
_onEvent(actor, event) {
if (this.menu &&
@@ -145,7 +149,7 @@ var Button = GObject.registerClass({
this.menu.toggle();
return Clutter.EVENT_PROPAGATE;
}
},
_onVisibilityChanged() {
if (!this.menu)
@@ -153,7 +157,7 @@ var Button = GObject.registerClass({
if (!this.actor.visible)
this.menu.close();
}
},
_onMenuKeyPress(actor, event) {
if (global.focus_manager.navigate_from_event(event))
@@ -169,7 +173,7 @@ var Button = GObject.registerClass({
}
}
return Clutter.EVENT_PROPAGATE;
}
},
_onOpenStateChanged(menu, open) {
if (open)
@@ -189,10 +193,10 @@ var Button = GObject.registerClass({
// factor when computing max-height
let maxHeight = Math.round((workArea.height - verticalMargins) / scaleFactor);
this.menu.actor.style = ('max-height: %spx;').format(maxHeight);
}
},
_onDestroy() {
super._onDestroy();
this.parent();
if (this.menu)
this.menu.destroy();
@@ -206,17 +210,19 @@ var Button = GObject.registerClass({
* of an icon and a menu section, which will be composed into the
* aggregate menu.
*/
var SystemIndicator = class {
constructor() {
var SystemIndicator = new Lang.Class({
Name: 'SystemIndicator',
_init() {
this.indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box',
reactive: true });
this.indicators.hide();
this.menu = new PopupMenu.PopupMenuSection();
}
},
_syncIndicatorsVisible() {
this.indicators.visible = this.indicators.get_children().some(a => a.visible);
}
},
_addIndicator() {
let icon = new St.Icon({ style_class: 'system-status-icon' });
@@ -225,5 +231,5 @@ var SystemIndicator = class {
this._syncIndicatorsVisible();
return icon;
}
};
});
Signals.addSignalMethods(SystemIndicator.prototype);

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const GnomeDesktop = imports.gi.GnomeDesktop;
@@ -21,12 +22,14 @@ function getPointerWatcher() {
return _pointerWatcher;
}
var PointerWatch = class {
constructor(watcher, interval, callback) {
var PointerWatch = new Lang.Class({
Name: 'PointerWatch',
_init(watcher, interval, callback) {
this.watcher = watcher;
this.interval = interval;
this.callback = callback;
}
},
// remove:
// remove this watch. This function may safely be called
@@ -34,17 +37,19 @@ var PointerWatch = class {
remove() {
this.watcher._removeWatch(this);
}
};
});
var PointerWatcher = class {
constructor() {
var PointerWatcher = new Lang.Class({
Name: 'PointerWatcher',
_init() {
this._idleMonitor = Meta.IdleMonitor.get_core();
this._idleMonitor.add_idle_watch(IDLE_TIME, this._onIdleMonitorBecameIdle.bind(this));
this._idle = this._idleMonitor.get_idletime() > IDLE_TIME;
this._watches = [];
this.pointerX = null;
this.pointerY = null;
}
},
// addWatch:
// @interval: hint as to the time resolution needed. When the user is
@@ -63,7 +68,7 @@ var PointerWatcher = class {
this._watches.push(watch);
this._updateTimeout();
return watch;
}
},
_removeWatch(watch) {
for (let i = 0; i < this._watches.length; i++) {
@@ -73,19 +78,19 @@ var PointerWatcher = class {
return;
}
}
}
},
_onIdleMonitorBecameActive(monitor) {
this._idle = false;
this._updatePointer();
this._updateTimeout();
}
},
_onIdleMonitorBecameIdle(monitor) {
this._idle = true;
this._idleMonitor.add_user_active_watch(this._onIdleMonitorBecameActive.bind(this));
this._updateTimeout();
}
},
_updateTimeout() {
if (this._timeoutId) {
@@ -103,12 +108,12 @@ var PointerWatcher = class {
this._timeoutId = Mainloop.timeout_add(minInterval,
this._onTimeout.bind(this));
GLib.Source.set_name_by_id(this._timeoutId, '[gnome-shell] this._onTimeout');
}
},
_onTimeout() {
this._updatePointer();
return GLib.SOURCE_CONTINUE;
}
},
_updatePointer() {
let [x, y, mods] = global.get_pointer();
@@ -125,4 +130,4 @@ var PointerWatcher = class {
i++;
}
}
};
});

View File

@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
@@ -57,8 +58,10 @@ function arrowIcon(side) {
return arrow;
}
var PopupBaseMenuItem = class {
constructor(params) {
var PopupBaseMenuItem = new Lang.Class({
Name: 'PopupBaseMenuItem',
_init(params) {
params = Params.parse (params, { reactive: true,
activate: true,
hover: true,
@@ -100,30 +103,30 @@ var PopupBaseMenuItem = class {
this.actor.connect('key-focus-in', this._onKeyFocusIn.bind(this));
this.actor.connect('key-focus-out', this._onKeyFocusOut.bind(this));
this.actor.connect('destroy', this._onDestroy.bind(this));
}
},
_getTopMenu() {
if (this._parent)
return this._parent._getTopMenu();
else
return this;
}
},
_setParent(parent) {
this._parent = parent;
}
},
_onButtonPressEvent(actor, event) {
// This is the CSS active state
this.actor.add_style_pseudo_class ('active');
return Clutter.EVENT_PROPAGATE;
}
},
_onButtonReleaseEvent(actor, event) {
this.actor.remove_style_pseudo_class ('active');
this.activate(event);
return Clutter.EVENT_STOP;
}
},
_onTouchEvent(actor, event) {
if (event.type() == Clutter.EventType.TOUCH_END) {
@@ -135,7 +138,7 @@ var PopupBaseMenuItem = class {
this.actor.add_style_pseudo_class ('active');
}
return Clutter.EVENT_PROPAGATE;
}
},
_onKeyPressEvent(actor, event) {
let state = event.get_state();
@@ -155,23 +158,23 @@ var PopupBaseMenuItem = class {
return Clutter.EVENT_STOP;
}
return Clutter.EVENT_PROPAGATE;
}
},
_onKeyFocusIn(actor) {
this.setActive(true);
}
},
_onKeyFocusOut(actor) {
this.setActive(false);
}
},
_onHoverChanged(actor) {
this.setActive(actor.hover);
}
},
activate(event) {
this.emit('activate', event);
}
},
setActive(active) {
let activeChanged = active != this.active;
@@ -192,7 +195,7 @@ var PopupBaseMenuItem = class {
}
this.emit('active-changed', active);
}
}
},
syncSensitive() {
let sensitive = this.getSensitive();
@@ -200,12 +203,12 @@ var PopupBaseMenuItem = class {
this.actor.can_focus = sensitive;
this.emit('sensitive-changed');
return sensitive;
}
},
getSensitive() {
let parentSensitive = this._parent ? this._parent.getSensitive() : true;
return this._activatable && this._sensitive && parentSensitive;
}
},
setSensitive(sensitive) {
if (this._sensitive == sensitive)
@@ -213,15 +216,15 @@ var PopupBaseMenuItem = class {
this._sensitive = sensitive;
this.syncSensitive();
}
},
destroy() {
this.actor.destroy();
}
},
_onDestroy() {
this.emit('destroy');
}
},
setOrnament(ornament) {
if (ornament == this._ornament)
@@ -240,23 +243,29 @@ var PopupBaseMenuItem = class {
this.actor.remove_accessible_state(Atk.StateType.CHECKED);
}
}
};
});
Signals.addSignalMethods(PopupBaseMenuItem.prototype);
var PopupMenuItem = class extends PopupBaseMenuItem {
constructor(text, params) {
super(params);
var PopupMenuItem = new Lang.Class({
Name: 'PopupMenuItem',
Extends: PopupBaseMenuItem,
_init(text, params) {
this.parent(params);
this.label = new St.Label({ text: text });
this.actor.add_child(this.label);
this.actor.label_actor = this.label
}
};
});
var PopupSeparatorMenuItem = class extends PopupBaseMenuItem {
constructor(text) {
super({ reactive: false,
can_focus: false});
var PopupSeparatorMenuItem = new Lang.Class({
Name: 'PopupSeparatorMenuItem',
Extends: PopupBaseMenuItem,
_init(text) {
this.parent({ reactive: false,
can_focus: false});
this.label = new St.Label({ text: text || '' });
this.actor.add(this.label);
@@ -270,15 +279,17 @@ var PopupSeparatorMenuItem = class extends PopupBaseMenuItem {
y_expand: true,
y_align: Clutter.ActorAlign.CENTER });
this.actor.add(this._separator, { expand: true });
}
},
_syncVisibility() {
this.label.visible = this.label.text != '';
}
};
});
var Switch = class {
constructor(state) {
var Switch = new Lang.Class({
Name: 'Switch',
_init(state) {
this.actor = new St.Bin({ style_class: 'toggle-switch',
accessible_role: Atk.Role.CHECK_BOX,
can_focus: true });
@@ -289,7 +300,7 @@ var Switch = class {
// simply result in invisible toggle switches.
this.actor.add_style_class_name(_("toggle-switch-us"));
this.setToggleState(state);
}
},
setToggleState(state) {
if (state)
@@ -297,16 +308,19 @@ var Switch = class {
else
this.actor.remove_style_pseudo_class('checked');
this.state = state;
}
},
toggle() {
this.setToggleState(!this.state);
}
};
});
var PopupSwitchMenuItem = class extends PopupBaseMenuItem {
constructor(text, active, params) {
super(params);
var PopupSwitchMenuItem = new Lang.Class({
Name: 'PopupSwitchMenuItem',
Extends: PopupBaseMenuItem,
_init(text, active, params) {
this.parent(params);
this.label = new St.Label({ text: text });
this._switch = new Switch(active);
@@ -324,7 +338,7 @@ var PopupSwitchMenuItem = class extends PopupBaseMenuItem {
style_class: 'popup-status-menu-item'
});
this._statusBin.child = this._switch.actor;
}
},
setStatus(text) {
if (text != null) {
@@ -338,7 +352,7 @@ var PopupSwitchMenuItem = class extends PopupBaseMenuItem {
this.actor.accessible_role = Atk.Role.CHECK_MENU_ITEM;
}
this.checkAccessibleState();
}
},
activate(event) {
if (this._switch.actor.mapped) {
@@ -351,23 +365,23 @@ var PopupSwitchMenuItem = class extends PopupBaseMenuItem {
event.get_key_symbol() == Clutter.KEY_space)
return;
super.activate(event);
}
this.parent(event);
},
toggle() {
this._switch.toggle();
this.emit('toggled', this._switch.state);
this.checkAccessibleState();
}
},
get state() {
return this._switch.state;
}
},
setToggleState(state) {
this._switch.setToggleState(state);
this.checkAccessibleState();
}
},
checkAccessibleState() {
switch (this.actor.accessible_role) {
@@ -381,11 +395,14 @@ var PopupSwitchMenuItem = class extends PopupBaseMenuItem {
this.actor.remove_accessible_state (Atk.StateType.CHECKED);
}
}
};
});
var PopupImageMenuItem = class extends PopupBaseMenuItem {
constructor(text, icon, params) {
super(params);
var PopupImageMenuItem = new Lang.Class({
Name: 'PopupImageMenuItem',
Extends: PopupBaseMenuItem,
_init(text, icon, params) {
this.parent(params);
this._icon = new St.Icon({ style_class: 'popup-menu-icon',
x_align: Clutter.ActorAlign.END });
@@ -395,7 +412,7 @@ var PopupImageMenuItem = class extends PopupBaseMenuItem {
this.actor.label_actor = this.label;
this.setIcon(icon);
}
},
setIcon(icon) {
// The 'icon' parameter can be either a Gio.Icon or a string.
@@ -404,13 +421,13 @@ var PopupImageMenuItem = class extends PopupBaseMenuItem {
else
this._icon.icon_name = icon;
}
};
});
var PopupMenuBase = class {
constructor(sourceActor, styleClass) {
if (new.target === PopupMenuBase)
throw new TypeError('Cannot instantiate abstract class ' + new.target.name);
var PopupMenuBase = new Lang.Class({
Name: 'PopupMenuBase',
Abstract: true,
_init(sourceActor, styleClass) {
this.sourceActor = sourceActor;
this._parent = null;
@@ -434,33 +451,33 @@ var PopupMenuBase = class {
this._sensitive = true;
this._sessionUpdatedId = Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
}
},
_getTopMenu() {
if (this._parent)
return this._parent._getTopMenu();
else
return this;
}
},
_setParent(parent) {
this._parent = parent;
}
},
getSensitive() {
let parentSensitive = this._parent ? this._parent.getSensitive() : true;
return this._sensitive && parentSensitive;
}
},
setSensitive(sensitive) {
this._sensitive = sensitive;
this.emit('sensitive-changed');
}
},
_sessionUpdated() {
this._setSettingsVisibility(Main.sessionMode.allowSettings);
this.close();
}
},
addAction(title, callback, icon) {
let menuItem;
@@ -475,7 +492,7 @@ var PopupMenuBase = class {
});
return menuItem;
}
},
addSettingsAction(title, desktopFile) {
let menuItem = this.addAction(title, () => {
@@ -494,14 +511,14 @@ var PopupMenuBase = class {
this._settingsActions[desktopFile] = menuItem;
return menuItem;
}
},
_setSettingsVisibility(visible) {
for (let id in this._settingsActions) {
let item = this._settingsActions[id];
item.actor.visible = visible;
}
}
},
isEmpty() {
let hasVisibleChildren = this.box.get_children().some(child => {
@@ -511,21 +528,21 @@ var PopupMenuBase = class {
});
return !hasVisibleChildren;
}
},
itemActivated(animate) {
if (animate == undefined)
animate = BoxPointer.PopupAnimation.FULL;
this._getTopMenu().close(animate);
}
},
_subMenuActiveChanged(submenu, submenuItem) {
if (this._activeMenuItem && this._activeMenuItem != submenuItem)
this._activeMenuItem.setActive(false);
this._activeMenuItem = submenuItem;
this.emit('active-changed', submenuItem);
}
},
_connectItemSignals(menuItem) {
menuItem._activeChangeId = menuItem.connect('active-changed', (menuItem, active) => {
@@ -573,7 +590,7 @@ var PopupMenuBase = class {
if (menuItem == this._activeMenuItem)
this._activeMenuItem = null;
});
}
},
_updateSeparatorVisibility(menuItem) {
if (menuItem.label.text)
@@ -609,7 +626,7 @@ var PopupMenuBase = class {
}
menuItem.actor.show();
}
},
moveMenuItem(menuItem, position) {
let items = this._getMenuItems();
@@ -627,7 +644,7 @@ var PopupMenuBase = class {
} else {
this.box.set_child_above_sibling(menuItem.actor, null);
}
}
},
addMenuItem(menuItem, position) {
let before_item = null;
@@ -704,13 +721,13 @@ var PopupMenuBase = class {
menuItem._setParent(this);
this.length++;
}
},
_getMenuItems() {
return this.box.get_children().map(a => a._delegate).filter(item => {
return item instanceof PopupBaseMenuItem || item instanceof PopupMenuSection;
});
}
},
get firstMenuItem() {
let items = this._getMenuItems();
@@ -718,11 +735,11 @@ var PopupMenuBase = class {
return items[0];
else
return null;
}
},
get numMenuItems() {
return this._getMenuItems().length;
}
},
removeAll() {
let children = this._getMenuItems();
@@ -730,14 +747,14 @@ var PopupMenuBase = class {
let item = children[i];
item.destroy();
}
}
},
toggle() {
if (this.isOpen)
this.close(BoxPointer.PopupAnimation.FULL);
else
this.open(BoxPointer.PopupAnimation.FULL);
}
},
destroy() {
this.close();
@@ -749,12 +766,15 @@ var PopupMenuBase = class {
Main.sessionMode.disconnect(this._sessionUpdatedId);
this._sessionUpdatedId = 0;
}
};
});
Signals.addSignalMethods(PopupMenuBase.prototype);
var PopupMenu = class extends PopupMenuBase {
constructor(sourceActor, arrowAlignment, arrowSide) {
super(sourceActor, 'popup-menu-content');
var PopupMenu = new Lang.Class({
Name: 'PopupMenu',
Extends: PopupMenuBase,
_init(sourceActor, arrowAlignment, arrowSide) {
this.parent(sourceActor, 'popup-menu-content');
this._arrowAlignment = arrowAlignment;
this._arrowSide = arrowSide;
@@ -778,14 +798,14 @@ var PopupMenu = class extends PopupMenuBase {
this._onKeyPress.bind(this));
this._openedSubMenu = null;
}
},
_setOpenedSubMenu(submenu) {
if (this._openedSubMenu)
this._openedSubMenu.close(true);
this._openedSubMenu = submenu;
}
},
_onKeyPress(actor, event) {
// Disable toggling the menu by keyboard
@@ -833,15 +853,16 @@ var PopupMenu = class extends PopupMenuBase {
return Clutter.EVENT_STOP;
} else
return Clutter.EVENT_PROPAGATE;
}
},
setArrowOrigin(origin) {
this._boxPointer.setArrowOrigin(origin);
}
},
setSourceAlignment(alignment) {
this._boxPointer.setSourceAlignment(alignment);
}
},
open(animate) {
if (this.isOpen)
@@ -858,7 +879,7 @@ var PopupMenu = class extends PopupMenuBase {
this.actor.raise_top();
this.emit('open-state-changed', true);
}
},
close(animate) {
if (this._activeMenuItem)
@@ -875,38 +896,43 @@ var PopupMenu = class extends PopupMenuBase {
this.isOpen = false;
this.emit('open-state-changed', false);
}
},
destroy() {
if (this._keyPressId)
this.sourceActor.disconnect(this._keyPressId);
super.destroy();
this.parent();
}
};
});
var PopupDummyMenu = class {
constructor(sourceActor) {
var PopupDummyMenu = new Lang.Class({
Name: 'PopupDummyMenu',
_init(sourceActor) {
this.sourceActor = sourceActor;
this.actor = sourceActor;
this.actor._delegate = this;
}
},
getSensitive() {
return true;
}
},
open() { this.emit('open-state-changed', true); }
close() { this.emit('open-state-changed', false); }
toggle() {}
open() { this.emit('open-state-changed', true); },
close() { this.emit('open-state-changed', false); },
toggle() {},
destroy() {
this.emit('destroy');
}
};
},
});
Signals.addSignalMethods(PopupDummyMenu.prototype);
var PopupSubMenu = class extends PopupMenuBase {
constructor(sourceActor, sourceArrow) {
super(sourceActor);
var PopupSubMenu = new Lang.Class({
Name: 'PopupSubMenu',
Extends: PopupMenuBase,
_init(sourceActor, sourceArrow) {
this.parent(sourceActor);
this._arrow = sourceArrow;
@@ -922,7 +948,7 @@ var PopupSubMenu = class extends PopupMenuBase {
this.actor.clip_to_allocation = true;
this.actor.connect('key-press-event', this._onKeyPressEvent.bind(this));
this.actor.hide();
}
},
_needsScrollbar() {
let topMenu = this._getTopMenu();
@@ -931,11 +957,11 @@ var PopupSubMenu = class extends PopupMenuBase {
let topMaxHeight = topThemeNode.get_max_height();
return topMaxHeight >= 0 && topNaturalHeight >= topMaxHeight;
}
},
getSensitive() {
return this._sensitive && this.sourceActor._delegate.getSensitive();
}
},
open(animate) {
if (this.isOpen)
@@ -991,7 +1017,7 @@ var PopupSubMenu = class extends PopupMenuBase {
} else {
this._arrow.rotation_angle_z = targetAngle;
}
}
},
close(animate) {
if (!this.isOpen)
@@ -1026,7 +1052,7 @@ var PopupSubMenu = class extends PopupMenuBase {
this._arrow.rotation_angle_z = 0;
this.actor.hide();
}
}
},
_onKeyPressEvent(actor, event) {
// Move focus back to parent menu if the user types Left.
@@ -1039,7 +1065,7 @@ var PopupSubMenu = class extends PopupMenuBase {
return Clutter.EVENT_PROPAGATE;
}
};
});
/**
* PopupMenuSection:
@@ -1049,24 +1075,30 @@ var PopupSubMenu = class extends PopupMenuBase {
* can add it to another menu), but is completely transparent
* to the user
*/
var PopupMenuSection = class extends PopupMenuBase {
constructor() {
super();
var PopupMenuSection = new Lang.Class({
Name: 'PopupMenuSection',
Extends: PopupMenuBase,
_init() {
this.parent();
this.actor = this.box;
this.actor._delegate = this;
this.isOpen = true;
}
},
// deliberately ignore any attempt to open() or close(), but emit the
// corresponding signal so children can still pick it up
open() { this.emit('open-state-changed', true); }
close() { this.emit('open-state-changed', false); }
};
open() { this.emit('open-state-changed', true); },
close() { this.emit('open-state-changed', false); },
});
var PopupSubMenuMenuItem = class extends PopupBaseMenuItem {
constructor(text, wantIcon) {
super();
var PopupSubMenuMenuItem = new Lang.Class({
Name: 'PopupSubMenuMenuItem',
Extends: PopupBaseMenuItem,
_init(text, wantIcon) {
this.parent();
this.actor.add_style_class_name('popup-submenu-menu-item');
@@ -1096,19 +1128,19 @@ var PopupSubMenuMenuItem = class extends PopupBaseMenuItem {
this.menu = new PopupSubMenu(this.actor, this._triangle);
this.menu.connect('open-state-changed', this._subMenuOpenStateChanged.bind(this));
}
},
_setParent(parent) {
super._setParent(parent);
this.parent(parent);
this.menu._setParent(parent);
}
},
syncSensitive() {
let sensitive = super.syncSensitive();
let sensitive = this.parent();
this._triangle.visible = sensitive;
if (!sensitive)
this.menu.close(false);
}
},
_subMenuOpenStateChanged(menu, open) {
if (open) {
@@ -1122,28 +1154,28 @@ var PopupSubMenuMenuItem = class extends PopupBaseMenuItem {
this.actor.remove_accessible_state (Atk.StateType.EXPANDED);
this.actor.remove_style_pseudo_class('checked');
}
}
},
destroy() {
this.menu.destroy();
super.destroy();
}
this.parent();
},
setSubmenuShown(open) {
if (open)
this.menu.open(BoxPointer.PopupAnimation.FULL);
else
this.menu.close(BoxPointer.PopupAnimation.FULL);
}
},
_setOpenState(open) {
this.setSubmenuShown(open);
}
},
_getOpenState() {
return this.menu.isOpen;
}
},
_onKeyPressEvent(actor, event) {
let symbol = event.get_key_symbol();
@@ -1157,12 +1189,12 @@ var PopupSubMenuMenuItem = class extends PopupBaseMenuItem {
return Clutter.EVENT_STOP;
}
return super._onKeyPressEvent(actor, event);
}
return this.parent(actor, event);
},
activate(event) {
this._setOpenState(true);
}
},
_onButtonReleaseEvent(actor) {
// Since we override the parent, we need to manage what the parent does
@@ -1170,7 +1202,7 @@ var PopupSubMenuMenuItem = class extends PopupBaseMenuItem {
this.actor.remove_style_pseudo_class ('active');
this._setOpenState(!this._getOpenState());
return Clutter.EVENT_PROPAGATE;
}
},
_onTouchEvent(actor, event) {
if (event.type() == Clutter.EventType.TOUCH_END) {
@@ -1181,19 +1213,21 @@ var PopupSubMenuMenuItem = class extends PopupBaseMenuItem {
}
return Clutter.EVENT_PROPAGATE;
}
};
});
/* Basic implementation of a menu manager.
* Call addMenu to add menus
*/
var PopupMenuManager = class {
constructor(owner, grabParams) {
var PopupMenuManager = new Lang.Class({
Name: 'PopupMenuManager',
_init(owner, grabParams) {
grabParams = Params.parse(grabParams,
{ actionMode: Shell.ActionMode.POPUP });
this._owner = owner;
this._grabHelper = new GrabHelper.GrabHelper(owner.actor, grabParams);
this._menus = [];
}
},
addMenu(menu, position) {
if (this._findMenu(menu) > -1)
@@ -1222,7 +1256,7 @@ var PopupMenuManager = class {
this._menus.push(menudata);
else
this._menus.splice(position, 0, menudata);
}
},
removeMenu(menu) {
if (menu == this.activeMenu)
@@ -1244,7 +1278,7 @@ var PopupMenuManager = class {
if (menu.sourceActor)
this._grabHelper.removeActor(menu.sourceActor);
this._menus.splice(position, 1);
}
},
get activeMenu() {
let firstGrab = this._grabHelper.grabStack[0];
@@ -1252,11 +1286,11 @@ var PopupMenuManager = class {
return firstGrab.actor._delegate;
else
return null;
}
},
ignoreRelease() {
return this._grabHelper.ignoreRelease();
}
},
_onMenuOpenState(menu, open) {
if (open) {
@@ -1269,12 +1303,12 @@ var PopupMenuManager = class {
} else {
this._grabHelper.ungrab({ actor: menu.actor });
}
}
},
_changeMenu(newMenu) {
newMenu.open(this.activeMenu ? BoxPointer.PopupAnimation.FADE
: BoxPointer.PopupAnimation.FULL);
}
},
_onMenuSourceEnter(menu) {
if (!this._grabHelper.grabbed)
@@ -1285,11 +1319,11 @@ var PopupMenuManager = class {
this._changeMenu(menu);
return Clutter.EVENT_PROPAGATE;
}
},
_onMenuDestroy(menu) {
this.removeMenu(menu);
}
},
_findMenu(item) {
for (let i = 0; i < this._menus.length; i++) {
@@ -1298,7 +1332,7 @@ var PopupMenuManager = class {
return i;
}
return -1;
}
},
_closeMenu(isUser, menu) {
// If this isn't a user action, we called close()
@@ -1307,4 +1341,4 @@ var PopupMenuManager = class {
if (isUser)
menu.close(BoxPointer.PopupAnimation.FULL);
}
};
});

213
js/ui/remoteMenu.js Normal file
View File

@@ -0,0 +1,213 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Atk = imports.gi.Atk;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const ShellMenu = imports.gi.ShellMenu;
const St = imports.gi.St;
const PopupMenu = imports.ui.popupMenu;
function stripMnemonics(label) {
if (!label)
return '';
// remove all underscores that are not followed by another underscore
return label.replace(/_([^_])/, '$1');
}
function _insertItem(menu, trackerItem, position) {
let mapper;
if (trackerItem.get_is_separator())
mapper = new RemoteMenuSeparatorItemMapper(trackerItem);
else if (trackerItem.get_has_submenu())
mapper = new RemoteMenuSubmenuItemMapper(trackerItem);
else
mapper = new RemoteMenuItemMapper(trackerItem);
let item = mapper.menuItem;
menu.addMenuItem(item, position);
}
function _removeItem(menu, position) {
let items = menu._getMenuItems();
items[position].destroy();
}
var RemoteMenuSeparatorItemMapper = new Lang.Class({
Name: 'RemoteMenuSeparatorItemMapper',
_init(trackerItem) {
this._trackerItem = trackerItem;
this.menuItem = new PopupMenu.PopupSeparatorMenuItem();
this._trackerItem.connect('notify::label', this._updateLabel.bind(this));
this._updateLabel();
this.menuItem.connect('destroy', () => {
trackerItem.run_dispose();
});
},
_updateLabel() {
this.menuItem.label.text = stripMnemonics(this._trackerItem.label);
},
});
var RequestSubMenu = new Lang.Class({
Name: 'RequestSubMenu',
Extends: PopupMenu.PopupSubMenuMenuItem,
_init() {
this.parent('');
this._requestOpen = false;
},
_setOpenState(open) {
this.emit('request-open', open);
this._requestOpen = open;
},
_getOpenState() {
return this._requestOpen;
},
});
var RemoteMenuSubmenuItemMapper = new Lang.Class({
Name: 'RemoteMenuSubmenuItemMapper',
_init(trackerItem) {
this._trackerItem = trackerItem;
this.menuItem = new RequestSubMenu();
this._trackerItem.connect('notify::label', this._updateLabel.bind(this));
this._updateLabel();
this._tracker = Shell.MenuTracker.new_for_item_submenu(this._trackerItem,
_insertItem.bind(null, this.menuItem.menu),
_removeItem.bind(null, this.menuItem.menu));
this.menuItem.connect('request-open', (menu, open) => {
this._trackerItem.request_submenu_shown(open);
});
this._trackerItem.connect('notify::submenu-shown', () => {
this.menuItem.setSubmenuShown(this._trackerItem.get_submenu_shown());
});
this.menuItem.connect('destroy', () => {
trackerItem.run_dispose();
});
},
destroy() {
this._tracker.destroy();
this.parent();
},
_updateLabel() {
this.menuItem.label.text = stripMnemonics(this._trackerItem.label);
},
});
var RemoteMenuItemMapper = new Lang.Class({
Name: 'RemoteMenuItemMapper',
_init(trackerItem) {
this._trackerItem = trackerItem;
this.menuItem = new PopupMenu.PopupBaseMenuItem();
this._icon = new St.Icon({ style_class: 'popup-menu-icon' });
this.menuItem.actor.add_child(this._icon);
this._label = new St.Label();
this.menuItem.actor.add_child(this._label);
this.menuItem.actor.label_actor = this._label;
this.menuItem.connect('activate', () => {
this._trackerItem.activated();
});
this._trackerItem.bind_property('visible', this.menuItem.actor, 'visible', GObject.BindingFlags.SYNC_CREATE);
this._trackerItem.connect('notify::icon', this._updateIcon.bind(this));
this._trackerItem.connect('notify::label', this._updateLabel.bind(this));
this._trackerItem.connect('notify::sensitive', this._updateSensitivity.bind(this));
this._trackerItem.connect('notify::role', this._updateRole.bind(this));
this._trackerItem.connect('notify::toggled', this._updateDecoration.bind(this));
this._updateIcon();
this._updateLabel();
this._updateSensitivity();
this._updateRole();
this.menuItem.connect('destroy', () => {
trackerItem.run_dispose();
});
},
_updateIcon() {
this._icon.gicon = this._trackerItem.icon;
this._icon.visible = (this._icon.gicon != null);
},
_updateLabel() {
this._label.text = stripMnemonics(this._trackerItem.label);
},
_updateSensitivity() {
this.menuItem.setSensitive(this._trackerItem.sensitive);
},
_updateDecoration() {
let ornamentForRole = {};
ornamentForRole[ShellMenu.MenuTrackerItemRole.RADIO] = PopupMenu.Ornament.DOT;
ornamentForRole[ShellMenu.MenuTrackerItemRole.CHECK] = PopupMenu.Ornament.CHECK;
let ornament = PopupMenu.Ornament.NONE;
if (this._trackerItem.toggled)
ornament = ornamentForRole[this._trackerItem.role];
this.menuItem.setOrnament(ornament);
},
_updateRole() {
let a11yRoles = {};
a11yRoles[ShellMenu.MenuTrackerItemRole.NORMAL] = Atk.Role.MENU_ITEM;
a11yRoles[ShellMenu.MenuTrackerItemRole.RADIO] = Atk.Role.RADIO_MENU_ITEM;
a11yRoles[ShellMenu.MenuTrackerItemRole.CHECK] = Atk.Role.CHECK_MENU_ITEM;
let a11yRole = a11yRoles[this._trackerItem.role];
this.menuItem.actor.accessible_role = a11yRole;
this._updateDecoration();
},
});
var RemoteMenu = new Lang.Class({
Name: 'RemoteMenu',
Extends: PopupMenu.PopupMenu,
_init(sourceActor, model, actionGroup) {
this.parent(sourceActor, 0.0, St.Side.TOP);
this._model = model;
this._actionGroup = actionGroup;
this._tracker = Shell.MenuTracker.new(this._actionGroup,
this._model,
null, /* action namespace */
_insertItem.bind(null, this),
_removeItem.bind(null, this));
},
get actionGroup() {
return this._actionGroup;
},
destroy() {
this._tracker.destroy();
this.parent();
},
});

View File

@@ -3,6 +3,7 @@
const GdkPixbuf = imports.gi.GdkPixbuf;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
@@ -189,8 +190,10 @@ function loadRemoteSearchProviders(searchSettings, callback) {
callback(loadedProviders);
}
var RemoteSearchProvider = class {
constructor(appInfo, dbusName, dbusPath, autoStart, proxyInfo) {
var RemoteSearchProvider = new Lang.Class({
Name: 'RemoteSearchProvider',
_init(appInfo, dbusName, dbusPath, autoStart, proxyInfo) {
if (!proxyInfo)
proxyInfo = SearchProviderProxyInfo;
@@ -212,7 +215,7 @@ var RemoteSearchProvider = class {
this.id = appInfo.get_id();
this.isRemoteProvider = true;
this.canLaunchSearch = false;
}
},
createIcon(size, meta) {
let gicon = null;
@@ -233,7 +236,7 @@ var RemoteSearchProvider = class {
icon = new St.Icon({ gicon: gicon,
icon_size: size });
return icon;
}
},
filterResults(results, maxNumber) {
if (results.length <= maxNumber)
@@ -243,7 +246,7 @@ var RemoteSearchProvider = class {
let specialResults = results.filter(r => r.startsWith('special:'));
return regularResults.slice(0, maxNumber).concat(specialResults.slice(0, maxNumber));
}
},
_getResultsFinished(results, error, callback) {
if (error) {
@@ -256,7 +259,7 @@ var RemoteSearchProvider = class {
}
callback(results[0]);
}
},
getInitialResultSet(terms, callback, cancellable) {
this.proxy.GetInitialResultSetRemote(terms,
@@ -264,7 +267,7 @@ var RemoteSearchProvider = class {
this._getResultsFinished(results, error, callback);
},
cancellable);
}
},
getSubsearchResultSet(previousResults, newTerms, callback, cancellable) {
this.proxy.GetSubsearchResultSetRemote(previousResults, newTerms,
@@ -272,7 +275,7 @@ var RemoteSearchProvider = class {
this._getResultsFinished(results, error, callback);
},
cancellable);
}
},
_getResultMetasFinished(results, error, callback) {
if (error) {
@@ -299,7 +302,7 @@ var RemoteSearchProvider = class {
clipboardText: metas[i]['clipboardText'] });
}
callback(resultMetas);
}
},
getResultMetas(ids, callback, cancellable) {
this.proxy.GetResultMetasRemote(ids,
@@ -307,11 +310,11 @@ var RemoteSearchProvider = class {
this._getResultMetasFinished(results, error, callback);
},
cancellable);
}
},
activateResult(id) {
this.proxy.ActivateResultRemote(id);
}
},
launchSearch(terms) {
// the provider is not compatible with the new version of the interface, launch
@@ -319,20 +322,23 @@ var RemoteSearchProvider = class {
log('Search provider ' + this.appInfo.get_id() + ' does not implement LaunchSearch');
this.appInfo.launch([], global.create_app_launch_context(0, -1));
}
};
});
var RemoteSearchProvider2 = class extends RemoteSearchProvider {
constructor(appInfo, dbusName, dbusPath, autoStart) {
super(appInfo, dbusName, dbusPath, autoStart, SearchProvider2ProxyInfo);
var RemoteSearchProvider2 = new Lang.Class({
Name: 'RemoteSearchProvider2',
Extends: RemoteSearchProvider,
_init(appInfo, dbusName, dbusPath, autoStart) {
this.parent(appInfo, dbusName, dbusPath, autoStart, SearchProvider2ProxyInfo);
this.canLaunchSearch = true;
}
},
activateResult(id, terms) {
this.proxy.ActivateResultRemote(id, terms, global.get_current_time());
}
},
launchSearch(terms) {
this.proxy.LaunchSearchRemote(terms, global.get_current_time());
}
};
});

View File

@@ -3,6 +3,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
@@ -29,10 +30,13 @@ const EXEC_ARG_KEY = 'exec-arg';
var DIALOG_GROW_TIME = 0.1;
var RunDialog = class extends ModalDialog.ModalDialog {
constructor() {
super({ styleClass: 'run-dialog',
destroyOnClose: false });
var RunDialog = new Lang.Class({
Name: 'RunDialog',
Extends: ModalDialog.ModalDialog,
_init() {
this.parent({ styleClass: 'run-dialog',
destroyOnClose: false });
this._lockdownSettings = new Gio.Settings({ schema_id: LOCKDOWN_SCHEMA });
this._terminalSettings = new Gio.Settings({ schema_id: TERMINAL_SCHEMA });
@@ -140,7 +144,7 @@ var RunDialog = class extends ModalDialog.ModalDialog {
}
return Clutter.EVENT_PROPAGATE;
});
}
},
_getCommandCompletion(text) {
function _getCommon(s1, s2) {
@@ -185,7 +189,7 @@ var RunDialog = class extends ModalDialog.ModalDialog {
let common = results.reduce(_getCommon, null);
return common.substr(text.length);
}
},
_getCompletion(text) {
if (text.indexOf('/') != -1) {
@@ -193,7 +197,7 @@ var RunDialog = class extends ModalDialog.ModalDialog {
} else {
return this._getCommandCompletion(text);
}
}
},
_run(input, inTerminal) {
let command = input;
@@ -244,7 +248,7 @@ var RunDialog = class extends ModalDialog.ModalDialog {
}
}
}
}
},
_showError(message) {
this._commandError = true;
@@ -265,7 +269,7 @@ var RunDialog = class extends ModalDialog.ModalDialog {
}
});
}
}
},
_restart() {
if (Meta.is_wayland_compositor()) {
@@ -275,7 +279,7 @@ var RunDialog = class extends ModalDialog.ModalDialog {
this._shouldFadeOut = false;
this.close();
Meta.restart(_("Restarting…"));
}
},
open() {
this._history.lastItem();
@@ -286,7 +290,7 @@ var RunDialog = class extends ModalDialog.ModalDialog {
if (this._lockdownSettings.get_boolean(DISABLE_COMMAND_LINE_KEY))
return;
super.open();
}
};
this.parent();
},
});
Signals.addSignalMethods(RunDialog.prototype);

View File

@@ -6,8 +6,8 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GnomeDesktop = imports.gi.GnomeDesktop;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
@@ -60,8 +60,10 @@ var MANUAL_FADE_TIME = 0.3;
var BACKGROUND_FADE_TIME = 1.0;
var CURTAIN_SLIDE_TIME = 0.3;
var Clock = class {
constructor() {
var Clock = new Lang.Class({
Name: 'ScreenShieldClock',
_init() {
this.actor = new St.BoxLayout({ style_class: 'screen-shield-clock',
vertical: true });
@@ -75,7 +77,7 @@ var Clock = class {
this._wallClock.connect('notify::clock', this._updateClock.bind(this));
this._updateClock();
}
},
_updateClock() {
this._time.text = this._wallClock.clock;
@@ -85,16 +87,18 @@ var Clock = class {
long format */
let dateFormat = Shell.util_translate_time_string(N_("%A, %B %d"));
this._date.text = date.toLocaleFormat(dateFormat);
}
},
destroy() {
this.actor.destroy();
this._wallClock.run_dispose();
}
};
});
var NotificationsBox = class {
constructor() {
var NotificationsBox = new Lang.Class({
Name: 'NotificationsBox',
_init() {
this.actor = new St.BoxLayout({ vertical: true,
name: 'screenShieldNotifications',
style_class: 'screen-shield-notifications-container' });
@@ -114,7 +118,7 @@ var NotificationsBox = class {
this._updateVisibility();
this._sourceAddedId = Main.messageTray.connect('source-added', this._sourceAdded.bind(this));
}
},
destroy() {
if (this._sourceAddedId) {
@@ -128,21 +132,21 @@ var NotificationsBox = class {
}
this.actor.destroy();
}
},
_updateVisibility() {
this._notificationBox.visible =
this._notificationBox.get_children().some(a => a.visible);
this.actor.visible = this._notificationBox.visible;
}
},
_makeNotificationCountText(count, isChat) {
if (isChat)
return ngettext("%d new message", "%d new messages", count).format(count);
else
return ngettext("%d new notification", "%d new notifications", count).format(count);
}
},
_makeNotificationSource(source, box) {
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
@@ -162,7 +166,7 @@ var NotificationsBox = class {
box.visible = count != 0;
return [title, countLabel];
}
},
_makeNotificationDetailedSource(source, box) {
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
@@ -200,7 +204,7 @@ var NotificationsBox = class {
box.visible = visible;
return [title, null];
}
},
_showSource(source, obj, box) {
if (obj.detailed) {
@@ -210,7 +214,7 @@ var NotificationsBox = class {
}
box.visible = obj.visible && (source.unseenCount > 0);
}
},
_sourceAdded(tray, source, initial) {
let obj = {
@@ -272,11 +276,11 @@ var NotificationsBox = class {
if (obj.sourceBox.visible)
this.emit('wake-up-screen');
}
}
},
_titleChanged(source, obj) {
obj.titleLabel.text = source.title;
}
},
_countChanged(source, obj) {
if (obj.detailed) {
@@ -296,7 +300,7 @@ var NotificationsBox = class {
this._updateVisibility();
if (obj.sourceBox.visible)
this.emit('wake-up-screen');
}
},
_visibleChanged(source, obj) {
if (obj.visible == source.policy.showInLockScreen)
@@ -308,7 +312,7 @@ var NotificationsBox = class {
this._updateVisibility();
if (obj.sourceBox.visible)
this.emit('wake-up-screen');
}
},
_detailedChanged(source, obj) {
if (obj.detailed == source.policy.detailsInLockScreen)
@@ -319,12 +323,12 @@ var NotificationsBox = class {
obj.sourceBox.destroy_all_children();
obj.titleLabel = obj.countLabel = null;
this._showSource(source, obj, obj.sourceBox);
}
},
_onSourceDestroy(source, obj) {
this._removeSource(source, obj);
this._updateVisibility();
}
},
_removeSource(source, obj) {
obj.sourceBox.destroy();
@@ -336,14 +340,16 @@ var NotificationsBox = class {
source.policy.disconnect(obj.policyChangedId);
this._sources.delete(source);
}
};
},
});
Signals.addSignalMethods(NotificationsBox.prototype);
var Arrow = GObject.registerClass(
class ScreenShieldArrow extends St.Bin {
var Arrow = new Lang.Class({
Name: 'Arrow',
Extends: St.Bin,
_init(params) {
super._init(params);
this.parent(params);
this.x_fill = this.y_fill = true;
this._drawingArea = new St.DrawingArea();
@@ -352,7 +358,7 @@ class ScreenShieldArrow extends St.Bin {
this._shadowHelper = null;
this._shadowWidth = this._shadowHeight = 0;
}
},
_drawArrow(arrow) {
let cr = arrow.get_context();
@@ -370,10 +376,10 @@ class ScreenShieldArrow extends St.Bin {
cr.lineTo(w - thickness / 2, h - thickness / 2);
cr.stroke();
cr.$dispose();
}
},
vfunc_get_paint_volume(volume) {
if (!super.vfunc_get_paint_volume(volume))
if (!this.parent(volume))
return false;
if (!this._shadow)
@@ -386,7 +392,7 @@ class ScreenShieldArrow extends St.Bin {
volume.set_height(Math.max(shadow_box.y2 - shadow_box.y1, volume.get_height()));
return true;
}
},
vfunc_style_changed() {
let node = this.get_theme_node();
@@ -396,8 +402,8 @@ class ScreenShieldArrow extends St.Bin {
else
this._shadowHelper = null;
super.vfunc_style_changed();
}
this.parent();
},
vfunc_paint() {
if (this._shadowHelper) {
@@ -424,8 +430,10 @@ function clamp(value, min, max) {
* This will ensure that the screen blanks at the right time when it fades out.
* https://bugzilla.gnome.org/show_bug.cgi?id=668703 explains the dependency.
*/
var ScreenShield = class {
constructor() {
var ScreenShield = new Lang.Class({
Name: 'ScreenShield',
_init() {
this.actor = Main.layoutManager.screenShieldGroup;
this._lockScreenState = MessageTray.State.HIDDEN;
@@ -565,7 +573,7 @@ var ScreenShield = class {
this._cursorTracker = Meta.CursorTracker.get_for_display(global.display);
this._syncInhibitor();
}
},
_setActive(active) {
let prevIsActive = this._isActive;
@@ -578,7 +586,7 @@ var ScreenShield = class {
this._loginSession.SetLockedHintRemote(active);
this._syncInhibitor();
}
},
_createBackground(monitorIndex) {
let monitor = Main.layoutManager.monitors[monitorIndex];
@@ -596,7 +604,7 @@ var ScreenShield = class {
this._bgManagers.push(bgManager);
this._backgroundGroup.add_child(widget);
}
},
_updateBackgrounds() {
for (let i = 0; i < this._bgManagers.length; i++)
@@ -607,7 +615,7 @@ var ScreenShield = class {
for (let i = 0; i < Main.layoutManager.monitors.length; i++)
this._createBackground(i);
}
},
_liftShield(onPrimary, velocity) {
if (this._isLocked) {
@@ -616,7 +624,7 @@ var ScreenShield = class {
} else {
this.deactivate(true /* animate */);
}
}
},
_maybeCancelDialog() {
if (!this._dialog)
@@ -631,7 +639,7 @@ var ScreenShield = class {
} else {
this._dialog = null;
}
}
},
_becomeModal() {
if (this._isModal)
@@ -646,7 +654,7 @@ var ScreenShield = class {
this._isModal = Main.pushModal(this.actor, { options: Meta.ModalOptions.POINTER_ALREADY_GRABBED,
actionMode: Shell.ActionMode.LOCK_SCREEN });
return this._isModal;
}
},
_onLockScreenKeyPress(actor, event) {
let symbol = event.get_key_symbol();
@@ -676,7 +684,7 @@ var ScreenShield = class {
this._liftShield(true, 0);
return Clutter.EVENT_STOP;
}
},
_onLockScreenScroll(actor, event) {
if (this._lockScreenState != MessageTray.State.SHOWN)
@@ -696,7 +704,7 @@ var ScreenShield = class {
}
return Clutter.EVENT_STOP;
}
},
_syncInhibitor() {
let lockEnabled = this._settings.get_boolean(LOCK_ENABLED_KEY);
@@ -715,7 +723,7 @@ var ScreenShield = class {
this._inhibitor.close(null);
this._inhibitor = null;
}
}
},
_prepareForSleep(loginManager, aboutToSuspend) {
if (aboutToSuspend) {
@@ -724,7 +732,7 @@ var ScreenShield = class {
} else {
this._wakeUpScreen();
}
}
},
_animateArrows() {
let arrows = this._arrowContainer.get_children();
@@ -746,7 +754,7 @@ var ScreenShield = class {
}
return GLib.SOURCE_CONTINUE;
}
},
_onDragBegin() {
Tweener.removeTweens(this._lockScreenGroup);
@@ -756,7 +764,7 @@ var ScreenShield = class {
this._ensureUnlockDialog(false, false);
return true;
}
},
_onDragMotion() {
let [origX, origY] = this._dragAction.get_press_coords(0);
@@ -768,7 +776,7 @@ var ScreenShield = class {
this._lockScreenGroup.y = newY;
return true;
}
},
_onDragEnd(action, actor, eventX, eventY, modifiers) {
if (this._lockScreenState != MessageTray.State.HIDING)
@@ -796,7 +804,7 @@ var ScreenShield = class {
this._maybeCancelDialog();
}
}
},
_onStatusChanged(status) {
if (status != GnomeSession.PresenceStatus.IDLE)
@@ -847,7 +855,7 @@ var ScreenShield = class {
}
this._activateFade(this._longLightbox, STANDARD_FADE_TIME);
}
},
_activateFade(lightbox, time) {
Main.uiGroup.set_child_above_sibling(lightbox.actor, null);
@@ -855,7 +863,7 @@ var ScreenShield = class {
if (this._becameActiveId == 0)
this._becameActiveId = this.idleMonitor.add_user_active_watch(this._onUserBecameActive.bind(this));
}
},
_onUserBecameActive() {
// This function gets called here when the user becomes active
@@ -885,15 +893,15 @@ var ScreenShield = class {
} else {
this.deactivate(false);
}
}
},
_onLongLightboxShown() {
this.activate(false);
}
},
_onShortLightboxShown() {
this._completeLockScreenShown();
}
},
showDialog() {
if (!this._becomeModal()) {
@@ -907,7 +915,7 @@ var ScreenShield = class {
this._isLocked = true;
if (this._ensureUnlockDialog(true, true))
this._hideLockScreen(false, 0);
}
},
_hideLockScreenComplete() {
if (Main.sessionMode.currentMode == 'lock-screen')
@@ -920,7 +928,7 @@ var ScreenShield = class {
this._dialog.actor.grab_key_focus();
this._dialog.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
}
}
},
_hideLockScreen(animate, velocity) {
if (this._lockScreenState == MessageTray.State.HIDDEN)
@@ -953,7 +961,7 @@ var ScreenShield = class {
}
this._cursorTracker.set_pointer_visible(true);
}
},
_ensureUnlockDialog(onPrimary, allowCancel) {
if (!this._dialog) {
@@ -981,12 +989,12 @@ var ScreenShield = class {
this._dialog.allowCancel = allowCancel;
return true;
}
},
_onUnlockFailed() {
this._resetLockScreen({ animateLockScreen: true,
fadeToBlack: false });
}
},
_resetLockScreen(params) {
// Don't reset the lock screen unless it is completely hidden
@@ -1028,7 +1036,7 @@ var ScreenShield = class {
if (Main.sessionMode.currentMode != 'lock-screen')
Main.sessionMode.pushMode('lock-screen');
}
},
_startArrowAnimation() {
this._arrowActiveWatchId = 0;
@@ -1042,7 +1050,7 @@ var ScreenShield = class {
if (!this._arrowWatchId)
this._arrowWatchId = this.idleMonitor.add_idle_watch(ARROW_IDLE_TIME,
this._pauseArrowAnimation.bind(this));
}
},
_pauseArrowAnimation() {
if (this._arrowAnimationId) {
@@ -1052,7 +1060,7 @@ var ScreenShield = class {
if (!this._arrowActiveWatchId)
this._arrowActiveWatchId = this.idleMonitor.add_user_active_watch(this._startArrowAnimation.bind(this));
}
},
_stopArrowAnimation() {
if (this._arrowAnimationId) {
@@ -1067,7 +1075,7 @@ var ScreenShield = class {
this.idleMonitor.remove_watch(this._arrowWatchId);
this._arrowWatchId = 0;
}
}
},
_checkArrowAnimation() {
let idleTime = this.idleMonitor.get_idletime();
@@ -1076,7 +1084,7 @@ var ScreenShield = class {
this._startArrowAnimation();
else
this._pauseArrowAnimation();
}
},
_lockScreenShown(params) {
if (this._dialog && !this._isGreeter) {
@@ -1114,12 +1122,12 @@ var ScreenShield = class {
this._completeLockScreenShown();
}
}
},
_completeLockScreenShown() {
this._setActive(true);
this.emit('lock-screen-shown');
}
},
// Some of the actors in the lock screen are heavy in
// resources, so we only create them when needed
@@ -1146,12 +1154,12 @@ var ScreenShield = class {
expand: true });
this._hasLockScreen = true;
}
},
_wakeUpScreen() {
this._onUserBecameActive();
this.emit('wake-up-screen');
}
},
_clearLockScreen() {
this._clock.destroy();
@@ -1168,26 +1176,26 @@ var ScreenShield = class {
this._lockScreenContentsBox.destroy();
this._hasLockScreen = false;
}
},
get locked() {
return this._isLocked;
}
},
get active() {
return this._isActive;
}
},
get activationTime() {
return this._activationTime;
}
},
deactivate(animate) {
if (this._dialog)
this._dialog.finish(() => { this._continueDeactivate(animate); });
else
this._continueDeactivate(animate);
}
},
_continueDeactivate(animate) {
this._hideLockScreen(animate, 0);
@@ -1229,7 +1237,7 @@ var ScreenShield = class {
onComplete: this._completeDeactivate.bind(this),
onCompleteScope: this
});
}
},
_completeDeactivate() {
if (this._dialog) {
@@ -1256,7 +1264,7 @@ var ScreenShield = class {
this._isLocked = false;
this.emit('locked-changed');
global.set_runtime_state(LOCKED_STATE_STR, null);
}
},
activate(animate) {
if (this._activationTime == 0)
@@ -1288,7 +1296,7 @@ var ScreenShield = class {
// blank during the animation.
// This is not a problem for the idle fade case, because we
// activate without animation in that case.
}
},
lock(animate) {
if (this._lockSettings.get_boolean(DISABLE_LOCK_KEY)) {
@@ -1320,7 +1328,7 @@ var ScreenShield = class {
this.activate(animate);
this.emit('locked-changed');
}
},
// If the previous shell crashed, and gnome-session restarted us, then re-lock
lockIfWasLocked() {
@@ -1333,5 +1341,5 @@ var ScreenShield = class {
this.lock(false);
});
}
};
});
Signals.addSignalMethods(ScreenShield.prototype);

View File

@@ -2,6 +2,7 @@
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@@ -11,8 +12,10 @@ const { loadInterfaceXML } = imports.misc.fileUtils;
const ScreencastIface = loadInterfaceXML('org.gnome.Shell.Screencast');
var ScreencastService = class {
constructor() {
var ScreencastService = new Lang.Class({
Name: 'ScreencastService',
_init() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreencastIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Screencast');
@@ -23,11 +26,11 @@ var ScreencastService = class {
this._lockdownSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.lockdown' });
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
}
},
get isRecording() {
return this._recorders.size > 0;
}
},
_ensureRecorderForSender(sender) {
let recorder = this._recorders.get(sender);
@@ -41,7 +44,7 @@ var ScreencastService = class {
this.emit('updated');
}
return recorder;
}
},
_sessionUpdated() {
if (Main.sessionMode.allowScreencast)
@@ -49,11 +52,11 @@ var ScreencastService = class {
for (let sender of this._recorders.keys())
this._stopRecordingForSender(sender);
}
},
_onNameVanished(connection, name) {
this._stopRecordingForSender(name);
}
},
_stopRecordingForSender(sender) {
let recorder = this._recorders.get(sender);
@@ -66,7 +69,7 @@ var ScreencastService = class {
this.emit('updated');
return true;
}
},
_applyOptionalParameters(recorder, options) {
for (let option in options)
@@ -78,7 +81,7 @@ var ScreencastService = class {
recorder.set_framerate(options['framerate']);
if ('draw-cursor' in options)
recorder.set_draw_cursor(options['draw-cursor']);
}
},
ScreencastAsync(params, invocation) {
let returnValue = [false, ''];
@@ -102,7 +105,7 @@ var ScreencastService = class {
}
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
},
ScreencastAreaAsync(params, invocation) {
let returnValue = [false, ''];
@@ -138,11 +141,11 @@ var ScreencastService = class {
}
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
}
},
StopScreencastAsync(params, invocation) {
let success = this._stopRecordingForSender(invocation.get_sender());
invocation.return_value(GLib.Variant.new('(b)', [success]));
}
};
});
Signals.addSignalMethods(ScreencastService.prototype);

View File

@@ -5,6 +5,7 @@ const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@@ -19,8 +20,10 @@ const { loadInterfaceXML } = imports.misc.fileUtils;
const ScreenshotIface = loadInterfaceXML('org.gnome.Shell.Screenshot');
var ScreenshotService = class {
constructor() {
var ScreenshotService = new Lang.Class({
Name: 'ScreenshotService',
_init() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreenshotIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Screenshot');
@@ -29,7 +32,7 @@ var ScreenshotService = class {
this._lockdownSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.lockdown' });
Gio.DBus.session.own_name('org.gnome.Shell.Screenshot', Gio.BusNameOwnerFlags.REPLACE, null, null);
}
},
_createScreenshot(invocation, needsDisk=true) {
let lockedDown = false;
@@ -50,11 +53,11 @@ var ScreenshotService = class {
this._screenShooter.set(sender, shooter);
return shooter;
}
},
_onNameVanished(connection, name) {
this._removeShooterForSender(name);
}
},
_removeShooterForSender(sender) {
let shooter = this._screenShooter.get(sender);
@@ -63,14 +66,14 @@ var ScreenshotService = class {
Gio.bus_unwatch_name(shooter._watchNameId);
this._screenShooter.delete(sender);
}
},
_checkArea(x, y, width, height) {
return x >= 0 && y >= 0 &&
width > 0 && height > 0 &&
x + width <= global.screen_width &&
y + height <= global.screen_height;
}
},
_onScreenshotComplete(result, area, filenameUsed, flash, invocation) {
if (result) {
@@ -86,7 +89,7 @@ var ScreenshotService = class {
let retval = GLib.Variant.new('(bs)', [result, filenameUsed]);
invocation.return_value(retval);
}
},
_scaleArea(x, y, width, height) {
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
@@ -95,7 +98,7 @@ var ScreenshotService = class {
width *= scaleFactor;
height *= scaleFactor;
return [x, y, width, height];
}
},
_unscaleArea(x, y, width, height) {
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
@@ -104,7 +107,7 @@ var ScreenshotService = class {
width /= scaleFactor;
height /= scaleFactor;
return [x, y, width, height];
}
},
ScreenshotAreaAsync(params, invocation) {
let [x, y, width, height, flash, filename, callback] = params;
@@ -129,7 +132,7 @@ var ScreenshotService = class {
invocation.return_gerror (e);
}
});
}
},
ScreenshotWindowAsync(params, invocation) {
let [include_frame, include_cursor, flash, filename] = params;
@@ -147,7 +150,7 @@ var ScreenshotService = class {
invocation.return_gerror (e);
}
});
}
},
ScreenshotAsync(params, invocation) {
let [include_cursor, flash, filename] = params;
@@ -165,7 +168,7 @@ var ScreenshotService = class {
invocation.return_gerror (e);
}
});
}
},
SelectAreaAsync(params, invocation) {
let selectArea = new SelectArea();
@@ -181,7 +184,7 @@ var ScreenshotService = class {
"Operation was cancelled");
}
});
}
},
FlashAreaAsync(params, invocation) {
let [x, y, width, height] = params;
@@ -195,7 +198,7 @@ var ScreenshotService = class {
let flashspot = new Flashspot({ x : x, y : y, width: width, height: height});
flashspot.fire();
invocation.return_value(null);
}
},
PickColorAsync(params, invocation) {
let pickPixel = new PickPixel();
@@ -224,10 +227,12 @@ var ScreenshotService = class {
}
});
}
};
});
var SelectArea = class {
constructor() {
var SelectArea = new Lang.Class({
Name: 'SelectArea',
_init() {
this._startX = -1;
this._startY = -1;
this._lastX = 0;
@@ -260,7 +265,7 @@ var SelectArea = class {
border_width: 1,
border_color: this._border });
this._group.add_actor(this._rubberband);
}
},
show() {
if (!this._grabHelper.grab({ actor: this._group,
@@ -270,7 +275,7 @@ var SelectArea = class {
global.display.set_cursor(Meta.Cursor.CROSSHAIR);
Main.uiGroup.set_child_above_sibling(this._group, null);
this._group.visible = true;
}
},
_initRubberbandColors() {
function colorFromRGBA(rgba) {
@@ -289,14 +294,14 @@ var SelectArea = class {
this._background = colorFromRGBA(context.get_background_color(Gtk.StateFlags.NORMAL));
this._border = colorFromRGBA(context.get_border_color(Gtk.StateFlags.NORMAL));
}
},
_getGeometry() {
return { x: Math.min(this._startX, this._lastX),
y: Math.min(this._startY, this._lastY),
width: Math.abs(this._startX - this._lastX) + 1,
height: Math.abs(this._startY - this._lastY) + 1 };
}
},
_onMotionEvent(actor, event) {
if (this._startX == -1 || this._startY == -1)
@@ -311,7 +316,7 @@ var SelectArea = class {
this._rubberband.set_size(geometry.width, geometry.height);
return Clutter.EVENT_PROPAGATE;
}
},
_onButtonPress(actor, event) {
[this._startX, this._startY] = event.get_coords();
@@ -320,7 +325,7 @@ var SelectArea = class {
this._rubberband.set_position(this._startX, this._startY);
return Clutter.EVENT_PROPAGATE;
}
},
_onButtonRelease(actor, event) {
this._result = this._getGeometry();
@@ -333,7 +338,7 @@ var SelectArea = class {
}
});
return Clutter.EVENT_PROPAGATE;
}
},
_onUngrab() {
global.display.set_cursor(Meta.Cursor.DEFAULT);
@@ -344,11 +349,13 @@ var SelectArea = class {
return GLib.SOURCE_REMOVE;
});
}
};
});
Signals.addSignalMethods(SelectArea.prototype);
var PickPixel = class {
constructor() {
var PickPixel = new Lang.Class({
Name: 'PickPixel',
_init() {
this._result = null;
this._group = new St.Widget({ visible: false,
@@ -363,7 +370,7 @@ var PickPixel = class {
let constraint = new Clutter.BindConstraint({ source: global.stage,
coordinate: Clutter.BindCoordinate.ALL });
this._group.add_constraint(constraint);
}
},
show() {
if (!this._grabHelper.grab({ actor: this._group,
@@ -373,13 +380,13 @@ var PickPixel = class {
global.display.set_cursor(Meta.Cursor.CROSSHAIR);
Main.uiGroup.set_child_above_sibling(this._group, null);
this._group.visible = true;
}
},
_onButtonRelease(actor, event) {
this._result = event.get_coords();
this._grabHelper.ungrab();
return Clutter.EVENT_PROPAGATE;
}
},
_onUngrab() {
global.display.set_cursor(Meta.Cursor.DEFAULT);
@@ -390,20 +397,23 @@ var PickPixel = class {
return GLib.SOURCE_REMOVE;
});
}
};
});
Signals.addSignalMethods(PickPixel.prototype);
var FLASHSPOT_ANIMATION_OUT_TIME = 0.5; // seconds
var Flashspot = class extends Lightbox.Lightbox {
constructor(area) {
super(Main.uiGroup, { inhibitEvents: true,
width: area.width,
height: area.height });
var Flashspot = new Lang.Class({
Name: 'Flashspot',
Extends: Lightbox.Lightbox,
_init(area) {
this.parent(Main.uiGroup, { inhibitEvents: true,
width: area.width,
height: area.height });
this.actor.style_class = 'flashspot';
this.actor.set_position(area.x, area.y);
}
},
fire(doneCallback) {
this.actor.show();
@@ -419,4 +429,4 @@ var Flashspot = class extends Lightbox.Lightbox {
}
});
}
};
});

View File

@@ -1,9 +1,9 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Signals = imports.signals;
@@ -24,8 +24,10 @@ const SEARCH_PROVIDERS_SCHEMA = 'org.gnome.desktop.search-providers';
var MAX_LIST_SEARCH_RESULTS_ROWS = 5;
var MAX_GRID_SEARCH_RESULTS_ROWS = 1;
var MaxWidthBin = GObject.registerClass(
class MaxWidthBin extends St.Bin {
var MaxWidthBin = new Lang.Class({
Name: 'MaxWidthBin',
Extends: St.Bin,
vfunc_allocate(box, flags) {
let themeNode = this.get_theme_node();
let maxWidth = themeNode.get_max_width();
@@ -38,12 +40,14 @@ class MaxWidthBin extends St.Bin {
adjustedBox.x2 -= Math.floor(excessWidth / 2);
}
super.vfunc_allocate(adjustedBox, flags);
this.parent(adjustedBox, flags);
}
});
var SearchResult = class {
constructor(provider, metaInfo, resultsView) {
var SearchResult = new Lang.Class({
Name: 'SearchResult',
_init(provider, metaInfo, resultsView) {
this.provider = provider;
this.metaInfo = metaInfo;
this._resultsView = resultsView;
@@ -56,18 +60,22 @@ var SearchResult = class {
this.actor._delegate = this;
this.actor.connect('clicked', this.activate.bind(this));
}
},
activate() {
this.emit('activate', this.metaInfo.id);
}
};
});
Signals.addSignalMethods(SearchResult.prototype);
var ListSearchResult = class extends SearchResult {
var ListSearchResult = new Lang.Class({
Name: 'ListSearchResult',
Extends: SearchResult,
constructor(provider, metaInfo, resultsView) {
super(provider, metaInfo, resultsView);
ICON_SIZE: 24,
_init(provider, metaInfo, resultsView) {
this.parent(provider, metaInfo, resultsView);
this.actor.style_class = 'list-search-result';
this.actor.x_fill = true;
@@ -114,27 +122,26 @@ var ListSearchResult = class extends SearchResult {
}
this.actor.connect('destroy', this._onDestroy.bind(this));
}
get ICON_SIZE() {
return 24;
}
},
_highlightTerms() {
let markup = this._resultsView.highlightTerms(this.metaInfo['description'].split('\n')[0]);
this._descriptionLabel.clutter_text.set_markup(markup);
}
},
_onDestroy() {
if (this._termsChangedId)
this._resultsView.disconnect(this._termsChangedId);
this._termsChangedId = 0;
}
};
});
var GridSearchResult = class extends SearchResult {
constructor(provider, metaInfo, resultsView) {
super(provider, metaInfo, resultsView);
var GridSearchResult = new Lang.Class({
Name: 'GridSearchResult',
Extends: SearchResult,
_init(provider, metaInfo, resultsView) {
this.parent(provider, metaInfo, resultsView);
this.actor.style_class = 'grid-search-result';
@@ -144,10 +151,12 @@ var GridSearchResult = class extends SearchResult {
this.actor.set_child(content);
this.actor.label_actor = this.icon.label;
}
};
});
var SearchResultsBase = class {
constructor(provider, resultsView) {
var SearchResultsBase = new Lang.Class({
Name: 'SearchResultsBase',
_init(provider, resultsView) {
this.provider = provider;
this._resultsView = resultsView;
@@ -168,19 +177,19 @@ var SearchResultsBase = class {
this._clipboard = St.Clipboard.get_default();
this._cancellable = new Gio.Cancellable();
}
},
destroy() {
this.actor.destroy();
this._terms = [];
}
},
_createResultDisplay(meta) {
if (this.provider.createResultObject)
return this.provider.createResultObject(meta, this._resultsView);
return null;
}
},
clear() {
this._cancellable.cancel();
@@ -189,21 +198,21 @@ var SearchResultsBase = class {
this._resultDisplays = {};
this._clearResultDisplay();
this.actor.hide();
}
},
_keyFocusIn(actor) {
this.emit('key-focus-in', actor);
}
},
_activateResult(result, id) {
this.provider.activateResult(id, this._terms);
if (result.metaInfo.clipboardText)
this._clipboard.set_text(St.ClipboardType.CLIPBOARD, result.metaInfo.clipboardText);
Main.overview.toggle();
}
},
_setMoreCount(count) {
}
},
_ensureResultActors(results, callback) {
let metasNeeded = results.filter(
@@ -245,7 +254,7 @@ var SearchResultsBase = class {
callback(true);
}, this._cancellable);
}
}
},
updateSearch(providerResults, terms, callback) {
this._terms = terms;
@@ -279,11 +288,14 @@ var SearchResultsBase = class {
});
}
}
};
});
var ListSearchResults = class extends SearchResultsBase {
constructor(provider, resultsView) {
super(provider, resultsView);
var ListSearchResults = new Lang.Class({
Name: 'ListSearchResults',
Extends: SearchResultsBase,
_init(provider, resultsView) {
this.parent(provider, resultsView);
this._container = new St.BoxLayout({ style_class: 'search-section-content' });
this.providerInfo = new ProviderInfo(provider);
@@ -304,28 +316,28 @@ var ListSearchResults = class extends SearchResultsBase {
this._container.add(this._content, { expand: true });
this._resultDisplayBin.set_child(this._container);
}
},
_setMoreCount(count) {
this.providerInfo.setMoreCount(count);
}
},
_getMaxDisplayedResults() {
return MAX_LIST_SEARCH_RESULTS_ROWS;
}
},
_clearResultDisplay() {
this._content.remove_all_children();
}
},
_createResultDisplay(meta) {
return super._createResultDisplay(meta, this._resultsView) ||
return this.parent(meta, this._resultsView) ||
new ListSearchResult(this.provider, meta, this._resultsView);
}
},
_addItem(display) {
this._content.add_actor(display.actor);
}
},
getFirstResult() {
if (this._content.get_n_children() > 0)
@@ -333,12 +345,15 @@ var ListSearchResults = class extends SearchResultsBase {
else
return null;
}
};
});
Signals.addSignalMethods(ListSearchResults.prototype);
var GridSearchResults = class extends SearchResultsBase {
constructor(provider, resultsView) {
super(provider, resultsView);
var GridSearchResults = new Lang.Class({
Name: 'GridSearchResults',
Extends: SearchResultsBase,
_init(provider, resultsView) {
this.parent(provider, resultsView);
// We need to use the parent container to know how much results we can show.
// None of the actors in this class can be used for that, since the main actor
// goes hidden when no results are displayed, and then it lost its allocation.
@@ -353,26 +368,26 @@ var GridSearchResults = class extends SearchResultsBase {
this._bin.set_child(this._grid);
this._resultDisplayBin.set_child(this._bin);
}
},
_getMaxDisplayedResults() {
let parentThemeNode = this._parentContainer.get_theme_node();
let availableWidth = parentThemeNode.adjust_for_width(this._parentContainer.width);
return this._grid.columnsForWidth(availableWidth) * this._grid.getRowLimit();
}
},
_clearResultDisplay() {
this._grid.removeAll();
}
},
_createResultDisplay(meta) {
return super._createResultDisplay(meta, this._resultsView) ||
return this.parent(meta, this._resultsView) ||
new GridSearchResult(this.provider, meta, this._resultsView);
}
},
_addItem(display) {
this._grid.addItem(display);
}
},
getFirstResult() {
if (this._grid.visibleItemsCount() > 0)
@@ -380,11 +395,13 @@ var GridSearchResults = class extends SearchResultsBase {
else
return null;
}
};
});
Signals.addSignalMethods(GridSearchResults.prototype);
var SearchResults = class {
constructor() {
var SearchResults = new Lang.Class({
Name: 'SearchResults',
_init() {
this.actor = new St.BoxLayout({ name: 'searchResults',
vertical: true });
@@ -442,7 +459,7 @@ var SearchResults = class {
this._registerProvider(new AppDisplay.AppSearchProvider());
this._reloadRemoteProviders();
}
},
_reloadRemoteProviders() {
let remoteProviders = this._providers.filter(p => p.isRemoteProvider);
@@ -453,13 +470,12 @@ var SearchResults = class {
RemoteSearch.loadRemoteSearchProviders(this._searchSettings, providers => {
providers.forEach(this._registerProvider.bind(this));
});
}
},
_registerProvider(provider) {
provider.searchInProgress = false;
this._providers.push(provider);
this._ensureProviderDisplay(provider);
}
},
_unregisterProvider(provider) {
let index = this._providers.indexOf(provider);
@@ -467,19 +483,19 @@ var SearchResults = class {
if (provider.display)
provider.display.destroy();
}
},
_gotResults(results, provider) {
this._results[provider.id] = results;
this._updateResults(provider, results);
}
},
_clearSearchTimeout() {
if (this._searchTimeoutId > 0) {
GLib.source_remove(this._searchTimeoutId);
this._searchTimeoutId = 0;
}
}
},
_reset() {
this._terms = [];
@@ -490,7 +506,7 @@ var SearchResults = class {
this._startingSearch = false;
this._updateSearchProgress();
}
},
_doSearch() {
this._startingSearch = false;
@@ -520,13 +536,13 @@ var SearchResults = class {
this._updateSearchProgress();
this._clearSearchTimeout();
}
},
_onSearchTimeout() {
this._searchTimeoutId = 0;
this._doSearch();
return GLib.SOURCE_REMOVE;
}
},
setTerms(terms) {
// Check for the case of making a duplicate previous search before
@@ -563,18 +579,18 @@ var SearchResults = class {
this._highlightRegex = new RegExp(`(${escapedTerms.join('|')})`, 'gi');
this.emit('terms-changed');
}
},
_onPan(action) {
let [dist, dx, dy] = action.get_motion_delta(0);
let adjustment = this._scrollView.vscroll.adjustment;
adjustment.value -= (dy / this.actor.height) * adjustment.page_size;
return false;
}
},
_keyFocusIn(provider, actor) {
Util.ensureActorVisibleInScrollView(this._scrollView, actor);
}
},
_ensureProviderDisplay(provider) {
if (provider.display)
@@ -590,13 +606,13 @@ var SearchResults = class {
providerDisplay.actor.hide();
this._content.add(providerDisplay.actor);
provider.display = providerDisplay;
}
},
_clearDisplay() {
this._providers.forEach(provider => {
provider.display.clear();
});
}
},
_maybeSetInitialSelection() {
let newDefaultResult = null;
@@ -622,14 +638,14 @@ var SearchResults = class {
this._defaultResult = newDefaultResult;
}
}
},
get searchInProgress() {
if (this._startingSearch)
return true;
return this._providers.some(p => p.searchInProgress);
}
},
_updateSearchProgress() {
let haveResults = this._providers.some(provider => {
@@ -647,7 +663,7 @@ var SearchResults = class {
this._statusText.set_text(_("No results."));
}
}
}
},
_updateResults(provider, results) {
let terms = this._terms;
@@ -659,7 +675,7 @@ var SearchResults = class {
this._maybeSetInitialSelection();
this._updateSearchProgress();
});
}
},
activateDefault() {
// If we have a search queued up, force the search now.
@@ -668,12 +684,12 @@ var SearchResults = class {
if (this._defaultResult)
this._defaultResult.activate();
}
},
highlightDefault(highlight) {
this._highlightDefault = highlight;
this._setSelected(this._defaultResult, highlight);
}
},
popupMenuDefault() {
// If we have a search queued up, force the search now.
@@ -682,7 +698,7 @@ var SearchResults = class {
if (this._defaultResult)
this._defaultResult.actor.popup_menu();
}
},
navigateFocus(direction) {
let rtl = this.actor.get_text_direction() == Clutter.TextDirection.RTL;
@@ -696,7 +712,7 @@ var SearchResults = class {
let from = this._defaultResult ? this._defaultResult.actor : null;
this.actor.navigate_focus(from, direction, false);
}
},
_setSelected(result, selected) {
if (!result)
@@ -708,7 +724,7 @@ var SearchResults = class {
} else {
result.actor.remove_style_pseudo_class('selected');
}
}
},
highlightTerms(description) {
if (!description)
@@ -719,14 +735,18 @@ var SearchResults = class {
return description.replace(this._highlightRegex, '<b>$1</b>');
}
};
});
Signals.addSignalMethods(SearchResults.prototype);
var ProviderInfo = GObject.registerClass(
class ProviderInfo extends St.Button {
var ProviderInfo = new Lang.Class({
Name: 'ProviderInfo',
Extends: St.Button,
PROVIDER_ICON_SIZE: 32,
_init(provider) {
this.provider = provider;
super._init({ style_class: 'search-provider-icon',
this.parent({ style_class: 'search-provider-icon',
reactive: true,
can_focus: true,
accessible_name: provider.appInfo.get_name(),
@@ -754,18 +774,14 @@ class ProviderInfo extends St.Button {
this._content.add_actor(icon);
this._content.add_actor(detailsBox);
}
get PROVIDER_ICON_SIZE() {
return 32;
}
},
animateLaunch() {
let appSys = Shell.AppSystem.get_default();
let app = appSys.lookup_app(this.provider.appInfo.get_id());
if (app.state == Shell.AppState.STOPPED)
IconGrid.zoomOutActor(this._content);
}
},
setMoreCount(count) {
this._moreLabel.text = ngettext("%d more", "%d more", count).format(count);

View File

@@ -2,6 +2,7 @@
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
@@ -98,7 +99,7 @@ const _modes = {
'keyring', 'autorunManager', 'automountManager'],
panel: {
left: ['activities'],
left: ['activities', 'appMenu'],
center: ['dateMenu'],
right: ['a11y', 'keyboard', 'aggregateMenu']
}
@@ -150,38 +151,40 @@ function listModes() {
Mainloop.run('listModes');
}
var SessionMode = class {
constructor() {
var SessionMode = new Lang.Class({
Name: 'SessionMode',
_init() {
_loadModes();
let isPrimary = (_modes[global.session_mode] &&
_modes[global.session_mode].isPrimary);
let mode = isPrimary ? global.session_mode : 'user';
this._modeStack = [mode];
this._sync();
}
},
pushMode(mode) {
this._modeStack.push(mode);
this._sync();
}
},
popMode(mode) {
if (this.currentMode != mode || this._modeStack.length === 1)
throw new Error("Invalid SessionMode.popMode");
this._modeStack.pop();
this._sync();
}
},
switchMode(to) {
if (this.currentMode == to)
return;
this._modeStack[this._modeStack.length - 1] = to;
this._sync();
}
},
get currentMode() {
return this._modeStack[this._modeStack.length - 1];
}
},
_sync() {
let params = _modes[this.currentMode];
@@ -202,5 +205,5 @@ var SessionMode = class {
this.emit('updated');
}
};
});
Signals.addSignalMethods(SessionMode.prototype);

View File

@@ -19,8 +19,10 @@ const { loadInterfaceXML } = imports.misc.fileUtils;
const GnomeShellIface = loadInterfaceXML('org.gnome.Shell');
const ScreenSaverIface = loadInterfaceXML('org.gnome.ScreenSaver');
var GnomeShell = class {
constructor() {
var GnomeShell = new Lang.Class({
Name: 'GnomeShellDBus',
_init() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
@@ -40,7 +42,7 @@ var GnomeShell = class {
this._checkOverviewVisibleChanged.bind(this));
Main.overview.connect('hidden',
this._checkOverviewVisibleChanged.bind(this));
}
},
/**
* Eval:
@@ -73,11 +75,11 @@ var GnomeShell = class {
success = false;
}
return [success, returnValue];
}
},
FocusSearch() {
Main.overview.focusSearch();
}
},
ShowOSD(params) {
for (let param in params)
@@ -97,23 +99,34 @@ var GnomeShell = class {
icon = Gio.Icon.new_for_string(serializedIcon);
Main.osdWindowManager.show(monitorIndex, icon, label, level, maxLevel);
}
},
FocusAppAsync(params, invocation) {
let [id] = params;
let appSys = Shell.AppSystem.get_default();
if (appSys.lookup_app(id) == null) {
invocation.return_error_literal(
Gio.DBusError,
Gio.DBusError.FILE_NOT_FOUND,
`No application with ID ${id}`);
return;
}
FocusApp(id) {
this.ShowApplications();
Main.overview.viewSelector.appDisplay.selectApp(id);
}
invocation.return_value(null);
},
ShowApplications() {
Main.overview.viewSelector.showApps();
}
},
GrabAcceleratorAsync(params, invocation) {
let [accel, flags] = params;
let sender = invocation.get_sender();
let bindingAction = this._grabAcceleratorForSender(accel, flags, sender);
return invocation.return_value(GLib.Variant.new('(u)', [bindingAction]));
}
},
GrabAcceleratorsAsync(params, invocation) {
let [accels] = params;
@@ -124,7 +137,7 @@ var GnomeShell = class {
bindingActions.push(this._grabAcceleratorForSender(accel, flags, sender));
}
return invocation.return_value(GLib.Variant.new('(au)', [bindingActions]));
}
},
UngrabAcceleratorAsync(params, invocation) {
let [action] = params;
@@ -136,7 +149,7 @@ var GnomeShell = class {
if (ungrabSucceeded)
this._grabbedAccelerators.delete(action);
return invocation.return_value(GLib.Variant.new('(b)', [ungrabSucceeded]));
}
},
_emitAcceleratorActivated(action, deviceid, timestamp) {
let destination = this._grabbedAccelerators.get(action);
@@ -153,7 +166,7 @@ var GnomeShell = class {
info ? info.name : null,
'AcceleratorActivated',
GLib.Variant.new('(ua{sv})', [action, params]));
}
},
_grabAcceleratorForSender(accelerator, flags, sender) {
let bindingAction = global.display.grab_accelerator(accelerator);
@@ -172,13 +185,13 @@ var GnomeShell = class {
}
return bindingAction;
}
},
_ungrabAccelerator(action) {
let ungrabSucceeded = global.display.ungrab_accelerator(action);
if (ungrabSucceeded)
this._grabbedAccelerators.delete(action);
}
},
_onGrabberBusNameVanished(connection, name) {
let grabs = this._grabbedAccelerators.entries();
@@ -188,61 +201,61 @@ var GnomeShell = class {
}
Gio.bus_unwatch_name(this._grabbers.get(name));
this._grabbers.delete(name);
}
},
ShowMonitorLabelsAsync(params, invocation) {
let sender = invocation.get_sender();
let [dict] = params;
Main.osdMonitorLabeler.show(sender, dict);
}
},
ShowMonitorLabels2Async(params, invocation) {
let sender = invocation.get_sender();
let [dict] = params;
Main.osdMonitorLabeler.show2(sender, dict);
}
},
HideMonitorLabelsAsync(params, invocation) {
let sender = invocation.get_sender();
Main.osdMonitorLabeler.hide(sender);
}
},
Mode: global.session_mode,
_checkOverviewVisibleChanged() {
if (Main.overview.visible !== this._cachedOverviewVisible) {
this._cachedOverviewVisible = Main.overview.visible;
this._dbusImpl.emit_property_changed('OverviewActive', new GLib.Variant('b', this._cachedOverviewVisible));
}
}
get Mode() {
return global.session_mode;
}
},
get OverviewActive() {
return this._cachedOverviewVisible;
}
},
set OverviewActive(visible) {
if (visible)
Main.overview.show();
else
Main.overview.hide();
}
},
get ShellVersion() {
return Config.PACKAGE_VERSION;
}
};
ShellVersion: Config.PACKAGE_VERSION
});
const GnomeShellExtensionsIface = loadInterfaceXML('org.gnome.Shell.Extensions');
var GnomeShellExtensions = class {
constructor() {
var GnomeShellExtensions = new Lang.Class({
Name: 'GnomeShellExtensionsDBus',
_init() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellExtensionsIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
ExtensionSystem.connect('extension-state-changed',
this._extensionStateChanged.bind(this));
}
},
ListExtensions() {
let out = {};
@@ -251,7 +264,7 @@ var GnomeShellExtensions = class {
out[uuid] = dbusObj;
}
return out;
}
},
GetExtensionInfo(uuid) {
let extension = ExtensionUtils.extensions[uuid];
@@ -289,7 +302,7 @@ var GnomeShellExtensions = class {
}
return out;
}
},
GetExtensionErrors(uuid) {
let extension = ExtensionUtils.extensions[uuid];
@@ -300,15 +313,15 @@ var GnomeShellExtensions = class {
return [];
return extension.errors;
}
},
InstallRemoteExtensionAsync([uuid], invocation) {
return ExtensionDownloader.installExtension(uuid, invocation);
}
},
UninstallExtension(uuid) {
return ExtensionDownloader.uninstallExtension(uuid);
}
},
LaunchExtensionPrefs(uuid) {
let appSys = Shell.AppSystem.get_default();
@@ -317,7 +330,7 @@ var GnomeShellExtensions = class {
let timestamp = global.display.get_current_time_roundtrip();
info.launch_uris(['extension:///' + uuid],
global.create_app_launch_context(timestamp, -1));
}
},
ReloadExtension(uuid) {
let extension = ExtensionUtils.extensions[uuid];
@@ -325,24 +338,26 @@ var GnomeShellExtensions = class {
return;
ExtensionSystem.reloadExtension(extension);
}
},
CheckForUpdates() {
ExtensionDownloader.checkForUpdates();
}
},
get ShellVersion() {
return Config.PACKAGE_VERSION;
}
ShellVersion: Config.PACKAGE_VERSION,
_extensionStateChanged(_, newState) {
this._dbusImpl.emit_signal('ExtensionStatusChanged',
GLib.Variant.new('(sis)', [newState.uuid, newState.state, newState.error]));
}
};
});
var ScreenSaverDBus = new Lang.Class({
Name: 'ScreenSaverDBus',
_init(screenShield) {
this.parent();
var ScreenSaverDBus = class {
constructor(screenShield) {
this._screenShield = screenShield;
screenShield.connect('active-changed', shield => {
this._dbusImpl.emit_signal('ActiveChanged', GLib.Variant.new('(b)', [shield.active]));
@@ -355,7 +370,7 @@ var ScreenSaverDBus = class {
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/ScreenSaver');
Gio.DBus.session.own_name('org.gnome.ScreenSaver', Gio.BusNameOwnerFlags.REPLACE, null, null);
}
},
LockAsync(parameters, invocation) {
let tmpId = this._screenShield.connect('lock-screen-shown', () => {
@@ -365,18 +380,18 @@ var ScreenSaverDBus = class {
});
this._screenShield.lock(true);
}
},
SetActive(active) {
if (active)
this._screenShield.activate(true);
else
this._screenShield.deactivate(false);
}
},
GetActive() {
return this._screenShield.active;
}
},
GetActiveTime() {
let started = this._screenShield.activationTime;
@@ -384,5 +399,5 @@ var ScreenSaverDBus = class {
return Math.floor((GLib.get_monotonic_time() - started) / 1000000);
else
return 0;
}
};
},
});

View File

@@ -2,6 +2,7 @@
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const St = imports.gi.St;
const BoxPointer = imports.ui.boxpointer;
@@ -9,9 +10,12 @@ const Main = imports.ui.main;
const Params = imports.misc.params;
const PopupMenu = imports.ui.popupMenu;
var EntryMenu = class extends PopupMenu.PopupMenu {
constructor(entry) {
super(entry, 0, St.Side.TOP);
var EntryMenu = new Lang.Class({
Name: 'ShellEntryMenu',
Extends: PopupMenu.PopupMenu,
_init(entry) {
this.parent(entry, 0, St.Side.TOP);
this._entry = entry;
this._clipboard = St.Clipboard.get_default();
@@ -32,18 +36,18 @@ var EntryMenu = class extends PopupMenu.PopupMenu {
Main.uiGroup.add_actor(this.actor);
this.actor.hide();
}
},
_makePasswordItem() {
let item = new PopupMenu.PopupMenuItem('');
item.connect('activate', this._onPasswordActivated.bind(this));
this.addMenuItem(item);
this._passwordItem = item;
}
},
get isPassword() {
return this._passwordItem != null;
}
},
set isPassword(v) {
if (v == this.isPassword)
@@ -57,7 +61,7 @@ var EntryMenu = class extends PopupMenu.PopupMenu {
this._passwordItem = null;
this._entry.input_purpose = Clutter.InputContentPurpose.NORMAL;
}
}
},
open(animate) {
this._updatePasteItem();
@@ -65,26 +69,26 @@ var EntryMenu = class extends PopupMenu.PopupMenu {
if (this._passwordItem)
this._updatePasswordItem();
super.open(animate);
this.parent(animate);
this._entry.add_style_pseudo_class('focus');
let direction = Gtk.DirectionType.TAB_FORWARD;
if (!this.actor.navigate_focus(null, direction, false))
this.actor.grab_key_focus();
}
},
_updateCopyItem() {
let selection = this._entry.clutter_text.get_selection();
this._copyItem.setSensitive(!this._entry.clutter_text.password_char &&
selection && selection != '');
}
},
_updatePasteItem() {
this._clipboard.get_text(St.ClipboardType.CLIPBOARD,
(clipboard, text) => {
this._pasteItem.setSensitive(text && text != '');
});
}
},
_updatePasswordItem() {
let textHidden = (this._entry.clutter_text.password_char);
@@ -92,12 +96,12 @@ var EntryMenu = class extends PopupMenu.PopupMenu {
this._passwordItem.label.set_text(_("Show Text"));
else
this._passwordItem.label.set_text(_("Hide Text"));
}
},
_onCopyActivated() {
let selection = this._entry.clutter_text.get_selection();
this._clipboard.set_text(St.ClipboardType.CLIPBOARD, selection);
}
},
_onPasteActivated() {
this._clipboard.get_text(St.ClipboardType.CLIPBOARD,
@@ -108,13 +112,13 @@ var EntryMenu = class extends PopupMenu.PopupMenu {
let pos = this._entry.clutter_text.get_cursor_position();
this._entry.clutter_text.insert_text(text, pos);
});
}
},
_onPasswordActivated() {
let visible = !!(this._entry.clutter_text.password_char);
this._entry.clutter_text.set_password_char(visible ? '' : '\u25cf');
}
};
});
function _setMenuAlignment(entry, stageX) {
let [success, entryX, entryY] = entry.transform_stage_point(stageX, 0);

View File

@@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const Signals = imports.signals;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
@@ -61,8 +62,10 @@ function _createIcon(gicon) {
/* -------------------------------------------------------- */
var ListItem = class {
constructor(app) {
var ListItem = new Lang.Class({
Name: 'ListItem',
_init(app) {
this._app = app;
let layout = new St.BoxLayout({ vertical: false});
@@ -87,17 +90,19 @@ var ListItem = class {
layout.add(labelBin);
this.actor.connect('clicked', this._onClicked.bind(this));
}
},
_onClicked() {
this.emit('activate');
this._app.activate();
}
};
});
Signals.addSignalMethods(ListItem.prototype);
var ShellMountOperation = class {
constructor(source, params) {
var ShellMountOperation = new Lang.Class({
Name: 'ShellMountOperation',
_init(source, params) {
params = Params.parse(params, { existingDialog: null });
this._dialog = null;
@@ -119,7 +124,7 @@ var ShellMountOperation = class {
this._onShowUnmountProgress.bind(this));
this._gicon = source.get_icon();
}
},
_closeExistingDialog() {
if (!this._existingDialog)
@@ -127,7 +132,7 @@ var ShellMountOperation = class {
this._existingDialog.close();
this._existingDialog = null;
}
},
_onAskQuestion(op, message, choices) {
this._closeExistingDialog();
@@ -143,7 +148,7 @@ var ShellMountOperation = class {
this._dialog.update(message, choices);
this._dialog.open();
}
},
_onAskPassword(op, message, defaultUser, defaultDomain, flags) {
if (this._existingDialog) {
@@ -168,7 +173,7 @@ var ShellMountOperation = class {
}
});
this._dialog.open();
}
},
close(op) {
this._closeExistingDialog();
@@ -183,7 +188,7 @@ var ShellMountOperation = class {
this._notifier.done();
this._notifier = null;
}
}
},
_onShowProcesses2(op) {
this._closeExistingDialog();
@@ -211,7 +216,7 @@ var ShellMountOperation = class {
}
this._processesDialog.update(message, processes, choices);
}
},
_onShowUnmountProgress(op, message, timeLeft, bytesLeft) {
if (!this._notifier)
@@ -221,7 +226,7 @@ var ShellMountOperation = class {
this._notifier.done(message);
else
this._notifier.show(message);
}
},
borrowDialog() {
if (this._dialogId != 0) {
@@ -231,15 +236,18 @@ var ShellMountOperation = class {
return this._dialog;
}
};
});
var ShellUnmountNotifier = class extends MessageTray.Source {
constructor() {
super('', 'media-removable');
var ShellUnmountNotifier = new Lang.Class({
Name: 'ShellUnmountNotifier',
Extends: MessageTray.Source,
_init() {
this.parent('', 'media-removable');
this._notification = null;
Main.messageTray.add(this);
}
},
show(message) {
let [header, text] = message.split('\n', 2);
@@ -253,7 +261,7 @@ var ShellUnmountNotifier = class extends MessageTray.Source {
}
this.notify(this._notification);
}
},
done(message) {
if (this._notification) {
@@ -268,29 +276,35 @@ var ShellUnmountNotifier = class extends MessageTray.Source {
this.notify(notification);
}
}
};
});
var ShellMountQuestionDialog = class extends ModalDialog.ModalDialog {
constructor(icon) {
super({ styleClass: 'mount-dialog' });
var ShellMountQuestionDialog = new Lang.Class({
Name: 'ShellMountQuestionDialog',
Extends: ModalDialog.ModalDialog,
_init(icon) {
this.parent({ styleClass: 'mount-dialog' });
this._content = new Dialog.MessageDialogContent({ icon });
this.contentLayout.add(this._content, { x_fill: true, y_fill: false });
}
},
update(message, choices) {
_setLabelsForMessage(this._content, message);
_setButtonsForChoices(this, choices);
}
};
});
Signals.addSignalMethods(ShellMountQuestionDialog.prototype);
var ShellMountPasswordDialog = class extends ModalDialog.ModalDialog {
constructor(message, icon, flags) {
var ShellMountPasswordDialog = new Lang.Class({
Name: 'ShellMountPasswordDialog',
Extends: ModalDialog.ModalDialog,
_init(message, icon, flags) {
let strings = message.split('\n');
let title = strings.shift() || null;
let body = strings.shift() || null;
super({ styleClass: 'prompt-dialog' });
this.parent({ styleClass: 'prompt-dialog' });
let content = new Dialog.MessageDialogContent({ icon, title, body });
this.contentLayout.add_actor(content);
@@ -338,20 +352,20 @@ var ShellMountPasswordDialog = class extends ModalDialog.ModalDialog {
}];
this.setButtons(buttons);
}
},
reaskPassword() {
this._passwordEntry.set_text('');
this._errorMessageLabel.show();
}
},
_onCancelButton() {
this.emit('response', -1, '', false);
}
},
_onUnlockButton() {
this._onEntryActivate();
}
},
_onEntryActivate() {
global.settings.set_boolean(REMEMBER_MOUNT_PASSWORD_KEY,
@@ -361,11 +375,14 @@ var ShellMountPasswordDialog = class extends ModalDialog.ModalDialog {
this._rememberChoice &&
this._rememberChoice.actor.checked);
}
};
});
var ShellProcessesDialog = class extends ModalDialog.ModalDialog {
constructor(icon) {
super({ styleClass: 'mount-dialog' });
var ShellProcessesDialog = new Lang.Class({
Name: 'ShellProcessesDialog',
Extends: ModalDialog.ModalDialog,
_init(icon) {
this.parent({ styleClass: 'mount-dialog' });
this._content = new Dialog.MessageDialogContent({ icon });
this.contentLayout.add(this._content, { x_fill: true, y_fill: false });
@@ -390,7 +407,7 @@ var ShellProcessesDialog = class extends ModalDialog.ModalDialog {
if (this._applicationList.get_n_children() == 0)
scrollView.hide();
});
}
},
_setAppsForPids(pids) {
// remove all the items
@@ -411,14 +428,14 @@ var ShellProcessesDialog = class extends ModalDialog.ModalDialog {
this.emit('response', -1);
});
});
}
},
update(message, processes, choices) {
this._setAppsForPids(processes);
_setLabelsForMessage(this._content, message);
_setButtonsForChoices(this, choices);
}
};
});
Signals.addSignalMethods(ShellProcessesDialog.prototype);
const GnomeShellMountOpIface = loadInterfaceXML('org.Gtk.MountOperationHandler');
@@ -430,8 +447,10 @@ var ShellMountOperationType = {
SHOW_PROCESSES: 3
};
var GnomeShellMountOpHandler = class {
constructor() {
var GnomeShellMountOpHandler = new Lang.Class({
Name: 'GnomeShellMountOpHandler',
_init() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellMountOpIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gtk/MountOperationHandler');
Gio.bus_own_name_on_connection(Gio.DBus.session, 'org.gtk.MountOperationHandler',
@@ -441,13 +460,13 @@ var GnomeShellMountOpHandler = class {
this._volumeMonitor = Gio.VolumeMonitor.get();
this._ensureEmptyRequest();
}
},
_ensureEmptyRequest() {
this._currentId = null;
this._currentInvocation = null;
this._currentType = ShellMountOperationType.NONE;
}
},
_clearCurrentRequest(response, details) {
if (this._currentInvocation) {
@@ -456,7 +475,7 @@ var GnomeShellMountOpHandler = class {
}
this._ensureEmptyRequest();
}
},
_setCurrentRequest(invocation, id, type) {
let oldId = this._currentId;
@@ -473,20 +492,20 @@ var GnomeShellMountOpHandler = class {
return true;
return false;
}
},
_closeDialog() {
if (this._dialog) {
this._dialog.close();
this._dialog = null;
}
}
},
_createGIcon(iconName) {
let realIconName = iconName ? iconName : 'drive-harddisk';
return new Gio.ThemedIcon({ name: realIconName,
use_default_fallbacks: true });
}
},
/**
* AskPassword:
@@ -538,7 +557,7 @@ var GnomeShellMountOpHandler = class {
this._clearCurrentRequest(response, details);
});
this._dialog.open();
}
},
/**
* AskQuestion:
@@ -576,7 +595,7 @@ var GnomeShellMountOpHandler = class {
this._dialog.update(message, choices);
this._dialog.open();
}
},
/**
* ShowProcesses:
@@ -624,7 +643,7 @@ var GnomeShellMountOpHandler = class {
this._dialog.update(message, applicationPids, choices);
this._dialog.open();
}
},
/**
* Close:
@@ -636,4 +655,4 @@ var GnomeShellMountOpHandler = class {
this._clearCurrentRequest(Gio.MountOperationResult.UNHANDLED, {});
this._closeDialog();
}
};
});

Some files were not shown because too many files have changed in this diff Show More