Compare commits
343 Commits
issue-36
...
wip/fmuell
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
035dfe2a19 | ||
|
|
2d791a51c0 | ||
|
|
7778d1c308 | ||
|
|
9e975ed9ef | ||
|
|
22531384f1 | ||
|
|
1bdb3f194d | ||
|
|
5d61e2563d | ||
|
|
72f5802be9 | ||
|
|
30cb2127a1 | ||
|
|
3aea290adc | ||
|
|
5b3ff7184e | ||
|
|
760406002f | ||
|
|
c47a740c83 | ||
|
|
0fe5a3c0c4 | ||
|
|
5bca4a884e | ||
|
|
9c41736a81 | ||
|
|
87da623d86 | ||
|
|
3033506f2c | ||
|
|
542f971176 | ||
|
|
96c5404fd4 | ||
|
|
afc7925e3e | ||
|
|
c2e9e68df7 | ||
|
|
bdbf804e69 | ||
|
|
9718175f4d | ||
|
|
0ba346b750 | ||
|
|
614c4480e2 | ||
|
|
f21f612ef7 | ||
|
|
935de3e80f | ||
|
|
0f541f60e8 | ||
|
|
902c99c757 | ||
|
|
f7029674b0 | ||
|
|
dd7ccda168 | ||
|
|
e207b45317 | ||
|
|
6b5117677d | ||
|
|
900398406c | ||
|
|
461d2b1945 | ||
|
|
6c2f11e8a4 | ||
|
|
dbf993300a | ||
|
|
f77b3da74f | ||
|
|
bc6a38dda7 | ||
|
|
f3a02057c1 | ||
|
|
ad15ce9139 | ||
|
|
5d178506bf | ||
|
|
14cc9bfb1e | ||
|
|
ce4c485f34 | ||
|
|
1877a2e00a | ||
|
|
b2fa7a6d8f | ||
|
|
36c604d793 | ||
|
|
9a5a4b2206 | ||
|
|
3ab9e9e8ad | ||
|
|
dd59212d3f | ||
|
|
2b654ec310 | ||
|
|
764fbbe052 | ||
|
|
328c63bf64 | ||
|
|
95788c9834 | ||
|
|
9cf571efbd | ||
|
|
dc4128c78b | ||
|
|
73d8c82640 | ||
|
|
2f7377b250 | ||
|
|
804f23b179 | ||
|
|
2be6ddc54e | ||
|
|
dff4f0109e | ||
|
|
2e663b2a94 | ||
|
|
9f4aa6ebf2 | ||
|
|
afe5703710 | ||
|
|
02d06bb1f3 | ||
|
|
3a78695bd9 | ||
|
|
13e8c35d36 | ||
|
|
3b8dfd98dd | ||
|
|
6b610b26f8 | ||
|
|
81956e9b84 | ||
|
|
6b41f82346 | ||
|
|
1fca090374 | ||
|
|
da2fc2c9d3 | ||
|
|
52cbc299a7 | ||
|
|
9f436ce373 | ||
|
|
d908940ef3 | ||
|
|
eeda54f24d | ||
|
|
b8b5da1e95 | ||
|
|
3a9ad5c577 | ||
|
|
d57dc94d9e | ||
|
|
393d7246cc | ||
|
|
6217c3b88d | ||
|
|
ddd4fd9c24 | ||
|
|
d2a97e7f1d | ||
|
|
aa75e89216 | ||
|
|
3f756dc608 | ||
|
|
ed8e89bc19 | ||
|
|
c90a4e4849 | ||
|
|
f433b12d6e | ||
|
|
7ca418a79a | ||
|
|
a9ad91c831 | ||
|
|
bd1c7774ee | ||
|
|
91da3789bc | ||
|
|
2991f9f102 | ||
|
|
49d8ff38e7 | ||
|
|
4b522a02c3 | ||
|
|
ebe6f59d7e | ||
|
|
e5c95b910d | ||
|
|
2f76951658 | ||
|
|
3efd296fc3 | ||
|
|
6688610c23 | ||
|
|
d2c75801ea | ||
|
|
be84a00022 | ||
|
|
da537cda43 | ||
|
|
304c667bca | ||
|
|
879a81abeb | ||
|
|
e68ca5adbd | ||
|
|
cf69fe4b18 | ||
|
|
8f848925f6 | ||
|
|
d21657fe61 | ||
|
|
ce3555382b | ||
|
|
837a00c3f0 | ||
|
|
132c8e0cf8 | ||
|
|
9c62522419 | ||
|
|
0d5bae3844 | ||
|
|
97f6a35b46 | ||
|
|
43e8dfacb4 | ||
|
|
0221099e7e | ||
|
|
374caade47 | ||
|
|
a5937d1d6d | ||
|
|
e36ba874a8 | ||
|
|
22392d1328 | ||
|
|
0dee82fb9f | ||
|
|
68f00f397f | ||
|
|
905801b178 | ||
|
|
4a7082bb0f | ||
|
|
2e90c5fa4b | ||
|
|
50e849a186 | ||
|
|
e7f2e92410 | ||
|
|
b1b455ff1a | ||
|
|
ab4c72d758 | ||
|
|
86a520b880 | ||
|
|
4bf033a885 | ||
|
|
e3ebc8d0c6 | ||
|
|
fc5ab44704 | ||
|
|
d5e8f174d4 | ||
|
|
d9a1434ae9 | ||
|
|
d0bdea3178 | ||
|
|
ccadf6aca1 | ||
|
|
266b0e9dd0 | ||
|
|
f7355f593d | ||
|
|
a301820258 | ||
|
|
47ea10b7c9 | ||
|
|
2c0376c150 | ||
|
|
ac58c4280b | ||
|
|
e39d7152f2 | ||
|
|
e522e2e804 | ||
|
|
2ba26407f1 | ||
|
|
996dd74157 | ||
|
|
878946962d | ||
|
|
84d2d3feb3 | ||
|
|
19e864ed3b | ||
|
|
c9bf72c5c4 | ||
|
|
5fe349d5ba | ||
|
|
1f03599d1c | ||
|
|
a24999b7a3 | ||
|
|
8237a1f6e0 | ||
|
|
f9dec475a1 | ||
|
|
68b01a8f56 | ||
|
|
f56ba0877a | ||
|
|
5ac6201d91 | ||
|
|
a21a22fdb5 | ||
|
|
a0fa50ac31 | ||
|
|
b1dd746443 | ||
|
|
c15e163eb1 | ||
|
|
7a3927c168 | ||
|
|
6eed4e31d7 | ||
|
|
f0557ea05c | ||
|
|
44894262f4 | ||
|
|
b03bcc85aa | ||
|
|
70057c6a55 | ||
|
|
86bd5b281d | ||
|
|
ad3e9ab205 | ||
|
|
02bbf409ea | ||
|
|
f56e4e177e | ||
|
|
fc26559f2c | ||
|
|
fdaddbd1e0 | ||
|
|
04f61567ba | ||
|
|
a0785cdbc1 | ||
|
|
94101e8bb8 | ||
|
|
f13dbf2f26 | ||
|
|
bae6f06e4e | ||
|
|
d8b9e23502 | ||
|
|
7d59eaa67e | ||
|
|
c0a453f64f | ||
|
|
5336175736 | ||
|
|
2997e4950b | ||
|
|
a49fb90d86 | ||
|
|
ffc0eb1de2 | ||
|
|
853c81eb62 | ||
|
|
594cc7cbef | ||
|
|
0932324d39 | ||
|
|
2d6cf236c4 | ||
|
|
642107a28f | ||
|
|
581b38ecf4 | ||
|
|
fbc03cc262 | ||
|
|
a6ff195893 | ||
|
|
f411724064 | ||
|
|
39f43a4cd4 | ||
|
|
c82cb918ae | ||
|
|
38cdaa6c20 | ||
|
|
0327069e83 | ||
|
|
7601b029c8 | ||
|
|
fb509dfc25 | ||
|
|
874a91968f | ||
|
|
0963ccddba | ||
|
|
c4e0f6df08 | ||
|
|
58aafe9520 | ||
|
|
a46df7f8ec | ||
|
|
1dd16618d1 | ||
|
|
a4190f83ac | ||
|
|
a8e17f73ec | ||
|
|
86a741c1ee | ||
|
|
5cc6fef689 | ||
|
|
522a5fe480 | ||
|
|
b1239b1257 | ||
|
|
58063d9ee1 | ||
|
|
d7aba2dece | ||
|
|
35fced27df | ||
|
|
be76b19300 | ||
|
|
376d696b8b | ||
|
|
695d61968d | ||
|
|
d6d09fd3c8 | ||
|
|
f1b1501f9b | ||
|
|
cdbc99e992 | ||
|
|
69afe7785d | ||
|
|
b99e304f1e | ||
|
|
c29bd46e7a | ||
|
|
5fcf40b973 | ||
|
|
a198dfe3d8 | ||
|
|
5b10d157fe | ||
|
|
5cc42b18b0 | ||
|
|
cb4252e888 | ||
|
|
09d3cdb023 | ||
|
|
71515a8a11 | ||
|
|
11ca8dd54f | ||
|
|
e00f22ebe6 | ||
|
|
13390543b0 | ||
|
|
de95ced92c | ||
|
|
f6a08472a0 | ||
|
|
9f7b101437 | ||
|
|
9c0707d4dc | ||
|
|
78a92fb6be | ||
|
|
01509cf1a5 | ||
|
|
61e9f51274 | ||
|
|
201bd9d42e | ||
|
|
8a78f08f6c | ||
|
|
a5e54f9712 | ||
|
|
526834e39b | ||
|
|
bdde2476d2 | ||
|
|
3171f9debe | ||
|
|
0e2aeac5f9 | ||
|
|
788fb5547c | ||
|
|
c4d2c0ee64 | ||
|
|
977686a77a | ||
|
|
44b29f210c | ||
|
|
36c7d65ccf | ||
|
|
b81d24fdb4 | ||
|
|
bfdbee8115 | ||
|
|
4a17c8f4a9 | ||
|
|
d4f67a7d42 | ||
|
|
d5769ae409 | ||
|
|
f356b61e5a | ||
|
|
398768dcbd | ||
|
|
272d5b6e4a | ||
|
|
a479aa2594 | ||
|
|
f48d620ac5 | ||
|
|
0684b42f67 | ||
|
|
190a31dd5f | ||
|
|
cccfc7faca | ||
|
|
5e9e4f8c73 | ||
|
|
b28e48094b | ||
|
|
01bad21704 | ||
|
|
aab9a20b6a | ||
|
|
201c5b23f3 | ||
|
|
b79e11bef8 | ||
|
|
81dfcb85ca | ||
|
|
c8e69a2154 | ||
|
|
3ee50adad9 | ||
|
|
d1386ee8e4 | ||
|
|
6b994602d5 | ||
|
|
00039bbb47 | ||
|
|
0195b2f7c0 | ||
|
|
adc60f3212 | ||
|
|
579f59816f | ||
|
|
9e0df3c5c6 | ||
|
|
c6b14ef97e | ||
|
|
59e535244f | ||
|
|
720b9dd3d2 | ||
|
|
60df5b4381 | ||
|
|
94a4dc4576 | ||
|
|
dbda223858 | ||
|
|
822875d5c3 | ||
|
|
b11b28b83b | ||
|
|
ea0770ae22 | ||
|
|
bdc9f293be | ||
|
|
922d73a09b | ||
|
|
46292fbdc5 | ||
|
|
3b1330880f | ||
|
|
213e38c2ef | ||
|
|
76f09b1e49 | ||
|
|
cff0b81f32 | ||
|
|
23d6c4dcc0 | ||
|
|
66c86109dd | ||
|
|
2e45be96b6 | ||
|
|
5d1626aba1 | ||
|
|
b7f083b1da | ||
|
|
2bce1f1510 | ||
|
|
1683f4953e | ||
|
|
1b2c67a726 | ||
|
|
e1d9bdbbd6 | ||
|
|
58827ba36d | ||
|
|
9ef1bc7273 | ||
|
|
a347ed9912 | ||
|
|
99d32d2add | ||
|
|
2d03e1974a | ||
|
|
07cae5377a | ||
|
|
436cac4134 | ||
|
|
117fcc9743 | ||
|
|
6d969250ca | ||
|
|
d68d1d1371 | ||
|
|
7d8b9b257a | ||
|
|
f237e42737 | ||
|
|
ca095acd34 | ||
|
|
630c70f13c | ||
|
|
ebb39bcbe2 | ||
|
|
9cf2ec8bd2 | ||
|
|
5f6745cad0 | ||
|
|
d8fd7b5a44 | ||
|
|
f8abe073eb | ||
|
|
0608413b96 | ||
|
|
7f8a1ec1fb | ||
|
|
e859fc8f16 | ||
|
|
2f9b0f8820 | ||
|
|
d66fcb60b1 | ||
|
|
2937cd7e77 | ||
|
|
c62e7a6a82 | ||
|
|
92f1aec3dd | ||
|
|
bc4462cd0c | ||
|
|
1ce5ed8685 | ||
|
|
433b28b223 | ||
|
|
3fe45e29e4 |
3
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
||||
[submodule "data/theme/gnome-shell-sass"]
|
||||
path = data/theme/gnome-shell-sass
|
||||
url = https://git.gnome.org/browse/gnome-shell-sass
|
||||
[submodule "subprojects/gvc"]
|
||||
path = subprojects/gvc
|
||||
url = https://git.gnome.org/browse/libgnome-volume-control
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
Coding guide
|
||||
============
|
||||
# Coding guide
|
||||
|
||||
Our goal is to have all JavaScript code in GNOME follow a consistent style. In
|
||||
a dynamic language like JavaScript, it is essential to be rigorous about style
|
||||
(and unit tests), or you rapidly end up with a spaghetti-code mess.
|
||||
|
||||
A quick note
|
||||
------------
|
||||
## A quick note
|
||||
|
||||
Life isn't fun if you can't break the rules. If a rule seems unnecessarily
|
||||
restrictive while you're coding, ignore it, and let the patch reviewer decide
|
||||
what to do.
|
||||
|
||||
Indentation and whitespace
|
||||
--------------------------
|
||||
## Indentation and whitespace
|
||||
|
||||
Use four-space indents. Braces are on the same line as their associated
|
||||
statements. You should only omit braces if *both* sides of the statement are
|
||||
@@ -22,7 +19,7 @@ on one line.
|
||||
* One space after the `function` keyword. No space between the function name
|
||||
* in a declaration or a call. One space before the parens in the `if`
|
||||
* statements, or `while`, or `for` loops.
|
||||
|
||||
```javascript
|
||||
function foo(a, b) {
|
||||
let bar;
|
||||
|
||||
@@ -39,22 +36,20 @@ on one line.
|
||||
print(20);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Semicolons
|
||||
----------
|
||||
## Semicolons
|
||||
|
||||
JavaScript allows omitting semicolons at the end of lines, but don't. Always
|
||||
end statements with a semicolon.
|
||||
|
||||
js2-mode
|
||||
--------
|
||||
## js2-mode
|
||||
|
||||
If using Emacs, do not use js2-mode. It is outdated and hasn't worked for a
|
||||
while. emacs now has a built-in JavaScript mode, js-mode, based on
|
||||
espresso-mode. It is the de facto emacs mode for JavaScript.
|
||||
|
||||
File naming and creation
|
||||
------------------------
|
||||
## File naming and creation
|
||||
|
||||
For JavaScript files, use lowerCamelCase-style names, with a `.js` extension.
|
||||
|
||||
@@ -67,14 +62,13 @@ library name followed by a dash, e.g. `shell-app-system.c`. Create a
|
||||
`-private.h` header when you want to share code internally in the
|
||||
library. These headers are not installed, distributed or introspected.
|
||||
|
||||
Imports
|
||||
-------
|
||||
## Imports
|
||||
|
||||
Use UpperCamelCase when importing modules to distinguish them from ordinary
|
||||
variables, e.g.
|
||||
|
||||
```javascript
|
||||
const GLib = imports.gi.GLib;
|
||||
|
||||
```
|
||||
Imports should be categorized into one of two places. The top-most import block
|
||||
should contain only "environment imports". These are either modules from
|
||||
gobject-introspection or modules added by gjs itself.
|
||||
@@ -85,7 +79,7 @@ e.g. `imports.ui.popupMenu`.
|
||||
|
||||
Each import block should be sorted alphabetically. Don't import modules you
|
||||
don't use.
|
||||
|
||||
```javascript
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
@@ -95,23 +89,22 @@ don't use.
|
||||
const Params = imports.misc.params;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
```
|
||||
The alphabetical ordering should be done independently of the location of the
|
||||
location. Never reference `imports` in actual code.
|
||||
|
||||
Constants
|
||||
---------
|
||||
## Constants
|
||||
|
||||
We use CONSTANTS_CASE to define constants. All constants should be directly
|
||||
under the imports:
|
||||
|
||||
```javascript
|
||||
const MY_DBUS_INTERFACE = 'org.my.Interface';
|
||||
```
|
||||
|
||||
Variable declaration
|
||||
--------------------
|
||||
## Variable declaration
|
||||
|
||||
Always use either `const` or `let` when defining a variable.
|
||||
|
||||
```javascript
|
||||
// Iterating over an array
|
||||
for (let i = 0; i < arr.length; ++i) {
|
||||
let item = arr[i];
|
||||
@@ -121,31 +114,32 @@ Always use either `const` or `let` when defining a variable.
|
||||
for (let prop in someobj) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
If you use "var" then the variable is added to function scope, not block scope.
|
||||
See [What's new in JavaScript 1.7](https://developer.mozilla.org/en/JavaScript/New_in_JavaScript/1.7#Block_scope_with_let_%28Merge_into_let_Statement%29)
|
||||
|
||||
Classes
|
||||
-------
|
||||
## Classes
|
||||
|
||||
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 = new Lang.Class({
|
||||
Name: 'IconLabelMenuItem',
|
||||
Extends: PopupMenu.PopupMenuBaseItem,
|
||||
|
||||
_init: function(icon, label) {
|
||||
_init(icon, label) {
|
||||
this.parent({ reactive: false });
|
||||
this.actor.add_child(icon);
|
||||
this.actor.add_child(label);
|
||||
},
|
||||
|
||||
open: function() {
|
||||
open() {
|
||||
log("menu opened!");
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
* 'Name' is required. 'Extends' is optional. If you leave it out, you will
|
||||
automatically inherit from Object.
|
||||
@@ -162,35 +156,34 @@ GObjects, although this feature isn't used very often in the Shell itself.
|
||||
still a giant function call, even though it may resemble a more
|
||||
conventional syntax.
|
||||
|
||||
GObject Introspection
|
||||
---------------------
|
||||
## 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 = new Lang.Class({
|
||||
Name: 'MyClutterActor',
|
||||
Extends: Clutter.Actor,
|
||||
|
||||
vfunc_get_preferred_width: function(actor, forHeight) {
|
||||
vfunc_get_preferred_width(actor, forHeight) {
|
||||
return [100, 100];
|
||||
},
|
||||
|
||||
vfunc_get_preferred_height: function(actor, forWidth) {
|
||||
vfunc_get_preferred_height(actor, forWidth) {
|
||||
return [100, 100];
|
||||
},
|
||||
|
||||
vfunc_paint: function(actor) {
|
||||
vfunc_paint(actor) {
|
||||
let alloc = this.get_allocation_box();
|
||||
Cogl.set_source_color4ub(255, 0, 0, 255);
|
||||
Cogl.rectangle(alloc.x1, alloc.y1,
|
||||
alloc.x2, alloc.y2);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Translatable strings, `environment.js`
|
||||
--------------------------------------
|
||||
## Translatable strings, `environment.js`
|
||||
|
||||
We use gettext to translate the GNOME Shell into all the languages that GNOME
|
||||
supports. The `gettext` function is aliased globally as `_`, you do not need to
|
||||
@@ -204,8 +197,7 @@ and "double quotes" for strings that the user may see. This allows us to
|
||||
quickly find untranslated or mistranslated strings by grepping through the
|
||||
sources for double quotes without a gettext call around them.
|
||||
|
||||
`actor` and `_delegate`
|
||||
-----------------------
|
||||
## `actor` and `_delegate`
|
||||
|
||||
gjs allows us to set so-called "expando properties" on introspected objects,
|
||||
allowing us to treat them like any other. Because the Shell was built before
|
||||
@@ -214,21 +206,22 @@ 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 = new Lang.Class({
|
||||
Name: 'MyClass',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this.actor = new St.Button({ text: "This is a button" });
|
||||
this.actor._delegate = this;
|
||||
|
||||
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
||||
this.actor.connect('clicked', this._onClicked.bind(this));
|
||||
},
|
||||
|
||||
_onClicked: function(actor) {
|
||||
_onClicked(actor) {
|
||||
actor.set_label("You clicked the button!");
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
The 'delegate' property is important for anything which trying to get the
|
||||
delegate object from an associated actor. For instance, the drag and drop
|
||||
@@ -236,57 +229,60 @@ system calls the `handleDragOver` function on the delegate of a "drop target"
|
||||
when the user drags an item over it. If you do not set the `_delegate`
|
||||
property, your actor will not be able to be dropped onto.
|
||||
|
||||
Functional style
|
||||
----------------
|
||||
## Functional style
|
||||
|
||||
JavaScript Array objects offer a lot of common functional programming
|
||||
capabilities such as forEach, map, filter and so on. You can use these when
|
||||
they make sense, but please don't have a spaghetti mess of function programming
|
||||
messed in a procedural style. Use your best judgment.
|
||||
|
||||
Closures
|
||||
--------
|
||||
## Closures
|
||||
|
||||
`this` will not be captured in a closure, it is relative to how the closure is
|
||||
invoked, not to the value of this where the closure is created, because "this"
|
||||
is a keyword with a value passed in at function invocation time, it is not a
|
||||
variable that can be captured in closures.
|
||||
|
||||
All closures should be wrapped with a Lang.bind.
|
||||
|
||||
All closures should be wrapped with Function.prototype.bind or use arrow
|
||||
notation.
|
||||
```javascript
|
||||
const Lang = imports.lang;
|
||||
|
||||
let closure = Lang.bind(this, function() { this._fnorbate(); });
|
||||
let closure1 = () => { this._fnorbate(); };
|
||||
let closure2 = this._fnorbate.bind(this);
|
||||
```
|
||||
|
||||
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 = new Lang.Class({
|
||||
_init: function() {
|
||||
_init() {
|
||||
let fnorb = new FnorbLib.Fnorb();
|
||||
fnorb.connect('frobate', Lang.bind(this, this._onFnorbFrobate));
|
||||
fnorb.connect('frobate', this._onFnorbFrobate.bind(this));
|
||||
},
|
||||
|
||||
_onFnorbFrobate: function(fnorb) {
|
||||
_onFnorbFrobate(fnorb) {
|
||||
this._updateFnorb();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Object literal syntax
|
||||
---------------------
|
||||
## Object literal syntax
|
||||
|
||||
In JavaScript, these are equivalent:
|
||||
|
||||
```javascript
|
||||
foo = { 'bar': 42 };
|
||||
foo = { bar: 42 };
|
||||
```
|
||||
|
||||
and so are these:
|
||||
|
||||
```javascript
|
||||
var b = foo['bar'];
|
||||
var b = foo.bar;
|
||||
```
|
||||
|
||||
If your usage of an object is like an object, then you're defining "member
|
||||
variables." For member variables, use the no-quotes no-brackets syntax: `{ bar:
|
||||
@@ -296,20 +292,19 @@ If your usage of an object is like a hash table (and thus conceptually the keys
|
||||
can have special chars in them), don't use quotes, but use brackets: `{ bar: 42
|
||||
}`, `foo['bar']`.
|
||||
|
||||
Getters, setters, and Tweener
|
||||
-----------------------------
|
||||
## Getters, setters, and Tweener
|
||||
|
||||
Getters and setters should be used when you are dealing with an API that is
|
||||
designed around setting properties, like Tweener. If you want to animate an
|
||||
arbitrary property, create a getter and setter, and use Tweener to animate the
|
||||
property.
|
||||
|
||||
```javascript
|
||||
var ANIMATION_TIME = 2000;
|
||||
|
||||
var MyClass = new Lang.Class({
|
||||
Name: 'MyClass',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this.actor = new St.BoxLayout();
|
||||
this._position = 0;
|
||||
},
|
||||
@@ -329,3 +324,4 @@ property.
|
||||
{ position: 100,
|
||||
time: ANIMATION_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
```
|
||||
@@ -1,7 +0,0 @@
|
||||
Owen Taylor
|
||||
E-mail: otaylor@redhat.com
|
||||
Userid: otaylor
|
||||
|
||||
Colin Walters
|
||||
E-mail: walters@verbum.org
|
||||
Userid: walters
|
||||
208
NEWS
@@ -1,3 +1,211 @@
|
||||
3.30.0
|
||||
======
|
||||
|
||||
Contributors:
|
||||
Harry Mallon, Marco Trevisan (Treviño)
|
||||
|
||||
Translators:
|
||||
Fran Dieguez [gl], Trần Ngọc Quân [vi], Balázs Meskó [hu],
|
||||
Rūdolfs Mazurs [lv], Jiri Grönroos [fi], Anders Jonsson [sv], gogo [hr],
|
||||
Ask Hjorth Larsen [da]
|
||||
|
||||
3.29.92
|
||||
=======
|
||||
* Choose some actors to cache on the GPU [Daniel; #792633]
|
||||
* inputMethod: Hide preedit text if requested [Takao; #431]
|
||||
* Fix forced fallback app-menus on wayland [Jonas; #276]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Takao Fujiwara, Mohammed Sadiq, Marco Trevisan (Treviño),
|
||||
Daniel van Vugt
|
||||
|
||||
Translators:
|
||||
Baurzhan Muftakhidinov [kk], Kukuh Syafaat [id], Milo Casagrande [it],
|
||||
Changwoo Ryu [ko], Marek Cernocky [cs]
|
||||
|
||||
3.29.91
|
||||
=======
|
||||
* Fix handling of 0/false options in ShowOSD D-Bus API [Florian; #791669]
|
||||
* overview: Fix handling of confirmation dialogs on wayland [verdre; !180]
|
||||
* Avoid some full relayout/redraws [Carlos; !197]
|
||||
* Keep workspace switcher slid out when workspaces are in use [Florian; !161]
|
||||
* Ignore auto-repeat for some keybindings [Andrea; #373]
|
||||
* Misc. bug fixes [Carlos, Florian, Pascal; #464, !189, !191, !192, !162]
|
||||
|
||||
Contributors:
|
||||
Andrea Azzarone, Olivier Blin, Carlos Garnacho, Florian Müllner,
|
||||
Pascal Nowack, verdre
|
||||
|
||||
Translators:
|
||||
Bruno Lopes da Silva [pt_BR], Matej Urbančič [sl], Piotr Drąg [pl],
|
||||
Aurimas Černius [lt], Emin Tufan Çetin [tr], Fabio Tomat [fur],
|
||||
Alexandre Franke [fr], Yi-Jyun Pan [zh_TW], Bernd Homuth [de],
|
||||
Andre Klapper [cs], Jordi Mas [ca], Daniel Șerbănescu [ro],
|
||||
Bruce Cowan [en_GB]
|
||||
|
||||
3.29.90
|
||||
=======
|
||||
* Add remote access indication on wayland [Jonas; !160]
|
||||
* Fix wrong window positions in overview on wayland [Marco; #776588]
|
||||
* Add gesture to unfullscreen a window [Jan-Michael; !123]
|
||||
* Add PickColor method to screenshot D-Bus interface [Florian; #286]
|
||||
* Consider "new-window" action when opening new windows [Florian; #756844]
|
||||
* Make workspace switching gestures follow motion [Carlos; #788994]
|
||||
* Support audio volumes above 100% [Didier; #790280]
|
||||
* Misc. bug fixes [Florian, Daniel; #424, !132, !182, #433, !179, #786496]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Jan-Michael Brummer, Piotr Drąg, Daniel Drake, Carlos Garnacho,
|
||||
Florian Müllner, Georges Basile Stavracas Neto, Didier Roche, Jakub Steiner,
|
||||
Marco Trevisan (Treviño)
|
||||
|
||||
Translators:
|
||||
Charles Monzat [fr], Daniel Mustieles [es]
|
||||
|
||||
3.29.4
|
||||
======
|
||||
* Fix "Clear All" for calendar events [Florian; #325]
|
||||
* Allow cancelling direct switch operations [Xavier; #315]
|
||||
* Support being started by systemd --user [Iain; !137, !138]
|
||||
* Support key event forwarding required by some input methods [Carlos; #275]
|
||||
* Misc. bug fixes and cleanups [Jasper, Andrea, Florian; #663461, #372, !112,
|
||||
#414, !151]
|
||||
|
||||
Contributors:
|
||||
Andrea Azzarone, Carlos Garnacho, Xavier Johnson, Iain Lane, Florian Müllner,
|
||||
Jasper St. Pierre
|
||||
|
||||
Translators:
|
||||
Stas Solovey [ru]
|
||||
|
||||
3.29.3
|
||||
======
|
||||
* Save creation time in screenshot metadata [Florian; #790481]
|
||||
* Improve consistency between ctrl- and middle-click on app icons [Xavier; #316]
|
||||
* Add support for font-feature-settings CSS property [Ryan; #34]
|
||||
* Adjust to MetaScreen removal [Jonas; #759538]
|
||||
* Misc. bug fixes [Florian, Marco, Sam; #298, #788931, #26, #76, !54, #788882,
|
||||
#791233]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Ryan Hendrickson, Xavier Johnson, Florian Müllner, Joe Rabinoff,
|
||||
Sam Spilsbury, Marco Trevisan (Treviño)
|
||||
|
||||
Translators:
|
||||
Gun Chleoc [gd], Yi-Jyun Pan [zh_TW], Cédric Valmary [oc], Jordi Mas [ca]
|
||||
|
||||
3.29.2
|
||||
======
|
||||
* Guard against untimely keyboard map changes [Carlos; #240]
|
||||
* Fix icons in search provider results [Florian; #249]
|
||||
* Fix blurriness of OSD under some resolutions [Silvère; #782011]
|
||||
* Fix lagging pointer when zoomed [Daniel; #682013]
|
||||
* Misc. bug fixes [Milan, Xiaoguang, Florian, Mario, Ole; #244, #787871,
|
||||
#781471, #136, #214, #294]
|
||||
|
||||
Contributors:
|
||||
Ole Jørgen Brønner, Milan Crha, Carlos Garnacho, Yussuf Khalil,
|
||||
Silvère Latchurié, Florian Müllner, Mario Sanchez Prada, Ray Strode,
|
||||
Daniel van Vugt, Xiaoguang Wang
|
||||
|
||||
Translators:
|
||||
Rafael Fontenelle [pt_BR], Kukuh Syafaat [id], Marcos Lans [gl],
|
||||
Anders Jonsson [sv], Mingcong Bai [zh_CN]
|
||||
|
||||
3.29.1
|
||||
======
|
||||
* Support icons in app-menu [Florian; #760985]
|
||||
* Misc. bug fixes [Marco, Florian, Lubomir; #792687, #221, !63]
|
||||
|
||||
Contributors:
|
||||
Piotr Drąg, Takao Fujiwara, Christian Kellner, Florian Müllner,
|
||||
Mario Sanchez Prada, Lubomir Rintel, Didier Roche, Marco Trevisan (Treviño),
|
||||
verdre
|
||||
|
||||
Translators:
|
||||
gogo [hr], Stas Solovey [ru], Matej Urbančič [sl], Daniel Șerbănescu [ro],
|
||||
Fabio Tomat [fur], Marek Cernocky [cs], Daniel Mustieles [es]
|
||||
|
||||
3.28.1
|
||||
======
|
||||
* Fix compose characters in shell entries [Carlos; #115]
|
||||
* Don't show authentication dialogs on lock screen [Florian; #179, #166]
|
||||
* Fix handling of UTC timezone in world clock [Florian; #150]
|
||||
* Fix keyboard navigation in overview when hovering windows [Florian; #50]
|
||||
* Misc. bug fixes [Florian; #127, #788908, #763886, !39]
|
||||
|
||||
Contributors:
|
||||
Jeremy Bicha, Carlos Garnacho, Andy Holmes, Florian Müllner, Bastien Nocera
|
||||
|
||||
Translators:
|
||||
Stas Solovey [ru], Daniel Șerbănescu [ro], Dušan Kazik [sk],
|
||||
Rafael Fontenelle [pt_BR], Nathan Follens [nl], Dz Chen [zh_CN],
|
||||
Matej Urbančič [sl], Hannie Dumoleyn [nl], Khaled Hosny [ar],
|
||||
Guillaume Bernard [fr]
|
||||
|
||||
3.28.0
|
||||
======
|
||||
|
||||
Translators:
|
||||
A S Alam [pa], gogo [hr], Chao-Hsiung Liao [zh_TW], Jordi Mas [ca],
|
||||
Anders Jonsson [sv], Balázs Úr [hu]
|
||||
|
||||
3.27.92
|
||||
=======
|
||||
* Misc. bug fixes [Florian; #64, #66, #72]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Christian Kellner, Florian Müllner
|
||||
|
||||
Translators:
|
||||
Daniel Mustieles [es], Wolfgang Stöggl [de], Cheng-Chia Tseng [zh_TW],
|
||||
Dušan Kazik [sk], Changwoo Ryu [ko], Furkan Ahmet Kara [tr], Balázs Úr [hu],
|
||||
Trần Ngọc Quân [vi], Milo Casagrande [it], GNOME Translation Robot [gd, nl],
|
||||
Marek Cernocky [cs], Aurimas Černius [lt], Alain Lojewski [fr],
|
||||
Rūdolfs Mazurs [lv], Stas Solovey [ru], Alan Mortensen [da]
|
||||
|
||||
3.27.91
|
||||
=======
|
||||
* Fix wrong bluetooth state when disabled by HW airplane mode [Mario; #789110]
|
||||
* Dump javascript stack on aborts, traps and segfaults [Marco; #789237]
|
||||
* Allow Escape to "cancel" top bar focus [Stefano; #671121]
|
||||
* Fix leaving the overview erroneously on window hover [Carlos; #784545]
|
||||
* Add keyboard accessibility dialog [Olivier; #788564]
|
||||
* Port to libnm [Lubomir, Florian; #789811]
|
||||
* Don't pop up on-screen-keyboard on touch events [Florian, Carlos; #788188]
|
||||
* Improve the on-screen-keyboard [Carlos; !9, #46]
|
||||
* Add Thunderbolt support [Christian; !14]
|
||||
* Don't lock immediately on login after a wayland session crash [Florian; !17]
|
||||
* Respect cursor's hot x/y coordinates when recording [Florian Z.; #792860]
|
||||
* Allow closing windows and apps during <alt>Tab [Florian, Mario; #620106]
|
||||
* Fix small app folder icons when using HiDPI [Nikita; #792259]
|
||||
* Make sassc a mandatory build dependency [Mario; #792822]
|
||||
* Misc. bug fixes [Florian, Marco, Alessandro, Gautier, Jeremy, Bastien, Ray,
|
||||
Carlos, Didier, Exalm, Rafal; #789231, #789277, #788542, #789103, #779974,
|
||||
#788931, #776940, #786987, #791007, #791233, #791148, #706191, #791655,
|
||||
#791487, #779413, #787845, #10, #788627, #792354, #792616, #781329, #780957,
|
||||
#33, #740142, !38, !23]
|
||||
|
||||
Contributors:
|
||||
Jeremy Bicha, Alessandro Bono, Nikita Churaev, Piotr Drąg, Exalm,
|
||||
Stefano Facchini, Olivier Fourdan, Carlos Garnacho, Christian Kellner,
|
||||
Rafal Luzynski, Iñigo Martínez, Florian Müllner, Bastien Nocera,
|
||||
Gautier Pelloux-Prayer, Mario Sanchez Prada, Lubomir Rintel, Didier Roche,
|
||||
Jakub Steiner, Ray Strode, Marco Trevisan (Treviño), Florian Zwoch
|
||||
|
||||
Translators:
|
||||
Mingcong Bai [zh_CN], Hannie Dumoleyn [nl], Khaled Hosny [ar],
|
||||
Kjartan Maraas [nb], Petr Kovar [cs], Marek Cernocky [cs],
|
||||
Aurimas Černius [lt], Yosef Or Boczko [he], Kukuh Syafaat [id],
|
||||
Sveinn í Felli [is], Jordi Mas [ca], Daniel Mustieles [es], Fabio Tomat [fur],
|
||||
Rūdolfs Mazurs [lv], Emin Tufan Çetin [tr], Anders Jonsson [sv],
|
||||
Matej Urbančič [sl], Jiri Grönroos [fi], Tim Sabsch [de], Gil Forcada [ca],
|
||||
Dušan Kazik [sk], Balázs Meskó [hu], Piotr Drąg [pl], Tong Hui [zh_CN],
|
||||
Fran Dieguez [gl], Enrico Nicoletto [pt_BR], gogo [hr],
|
||||
Baurzhan Muftakhidinov [kk], Robert Antoni Buj Gelonch [ca],
|
||||
Bruce Cowan [en_GB], Борисав Живановић [sr], Милош Поповић [sr@latin],
|
||||
Марко Костић [sr]
|
||||
|
||||
3.27.1
|
||||
======
|
||||
* Fix using icon-name strings with PopupImageMenuItems [Florian; #789018]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# GNOME Shell
|
||||
GNOME Shell provides core user interface functions for the GNOME 3 desktop,
|
||||
like switching to windows and launching applications. GNOME Shell takes
|
||||
advantage of the capabilities of modern graphics hardware and introduces
|
||||
@@ -6,15 +7,14 @@ easy to use experience.
|
||||
|
||||
For more information about GNOME Shell, including instructions on how
|
||||
to build GNOME Shell from source and how to get involved with the project,
|
||||
see:
|
||||
see the [project wiki][project-wiki].
|
||||
|
||||
https://wiki.gnome.org/Projects/GnomeShell
|
||||
Bugs should be reported to the GNOME [bug tracking system][bug-tracker].
|
||||
|
||||
Bugs should be reported at http://bugzilla.gnome.org against the 'gnome-shell'
|
||||
product.
|
||||
|
||||
License
|
||||
=======
|
||||
## License
|
||||
GNOME Shell is distributed under the terms of the GNU General Public License,
|
||||
version 2 or later. See the COPYING file for details.
|
||||
version 2 or later. See the [COPYING][license] file for details.
|
||||
|
||||
[project-wiki]: https://wiki.gnome.org/Projects/GnomeShell
|
||||
[bug-tracker]: https://gitlab.gnome.org/GNOME/gnome-shell/issues
|
||||
[license]: COPYING
|
||||
@@ -4,14 +4,14 @@ the extensions repository to provide good integration, letting the website
|
||||
know which extensions are enabled and disabled, and allowing the website to
|
||||
enable, disable and install them.
|
||||
|
||||
Bugs should be reported at http://bugzilla.gnome.org against the 'gnome-shell'
|
||||
product.
|
||||
Bugs should be reported to the GNOME [bug tracking system][bug-tracker].
|
||||
|
||||
License
|
||||
=======
|
||||
## License
|
||||
The GNOME Shell Browser Plugin, like GNOME Shell itself is distributed under
|
||||
the GNU General Public License, version 2 or later. The plugin also contains
|
||||
header files from the "NPAPI SDK" project, tri-licensed under MPL 1.1, GPL 2.0
|
||||
and LGPL 2.1. These headers are third-party sources and can be retrieved from:
|
||||
|
||||
http://code.google.com/p/npapi-sdk/
|
||||
|
||||
[bug-tracker]: https://gitlab.gnome.org/GNOME/gnome-shell/issues
|
||||
@@ -24,3 +24,9 @@
|
||||
|
||||
/* Define if _NL_TIME_FIRST_WEEKDATE is available */
|
||||
#mesondefine HAVE__NL_TIME_FIRST_WEEKDAY
|
||||
|
||||
/* Define if you have the `g_desktop_app_info_launch_uris_as_manager_with_fds` function */
|
||||
#mesondefine HAVE_GIO_DESKTOP_LAUNCH_URIS_WITH_FDS
|
||||
|
||||
/* Define if fdwalk is available in libc */
|
||||
#mesondefine HAVE_FDWALK
|
||||
|
||||
6
data/00_org.gnome.shell.gschema.override
Normal file
@@ -0,0 +1,6 @@
|
||||
[org.gnome.mutter:GNOME]
|
||||
attach-modal-dialogs=true
|
||||
edge-tiling=true
|
||||
dynamic-workspaces=true
|
||||
workspaces-only-on-primary=true
|
||||
focus-change-on-pointer-rest=true
|
||||
@@ -22,6 +22,7 @@
|
||||
<file>id.json</file>
|
||||
<file>il.json</file>
|
||||
<file>in+bolnagri.json</file>
|
||||
<file>in+mal.json</file>
|
||||
<file>ir.json</file>
|
||||
<file>is.json</file>
|
||||
<file>it.json</file>
|
||||
|
||||
5
data/gnome-shell-overrides-migration.desktop.in
Normal file
@@ -0,0 +1,5 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=GNOME settings overrides migration
|
||||
NoDisplay=true
|
||||
Exec=@libexecdir@/gnome-shell-overrides-migration.sh
|
||||
@@ -11,15 +11,17 @@
|
||||
<file>close-window.svg</file>
|
||||
<file>close-window-active.svg</file>
|
||||
<file>close-window-hover.svg</file>
|
||||
<file>close.svg</file>
|
||||
<file>corner-ripple-ltr.png</file>
|
||||
<file>corner-ripple-rtl.png</file>
|
||||
<file>dash-placeholder.svg</file>
|
||||
<file>filter-selected-ltr.svg</file>
|
||||
<file>filter-selected-rtl.svg</file>
|
||||
<file>gnome-shell.css</file>
|
||||
<file>gnome-shell-high-contrast.css</file>
|
||||
<file>logged-in-indicator.svg</file>
|
||||
<file>key-enter.svg</file>
|
||||
<file>key-hide.svg</file>
|
||||
<file>key-layout.svg</file>
|
||||
<file>key-shift.svg</file>
|
||||
<file>key-shift-uppercase.svg</file>
|
||||
<file>key-shift-latched-uppercase.svg</file>
|
||||
<file alias="icons/message-indicator-symbolic.svg">message-indicator-symbolic.svg</file>
|
||||
<file>no-events.svg</file>
|
||||
<file>no-notifications.svg</file>
|
||||
@@ -30,16 +32,11 @@
|
||||
<file>page-indicator-checked.svg</file>
|
||||
<file>page-indicator-hover.svg</file>
|
||||
<file>process-working.svg</file>
|
||||
<file>running-indicator.svg</file>
|
||||
<file>source-button-border.svg</file>
|
||||
<file>summary-counter.svg</file>
|
||||
<file>toggle-off-us.svg</file>
|
||||
<file>toggle-off-intl.svg</file>
|
||||
<file>toggle-off-hc.svg</file>
|
||||
<file>toggle-on-us.svg</file>
|
||||
<file>toggle-on-intl.svg</file>
|
||||
<file>toggle-on-hc.svg</file>
|
||||
<file>ws-switch-arrow-up.png</file>
|
||||
<file>ws-switch-arrow-down.png</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
5
data/gnome-shell-wayland.target
Normal file
@@ -0,0 +1,5 @@
|
||||
[Unit]
|
||||
Description=GNOME Shell (wayland sync point)
|
||||
After=gnome-shell.service
|
||||
BindsTo=gnome-shell.service
|
||||
Conflicts=gnome-shell-x11.target
|
||||
5
data/gnome-shell-x11.target
Normal file
@@ -0,0 +1,5 @@
|
||||
[Unit]
|
||||
Description=GNOME Shell (x11 sync point)
|
||||
After=gnome-shell.service
|
||||
BindsTo=gnome-shell.service
|
||||
Conflicts=gnome-shell-wayland.target
|
||||
11
data/gnome-shell.service.in
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=GNOME Shell
|
||||
Wants=gnome-session.service
|
||||
After=graphical-session-pre.target gnome-session-bus.target
|
||||
PartOf=graphical-session.target
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
ExecStart=@bindir@/gnome-shell
|
||||
Restart=on-failure
|
||||
BusName=org.gnome.Shell
|
||||
@@ -92,6 +92,33 @@ schema = configure_file(
|
||||
configuration: schemaconf,
|
||||
install_dir: schemadir
|
||||
)
|
||||
install_data('00_org.gnome.shell.gschema.override', install_dir: schemadir)
|
||||
|
||||
overrides_migration_conf = configuration_data()
|
||||
overrides_migration_conf.set('libexecdir', libexecdir)
|
||||
overrides_migration = configure_file(
|
||||
input: 'gnome-shell-overrides-migration.desktop.in',
|
||||
output: 'gnome-shell-overrides-migration.desktop',
|
||||
configuration: overrides_migration_conf,
|
||||
install_dir: autostartdir
|
||||
)
|
||||
|
||||
if have_systemd
|
||||
unitconf = configuration_data()
|
||||
unitconf.set('bindir', bindir)
|
||||
|
||||
unit = configure_file(
|
||||
input: 'gnome-shell.service.in',
|
||||
output: 'gnome-shell.service',
|
||||
configuration: unitconf,
|
||||
install_dir: systemduserunitdir
|
||||
)
|
||||
|
||||
units = files('gnome-shell-wayland.target',
|
||||
'gnome-shell-x11.target')
|
||||
|
||||
install_data(units, install_dir: systemduserunitdir)
|
||||
endif
|
||||
|
||||
# for unit tests - gnome.compile_schemas() only looks in srcdir
|
||||
custom_target('compile-schemas',
|
||||
|
||||
@@ -91,6 +91,23 @@
|
||||
<arg type="s" direction="out" name="filename_used"/>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
PickColor:
|
||||
|
||||
Picks a color and returns the result.
|
||||
|
||||
The @result vardict contains:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>color (ddd)</term>
|
||||
<listitem><para>The color, RGB values in the range [0,1].</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
-->
|
||||
<method name="PickColor">
|
||||
<arg type="a{sv}" direction="out" name="result"/>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
FlashArea:
|
||||
@x: the X coordinate of the area to flash
|
||||
|
||||
@@ -190,6 +190,7 @@
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
<!-- unused, change 00_org.gnome.shell.gschema.override instead -->
|
||||
<schema id="org.gnome.shell.overrides" path="/org/gnome/shell/overrides/"
|
||||
gettext-domain="@GETTEXT_PACKAGE@">
|
||||
<key name="attach-modal-dialogs" type="b">
|
||||
|
||||
559
data/osk-layouts/in+mal.json
Normal file
@@ -0,0 +1,559 @@
|
||||
{
|
||||
"levels": [
|
||||
{
|
||||
"level": "",
|
||||
"mode": "default",
|
||||
"rows": [
|
||||
[
|
||||
[
|
||||
"െ"
|
||||
],
|
||||
[
|
||||
"ൌ"
|
||||
],
|
||||
[
|
||||
"ൈ"
|
||||
],
|
||||
[
|
||||
"ാ"
|
||||
],
|
||||
[
|
||||
"ീ"
|
||||
],
|
||||
[
|
||||
"ൂ"
|
||||
],
|
||||
[
|
||||
"ബ"
|
||||
],
|
||||
[
|
||||
"ഹ"
|
||||
],
|
||||
[
|
||||
"ഗ"
|
||||
],
|
||||
[
|
||||
"ദ"
|
||||
],
|
||||
[
|
||||
"ജ"
|
||||
],
|
||||
[
|
||||
"ഡ"
|
||||
],
|
||||
[
|
||||
""
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"ോ"
|
||||
],
|
||||
[
|
||||
"േ"
|
||||
],
|
||||
[
|
||||
"്"
|
||||
],
|
||||
[
|
||||
"ി"
|
||||
],
|
||||
[
|
||||
"ു"
|
||||
],
|
||||
[
|
||||
"പ"
|
||||
],
|
||||
[
|
||||
"ര"
|
||||
],
|
||||
[
|
||||
"ക"
|
||||
],
|
||||
[
|
||||
"ത"
|
||||
],
|
||||
[
|
||||
"ച"
|
||||
],
|
||||
[
|
||||
"ട"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"െ"
|
||||
],
|
||||
[
|
||||
"ം"
|
||||
],
|
||||
[
|
||||
"മ",
|
||||
"ç"
|
||||
],
|
||||
[
|
||||
"ന"
|
||||
],
|
||||
[
|
||||
"വ"
|
||||
],
|
||||
[
|
||||
"ല",
|
||||
"ñ"
|
||||
],
|
||||
[
|
||||
"സ"
|
||||
],
|
||||
[
|
||||
"ഷ"
|
||||
],
|
||||
[
|
||||
"യ"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
","
|
||||
],
|
||||
[
|
||||
" "
|
||||
],
|
||||
[
|
||||
".",
|
||||
"#",
|
||||
"!",
|
||||
",",
|
||||
"?",
|
||||
"-",
|
||||
":",
|
||||
"'",
|
||||
"@"
|
||||
]
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"level": "shift",
|
||||
"mode": "latched",
|
||||
"rows": [
|
||||
[
|
||||
[
|
||||
"ഔ"
|
||||
],
|
||||
[
|
||||
"ഐ"
|
||||
],
|
||||
[
|
||||
"ആ"
|
||||
],
|
||||
[
|
||||
"ഈ"
|
||||
],
|
||||
[
|
||||
"ഊ"
|
||||
],
|
||||
[
|
||||
"ഭ"
|
||||
],
|
||||
[
|
||||
"ങ"
|
||||
],
|
||||
[
|
||||
"ഘ"
|
||||
],
|
||||
[
|
||||
"ധ"
|
||||
],
|
||||
[
|
||||
"ഝ"
|
||||
],
|
||||
[
|
||||
"ഢ"
|
||||
],
|
||||
[
|
||||
"ഞ"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"ഓ"
|
||||
],
|
||||
[
|
||||
"ഏ"
|
||||
],
|
||||
[
|
||||
"അ"
|
||||
],
|
||||
[
|
||||
"ഇ"
|
||||
],
|
||||
[
|
||||
"ഉ"
|
||||
],
|
||||
[
|
||||
"ഫ"
|
||||
],
|
||||
[
|
||||
"റ"
|
||||
],
|
||||
[
|
||||
"ഖ"
|
||||
],
|
||||
[
|
||||
"ഥ"
|
||||
],
|
||||
[
|
||||
"ഛ"
|
||||
],
|
||||
[
|
||||
"ഠ"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"എ"
|
||||
],
|
||||
[
|
||||
""
|
||||
],
|
||||
[
|
||||
"ണ"
|
||||
],
|
||||
[
|
||||
"ന"
|
||||
],
|
||||
[
|
||||
"ഴ"
|
||||
],
|
||||
[
|
||||
"ള"
|
||||
],
|
||||
[
|
||||
"ശ"
|
||||
],
|
||||
[
|
||||
"ഷ"
|
||||
],
|
||||
[
|
||||
"യ"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
","
|
||||
],
|
||||
[
|
||||
" "
|
||||
],
|
||||
[
|
||||
".",
|
||||
"#",
|
||||
"!",
|
||||
",",
|
||||
"?",
|
||||
"-",
|
||||
":",
|
||||
"'",
|
||||
"@"
|
||||
]
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"level": "opt",
|
||||
"mode": "locked",
|
||||
"rows": [
|
||||
[
|
||||
[
|
||||
"൧",
|
||||
"1",
|
||||
"¹",
|
||||
"½",
|
||||
"⅓",
|
||||
"¼",
|
||||
"⅛"
|
||||
],
|
||||
[
|
||||
"൨",
|
||||
"2",
|
||||
"²",
|
||||
"⅔"
|
||||
],
|
||||
[
|
||||
"൩",
|
||||
"3",
|
||||
"³",
|
||||
"¾",
|
||||
"⅜"
|
||||
],
|
||||
[
|
||||
"൪",
|
||||
"4",
|
||||
"⁴"
|
||||
],
|
||||
[
|
||||
"൫",
|
||||
"5",
|
||||
"⅝"
|
||||
],
|
||||
[
|
||||
"൬",
|
||||
"6"
|
||||
],
|
||||
[
|
||||
"൭",
|
||||
"7",
|
||||
"⅞"
|
||||
],
|
||||
[
|
||||
"൮",
|
||||
"8"
|
||||
],
|
||||
[
|
||||
"൯",
|
||||
"9"
|
||||
],
|
||||
[
|
||||
"൦",
|
||||
"0",
|
||||
"ⁿ",
|
||||
"∅"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"@"
|
||||
],
|
||||
[
|
||||
"#"
|
||||
],
|
||||
[
|
||||
"₹",
|
||||
"$",
|
||||
"¢",
|
||||
"£",
|
||||
"€",
|
||||
"¥",
|
||||
"₱"
|
||||
],
|
||||
[
|
||||
"%",
|
||||
"‰"
|
||||
],
|
||||
[
|
||||
"&"
|
||||
],
|
||||
[
|
||||
"-",
|
||||
"_",
|
||||
"–",
|
||||
"—",
|
||||
"·"
|
||||
],
|
||||
[
|
||||
"+",
|
||||
"±"
|
||||
],
|
||||
[
|
||||
"(",
|
||||
"<",
|
||||
"{",
|
||||
"["
|
||||
],
|
||||
[
|
||||
")",
|
||||
">",
|
||||
"}",
|
||||
"]"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"*",
|
||||
"†",
|
||||
"‡",
|
||||
"★"
|
||||
],
|
||||
[
|
||||
"\"",
|
||||
"“",
|
||||
"”",
|
||||
"«",
|
||||
"»"
|
||||
],
|
||||
[
|
||||
"'",
|
||||
"‘",
|
||||
"’",
|
||||
"‹",
|
||||
"›"
|
||||
],
|
||||
[
|
||||
":"
|
||||
],
|
||||
[
|
||||
";"
|
||||
],
|
||||
[
|
||||
"!",
|
||||
"¡"
|
||||
],
|
||||
[
|
||||
"?",
|
||||
"¿"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"_"
|
||||
],
|
||||
[
|
||||
"/"
|
||||
],
|
||||
[
|
||||
" "
|
||||
],
|
||||
[
|
||||
","
|
||||
],
|
||||
[
|
||||
".",
|
||||
"…"
|
||||
]
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"level": "opt+shift",
|
||||
"mode": "locked",
|
||||
"rows": [
|
||||
[
|
||||
[
|
||||
"~"
|
||||
],
|
||||
[
|
||||
"`"
|
||||
],
|
||||
[
|
||||
"|"
|
||||
],
|
||||
[
|
||||
"•",
|
||||
"♪",
|
||||
"♥",
|
||||
"♠",
|
||||
"♦",
|
||||
"♣"
|
||||
],
|
||||
[
|
||||
"√"
|
||||
],
|
||||
[
|
||||
"Π",
|
||||
"π"
|
||||
],
|
||||
[
|
||||
"÷"
|
||||
],
|
||||
[
|
||||
"×"
|
||||
],
|
||||
[
|
||||
"¶",
|
||||
"§"
|
||||
],
|
||||
[
|
||||
"∆"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"£"
|
||||
],
|
||||
[
|
||||
"¢"
|
||||
],
|
||||
[
|
||||
"€"
|
||||
],
|
||||
[
|
||||
"¥"
|
||||
],
|
||||
[
|
||||
"^",
|
||||
"↑",
|
||||
"↓",
|
||||
"←",
|
||||
"→"
|
||||
],
|
||||
[
|
||||
"°",
|
||||
"′",
|
||||
"″"
|
||||
],
|
||||
[
|
||||
"=",
|
||||
"≠",
|
||||
"≈",
|
||||
"∞"
|
||||
],
|
||||
[
|
||||
"{"
|
||||
],
|
||||
[
|
||||
"}"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"\\"
|
||||
],
|
||||
[
|
||||
"©"
|
||||
],
|
||||
[
|
||||
"®"
|
||||
],
|
||||
[
|
||||
"™"
|
||||
],
|
||||
[
|
||||
"℅"
|
||||
],
|
||||
[
|
||||
"["
|
||||
],
|
||||
[
|
||||
"]"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"<",
|
||||
"‹",
|
||||
"≤",
|
||||
"«"
|
||||
],
|
||||
[
|
||||
">",
|
||||
"›",
|
||||
"≥",
|
||||
"»"
|
||||
],
|
||||
[
|
||||
" "
|
||||
],
|
||||
[
|
||||
","
|
||||
],
|
||||
[
|
||||
".",
|
||||
"…"
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
],
|
||||
"locale": "ml",
|
||||
"name": "Malayalam"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
To generate the css files, from the project directory:
|
||||
|
||||
sass --sourcemap=none --update .
|
||||
@@ -1,34 +0,0 @@
|
||||
Summary
|
||||
-------
|
||||
|
||||
* Do not edit the CSS directly, edit the source SCSS files and process them with SASS (running
|
||||
`make` should do that when you have the required software installed, as described below;
|
||||
run `./parse-sass.sh` manually if it doesn't)
|
||||
* Most SASS preprocessors should produce similar results, however the build system
|
||||
integration and 'parse-sass.sh' script use sassc. You should be able to install
|
||||
it with `pkcon install sassc` or your distribution's package manager.
|
||||
|
||||
How to tweak the theme
|
||||
----------------------
|
||||
|
||||
Adwaita is a complex theme, so to keep it maintainable it's written and processed in SASS, the
|
||||
generated CSS is then transformed into a gresource file during gtk build and used at runtime in a
|
||||
non-legible or editable form.
|
||||
|
||||
It is very likely your change will happen in the _common.scss file. That's where all the widget
|
||||
selectors are defined. Here's a rundown of the "supporting" stylesheets, that are unlikely to be the
|
||||
right place for a drive by stylesheet fix:
|
||||
|
||||
_colors.scss - global color definitions. We keep the number of defined colors to a necessary minimum,
|
||||
most colors are derived from a handful of basics. It is an exact copy of the gtk+
|
||||
counterpart. Light theme is used for the classic theme and dark is for GNOME3 shell
|
||||
default.
|
||||
|
||||
_drawing.scss - drawing helper mixings/functions to allow easier definition of widget drawing under
|
||||
specific context. This is why Adwaita isn't 15000 LOC.
|
||||
|
||||
_common.scss - actual definitions of style for each widget. This is where you are likely to add/remove
|
||||
your changes.
|
||||
|
||||
You can read about SASS at http://sass-lang.com/documentation/. Once you make your changes to the
|
||||
_common.scss file, you can either run make or the ./parse-sass.sh script.
|
||||
32
data/theme/README.md
Normal file
@@ -0,0 +1,32 @@
|
||||
## Summary
|
||||
|
||||
Do not edit the CSS directly, edit the source SCSS files and the CSS files
|
||||
will be generated automatically when building with meson + ninja and left
|
||||
inside the build directory to be incorporated into the gresource XML (you'll
|
||||
need to have sassc installed).
|
||||
|
||||
## How to tweak the theme
|
||||
|
||||
Adwaita is a complex theme, so to keep it maintainable it's written and
|
||||
processed in SASS, the generated CSS is then transformed into a gresource
|
||||
file during gtk build and used at runtime in a non-legible or editable form.
|
||||
|
||||
It is very likely your change will happen in the [_common.scss][common] file.
|
||||
That's where all the widget selectors are defined. Here's a rundown of
|
||||
the "supporting" stylesheets, that are unlikely to be the right place
|
||||
for a drive by stylesheet fix:
|
||||
|
||||
| File | Description |
|
||||
| ------------------------ | ----------------- |
|
||||
| [_colors.scss][colors] | global color definitions. We keep the number of defined colors to a necessary minimum, most colors are derived from a handful of basics. It is an exact copy of the gtk+ counterpart. Light theme is used for the classic theme and dark is for GNOME3 shell default. |
|
||||
| [_drawing.scss][drawing] | drawing helper mixings/functions to allow easier definition of widget drawing under specific context. This is why Adwaita isn't 15000 LOC. |
|
||||
| [_common.scss][common] | actual definitions of style for each widget. This is where you are likely to add/remove your changes. |
|
||||
|
||||
You can read about SASS on its [web page][sass-web]. Once you make your
|
||||
changes to the [_common.scss][common] file, you can run ninja to generate the
|
||||
final CSS files.
|
||||
|
||||
[common]: data/theme/gnome-shell-sass/_common.scss
|
||||
[colors]: data/theme/gnome-shell-sass/_colors.scss
|
||||
[drawing]: data/theme/gnome-shell-sass/_drawing.scss
|
||||
[sass-web]: http://sass-lang.com/documentation/
|
||||
@@ -1,74 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Foreground"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="16px"
|
||||
height="16px"
|
||||
viewBox="0 0 16 16"
|
||||
enable-background="new 0 0 16 16"
|
||||
xml:space="preserve"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46"
|
||||
sodipodi:docname="x_circle_16.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
|
||||
id="metadata2399"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs2397"><linearGradient
|
||||
id="linearGradient3173"><stop
|
||||
style="stop-color:#c4c4c4;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3175" /><stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3177" /></linearGradient><inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 8 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="16 : 8 : 1"
|
||||
inkscape:persp3d-origin="8 : 5.3333333 : 1"
|
||||
id="perspective2401" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3173"
|
||||
id="linearGradient3179"
|
||||
x1="7.844358"
|
||||
y1="16"
|
||||
x2="7.7198443"
|
||||
y2="-0.062256809"
|
||||
gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
|
||||
inkscape:window-height="713"
|
||||
inkscape:window-width="1197"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
guidetolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
objecttolerance="10.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base"
|
||||
showgrid="false"
|
||||
inkscape:zoom="32.125"
|
||||
inkscape:cx="8"
|
||||
inkscape:cy="8"
|
||||
inkscape:window-x="40"
|
||||
inkscape:window-y="40"
|
||||
inkscape:current-layer="Foreground" />
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M10.5,3.5l2,2L10,8l2.5,2.5l-2,2L8,10l-2.5,2.5l-2-2L6,8L3.5,5.5l2-2L8,6L10.5,3.5 z M0,8c0-4.418,3.582-8,8-8s8,3.582,8,8s-3.582,8-8,8S0,12.418,0,8z"
|
||||
id="path2394"
|
||||
style="fill-opacity:1;fill:url(#linearGradient3179)" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.6 KiB |
@@ -1,81 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="10"
|
||||
height="20"
|
||||
id="svg10003"
|
||||
version="1.1"
|
||||
inkscape:version="0.47 r22583"
|
||||
sodipodi:docname="filter-selected.svg">
|
||||
<defs
|
||||
id="defs10005">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective10011" />
|
||||
<inkscape:perspective
|
||||
id="perspective9998"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.5"
|
||||
inkscape:cx="32"
|
||||
inkscape:cy="10.181818"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="994"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="26"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata10008">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
transform="translate(0,-44)">
|
||||
<path
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/app-picker.png"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect34320"
|
||||
d="m -0.18726572,54.181804 10.55634072,10.55636 10e-6,-21.11269 z"
|
||||
style="opacity:0.21000001;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.99999988;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.6 KiB |
@@ -1,81 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="10"
|
||||
height="20"
|
||||
id="svg10003"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="filter-selected-ltr.svg">
|
||||
<defs
|
||||
id="defs10005">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective10011" />
|
||||
<inkscape:perspective
|
||||
id="perspective9998"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.5"
|
||||
inkscape:cx="32.363636"
|
||||
inkscape:cy="10.181818"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="839"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="26"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata10008">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
transform="translate(0,-44)">
|
||||
<path
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/app-picker.png"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect34320"
|
||||
d="m 10.369085,54.181804 -10.55634072,10.55636 -1e-5,-21.11269 z"
|
||||
style="opacity:0.21000001;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.99999988;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.7 KiB |
339
data/theme/gnome-shell-sass/COPYING
Normal file
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc. <http://fsf.org>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
16
data/theme/gnome-shell-sass/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# GNOME Shell Sass
|
||||
GNOME Shell Sass is a project intended to allow the sharing of the
|
||||
theme sources in sass between gnome-shell and other projects like
|
||||
gnome-shell-extensions.
|
||||
|
||||
Any changes should be done in the [GNOME Shell subtree][shell-subtree]
|
||||
and not the stand-alone [gnome-shell-sass repository][sass-repo]. They
|
||||
will then be synchronized periodically before releases.
|
||||
|
||||
## License
|
||||
GNOME Shell Sass is distributed under the terms of the GNU General Public
|
||||
License, version 2 or later. See the [COPYING][license] file for details.
|
||||
|
||||
[shell-subtree]: https://gitlab.gnome.org/GNOME/gnome-shell/tree/master/data/theme/gnome-shell-sass
|
||||
[sass-repo]: https://gitlab.gnome.org/GNOME/gnome-shell-sass
|
||||
[license]: COPYING
|
||||
44
data/theme/gnome-shell-sass/_colors.scss
Normal file
@@ -0,0 +1,44 @@
|
||||
// When color definition differs for dark and light variant,
|
||||
// it gets @if ed depending on $variant
|
||||
|
||||
|
||||
$base_color: if($variant =='light', #ffffff, #292929);
|
||||
$bg_color: if($variant =='light', #ededed, #393f3f);
|
||||
$fg_color: if($variant =='light', #2e3436, #eeeeec);
|
||||
|
||||
$selected_fg_color: #ffffff;
|
||||
$selected_bg_color: if($variant == 'light', #4a90d9, darken(#4a90d9,20%));
|
||||
$selected_borders_color: if($variant=='light', darken($selected_bg_color, 30%),
|
||||
darken($selected_bg_color, 20%));
|
||||
$borders_color: if($variant =='light', darken($bg_color,30%), darken($bg_color,12%));
|
||||
$borders_edge: if($variant =='light', white, transparentize($fg_color, 0.9));
|
||||
$link_color: if($variant == 'light', darken($selected_bg_color,10%),
|
||||
lighten($selected_bg_color,20%));
|
||||
$link_visited_color: if($variant == 'light', darken($selected_bg_color,20%),
|
||||
lighten($selected_bg_color,10%));
|
||||
$top_hilight: $borders_edge;
|
||||
|
||||
$warning_color: #f57900;
|
||||
$error_color: #cc0000;
|
||||
$success_color: if($variant =='light', #73d216, darken(#73d216,10%));
|
||||
$destructive_color: if($variant =='light', #ef2929, darken(#ef2929,10%));
|
||||
|
||||
$osd_fg_color: #eeeeec;
|
||||
$osd_bg_color: #2e3436;
|
||||
$osd_borders_color: transparentize(black, 0.3);
|
||||
$osd_outer_borders_color: transparentize(white, 0.9);
|
||||
|
||||
$tooltip_borders_color: $osd_outer_borders_color;
|
||||
|
||||
//insensitive state derived colors
|
||||
$insensitive_fg_color: mix($fg_color, $bg_color, 50%);
|
||||
$insensitive_bg_color: mix($bg_color, $base_color, 60%);
|
||||
$insensitive_borders_color: $borders_color;
|
||||
|
||||
//colors for the backdrop state, derived from the main colors.
|
||||
$backdrop_base_color: if($variant =='light', darken($base_color,1%), lighten($base_color,1%));
|
||||
$backdrop_bg_color: $bg_color;
|
||||
$backdrop_fg_color: mix($fg_color, $backdrop_bg_color, 80%);
|
||||
$backdrop_insensitive_color: if($variant =='light', darken($backdrop_bg_color,15%), lighten($backdrop_bg_color,15%));
|
||||
$backdrop_borders_color: mix($borders_color, $bg_color, 90%);
|
||||
$backdrop_dark_fill: mix($backdrop_borders_color,$backdrop_bg_color, 35%);
|
||||
2022
data/theme/gnome-shell-sass/_common.scss
Normal file
221
data/theme/gnome-shell-sass/_drawing.scss
Normal file
@@ -0,0 +1,221 @@
|
||||
// Drawing mixins
|
||||
|
||||
// generic drawing of more complex things
|
||||
|
||||
@function _widget_edge($c:$borders_edge) {
|
||||
// outer highlight "used" on most widgets
|
||||
@return 0 1px $c;
|
||||
}
|
||||
|
||||
// provide font size in rem, with px fallback
|
||||
@mixin fontsize($size: 24, $base: 16) {
|
||||
font-size: round($size) + pt;
|
||||
//font-size: ($size / $base) * 1rem;
|
||||
}
|
||||
|
||||
@mixin _shadows($shadow1, $shadow2:none, $shadow3:none, $shadow4:none) {
|
||||
//
|
||||
// Helper function to stack up to 4 box-shadows;
|
||||
//
|
||||
@if $shadow4!=none { box-shadow: $shadow1, $shadow2, $shadow3, $shadow4; }
|
||||
@else if $shadow3!=none { box-shadow: $shadow1, $shadow2, $shadow3; }
|
||||
@else if $shadow2!=none { box-shadow: $shadow1, $shadow2; }
|
||||
@else { box-shadow: $shadow1; }
|
||||
}
|
||||
|
||||
// entries
|
||||
|
||||
@mixin entry($t, $fc:$selected_bg_color, $edge: $borders_edge) {
|
||||
//
|
||||
// Entries drawing function
|
||||
//
|
||||
// $t: entry type
|
||||
// $fc: focus color
|
||||
// $edge: set to none to not draw the bottom edge or specify a color to not
|
||||
// use the default one
|
||||
//
|
||||
// possible $t values:
|
||||
// normal, focus, insensitive
|
||||
//
|
||||
$_inner_shadows: inset 0 2px 4px transparentize(black, 0.6);
|
||||
|
||||
@if $t==normal {
|
||||
background-color: $base_color;
|
||||
border-color: $borders_color;
|
||||
@include _shadows($_inner_shadows);
|
||||
|
||||
}
|
||||
@if $t==focus {
|
||||
@include _shadows($_inner_shadows);
|
||||
border-color: if($fc==$selected_bg_color,
|
||||
$selected_borders_color,
|
||||
darken($fc,35%));
|
||||
}
|
||||
@if $t==hover { }
|
||||
@if $t==insensitive {
|
||||
color: $insensitive_fg_color;
|
||||
border-color: $insensitive_bg_color;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
// buttons
|
||||
|
||||
@function _border_color ($c) { @return darken($c,25%); } // colored buttons want
|
||||
// the border form the
|
||||
// base color
|
||||
|
||||
@function _text_shadow_color ($tc:$fg_color, $bg:$bg_color) {
|
||||
//
|
||||
// calculate the color of text shadows
|
||||
//
|
||||
// $tc is the text color
|
||||
// $bg is the background color
|
||||
//
|
||||
$_lbg: lightness($bg)/100%;
|
||||
@if lightness($tc)<50% { @return transparentize(white,1-$_lbg/($_lbg*1.3)); }
|
||||
@else { @return transparentize(black,$_lbg*0.8); }
|
||||
}
|
||||
|
||||
@function _button_hilight_color($c) {
|
||||
//
|
||||
// calculate the right top hilight color for buttons
|
||||
//
|
||||
// $c: base color;
|
||||
//
|
||||
@if lightness($c)>90% { @return white; }
|
||||
@else if lightness($c)>80% { @return transparentize(white, 0.3); }
|
||||
@else if lightness($c)>50% { @return transparentize(white, 0.5); }
|
||||
@else if lightness($c)>40% { @return transparentize(white, 0.7); }
|
||||
@else { @return transparentize(white, 0.9); }
|
||||
}
|
||||
|
||||
@mixin _button_text_shadow ($tc:$fg_color, $bg:$bg_color) {
|
||||
//
|
||||
// helper function for the text emboss effect
|
||||
//
|
||||
// $tc is the optional text color, not the shadow color
|
||||
//
|
||||
// TODO: this functions needs a way to deal with special cases
|
||||
//
|
||||
|
||||
$_shadow: _text_shadow_color($tc, $bg);
|
||||
|
||||
@if lightness($tc)<50% {
|
||||
text-shadow: 0 1px $_shadow;
|
||||
icon-shadow: 0 1px $_shadow;
|
||||
}
|
||||
@else {
|
||||
text-shadow: 0 -1px $_shadow;
|
||||
icon-shadow: 0 -1px $_shadow;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin button($t, $c:$osd_bg_color, $tc:$fg_color, $edge: $borders_edge) {
|
||||
//
|
||||
// Button drawing function
|
||||
//
|
||||
// $t: button type,
|
||||
// $c: base button color for colored* types
|
||||
// $tc: optional text color for colored* types
|
||||
// $edge: set to none to not draw the bottom edge or specify a color to not
|
||||
// use the default one
|
||||
//
|
||||
// possible $t values:
|
||||
// normal, hover, active, insensitive, insensitive-active,
|
||||
// backdrop, backdrop-active, backdrop-insensitive, backdrop-insensitive-active,
|
||||
// osd, osd-hover, osd-active, osd-insensitive, osd-backdrop, undecorated
|
||||
//
|
||||
|
||||
$_hilight_color: _button_hilight_color($c);
|
||||
$_button_edge: if($edge == none, none, _widget_edge($edge));
|
||||
$_blank_edge: if($edge == none, none, _widget_edge(transparentize($edge,1)));
|
||||
|
||||
|
||||
@if $t==normal {
|
||||
//
|
||||
// normal button
|
||||
//
|
||||
$_bg: if($c!=$osd_bg_color, transparentize($c, 0.5),
|
||||
$osd_bg_color);
|
||||
|
||||
color: $osd_fg_color;
|
||||
background-color: $_bg;
|
||||
border-color: $osd_borders_color;
|
||||
box-shadow: inset 0 1px lighten($osd_bg_color,10%);
|
||||
text-shadow: 0 1px black;
|
||||
icon-shadow: 0 1px black;
|
||||
}
|
||||
@if $t==focus {
|
||||
//
|
||||
// focused button
|
||||
//
|
||||
$_bg: if($c!=$osd_bg_color, transparentize($c, 0.3),
|
||||
lighten($osd_bg_color,3%));
|
||||
|
||||
color: $osd_fg_color;
|
||||
text-shadow: 0 1px black;
|
||||
icon-shadow: 0 1px black;
|
||||
box-shadow: inset 0px 0px 0px 1px $selected_bg_color;
|
||||
}
|
||||
|
||||
@else if $t==hover {
|
||||
//
|
||||
// active osd button
|
||||
//
|
||||
$_bg: if($c!=$osd_bg_color, transparentize($c, 0.3),
|
||||
lighten($osd_bg_color,3%));
|
||||
|
||||
color: white;
|
||||
border-color: $osd_borders_color;
|
||||
background-color: $_bg;
|
||||
box-shadow: inset 0 1px lighten($osd_bg_color,20%);
|
||||
text-shadow: 0 1px black;
|
||||
icon-shadow: 0 1px black;
|
||||
|
||||
}
|
||||
@else if $t==active {
|
||||
//
|
||||
// active osd button
|
||||
//
|
||||
$_bg: if($c!=$bg_color, $c, $osd_borders_color);
|
||||
|
||||
color: white;
|
||||
border-color: $osd_borders_color;
|
||||
background-color: $selected_bg_color;
|
||||
// This should be none, but it's creating some issues with borders, so to
|
||||
// workaround it for now, use inset wich goes through a different code path.
|
||||
// see https://bugzilla.gnome.org/show_bug.cgi?id=752934
|
||||
box-shadow: inset 0 0 black;
|
||||
text-shadow: none;
|
||||
icon-shadow: none;
|
||||
}
|
||||
@else if $t==insensitive {
|
||||
//
|
||||
// insensitive osd button
|
||||
//
|
||||
$_bg: transparentize(mix($insensitive_fg_color,$osd_bg_color,20%),0.3);
|
||||
|
||||
color: $insensitive_fg_color;
|
||||
border-color: $osd_borders_color;
|
||||
background-color: $_bg;
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
icon-shadow: none;
|
||||
}
|
||||
@else if $t==undecorated {
|
||||
//
|
||||
// reset
|
||||
//
|
||||
border-color: transparent;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
|
||||
@include _shadows(inset 0 1px transparentize(white,1),
|
||||
$_blank_edge);
|
||||
|
||||
text-shadow: none;
|
||||
icon-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
41
data/theme/gnome-shell-sass/_high-contrast-colors.scss
Normal file
@@ -0,0 +1,41 @@
|
||||
// When color definition differs for dark and light variant,
|
||||
// it gets @if ed depending on $variant
|
||||
|
||||
|
||||
$base_color: #222;
|
||||
$bg_color: #000;
|
||||
$fg_color: #fff;
|
||||
|
||||
$selected_fg_color: #ffffff;
|
||||
$selected_bg_color: darken(#4a90d9,20%);
|
||||
$selected_borders_color: darken($selected_bg_color, 20%);
|
||||
$borders_color: darken($bg_color,12%);
|
||||
$borders_edge: transparentize($fg_color, 0.9);
|
||||
$link_color: lighten($selected_bg_color,20%);
|
||||
$link_visited_color: lighten($selected_bg_color,10%);
|
||||
$top_hilight: $borders_edge;
|
||||
|
||||
$warning_color: #f57900;
|
||||
$error_color: #cc0000;
|
||||
$success_color: darken(#73d216,10%);
|
||||
$destructive_color: darken(#ef2929,10%);
|
||||
|
||||
$osd_fg_color: #eeeeec;
|
||||
$osd_bg_color: #2e3436;
|
||||
$osd_borders_color: transparentize(black, 0.3);
|
||||
$osd_outer_borders_color: transparentize(white, 0.9);
|
||||
|
||||
$tooltip_borders_color: $osd_outer_borders_color;
|
||||
|
||||
//insensitive state derived colors
|
||||
$insensitive_fg_color: mix($fg_color, $bg_color, 50%);
|
||||
$insensitive_bg_color: mix($bg_color, $base_color, 60%);
|
||||
$insensitive_borders_color: $borders_color;
|
||||
|
||||
//colors for the backdrop state, derived from the main colors.
|
||||
$backdrop_base_color: lighten($base_color,1%);
|
||||
$backdrop_bg_color: $bg_color;
|
||||
$backdrop_fg_color: mix($fg_color, $backdrop_bg_color, 80%);
|
||||
$backdrop_insensitive_color: lighten($backdrop_bg_color,15%);
|
||||
$backdrop_borders_color: mix($borders_color, $bg_color, 90%);
|
||||
$backdrop_dark_fill: mix($backdrop_borders_color,$backdrop_bg_color, 35%);
|
||||
37
data/theme/gnome-shell-sass/gnome-shell-sass.doap
Normal file
@@ -0,0 +1,37 @@
|
||||
<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
|
||||
xmlns:foaf="http://xmlns.com/foaf/0.1/"
|
||||
xmlns:gnome="http://api.gnome.org/doap-extensions#"
|
||||
xmlns="http://usefulinc.com/ns/doap#">
|
||||
|
||||
<name xml:lang="en">GNOME Shell Sass</name>
|
||||
<shortdesc xml:lang="en">Sass sources of GNOME Shell</shortdesc>
|
||||
<description>GNOME Shell Sass is a project intended to allow the sharing of the
|
||||
sass theme sources between gnome-shell and other projects like gnome-shell-extensions.</description>
|
||||
|
||||
<category rdf:resource="http://api.gnome.org/doap-extensions#core" />
|
||||
<programming-language>sass</programming-language>
|
||||
<programming-language>css</programming-language>
|
||||
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Carlos Soriano</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:csoriano@gnome.org" />
|
||||
<gnome:userid>csoriano</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Florian Müllner</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:fmuellner@gnome.org" />
|
||||
<gnome:userid>fmuellner</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Jakub Steiner</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:jimmac@gmail.com" />
|
||||
<gnome:userid>jimmac</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
</Project>
|
||||
109
data/theme/key-enter.svg
Normal file
@@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="32"
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg7384"
|
||||
height="32"
|
||||
sodipodi:docname="key-enter.svg"
|
||||
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1744"
|
||||
inkscape:window-height="866"
|
||||
id="namedview19"
|
||||
showgrid="false"
|
||||
inkscape:zoom="14.75"
|
||||
inkscape:cx="7.9322034"
|
||||
inkscape:cy="14.554666"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="55"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg7384" />
|
||||
<metadata
|
||||
id="metadata90">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<title
|
||||
id="title9167">Gnome Symbolic Icon Theme</title>
|
||||
<defs
|
||||
id="defs7386">
|
||||
<linearGradient
|
||||
osb:paint="solid"
|
||||
id="linearGradient19282"
|
||||
gradientTransform="matrix(-2.7365795,0.28202934,-0.18908311,-0.99988321,239.54008,-879.45557)">
|
||||
<stop
|
||||
style="stop-color:#666666;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop19284" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer9" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer10" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
id="layer11" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer13" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
id="layer14" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer15" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="g71291" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="g4953" />
|
||||
<g
|
||||
transform="matrix(2,0,0,2,-281.56285,-1615.0002)"
|
||||
style="display:inline"
|
||||
id="layer12">
|
||||
<path
|
||||
id="path16589"
|
||||
d="m 148.00015,821.0002 h -1 c -0.26528,0 -0.53057,-0.093 -0.71875,-0.2812 l -3.71875,-3.7188 c 0,0 2.47917,-2.4792 3.71875,-3.7187 0.18817,-0.1882 0.45344,-0.2813 0.71875,-0.2813 h 1 v 1 c 0,0.2653 -0.0931,0.5306 -0.28125,0.7188 l -2.28125,2.2812 2.28125,2.2813 c 0.18811,0.1881 0.28129,0.4534 0.28125,0.7187 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#bebebe;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
d="m 154.0002,810 v 4.5 c 0,1.3807 -1.11929,2.5 -2.5,2.5 h -6.50005"
|
||||
id="path16591"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
114
data/theme/key-hide.svg
Normal file
@@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="32"
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg7384"
|
||||
height="32"
|
||||
sodipodi:docname="key-hide.svg"
|
||||
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1919"
|
||||
inkscape:window-height="1011"
|
||||
id="namedview19"
|
||||
showgrid="false"
|
||||
inkscape:zoom="14.75"
|
||||
inkscape:cx="-12.338983"
|
||||
inkscape:cy="14.554666"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="55"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg7384" />
|
||||
<metadata
|
||||
id="metadata90">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<title
|
||||
id="title9167">Gnome Symbolic Icon Theme</title>
|
||||
<defs
|
||||
id="defs7386">
|
||||
<linearGradient
|
||||
osb:paint="solid"
|
||||
id="linearGradient19282"
|
||||
gradientTransform="matrix(-2.7365795,0.28202934,-0.18908311,-0.99988321,239.54008,-879.45557)">
|
||||
<stop
|
||||
style="stop-color:#666666;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop19284" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer9" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer10" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
id="layer11" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer13" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
id="layer14" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer15" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="g71291" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="g4953" />
|
||||
<g
|
||||
style="display:inline"
|
||||
inkscape:label="go-down"
|
||||
id="g11722"
|
||||
transform="matrix(2,0,0,2,-362.0004,-1494)">
|
||||
<rect
|
||||
transform="rotate(90)"
|
||||
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none;enable-background:new"
|
||||
id="rect11718"
|
||||
y="-197.0002"
|
||||
x="747"
|
||||
height="16"
|
||||
width="16" />
|
||||
<path
|
||||
style="display:inline;fill:#e5e5e5;fill-opacity:1;stroke:none"
|
||||
d="m 189.0002,759.4375 -5.71875,-5.7187 C 183.08558,753.5229 183.0002,753.2556 183.0002,753 v -1 h 1 c 0.25562,0 0.52288,0.085 0.71875,0.2813 l 4.28125,4.2812 4.28125,-4.2812 C 193.47732,752.0854 193.74458,752 194.0002,752 h 1 v 1 c 0,0.2556 -0.0854,0.5229 -0.28125,0.7188 z"
|
||||
id="path11720"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccscsccsscscc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
129
data/theme/key-layout.svg
Normal file
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="32"
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg7384"
|
||||
height="32"
|
||||
sodipodi:docname="key-layout.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="3440"
|
||||
inkscape:window-height="1376"
|
||||
id="namedview19"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="46.246852"
|
||||
inkscape:cy="17.474578"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg7384">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid861" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata90">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<title
|
||||
id="title9167">Gnome Symbolic Icon Theme</title>
|
||||
<defs
|
||||
id="defs7386">
|
||||
<linearGradient
|
||||
osb:paint="solid"
|
||||
id="linearGradient19282"
|
||||
gradientTransform="matrix(-2.7365795,0.28202934,-0.18908311,-0.99988321,239.54008,-879.45557)">
|
||||
<stop
|
||||
style="stop-color:#666666;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop19284" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer9" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer10" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
id="layer11" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer13" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
id="layer14" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer15" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="g71291" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="g4953" />
|
||||
<g
|
||||
style="stroke-width:0.5;enable-background:new"
|
||||
id="g3561"
|
||||
inkscape:label="preferences-desktop-locale"
|
||||
transform="matrix(2,0,0,2,135.99464,-895.9793)">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3535"
|
||||
d="m -65,450 v 12"
|
||||
style="fill:#e5e5e5;fill-opacity:1;fill-rule:evenodd;stroke:#e5e5e5;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3537"
|
||||
d="m -65,456 h 4 l 1,2 h 5 v -6 h -4 l -1,-2 h -5 z"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#e5e5e5;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:#e5e5e5;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m -65,456 h 4 l 1,2 h 5 v -6 h -4 l -1,-2 h -5 z"
|
||||
id="path3539"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
<rect
|
||||
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:0.89050001;marker:none;enable-background:new"
|
||||
id="rect3543"
|
||||
y="448"
|
||||
x="-68"
|
||||
height="16"
|
||||
width="16" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
109
data/theme/key-shift-latched-uppercase.svg
Normal file
@@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="32"
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg7384"
|
||||
height="32"
|
||||
sodipodi:docname="key-shift-latched-uppercase.svg"
|
||||
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1791"
|
||||
inkscape:window-height="984"
|
||||
id="namedview19"
|
||||
showgrid="false"
|
||||
inkscape:zoom="14.75"
|
||||
inkscape:cx="-0.77966097"
|
||||
inkscape:cy="18.847458"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="55"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg7384" />
|
||||
<metadata
|
||||
id="metadata90">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<title
|
||||
id="title9167">Gnome Symbolic Icon Theme</title>
|
||||
<defs
|
||||
id="defs7386">
|
||||
<linearGradient
|
||||
osb:paint="solid"
|
||||
id="linearGradient19282"
|
||||
gradientTransform="matrix(-2.7365795,0.28202934,-0.18908311,-0.99988321,239.54008,-879.45557)">
|
||||
<stop
|
||||
style="stop-color:#666666;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop19284" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer9" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer10" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
id="layer11" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer13" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
id="layer14" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer15" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="g71291" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="g4953" />
|
||||
<g
|
||||
transform="matrix(2,0,0,2,-282.0004,-1614.2187)"
|
||||
style="display:inline;fill:#006098;fill-opacity:1"
|
||||
id="layer12">
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#006098;fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:new"
|
||||
d="m 147,818 v -4 h -3.1248 l 5.125,-5.7813 5.125,5.7813 h -3.1875 v 4 z"
|
||||
id="path16532"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path16534"
|
||||
d="m 147,822 v -2 h 3.9377 v 2 z"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#006098;fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:new"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
104
data/theme/key-shift-uppercase.svg
Normal file
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="32"
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg7384"
|
||||
height="32"
|
||||
sodipodi:docname="key-shift-uppercase.svg"
|
||||
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2160"
|
||||
inkscape:window-height="1311"
|
||||
id="namedview18"
|
||||
showgrid="false"
|
||||
inkscape:zoom="14.75"
|
||||
inkscape:cx="-27.898305"
|
||||
inkscape:cy="8"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="55"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg7384" />
|
||||
<metadata
|
||||
id="metadata90">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<title
|
||||
id="title9167">Gnome Symbolic Icon Theme</title>
|
||||
<defs
|
||||
id="defs7386">
|
||||
<linearGradient
|
||||
osb:paint="solid"
|
||||
id="linearGradient19282"
|
||||
gradientTransform="matrix(-2.7365795,0.28202934,-0.18908311,-0.99988321,239.54008,-879.45557)">
|
||||
<stop
|
||||
style="stop-color:#666666;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop19284" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer9" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer10" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
id="layer11" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer13" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
id="layer14" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="layer15" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="g71291" />
|
||||
<g
|
||||
transform="translate(-141.0002,-791)"
|
||||
style="display:inline"
|
||||
id="g4953" />
|
||||
<g
|
||||
transform="matrix(2,0,0,2,-282.0008,-1614.2187)"
|
||||
style="display:inline;fill:#006098;fill-opacity:1"
|
||||
id="layer12">
|
||||
<path
|
||||
id="path16548"
|
||||
d="m 147.0002,820 v -4 h -3.1248 l 5.125,-5.7813 5.125,5.7813 h -3.1875 v 4 z"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#006098;fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:new"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
108
data/theme/key-shift.svg
Normal file
@@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="32"
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg7384"
|
||||
height="32"
|
||||
sodipodi:docname="key-shift.svg"
|
||||
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1400"
|
||||
inkscape:window-height="1034"
|
||||
id="namedview4569"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:zoom="14.75"
|
||||
inkscape:cx="1.5993763"
|
||||
inkscape:cy="5"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="55"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg7384" />
|
||||
<metadata
|
||||
id="metadata90">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<title
|
||||
id="title9167">Gnome Symbolic Icon Theme</title>
|
||||
<defs
|
||||
id="defs7386">
|
||||
<linearGradient
|
||||
osb:paint="solid"
|
||||
id="linearGradient19282"
|
||||
gradientTransform="matrix(-2.7365795,0.28202934,-0.18908311,-0.99988321,239.54008,-879.45557)">
|
||||
<stop
|
||||
style="stop-color:#666666;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop19284" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
transform="translate(-143.8754,-788)"
|
||||
style="display:inline"
|
||||
id="layer9" />
|
||||
<g
|
||||
transform="translate(-143.8754,-788)"
|
||||
style="display:inline"
|
||||
id="layer10" />
|
||||
<g
|
||||
transform="translate(-143.8754,-788)"
|
||||
id="layer11" />
|
||||
<g
|
||||
transform="translate(-143.8754,-788)"
|
||||
style="display:inline"
|
||||
id="layer13" />
|
||||
<g
|
||||
transform="translate(-143.8754,-788)"
|
||||
id="layer14" />
|
||||
<g
|
||||
transform="translate(-143.8754,-788)"
|
||||
style="display:inline"
|
||||
id="layer15" />
|
||||
<g
|
||||
transform="translate(-143.8754,-788)"
|
||||
style="display:inline"
|
||||
id="g71291" />
|
||||
<g
|
||||
transform="translate(-143.8754,-788)"
|
||||
style="display:inline"
|
||||
id="g4953" />
|
||||
<g
|
||||
transform="matrix(2,0,0,2,-282.0008,-1614.2187)"
|
||||
style="display:inline"
|
||||
id="layer12">
|
||||
<path
|
||||
id="path16548"
|
||||
d="m 147.0002,820 v -4 h -3.1248 l 5.125,-5.7813 5.125,5.7813 h -3.1875 v 4 z"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;enable-background:new"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
@@ -1,130 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="300"
|
||||
height="80"
|
||||
id="svg7355"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.2 r9819"
|
||||
sodipodi:docname="logged-in-indicator.svg">
|
||||
<metadata
|
||||
id="metadata4175">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#2c1cff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="843"
|
||||
id="namedview4173"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.8760889"
|
||||
inkscape:cx="106.00403"
|
||||
inkscape:cy="80.68078"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g30864" />
|
||||
<defs
|
||||
id="defs7357">
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient36429"
|
||||
id="radialGradient7461"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.5919312,0,0,0.57582113,-20.687059,48.400487)"
|
||||
cx="47.428951"
|
||||
cy="167.16817"
|
||||
fx="47.428951"
|
||||
fy="167.16817"
|
||||
r="37" />
|
||||
<linearGradient
|
||||
id="linearGradient36429">
|
||||
<stop
|
||||
id="stop36431"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop36433"
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient36471"
|
||||
id="radialGradient7463"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1891549,0,0,0.55513246,-9.281289,36.12653)"
|
||||
cx="49.067139"
|
||||
cy="242.50381"
|
||||
fx="49.067139"
|
||||
fy="242.50381"
|
||||
r="37.00671" />
|
||||
<linearGradient
|
||||
id="linearGradient36471">
|
||||
<stop
|
||||
id="stop36473"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop36475"
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="37.00671"
|
||||
fy="242.50381"
|
||||
fx="49.067139"
|
||||
cy="242.50381"
|
||||
cx="49.067139"
|
||||
gradientTransform="matrix(3.4218418,0,0,0.03365337,-61.309005,138.5071)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient7488"
|
||||
xlink:href="#linearGradient36471" />
|
||||
</defs>
|
||||
<g
|
||||
id="layer1"
|
||||
transform="matrix(1.6213276,0,0,1.6213276,-431.6347,-272.5745)">
|
||||
<g
|
||||
style="display:inline"
|
||||
id="g30864"
|
||||
transform="translate(255.223,70.118091)">
|
||||
<rect
|
||||
ry="3.4593496"
|
||||
rx="8.8641119"
|
||||
y="76.159348"
|
||||
x="12.596948"
|
||||
height="71.116341"
|
||||
width="182.22595"
|
||||
id="rect14000"
|
||||
style="opacity:0.371875;fill:url(#radialGradient7461);fill-opacity:1;stroke:none" />
|
||||
<path
|
||||
id="rect34520"
|
||||
d="m 194.80022,146.83551 -182.559919,0"
|
||||
style="opacity:0.35;fill:none;stroke:url(#radialGradient7488);stroke-width:0.61184424;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
connector-curvature="0"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.8 KiB |
@@ -7,15 +7,19 @@ theme_sources = files([
|
||||
'gnome-shell-sass/_high-contrast-colors.scss'
|
||||
])
|
||||
|
||||
styles = [
|
||||
'gnome-shell-high-contrast',
|
||||
'gnome-shell'
|
||||
]
|
||||
|
||||
theme_deps = []
|
||||
|
||||
if sassc.found()
|
||||
parse_sass = files('parse-sass.sh')
|
||||
|
||||
theme_deps += custom_target('update-theme',
|
||||
output: 'theme-update.stamp',
|
||||
depend_files: theme_sources,
|
||||
command: [parse_sass, '@OUTPUT@'],
|
||||
build_by_default: true
|
||||
)
|
||||
endif
|
||||
foreach style: styles
|
||||
theme_deps += custom_target('style-' + style,
|
||||
input: '@0@.scss'.format(style),
|
||||
output: '@0@.css'.format(style),
|
||||
command: [
|
||||
sassc, '-a', '@INPUT@', '@OUTPUT@'
|
||||
],
|
||||
depend_files: theme_sources)
|
||||
endforeach
|
||||
|
||||
@@ -13,10 +13,102 @@
|
||||
height="64px"
|
||||
id="svg3393"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.5 r10040"
|
||||
sodipodi:docname="New document 2">
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="no-notifications.svg">
|
||||
<defs
|
||||
id="defs3395" />
|
||||
id="defs3395">
|
||||
<clipPath
|
||||
id="clipPath6262-0"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<rect
|
||||
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none"
|
||||
id="rect6264-6"
|
||||
width="3.8250003"
|
||||
height="6.3750005"
|
||||
x="26.849981"
|
||||
y="220.75" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="clipPath6258-0"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<rect
|
||||
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none"
|
||||
id="rect6260-6"
|
||||
width="2.8977275"
|
||||
height="5.3129687"
|
||||
x="26.965673"
|
||||
y="221.28162" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="clipPath6254-6"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<rect
|
||||
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none"
|
||||
id="rect6256-6"
|
||||
width="1.876245"
|
||||
height="4.8783236"
|
||||
x="26.998718"
|
||||
y="221.50153" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="clipPath8028-3"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m -73,-30 -7,-7 v -4.5 h 16.5 v 4.5 l -7.5,7 z"
|
||||
id="path8030-6"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath6810-7-87-7">
|
||||
<rect
|
||||
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none"
|
||||
id="rect6812-2-4-5"
|
||||
width="14"
|
||||
height="11"
|
||||
x="21"
|
||||
y="281" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="clipPath6262"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<rect
|
||||
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none"
|
||||
id="rect6264"
|
||||
width="3.8250003"
|
||||
height="6.3750005"
|
||||
x="26.849981"
|
||||
y="220.75" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="clipPath6258"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<rect
|
||||
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none"
|
||||
id="rect6260"
|
||||
width="2.8977275"
|
||||
height="5.3129687"
|
||||
x="26.965673"
|
||||
y="221.28162" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="clipPath6254"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<rect
|
||||
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none"
|
||||
id="rect6256"
|
||||
width="1.876245"
|
||||
height="4.8783236"
|
||||
x="26.998718"
|
||||
y="221.50153" />
|
||||
</clipPath>
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect3951"
|
||||
is_visible="true" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
@@ -24,17 +116,17 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.5"
|
||||
inkscape:cx="32"
|
||||
inkscape:cy="32"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="125.08157"
|
||||
inkscape:cy="-13.805087"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="697"
|
||||
inkscape:window-height="613"
|
||||
inkscape:window-x="100"
|
||||
inkscape:window-y="77"
|
||||
inkscape:window-width="1664"
|
||||
inkscape:window-height="1034"
|
||||
inkscape:window-x="1479"
|
||||
inkscape:window-y="252"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata3398">
|
||||
@@ -54,7 +146,7 @@
|
||||
inkscape:groupmode="layer">
|
||||
<g
|
||||
style="display:inline"
|
||||
transform="matrix(4,0,0,4,0.29733827,-0.35415646)"
|
||||
transform="matrix(4,0,0,4,-79.702662,-0.35415646)"
|
||||
id="g19245">
|
||||
<g
|
||||
id="g19247"
|
||||
@@ -71,15 +163,15 @@
|
||||
transform="translate(-323.02908,-649.02581)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 331.9377,653 c 0.0187,0.16677 0.0625,0.32822 0.0625,0.5 0,2.48528 -2.01472,4.5 -4.5,4.5 -0.11769,0 -0.22834,-0.0224 -0.34375,-0.0312 l 0,2.21875 c 0,1.00412 0.80838,1.8125 1.8125,1.8125 l 1.54511,-5e-5 2,2.04688 2.0625,-2.04688 1.61114,0 c 1.00413,0 1.8125,-0.80838 1.8125,-1.8125 l 0,-5.375 c 0,-1.00412 -0.80837,-1.8125 -1.8125,-1.8125 z"
|
||||
d="m 331.9377,653 c 0.0187,0.16677 0.0625,0.32822 0.0625,0.5 0,2.48528 -2.01472,4.5 -4.5,4.5 -0.11769,0 -0.22834,-0.0224 -0.34375,-0.0312 v 2.21875 c 0,1.00412 0.80838,1.8125 1.8125,1.8125 l 1.54511,-5e-5 2,2.04688 2.0625,-2.04688 h 1.61114 c 1.00413,0 1.8125,-0.80838 1.8125,-1.8125 v -5.375 c 0,-1.00412 -0.80837,-1.8125 -1.8125,-1.8125 z"
|
||||
id="path19253"
|
||||
sodipodi:nodetypes="csscsscccssssc"
|
||||
style="opacity:0.5;color:#000000;fill:#c3c3c3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.5;fill:#c3c3c3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 327.5002,650 c -1.933,0 -3.5,1.567 -3.5,3.5 0,1.933 1.567,3.5 3.5,3.5 1.933,0 3.5,-1.567 3.5,-3.5 0,-1.933 -1.567,-3.5 -3.5,-3.5 z m -0.53125,1 1.03125,0 -0.0625,1.375 a 0.19951718,0.19951718 0 0 0 0,0.0625 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0.125,0.125 0.19951718,0.19951718 0 0 0 0.0312,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 l 1.15625,-0.75 0.5,0.90625 -1.21875,0.625 a 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0312,0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0.0937 0.19951718,0.19951718 0 0 0 0,0.0625 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0.0312,0.0625 0.19951718,0.19951718 0 0 0 0.0312,0.0312 0.19951718,0.19951718 0 0 0 0.0312,0.0312 l 1.25,0.625 -0.53125,0.90625 -1.15625,-0.781 a 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0625,0 0.19951718,0.19951718 0 0 0 -0.125,0.0937 0.19951718,0.19951718 0 0 0 -0.0312,0.0312 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0,0.0625 l 0.0625,1.3751 -1.03125,0 0.0937,-1.375 a 0.19951718,0.19951718 0 0 0 -0.0312,-0.0937 0.19951718,0.19951718 0 0 0 -0.0312,-0.0625 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0937,0.0312 l -1.1875,0.78125 -0.5,-0.90625 1.25,-0.625 a 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 0,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,-0.0625 0.19951718,0.19951718 0 0 0 -0.0312,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0 l -1.25,-0.625 0.5,-0.90625 1.1875,0.75 a 0.19951718,0.19951718 0 0 0 0.0312,0.0312 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0312,0 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 L 326.96895,651 z"
|
||||
d="m 327.5002,650 c -1.933,0 -3.5,1.567 -3.5,3.5 0,1.933 1.567,3.5 3.5,3.5 1.933,0 3.5,-1.567 3.5,-3.5 0,-1.933 -1.567,-3.5 -3.5,-3.5 z m -0.53125,1 h 1.03125 l -0.0625,1.375 a 0.19951718,0.19951718 0 0 0 0,0.0625 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0.125,0.125 0.19951718,0.19951718 0 0 0 0.0312,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 l 1.15625,-0.75 0.5,0.90625 -1.21875,0.625 a 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0312,0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0.0937 0.19951718,0.19951718 0 0 0 0,0.0625 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0.0312,0.0625 0.19951718,0.19951718 0 0 0 0.0312,0.0312 0.19951718,0.19951718 0 0 0 0.0312,0.0312 l 1.25,0.625 -0.53125,0.90625 -1.15625,-0.781 a 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0625,0 0.19951718,0.19951718 0 0 0 -0.125,0.0937 0.19951718,0.19951718 0 0 0 -0.0312,0.0312 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0,0.0625 L 328.0002,656 h -1.03125 l 0.0937,-1.375 a 0.19951718,0.19951718 0 0 0 -0.0312,-0.0937 0.19951718,0.19951718 0 0 0 -0.0312,-0.0625 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0937,0.0312 l -1.1875,0.78125 -0.5,-0.90625 1.25,-0.625 a 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 0,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,-0.0625 0.19951718,0.19951718 0 0 0 -0.0312,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0 l -1.25,-0.625 0.5,-0.90625 1.1875,0.75 a 0.19951718,0.19951718 0 0 0 0.0312,0.0312 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0312,0 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 z"
|
||||
id="path19255"
|
||||
style="color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate" />
|
||||
</g>
|
||||
<g
|
||||
id="g19257"
|
||||
@@ -110,5 +202,22 @@
|
||||
style="display:inline"
|
||||
transform="translate(-323.02908,-649.02581)" />
|
||||
</g>
|
||||
<g
|
||||
style="opacity:1;vector-effect:none;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:new"
|
||||
inkscape:label="preferences-system-notifications"
|
||||
id="g13967"
|
||||
transform="matrix(4,0,0,4,-1044.0008,-2172)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 268.94244,544.94838 c -2.20914,0 -3.33013,1.5 -4,4 l -1,5 c -0.10831,0.54156 -0.44772,1 -1,1 v 1 h 12 v -1 c -0.55229,0 -0.89169,-0.45844 -1,-1 l -1,-5 c -0.53033,-2.5 -1.79086,-4 -4,-4 z"
|
||||
id="path40220"
|
||||
sodipodi:nodetypes="ccsccccscc"
|
||||
style="opacity:1;vector-effect:none;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 269.11822,556.94838 a 1.5,1.5 0 0 0 1.41211,1 1.5,1.5 0 0 0 1.41211,-1 z"
|
||||
id="path40774"
|
||||
style="opacity:1;vector-effect:none;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 11 KiB |
@@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
srcdir=`dirname $0`
|
||||
stamp=${1}
|
||||
for scss in $srcdir/*.scss
|
||||
do
|
||||
sassc -a $scss ${scss%%.scss}.css || exit 1
|
||||
done
|
||||
|
||||
[ "$stamp" ] && touch $stamp
|
||||
@@ -1,74 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="21"
|
||||
height="10"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.0 r9654"
|
||||
sodipodi:docname="source-button-border.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#000000"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="44.8"
|
||||
inkscape:cx="8.704132"
|
||||
inkscape:cy="5.7029946"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="1145"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="26"
|
||||
inkscape:window-maximized="1"
|
||||
guidetolerance="10000"
|
||||
objecttolerance="10000">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3792"
|
||||
empspacing="10"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="rect3796"
|
||||
width="19"
|
||||
height="2"
|
||||
x="1"
|
||||
y="8" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.0 KiB |
@@ -1,120 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.0"
|
||||
id="Foreground"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 23.272727 23.272727"
|
||||
enable-background="new 0 0 16 16"
|
||||
xml:space="preserve"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.2 r9819"
|
||||
sodipodi:docname="summary-counter.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
|
||||
id="metadata2399"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs2397"><linearGradient
|
||||
id="linearGradient3173"><stop
|
||||
style="stop-color:#c4c4c4;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3175" /><stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3177" /></linearGradient><inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 8 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="16 : 8 : 1"
|
||||
inkscape:persp3d-origin="8 : 5.3333333 : 1"
|
||||
id="perspective2401" /><filter
|
||||
color-interpolation-filters="sRGB"
|
||||
inkscape:collect="always"
|
||||
id="filter16494-4"
|
||||
x="-0.20989846"
|
||||
width="1.4197969"
|
||||
y="-0.20903821"
|
||||
height="1.4180764"><feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="1.3282637"
|
||||
id="feGaussianBlur16496-8" /></filter><radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient16498-6"
|
||||
id="radialGradient16504-1"
|
||||
cx="7.6582627"
|
||||
cy="5.8191104"
|
||||
fx="7.6582627"
|
||||
fy="5.8191104"
|
||||
r="8.6928644"
|
||||
gradientTransform="matrix(1.0474339,0,0,1.0517402,-0.3632615,-0.42032492)"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient16498-6"><stop
|
||||
style="stop-color:#9FD0FF;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop16500-8" /><stop
|
||||
style="stop-color:#3465A4;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop16502-0" /></linearGradient></defs><sodipodi:namedview
|
||||
inkscape:window-height="709"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0"
|
||||
guidetolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
objecttolerance="10.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#000000"
|
||||
id="base"
|
||||
showgrid="false"
|
||||
inkscape:zoom="11.313708"
|
||||
inkscape:cx="15.386407"
|
||||
inkscape:cy="13.739577"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1179"
|
||||
inkscape:current-layer="g16402-8"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
borderlayer="true"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:window-maximized="1"><inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid11246"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true" /></sodipodi:namedview><g
|
||||
style="display:inline"
|
||||
id="g16402-8"
|
||||
transform="translate(4.7533483,2.8238929)"><g
|
||||
id="g3175-4"
|
||||
transform="translate(-0.89995416,0.94028614)"><path
|
||||
sodipodi:type="inkscape:offset"
|
||||
inkscape:radius="0"
|
||||
inkscape:original="M 7.65625 0.125 C 3.2589349 0.125 -0.3125 3.7070002 -0.3125 8.125 C -0.3125 12.543001 3.2589349 16.125 7.65625 16.125 C 12.053566 16.125 15.625 12.543001 15.625 8.125 C 15.625 3.7070002 12.053566 0.125 7.65625 0.125 z "
|
||||
xlink:href="#path2394-32"
|
||||
style="opacity:0.52994014;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.18181825;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter16494-4);enable-background:accumulate"
|
||||
id="path16480-5"
|
||||
inkscape:href="#path2394-32"
|
||||
d="m 7.65625,0.125 c -4.3973151,0 -7.96875,3.5820002 -7.96875,8 0,4.418001 3.5714349,8 7.96875,8 4.397316,0 7.96875,-3.581999 7.96875,-8 0,-4.4179998 -3.571434,-8 -7.96875,-8 z"
|
||||
transform="translate(0,1.028519)" /><path
|
||||
clip-rule="evenodd"
|
||||
d="m -0.30428257,8.1237596 c 0,-4.4179998 3.56522987,-7.9999996 7.96254497,-7.9999996 4.3973156,0 7.9625456,3.5819998 7.9625456,7.9999996 0,4.4180014 -3.56523,8.0000004 -7.9625456,8.0000004 -4.3973151,0 -7.96254497,-3.581999 -7.96254497,-8.0000004 z"
|
||||
id="path2394-32"
|
||||
style="color:#000000;fill:url(#radialGradient16504-1);fill-opacity:1;fill-rule:nonzero;stroke:#eeeeec;stroke-width:1.4545455;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
sodipodi:nodetypes="csssc"
|
||||
inkscape:connector-curvature="0" /><g
|
||||
id="g3172-6" /></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 850 B |
|
Before Width: | Height: | Size: 841 B |
@@ -50,8 +50,7 @@ gnome.gtkdoc('shell',
|
||||
join_paths(meson.build_root(), 'src')
|
||||
],
|
||||
scan_args: [
|
||||
'--ignore-headers=' + ' '.join(private_headers + exclude_directories),
|
||||
'--rebuild-types'
|
||||
'--ignore-headers=' + ' '.join(private_headers + exclude_directories)
|
||||
],
|
||||
install: true
|
||||
)
|
||||
|
||||
@@ -17,8 +17,7 @@ gnome.gtkdoc('st',
|
||||
],
|
||||
scan_args: [
|
||||
'--ignore-headers=' + ' '.join(private_headers),
|
||||
'--rebuild-sections',
|
||||
'--rebuild-types'
|
||||
'--rebuild-sections'
|
||||
],
|
||||
install: true
|
||||
)
|
||||
|
||||
@@ -14,15 +14,16 @@ const _ = Gettext.gettext;
|
||||
const Config = imports.misc.config;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
|
||||
const GnomeShellIface = '<node> \
|
||||
<interface name="org.gnome.Shell.Extensions"> \
|
||||
<signal name="ExtensionStatusChanged"> \
|
||||
<arg type="s" name="uuid"/> \
|
||||
<arg type="i" name="state"/> \
|
||||
<arg type="s" name="error"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const GnomeShellIface = `
|
||||
<node>
|
||||
<interface name="org.gnome.Shell.Extensions">
|
||||
<signal name="ExtensionStatusChanged">
|
||||
<arg type="s" name="uuid"/>
|
||||
<arg type="i" name="state"/>
|
||||
<arg type="s" name="error"/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const GnomeShellProxy = Gio.DBusProxy.makeProxyWrapper(GnomeShellIface);
|
||||
|
||||
@@ -34,16 +35,16 @@ function stripPrefix(string, prefix) {
|
||||
|
||||
var Application = new Lang.Class({
|
||||
Name: 'Application',
|
||||
_init: function() {
|
||||
_init() {
|
||||
GLib.set_prgname('gnome-shell-extension-prefs');
|
||||
this.application = new Gtk.Application({
|
||||
application_id: 'org.gnome.shell.ExtensionPrefs',
|
||||
flags: Gio.ApplicationFlags.HANDLES_COMMAND_LINE
|
||||
});
|
||||
|
||||
this.application.connect('activate', Lang.bind(this, this._onActivate));
|
||||
this.application.connect('command-line', Lang.bind(this, this._onCommandLine));
|
||||
this.application.connect('startup', Lang.bind(this, this._onStartup));
|
||||
this.application.connect('activate', this._onActivate.bind(this));
|
||||
this.application.connect('command-line', this._onCommandLine.bind(this));
|
||||
this.application.connect('startup', this._onStartup.bind(this));
|
||||
|
||||
this._extensionPrefsModules = {};
|
||||
|
||||
@@ -52,7 +53,7 @@ var Application = new Lang.Class({
|
||||
this._skipMainWindow = false;
|
||||
},
|
||||
|
||||
_extensionAvailable: function(uuid) {
|
||||
_extensionAvailable(uuid) {
|
||||
let extension = ExtensionUtils.extensions[uuid];
|
||||
|
||||
if (!extension)
|
||||
@@ -64,7 +65,7 @@ var Application = new Lang.Class({
|
||||
return true;
|
||||
},
|
||||
|
||||
_getExtensionPrefsModule: function(extension) {
|
||||
_getExtensionPrefsModule(extension) {
|
||||
let uuid = extension.metadata.uuid;
|
||||
|
||||
if (this._extensionPrefsModules.hasOwnProperty(uuid))
|
||||
@@ -79,7 +80,7 @@ var Application = new Lang.Class({
|
||||
return prefsModule;
|
||||
},
|
||||
|
||||
_selectExtension: function(uuid) {
|
||||
_selectExtension(uuid) {
|
||||
if (!this._extensionAvailable(uuid))
|
||||
return;
|
||||
|
||||
@@ -114,7 +115,7 @@ var Application = new Lang.Class({
|
||||
dialog.show();
|
||||
},
|
||||
|
||||
_buildErrorUI: function(extension, exc) {
|
||||
_buildErrorUI(extension, exc) {
|
||||
let box = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
|
||||
let label = new Gtk.Label({
|
||||
label: _("There was an error loading the preferences dialog for %s:").format(extension.metadata.name)
|
||||
@@ -127,9 +128,7 @@ var Application = new Lang.Class({
|
||||
errortext += 'Stack trace:\n';
|
||||
|
||||
// Indent stack trace.
|
||||
errortext += exc.stack.split('\n').map(function(line) {
|
||||
return ' ' + line;
|
||||
}).join('\n');
|
||||
errortext += exc.stack.split('\n').map(line => ' ' + line).join('\n');
|
||||
|
||||
let scroll = new Gtk.ScrolledWindow({ vexpand: true });
|
||||
let buffer = new Gtk.TextBuffer({ text: errortext });
|
||||
@@ -142,7 +141,7 @@ var Application = new Lang.Class({
|
||||
return box;
|
||||
},
|
||||
|
||||
_buildUI: function(app) {
|
||||
_buildUI(app) {
|
||||
this._window = new Gtk.ApplicationWindow({ application: app,
|
||||
window_position: Gtk.WindowPosition.CENTER });
|
||||
|
||||
@@ -164,28 +163,28 @@ var Application = new Lang.Class({
|
||||
this._window.add(scroll);
|
||||
|
||||
this._extensionSelector = new Gtk.ListBox({ selection_mode: Gtk.SelectionMode.NONE });
|
||||
this._extensionSelector.set_sort_func(Lang.bind(this, this._sortList));
|
||||
this._extensionSelector.set_header_func(Lang.bind(this, this._updateHeader));
|
||||
this._extensionSelector.set_sort_func(this._sortList.bind(this));
|
||||
this._extensionSelector.set_header_func(this._updateHeader.bind(this));
|
||||
|
||||
scroll.add(this._extensionSelector);
|
||||
|
||||
|
||||
this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell');
|
||||
this._shellProxy.connectSignal('ExtensionStatusChanged', Lang.bind(this, function(proxy, senderName, [uuid, state, error]) {
|
||||
this._shellProxy.connectSignal('ExtensionStatusChanged', (proxy, senderName, [uuid, state, error]) => {
|
||||
if (ExtensionUtils.extensions[uuid] !== undefined)
|
||||
this._scanExtensions();
|
||||
}));
|
||||
});
|
||||
|
||||
this._window.show_all();
|
||||
},
|
||||
|
||||
_sortList: function(row1, row2) {
|
||||
_sortList(row1, row2) {
|
||||
let name1 = ExtensionUtils.extensions[row1.uuid].metadata.name;
|
||||
let name2 = ExtensionUtils.extensions[row2.uuid].metadata.name;
|
||||
return name1.localeCompare(name2);
|
||||
},
|
||||
|
||||
_updateHeader: function(row, before) {
|
||||
_updateHeader(row, before) {
|
||||
if (!before || row.get_header())
|
||||
return;
|
||||
|
||||
@@ -193,27 +192,26 @@ var Application = new Lang.Class({
|
||||
row.set_header(sep);
|
||||
},
|
||||
|
||||
_scanExtensions: function() {
|
||||
_scanExtensions() {
|
||||
let finder = new ExtensionUtils.ExtensionFinder();
|
||||
finder.connect('extension-found', Lang.bind(this, this._extensionFound));
|
||||
finder.connect('extension-found', this._extensionFound.bind(this));
|
||||
finder.scanExtensions();
|
||||
this._extensionsLoaded();
|
||||
},
|
||||
|
||||
_extensionFound: function(finder, extension) {
|
||||
_extensionFound(finder, extension) {
|
||||
let row = new ExtensionRow(extension.uuid);
|
||||
|
||||
row.prefsButton.visible = this._extensionAvailable(row.uuid);
|
||||
row.prefsButton.connect('clicked', Lang.bind(this,
|
||||
function() {
|
||||
this._selectExtension(row.uuid);
|
||||
}));
|
||||
row.prefsButton.connect('clicked', () => {
|
||||
this._selectExtension(row.uuid);
|
||||
});
|
||||
|
||||
row.show_all();
|
||||
this._extensionSelector.add(row);
|
||||
},
|
||||
|
||||
_extensionsLoaded: function() {
|
||||
_extensionsLoaded() {
|
||||
if (this._startupUuid && this._extensionAvailable(this._startupUuid))
|
||||
this._selectExtension(this._startupUuid);
|
||||
this._startupUuid = null;
|
||||
@@ -221,16 +219,16 @@ var Application = new Lang.Class({
|
||||
this._loaded = true;
|
||||
},
|
||||
|
||||
_onActivate: function() {
|
||||
_onActivate() {
|
||||
this._window.present();
|
||||
},
|
||||
|
||||
_onStartup: function(app) {
|
||||
_onStartup(app) {
|
||||
this._buildUI(app);
|
||||
this._scanExtensions();
|
||||
},
|
||||
|
||||
_onCommandLine: function(app, commandLine) {
|
||||
_onCommandLine(app, commandLine) {
|
||||
app.activate();
|
||||
let args = commandLine.get_arguments();
|
||||
|
||||
@@ -257,7 +255,7 @@ var DescriptionLabel = new Lang.Class({
|
||||
Name: 'DescriptionLabel',
|
||||
Extends: Gtk.Label,
|
||||
|
||||
vfunc_get_preferred_height_for_width: function(width) {
|
||||
vfunc_get_preferred_height_for_width(width) {
|
||||
// Hack: Request the maximum height allowed by the line limit
|
||||
if (this.lines > 0)
|
||||
return this.parent(0);
|
||||
@@ -269,29 +267,28 @@ var ExtensionRow = new Lang.Class({
|
||||
Name: 'ExtensionRow',
|
||||
Extends: Gtk.ListBoxRow,
|
||||
|
||||
_init: function(uuid) {
|
||||
_init(uuid) {
|
||||
this.parent();
|
||||
|
||||
this.uuid = uuid;
|
||||
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
|
||||
this._settings.connect('changed::enabled-extensions', Lang.bind(this,
|
||||
function() {
|
||||
this._switch.state = this._isEnabled();
|
||||
}));
|
||||
this._settings.connect('changed::enabled-extensions', () => {
|
||||
this._switch.state = this._isEnabled();
|
||||
});
|
||||
this._settings.connect('changed::disable-extension-version-validation',
|
||||
Lang.bind(this, function() {
|
||||
() => {
|
||||
this._switch.sensitive = this._canEnable();
|
||||
}));
|
||||
});
|
||||
this._settings.connect('changed::disable-user-extensions',
|
||||
Lang.bind(this, function() {
|
||||
() => {
|
||||
this._switch.sensitive = this._canEnable();
|
||||
}));
|
||||
});
|
||||
|
||||
this._buildUI();
|
||||
},
|
||||
|
||||
_buildUI: function() {
|
||||
_buildUI() {
|
||||
let extension = ExtensionUtils.extensions[this.uuid];
|
||||
|
||||
let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
|
||||
@@ -328,18 +325,17 @@ var ExtensionRow = new Lang.Class({
|
||||
this._switch = new Gtk.Switch({ valign: Gtk.Align.CENTER,
|
||||
sensitive: this._canEnable(),
|
||||
state: this._isEnabled() });
|
||||
this._switch.connect('notify::active', Lang.bind(this,
|
||||
function() {
|
||||
if (this._switch.active)
|
||||
this._enable();
|
||||
else
|
||||
this._disable();
|
||||
}));
|
||||
this._switch.connect('state-set', function() { return true; });
|
||||
this._switch.connect('notify::active', () => {
|
||||
if (this._switch.active)
|
||||
this._enable();
|
||||
else
|
||||
this._disable();
|
||||
});
|
||||
this._switch.connect('state-set', () => true);
|
||||
hbox.add(this._switch);
|
||||
},
|
||||
|
||||
_canEnable: function() {
|
||||
_canEnable() {
|
||||
let extension = ExtensionUtils.extensions[this.uuid];
|
||||
let checkVersion = !this._settings.get_boolean('disable-extension-version-validation');
|
||||
|
||||
@@ -347,12 +343,12 @@ var ExtensionRow = new Lang.Class({
|
||||
!(checkVersion && ExtensionUtils.isOutOfDate(extension));
|
||||
},
|
||||
|
||||
_isEnabled: function() {
|
||||
_isEnabled() {
|
||||
let extensions = this._settings.get_strv('enabled-extensions');
|
||||
return extensions.indexOf(this.uuid) != -1;
|
||||
},
|
||||
|
||||
_enable: function() {
|
||||
_enable() {
|
||||
let extensions = this._settings.get_strv('enabled-extensions');
|
||||
if (extensions.indexOf(this.uuid) != -1)
|
||||
return;
|
||||
@@ -361,7 +357,7 @@ var ExtensionRow = new Lang.Class({
|
||||
this._settings.set_strv('enabled-extensions', extensions);
|
||||
},
|
||||
|
||||
_disable: function() {
|
||||
_disable() {
|
||||
let extensions = this._settings.get_strv('enabled-extensions');
|
||||
let pos = extensions.indexOf(this.uuid);
|
||||
if (pos == -1)
|
||||
@@ -378,11 +374,11 @@ function initEnvironment() {
|
||||
// Monkey-patch in a "global" object that fakes some Shell utilities
|
||||
// that ExtensionUtils depends on.
|
||||
window.global = {
|
||||
log: function() {
|
||||
log() {
|
||||
print([].join.call(arguments, ', '));
|
||||
},
|
||||
|
||||
logError: function(s) {
|
||||
logError(s) {
|
||||
log('ERROR: ' + s);
|
||||
},
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ var BeginRequestType = {
|
||||
var AuthPrompt = new Lang.Class({
|
||||
Name: 'AuthPrompt',
|
||||
|
||||
_init: function(gdmClient, mode) {
|
||||
_init(gdmClient, mode) {
|
||||
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
|
||||
|
||||
this._gdmClient = gdmClient;
|
||||
@@ -55,35 +55,33 @@ var AuthPrompt = new Lang.Class({
|
||||
|
||||
this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly: reauthenticationOnly });
|
||||
|
||||
this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion));
|
||||
this._userVerifier.connect('show-message', Lang.bind(this, this._onShowMessage));
|
||||
this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed));
|
||||
this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete));
|
||||
this._userVerifier.connect('reset', Lang.bind(this, this._onReset));
|
||||
this._userVerifier.connect('smartcard-status-changed', Lang.bind(this, this._onSmartcardStatusChanged));
|
||||
this._userVerifier.connect('ovirt-user-authenticated', Lang.bind(this, this._onOVirtUserAuthenticated));
|
||||
this._userVerifier.connect('ask-question', this._onAskQuestion.bind(this));
|
||||
this._userVerifier.connect('show-message', this._onShowMessage.bind(this));
|
||||
this._userVerifier.connect('verification-failed', this._onVerificationFailed.bind(this));
|
||||
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
|
||||
this._userVerifier.connect('reset', this._onReset.bind(this));
|
||||
this._userVerifier.connect('smartcard-status-changed', this._onSmartcardStatusChanged.bind(this));
|
||||
this._userVerifier.connect('ovirt-user-authenticated', this._onOVirtUserAuthenticated.bind(this));
|
||||
this.smartcardDetected = this._userVerifier.smartcardDetected;
|
||||
|
||||
this.connect('next', Lang.bind(this, function() {
|
||||
this.updateSensitivity(false);
|
||||
this.startSpinning();
|
||||
if (this._queryingService) {
|
||||
this._userVerifier.answerQuery(this._queryingService, this._entry.text);
|
||||
} else {
|
||||
this._preemptiveAnswer = this._entry.text;
|
||||
}
|
||||
}));
|
||||
this.connect('next', () => {
|
||||
this.updateSensitivity(false);
|
||||
this.startSpinning();
|
||||
if (this._queryingService) {
|
||||
this._userVerifier.answerQuery(this._queryingService, this._entry.text);
|
||||
} else {
|
||||
this._preemptiveAnswer = this._entry.text;
|
||||
}
|
||||
});
|
||||
|
||||
this.actor = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
|
||||
vertical: true });
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
this.actor.connect('key-press-event',
|
||||
Lang.bind(this, function(actor, event) {
|
||||
if (event.get_key_symbol() == Clutter.KEY_Escape) {
|
||||
this.cancel();
|
||||
}
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}));
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.actor.connect('key-press-event', (actor, event) => {
|
||||
if (event.get_key_symbol() == Clutter.KEY_Escape)
|
||||
this.cancel();
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
});
|
||||
|
||||
this._userWell = new St.Bin({ x_fill: true,
|
||||
x_align: St.Align.START });
|
||||
@@ -136,21 +134,18 @@ var AuthPrompt = new Lang.Class({
|
||||
this._defaultButtonWell.add_child(this._spinner.actor);
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
_onDestroy() {
|
||||
this._userVerifier.destroy();
|
||||
this._userVerifier = null;
|
||||
},
|
||||
|
||||
_initButtons: function() {
|
||||
_initButtons() {
|
||||
this.cancelButton = new St.Button({ style_class: 'modal-dialog-button button',
|
||||
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
||||
reactive: true,
|
||||
can_focus: true,
|
||||
label: _("Cancel") });
|
||||
this.cancelButton.connect('clicked',
|
||||
Lang.bind(this, function() {
|
||||
this.cancel();
|
||||
}));
|
||||
this.cancelButton.connect('clicked', () => { this.cancel(); });
|
||||
this._buttonBox.add(this.cancelButton,
|
||||
{ expand: false,
|
||||
x_fill: false,
|
||||
@@ -169,10 +164,7 @@ var AuthPrompt = new Lang.Class({
|
||||
reactive: true,
|
||||
can_focus: true,
|
||||
label: _("Next") });
|
||||
this.nextButton.connect('clicked',
|
||||
Lang.bind(this, function() {
|
||||
this.emit('next');
|
||||
}));
|
||||
this.nextButton.connect('clicked', () => { this.emit('next'); });
|
||||
this.nextButton.add_style_pseudo_class('default');
|
||||
this._buttonBox.add(this.nextButton,
|
||||
{ expand: false,
|
||||
@@ -183,20 +175,19 @@ var AuthPrompt = new Lang.Class({
|
||||
|
||||
this._updateNextButtonSensitivity(this._entry.text.length > 0);
|
||||
|
||||
this._entry.clutter_text.connect('text-changed',
|
||||
Lang.bind(this, function() {
|
||||
if (!this._userVerifier.hasPendingMessages)
|
||||
this._fadeOutMessage();
|
||||
this._entry.clutter_text.connect('text-changed', () => {
|
||||
if (!this._userVerifier.hasPendingMessages)
|
||||
this._fadeOutMessage();
|
||||
|
||||
this._updateNextButtonSensitivity(this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING);
|
||||
}));
|
||||
this._entry.clutter_text.connect('activate', Lang.bind(this, function() {
|
||||
this._updateNextButtonSensitivity(this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING);
|
||||
});
|
||||
this._entry.clutter_text.connect('activate', () => {
|
||||
if (this.nextButton.reactive)
|
||||
this.emit('next');
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
_onAskQuestion: function(verifier, serviceName, question, passwordChar) {
|
||||
_onAskQuestion(verifier, serviceName, question, passwordChar) {
|
||||
if (this._queryingService)
|
||||
this.clear();
|
||||
|
||||
@@ -222,12 +213,12 @@ var AuthPrompt = new Lang.Class({
|
||||
this.emit('prompted');
|
||||
},
|
||||
|
||||
_onOVirtUserAuthenticated: function() {
|
||||
_onOVirtUserAuthenticated() {
|
||||
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
|
||||
this.reset();
|
||||
},
|
||||
|
||||
_onSmartcardStatusChanged: function() {
|
||||
_onSmartcardStatusChanged() {
|
||||
this.smartcardDetected = this._userVerifier.smartcardDetected;
|
||||
|
||||
// Most of the time we want to reset if the user inserts or removes
|
||||
@@ -246,36 +237,36 @@ var AuthPrompt = new Lang.Class({
|
||||
this.reset();
|
||||
},
|
||||
|
||||
_onShowMessage: function(userVerifier, message, type) {
|
||||
_onShowMessage(userVerifier, message, type) {
|
||||
this.setMessage(message, type);
|
||||
this.emit('prompted');
|
||||
},
|
||||
|
||||
_onVerificationFailed: function() {
|
||||
_onVerificationFailed(userVerifier, canRetry) {
|
||||
this._queryingService = null;
|
||||
this.clear();
|
||||
|
||||
this.updateSensitivity(true);
|
||||
this.updateSensitivity(canRetry);
|
||||
this.setActorInDefaultButtonWell(null);
|
||||
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
|
||||
},
|
||||
|
||||
_onVerificationComplete: function() {
|
||||
_onVerificationComplete() {
|
||||
this.setActorInDefaultButtonWell(null);
|
||||
this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED;
|
||||
this.cancelButton.reactive = false;
|
||||
},
|
||||
|
||||
_onReset: function() {
|
||||
_onReset() {
|
||||
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
|
||||
this.reset();
|
||||
},
|
||||
|
||||
addActorToDefaultButtonWell: function(actor) {
|
||||
addActorToDefaultButtonWell(actor) {
|
||||
this._defaultButtonWell.add_child(actor);
|
||||
},
|
||||
|
||||
setActorInDefaultButtonWell: function(actor, animate) {
|
||||
setActorInDefaultButtonWell(actor, animate) {
|
||||
if (!this._defaultButtonWellActor &&
|
||||
!actor)
|
||||
return;
|
||||
@@ -312,7 +303,7 @@ var AuthPrompt = new Lang.Class({
|
||||
delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
|
||||
transition: 'linear',
|
||||
onCompleteScope: this,
|
||||
onComplete: function() {
|
||||
onComplete() {
|
||||
if (wasSpinner) {
|
||||
if (this._spinner)
|
||||
this._spinner.stop();
|
||||
@@ -339,25 +330,25 @@ var AuthPrompt = new Lang.Class({
|
||||
this._defaultButtonWellActor = actor;
|
||||
},
|
||||
|
||||
startSpinning: function() {
|
||||
startSpinning() {
|
||||
this.setActorInDefaultButtonWell(this._spinner.actor, true);
|
||||
},
|
||||
|
||||
stopSpinning: function() {
|
||||
stopSpinning() {
|
||||
this.setActorInDefaultButtonWell(null, false);
|
||||
},
|
||||
|
||||
clear: function() {
|
||||
clear() {
|
||||
this._entry.text = '';
|
||||
this.stopSpinning();
|
||||
},
|
||||
|
||||
setPasswordChar: function(passwordChar) {
|
||||
setPasswordChar(passwordChar) {
|
||||
this._entry.clutter_text.set_password_char(passwordChar);
|
||||
this._entry.menu.isPassword = passwordChar != '';
|
||||
},
|
||||
|
||||
setQuestion: function(question) {
|
||||
setQuestion(question) {
|
||||
this._label.set_text(question);
|
||||
|
||||
this._label.show();
|
||||
@@ -366,7 +357,7 @@ var AuthPrompt = new Lang.Class({
|
||||
this._entry.grab_key_focus();
|
||||
},
|
||||
|
||||
getAnswer: function() {
|
||||
getAnswer() {
|
||||
let text;
|
||||
|
||||
if (this._preemptiveAnswer) {
|
||||
@@ -379,7 +370,7 @@ var AuthPrompt = new Lang.Class({
|
||||
return text;
|
||||
},
|
||||
|
||||
_fadeOutMessage: function() {
|
||||
_fadeOutMessage() {
|
||||
if (this._message.opacity == 0)
|
||||
return;
|
||||
Tweener.removeTweens(this._message);
|
||||
@@ -390,7 +381,7 @@ var AuthPrompt = new Lang.Class({
|
||||
});
|
||||
},
|
||||
|
||||
setMessage: function(message, type) {
|
||||
setMessage(message, type) {
|
||||
if (type == GdmUtil.MessageType.ERROR)
|
||||
this._message.add_style_class_name('login-dialog-message-warning');
|
||||
else
|
||||
@@ -410,18 +401,18 @@ var AuthPrompt = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_updateNextButtonSensitivity: function(sensitive) {
|
||||
_updateNextButtonSensitivity(sensitive) {
|
||||
this.nextButton.reactive = sensitive;
|
||||
this.nextButton.can_focus = sensitive;
|
||||
},
|
||||
|
||||
updateSensitivity: function(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: function() {
|
||||
hide() {
|
||||
this.setActorInDefaultButtonWell(null, true);
|
||||
this.actor.hide();
|
||||
this._message.opacity = 0;
|
||||
@@ -432,7 +423,7 @@ var AuthPrompt = new Lang.Class({
|
||||
this._entry.set_text('');
|
||||
},
|
||||
|
||||
setUser: function(user) {
|
||||
setUser(user) {
|
||||
let oldChild = this._userWell.get_child();
|
||||
if (oldChild)
|
||||
oldChild.destroy();
|
||||
@@ -443,11 +434,12 @@ var AuthPrompt = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
reset() {
|
||||
let oldStatus = this.verificationStatus;
|
||||
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
|
||||
this.cancelButton.reactive = true;
|
||||
this.nextButton.label = _("Next");
|
||||
this._preemptiveAnswer = null;
|
||||
|
||||
if (this._userVerifier)
|
||||
this._userVerifier.cancel();
|
||||
@@ -480,7 +472,7 @@ var AuthPrompt = new Lang.Class({
|
||||
this.emit('reset', beginRequestType);
|
||||
},
|
||||
|
||||
addCharacter: function(unichar) {
|
||||
addCharacter(unichar) {
|
||||
if (!this._entry.visible)
|
||||
return;
|
||||
|
||||
@@ -488,7 +480,7 @@ var AuthPrompt = new Lang.Class({
|
||||
this._entry.clutter_text.insert_unichar(unichar);
|
||||
},
|
||||
|
||||
begin: function(params) {
|
||||
begin(params) {
|
||||
params = Params.parse(params, { userName: null,
|
||||
hold: null });
|
||||
|
||||
@@ -502,22 +494,21 @@ var AuthPrompt = new Lang.Class({
|
||||
this.verificationStatus = AuthPromptStatus.VERIFYING;
|
||||
},
|
||||
|
||||
finish: function(onComplete) {
|
||||
finish(onComplete) {
|
||||
if (!this._userVerifier.hasPendingMessages) {
|
||||
this._userVerifier.clear();
|
||||
onComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
let signalId = this._userVerifier.connect('no-more-messages',
|
||||
Lang.bind(this, function() {
|
||||
this._userVerifier.disconnect(signalId);
|
||||
this._userVerifier.clear();
|
||||
onComplete();
|
||||
}));
|
||||
let signalId = this._userVerifier.connect('no-more-messages', () => {
|
||||
this._userVerifier.disconnect(signalId);
|
||||
this._userVerifier.clear();
|
||||
onComplete();
|
||||
});
|
||||
},
|
||||
|
||||
cancel: function() {
|
||||
cancel() {
|
||||
if (this.verificationStatus == AuthPromptStatus.VERIFICATION_SUCCEEDED) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ const Signals = imports.signals;
|
||||
var Task = new Lang.Class({
|
||||
Name: 'Task',
|
||||
|
||||
_init: function(scope, handler) {
|
||||
_init(scope, handler) {
|
||||
if (scope)
|
||||
this.scope = scope;
|
||||
else
|
||||
@@ -59,7 +59,7 @@ var Task = new Lang.Class({
|
||||
this.handler = handler;
|
||||
},
|
||||
|
||||
run: function() {
|
||||
run() {
|
||||
if (this.handler)
|
||||
return this.handler.call(this.scope);
|
||||
|
||||
@@ -72,39 +72,37 @@ var Hold = new Lang.Class({
|
||||
Name: 'Hold',
|
||||
Extends: Task,
|
||||
|
||||
_init: function() {
|
||||
this.parent(this, function () {
|
||||
return this;
|
||||
});
|
||||
_init() {
|
||||
this.parent(this, () => this);
|
||||
|
||||
this._acquisitions = 1;
|
||||
},
|
||||
|
||||
acquire: function() {
|
||||
acquire() {
|
||||
if (this._acquisitions <= 0)
|
||||
throw new Error("Cannot acquire hold after it's been released");
|
||||
this._acquisitions++;
|
||||
},
|
||||
|
||||
acquireUntilAfter: function(hold) {
|
||||
acquireUntilAfter(hold) {
|
||||
if (!hold.isAcquired())
|
||||
return;
|
||||
|
||||
this.acquire();
|
||||
let signalId = hold.connect('release', Lang.bind(this, function() {
|
||||
hold.disconnect(signalId);
|
||||
this.release();
|
||||
}));
|
||||
let signalId = hold.connect('release', () => {
|
||||
hold.disconnect(signalId);
|
||||
this.release();
|
||||
});
|
||||
},
|
||||
|
||||
release: function() {
|
||||
release() {
|
||||
this._acquisitions--;
|
||||
|
||||
if (this._acquisitions == 0)
|
||||
this.emit('release');
|
||||
},
|
||||
|
||||
isAcquired: function() {
|
||||
isAcquired() {
|
||||
return this._acquisitions > 0;
|
||||
}
|
||||
});
|
||||
@@ -114,7 +112,7 @@ var Batch = new Lang.Class({
|
||||
Name: 'Batch',
|
||||
Extends: Task,
|
||||
|
||||
_init: function(scope, tasks) {
|
||||
_init(scope, tasks) {
|
||||
this.parent();
|
||||
|
||||
this.tasks = [];
|
||||
@@ -134,11 +132,11 @@ var Batch = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
process: function() {
|
||||
process() {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
runTask: function() {
|
||||
runTask() {
|
||||
if (!(this._currentTaskIndex in this.tasks)) {
|
||||
return null;
|
||||
}
|
||||
@@ -146,11 +144,11 @@ var Batch = new Lang.Class({
|
||||
return this.tasks[this._currentTaskIndex].run();
|
||||
},
|
||||
|
||||
_finish: function() {
|
||||
_finish() {
|
||||
this.hold.release();
|
||||
},
|
||||
|
||||
nextTask: function() {
|
||||
nextTask() {
|
||||
this._currentTaskIndex++;
|
||||
|
||||
// if the entire batch of tasks is finished, release
|
||||
@@ -163,7 +161,7 @@ var Batch = new Lang.Class({
|
||||
this.process();
|
||||
},
|
||||
|
||||
_start: function() {
|
||||
_start() {
|
||||
// acquire a hold to get released when the entire
|
||||
// batch of tasks is finished
|
||||
this.hold = new Hold();
|
||||
@@ -171,7 +169,7 @@ var Batch = new Lang.Class({
|
||||
this.process();
|
||||
},
|
||||
|
||||
run: function() {
|
||||
run() {
|
||||
this._start();
|
||||
|
||||
// hold may be destroyed at this point
|
||||
@@ -179,7 +177,7 @@ var Batch = new Lang.Class({
|
||||
return this.hold;
|
||||
},
|
||||
|
||||
cancel: function() {
|
||||
cancel() {
|
||||
this.tasks = this.tasks.splice(0, this._currentTaskIndex + 1);
|
||||
}
|
||||
});
|
||||
@@ -189,7 +187,7 @@ var ConcurrentBatch = new Lang.Class({
|
||||
Name: 'ConcurrentBatch',
|
||||
Extends: Batch,
|
||||
|
||||
process: function() {
|
||||
process() {
|
||||
let hold = this.runTask();
|
||||
|
||||
if (hold) {
|
||||
@@ -208,17 +206,16 @@ var ConsecutiveBatch = new Lang.Class({
|
||||
Name: 'ConsecutiveBatch',
|
||||
Extends: Batch,
|
||||
|
||||
process: function() {
|
||||
process() {
|
||||
let hold = this.runTask();
|
||||
|
||||
if (hold && hold.isAcquired()) {
|
||||
// This task is inhibiting the batch. Wait on it
|
||||
// before processing the next one.
|
||||
let signalId = hold.connect('release',
|
||||
Lang.bind(this, function() {
|
||||
hold.disconnect(signalId);
|
||||
this.nextTask();
|
||||
}));
|
||||
let signalId = hold.connect('release', () => {
|
||||
hold.disconnect(signalId);
|
||||
this.nextTask();
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
// This task finished, process the next one
|
||||
|
||||
@@ -5,13 +5,14 @@ const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const FprintManagerIface = '<node> \
|
||||
<interface name="net.reactivated.Fprint.Manager"> \
|
||||
<method name="GetDefaultDevice"> \
|
||||
<arg type="o" direction="out" /> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const FprintManagerIface = `
|
||||
<node>
|
||||
<interface name="net.reactivated.Fprint.Manager">
|
||||
<method name="GetDefaultDevice">
|
||||
<arg type="o" direction="out" />
|
||||
</method>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const FprintManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(FprintManagerIface);
|
||||
|
||||
|
||||
@@ -4,13 +4,14 @@ const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const OVirtCredentialsIface = '<node> \
|
||||
<interface name="org.ovirt.vdsm.Credentials"> \
|
||||
<signal name="UserAuthenticated"> \
|
||||
<arg type="s" name="token"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const OVirtCredentialsIface = `
|
||||
<node>
|
||||
<interface name="org.ovirt.vdsm.Credentials">
|
||||
<signal name="UserAuthenticated">
|
||||
<arg type="s" name="token"/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const OVirtCredentialsInfo = Gio.DBusInterfaceInfo.new_for_xml(OVirtCredentialsIface);
|
||||
|
||||
@@ -29,28 +30,28 @@ function OVirtCredentials() {
|
||||
|
||||
var OVirtCredentialsManager = new Lang.Class({
|
||||
Name: 'OVirtCredentialsManager',
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._token = null;
|
||||
|
||||
this._credentials = new OVirtCredentials();
|
||||
this._credentials.connectSignal('UserAuthenticated',
|
||||
Lang.bind(this, this._onUserAuthenticated));
|
||||
this._onUserAuthenticated.bind(this));
|
||||
},
|
||||
|
||||
_onUserAuthenticated: function(proxy, sender, [token]) {
|
||||
_onUserAuthenticated(proxy, sender, [token]) {
|
||||
this._token = token;
|
||||
this.emit('user-authenticated', token);
|
||||
},
|
||||
|
||||
hasToken: function() {
|
||||
hasToken() {
|
||||
return this._token != null;
|
||||
},
|
||||
|
||||
getToken: function() {
|
||||
getToken() {
|
||||
return this._token;
|
||||
},
|
||||
|
||||
resetToken: function() {
|
||||
resetToken() {
|
||||
this._token = null;
|
||||
}
|
||||
});
|
||||
|
||||
136
js/gdm/realmd.js
@@ -5,78 +5,81 @@ const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const ProviderIface = '<node> \
|
||||
<interface name="org.freedesktop.realmd.Provider"> \
|
||||
<property name="Name" type="s" access="read"/> \
|
||||
<property name="Version" type="s" access="read"/> \
|
||||
<property name="Realms" type="ao" access="read"/> \
|
||||
<method name="Discover"> \
|
||||
<arg name="string" type="s" direction="in"/> \
|
||||
<arg name="options" type="a{sv}" direction="in"/> \
|
||||
<arg name="relevance" type="i" direction="out"/> \
|
||||
<arg name="realm" type="ao" direction="out"/> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ProviderIface = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.realmd.Provider">
|
||||
<property name="Name" type="s" access="read"/>
|
||||
<property name="Version" type="s" access="read"/>
|
||||
<property name="Realms" type="ao" access="read"/>
|
||||
<method name="Discover">
|
||||
<arg name="string" type="s" direction="in"/>
|
||||
<arg name="options" type="a{sv}" direction="in"/>
|
||||
<arg name="relevance" type="i" direction="out"/>
|
||||
<arg name="realm" type="ao" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>`;
|
||||
const Provider = Gio.DBusProxy.makeProxyWrapper(ProviderIface);
|
||||
|
||||
const ServiceIface = '<node> \
|
||||
<interface name="org.freedesktop.realmd.Service"> \
|
||||
<method name="Cancel"> \
|
||||
<arg name="operation" type="s" direction="in"/> \
|
||||
</method> \
|
||||
<method name="Release" /> \
|
||||
<method name="SetLocale"> \
|
||||
<arg name="locale" type="s" direction="in"/> \
|
||||
</method> \
|
||||
<signal name="Diagnostics"> \
|
||||
<arg name="data" type="s"/> \
|
||||
<arg name="operation" type="s"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ServiceIface = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.realmd.Service">
|
||||
<method name="Cancel">
|
||||
<arg name="operation" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="Release" />
|
||||
<method name="SetLocale">
|
||||
<arg name="locale" type="s" direction="in"/>
|
||||
</method>
|
||||
<signal name="Diagnostics">
|
||||
<arg name="data" type="s"/>
|
||||
<arg name="operation" type="s"/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>`;
|
||||
const Service = Gio.DBusProxy.makeProxyWrapper(ServiceIface);
|
||||
|
||||
const RealmIface = '<node> \
|
||||
<interface name="org.freedesktop.realmd.Realm"> \
|
||||
<property name="Name" type="s" access="read"/> \
|
||||
<property name="Configured" type="s" access="read"/> \
|
||||
<property name="Details" type="a(ss)" access="read"/> \
|
||||
<property name="LoginFormats" type="as" access="read"/> \
|
||||
<property name="LoginPolicy" type="s" access="read"/> \
|
||||
<property name="PermittedLogins" type="as" access="read"/> \
|
||||
<property name="SupportedInterfaces" type="as" access="read"/> \
|
||||
<method name="ChangeLoginPolicy"> \
|
||||
<arg name="login_policy" type="s" direction="in"/> \
|
||||
<arg name="permitted_add" type="as" direction="in"/> \
|
||||
<arg name="permitted_remove" type="as" direction="in"/> \
|
||||
<arg name="options" type="a{sv}" direction="in"/> \
|
||||
</method> \
|
||||
<method name="Deconfigure"> \
|
||||
<arg name="options" type="a{sv}" direction="in"/> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const RealmIface = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.realmd.Realm">
|
||||
<property name="Name" type="s" access="read"/>
|
||||
<property name="Configured" type="s" access="read"/>
|
||||
<property name="Details" type="a(ss)" access="read"/>
|
||||
<property name="LoginFormats" type="as" access="read"/>
|
||||
<property name="LoginPolicy" type="s" access="read"/>
|
||||
<property name="PermittedLogins" type="as" access="read"/>
|
||||
<property name="SupportedInterfaces" type="as" access="read"/>
|
||||
<method name="ChangeLoginPolicy">
|
||||
<arg name="login_policy" type="s" direction="in"/>
|
||||
<arg name="permitted_add" type="as" direction="in"/>
|
||||
<arg name="permitted_remove" type="as" direction="in"/>
|
||||
<arg name="options" type="a{sv}" direction="in"/>
|
||||
</method>
|
||||
<method name="Deconfigure">
|
||||
<arg name="options" type="a{sv}" direction="in"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>`;
|
||||
const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface);
|
||||
|
||||
var Manager = new Lang.Class({
|
||||
Name: 'Manager',
|
||||
|
||||
_init: function(parentActor) {
|
||||
_init(parentActor) {
|
||||
this._aggregateProvider = Provider(Gio.DBus.system,
|
||||
'org.freedesktop.realmd',
|
||||
'/org/freedesktop/realmd',
|
||||
Lang.bind(this, this._reloadRealms))
|
||||
this._reloadRealms.bind(this))
|
||||
this._realms = {};
|
||||
|
||||
this._signalId = this._aggregateProvider.connect('g-properties-changed',
|
||||
Lang.bind(this, function(proxy, properties) {
|
||||
if ('Realms' in properties.deep_unpack())
|
||||
this._reloadRealms();
|
||||
}));
|
||||
(proxy, properties) => {
|
||||
if ('Realms' in properties.deep_unpack())
|
||||
this._reloadRealms();
|
||||
});
|
||||
},
|
||||
|
||||
_reloadRealms: function() {
|
||||
_reloadRealms() {
|
||||
let realmPaths = this._aggregateProvider.Realms;
|
||||
|
||||
if (!realmPaths)
|
||||
@@ -86,11 +89,11 @@ var Manager = new Lang.Class({
|
||||
let realm = Realm(Gio.DBus.system,
|
||||
'org.freedesktop.realmd',
|
||||
realmPaths[i],
|
||||
Lang.bind(this, this._onRealmLoaded));
|
||||
this._onRealmLoaded.bind(this));
|
||||
}
|
||||
},
|
||||
|
||||
_reloadRealm: function(realm) {
|
||||
_reloadRealm(realm) {
|
||||
if (!realm.Configured) {
|
||||
if (this._realms[realm.get_object_path()])
|
||||
delete this._realms[realm.get_object_path()];
|
||||
@@ -103,20 +106,19 @@ var Manager = new Lang.Class({
|
||||
this._updateLoginFormat();
|
||||
},
|
||||
|
||||
_onRealmLoaded: function(realm, error) {
|
||||
_onRealmLoaded(realm, error) {
|
||||
if (error)
|
||||
return;
|
||||
|
||||
this._reloadRealm(realm);
|
||||
|
||||
realm.connect('g-properties-changed',
|
||||
Lang.bind(this, function(proxy, properties) {
|
||||
if ('Configured' in properties.deep_unpack())
|
||||
this._reloadRealm(realm);
|
||||
}));
|
||||
realm.connect('g-properties-changed', (proxy, properties) => {
|
||||
if ('Configured' in properties.deep_unpack())
|
||||
this._reloadRealm(realm);
|
||||
});
|
||||
},
|
||||
|
||||
_updateLoginFormat: function() {
|
||||
_updateLoginFormat() {
|
||||
let newLoginFormat;
|
||||
|
||||
for (let realmPath in this._realms) {
|
||||
@@ -142,13 +144,11 @@ var Manager = new Lang.Class({
|
||||
return this._loginFormat;
|
||||
},
|
||||
|
||||
release: function() {
|
||||
release() {
|
||||
Service(Gio.DBus.system,
|
||||
'org.freedesktop.realmd',
|
||||
'/org/freedesktop/realmd',
|
||||
function(service) {
|
||||
service.ReleaseRemote();
|
||||
});
|
||||
service => { service.ReleaseRemote(); });
|
||||
this._aggregateProvider.disconnect(this._signalId);
|
||||
this._realms = { };
|
||||
this._updateLoginFormat();
|
||||
|
||||
196
js/gdm/util.js
@@ -60,7 +60,7 @@ function fadeInActor(actor) {
|
||||
height: naturalHeight,
|
||||
time: FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: function() {
|
||||
onComplete() {
|
||||
this.set_height(-1);
|
||||
hold.release();
|
||||
},
|
||||
@@ -82,7 +82,7 @@ function fadeOutActor(actor) {
|
||||
height: 0,
|
||||
time: FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: function() {
|
||||
onComplete() {
|
||||
this.hide();
|
||||
this.set_height(-1);
|
||||
hold.release();
|
||||
@@ -111,7 +111,7 @@ function cloneAndFadeOutActor(actor) {
|
||||
{ opacity: 0,
|
||||
time: CLONE_FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: function() {
|
||||
onComplete() {
|
||||
clone.destroy();
|
||||
hold.release();
|
||||
}
|
||||
@@ -122,7 +122,7 @@ function cloneAndFadeOutActor(actor) {
|
||||
var ShellUserVerifier = new Lang.Class({
|
||||
Name: 'ShellUserVerifier',
|
||||
|
||||
_init: function(client, params) {
|
||||
_init(client, params) {
|
||||
params = Params.parse(params, { reauthenticationOnly: false });
|
||||
this._reauthOnly = params.reauthenticationOnly;
|
||||
|
||||
@@ -133,7 +133,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
|
||||
this._settings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA });
|
||||
this._settings.connect('changed',
|
||||
Lang.bind(this, this._updateDefaultService));
|
||||
this._updateDefaultService.bind(this));
|
||||
this._updateDefaultService();
|
||||
|
||||
this._fprintManager = Fprint.FprintManager();
|
||||
@@ -147,9 +147,9 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._checkForSmartcard();
|
||||
|
||||
this._smartcardInsertedId = this._smartcardManager.connect('smartcard-inserted',
|
||||
Lang.bind(this, this._checkForSmartcard));
|
||||
this._checkForSmartcard.bind(this));
|
||||
this._smartcardRemovedId = this._smartcardManager.connect('smartcard-removed',
|
||||
Lang.bind(this, this._checkForSmartcard));
|
||||
this._checkForSmartcard.bind(this));
|
||||
|
||||
this._messageQueue = [];
|
||||
this._messageQueueTimeoutId = 0;
|
||||
@@ -164,10 +164,10 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._oVirtUserAuthenticated(this._oVirtCredentialsManager.getToken());
|
||||
|
||||
this._oVirtUserAuthenticatedId = this._oVirtCredentialsManager.connect('user-authenticated',
|
||||
Lang.bind(this, this._oVirtUserAuthenticated));
|
||||
this._oVirtUserAuthenticated.bind(this));
|
||||
},
|
||||
|
||||
begin: function(userName, hold) {
|
||||
begin(userName, hold) {
|
||||
this._cancellable = new Gio.Cancellable();
|
||||
this._hold = hold;
|
||||
this._userName = userName;
|
||||
@@ -179,13 +179,13 @@ var ShellUserVerifier = new Lang.Class({
|
||||
// If possible, reauthenticate an already running session,
|
||||
// so any session specific credentials get updated appropriately
|
||||
this._client.open_reauthentication_channel(userName, this._cancellable,
|
||||
Lang.bind(this, this._reauthenticationChannelOpened));
|
||||
this._reauthenticationChannelOpened.bind(this));
|
||||
} else {
|
||||
this._client.get_user_verifier(this._cancellable, Lang.bind(this, this._userVerifierGot));
|
||||
this._client.get_user_verifier(this._cancellable, this._userVerifierGot.bind(this));
|
||||
}
|
||||
},
|
||||
|
||||
cancel: function() {
|
||||
cancel() {
|
||||
if (this._cancellable)
|
||||
this._cancellable.cancel();
|
||||
|
||||
@@ -195,14 +195,14 @@ var ShellUserVerifier = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_clearUserVerifier: function() {
|
||||
_clearUserVerifier() {
|
||||
if (this._userVerifier) {
|
||||
this._userVerifier.run_dispose();
|
||||
this._userVerifier = null;
|
||||
}
|
||||
},
|
||||
|
||||
clear: function() {
|
||||
clear() {
|
||||
if (this._cancellable) {
|
||||
this._cancellable.cancel();
|
||||
this._cancellable = null;
|
||||
@@ -212,7 +212,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._clearMessageQueue();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
destroy() {
|
||||
this.clear();
|
||||
|
||||
this._settings.run_dispose();
|
||||
@@ -226,24 +226,23 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._oVirtCredentialsManager = null;
|
||||
},
|
||||
|
||||
answerQuery: function(serviceName, answer) {
|
||||
answerQuery(serviceName, answer) {
|
||||
if (!this.hasPendingMessages) {
|
||||
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
||||
} else {
|
||||
let signalId = this.connect('no-more-messages',
|
||||
Lang.bind(this, function() {
|
||||
this.disconnect(signalId);
|
||||
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
||||
}));
|
||||
let signalId = this.connect('no-more-messages', () => {
|
||||
this.disconnect(signalId);
|
||||
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_getIntervalForMessage: function(message) {
|
||||
_getIntervalForMessage(message) {
|
||||
// We probably could be smarter here
|
||||
return message.length * USER_READ_TIME;
|
||||
},
|
||||
|
||||
finishMessageQueue: function() {
|
||||
finishMessageQueue() {
|
||||
if (!this.hasPendingMessages)
|
||||
return;
|
||||
|
||||
@@ -253,7 +252,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this.emit('no-more-messages');
|
||||
},
|
||||
|
||||
_queueMessageTimeout: function() {
|
||||
_queueMessageTimeout() {
|
||||
if (this._messageQueue.length == 0) {
|
||||
this.finishMessageQueue();
|
||||
return;
|
||||
@@ -268,15 +267,15 @@ var ShellUserVerifier = new Lang.Class({
|
||||
|
||||
this._messageQueueTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
|
||||
message.interval,
|
||||
Lang.bind(this, function() {
|
||||
() => {
|
||||
this._messageQueueTimeoutId = 0;
|
||||
this._queueMessageTimeout();
|
||||
return GLib.SOURCE_REMOVE;
|
||||
}));
|
||||
});
|
||||
GLib.Source.set_name_by_id(this._messageQueueTimeoutId, '[gnome-shell] this._queueMessageTimeout');
|
||||
},
|
||||
|
||||
_queueMessage: function(message, messageType) {
|
||||
_queueMessage(message, messageType) {
|
||||
let interval = this._getIntervalForMessage(message);
|
||||
|
||||
this.hasPendingMessages = true;
|
||||
@@ -284,7 +283,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._queueMessageTimeout();
|
||||
},
|
||||
|
||||
_clearMessageQueue: function() {
|
||||
_clearMessageQueue() {
|
||||
this.finishMessageQueue();
|
||||
|
||||
if (this._messageQueueTimeoutId != 0) {
|
||||
@@ -294,7 +293,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this.emit('show-message', null, MessageType.NONE);
|
||||
},
|
||||
|
||||
_checkForFingerprintReader: function() {
|
||||
_checkForFingerprintReader() {
|
||||
this._haveFingerprintReader = false;
|
||||
|
||||
if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY) ||
|
||||
@@ -303,21 +302,21 @@ var ShellUserVerifier = new Lang.Class({
|
||||
return;
|
||||
}
|
||||
|
||||
this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, this._cancellable, Lang.bind(this,
|
||||
function(device, error) {
|
||||
this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, this._cancellable,
|
||||
(device, error) => {
|
||||
if (!error && device) {
|
||||
this._haveFingerprintReader = true;
|
||||
this._updateDefaultService();
|
||||
}
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
_oVirtUserAuthenticated: function(token) {
|
||||
_oVirtUserAuthenticated(token) {
|
||||
this._preemptingService = OVIRT_SERVICE_NAME;
|
||||
this.emit('ovirt-user-authenticated');
|
||||
},
|
||||
|
||||
_checkForSmartcard: function() {
|
||||
_checkForSmartcard() {
|
||||
let smartcardDetected;
|
||||
|
||||
if (!this._settings.get_boolean(SMARTCARD_AUTHENTICATION_KEY))
|
||||
@@ -339,7 +338,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_reportInitError: function(where, error) {
|
||||
_reportInitError(where, error) {
|
||||
logError(error, where);
|
||||
this._hold.release();
|
||||
|
||||
@@ -347,20 +346,23 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._verificationFailed(false);
|
||||
},
|
||||
|
||||
_reauthenticationChannelOpened: function(client, result) {
|
||||
_reauthenticationChannelOpened(client, result) {
|
||||
try {
|
||||
this._clearUserVerifier();
|
||||
this._userVerifier = client.open_reauthentication_channel_finish(result);
|
||||
} catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
|
||||
return;
|
||||
} catch(e if e.matches(Gio.DBusError, Gio.DBusError.ACCESS_DENIED) &&
|
||||
!this._reauthOnly) {
|
||||
// Gdm emits org.freedesktop.DBus.Error.AccessDenied when there is
|
||||
// no session to reauthenticate. Fall back to performing verification
|
||||
// from this login session
|
||||
client.get_user_verifier(this._cancellable, Lang.bind(this, this._userVerifierGot));
|
||||
return;
|
||||
} catch(e) {
|
||||
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||
return;
|
||||
if (e.matches(Gio.DBusError, Gio.DBusError.ACCESS_DENIED) &&
|
||||
!this._reauthOnly) {
|
||||
// Gdm emits org.freedesktop.DBus.Error.AccessDenied when there
|
||||
// is no session to reauthenticate. Fall back to performing
|
||||
// verification from this login session
|
||||
client.get_user_verifier(this._cancellable,
|
||||
this._userVerifierGot.bind(this));
|
||||
return;
|
||||
}
|
||||
|
||||
this._reportInitError('Failed to open reauthentication channel', e);
|
||||
return;
|
||||
}
|
||||
@@ -371,13 +373,13 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._hold.release();
|
||||
},
|
||||
|
||||
_userVerifierGot: function(client, result) {
|
||||
_userVerifierGot(client, result) {
|
||||
try {
|
||||
this._clearUserVerifier();
|
||||
this._userVerifier = client.get_user_verifier_finish(result);
|
||||
} catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
|
||||
return;
|
||||
} catch(e) {
|
||||
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||
return;
|
||||
this._reportInitError('Failed to obtain user verifier', e);
|
||||
return;
|
||||
}
|
||||
@@ -387,84 +389,89 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._hold.release();
|
||||
},
|
||||
|
||||
_connectSignals: function() {
|
||||
this._userVerifier.connect('info', Lang.bind(this, this._onInfo));
|
||||
this._userVerifier.connect('problem', Lang.bind(this, this._onProblem));
|
||||
this._userVerifier.connect('info-query', Lang.bind(this, this._onInfoQuery));
|
||||
this._userVerifier.connect('secret-info-query', Lang.bind(this, this._onSecretInfoQuery));
|
||||
this._userVerifier.connect('conversation-stopped', Lang.bind(this, this._onConversationStopped));
|
||||
this._userVerifier.connect('reset', Lang.bind(this, this._onReset));
|
||||
this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete));
|
||||
_connectSignals() {
|
||||
this._userVerifier.connect('info', this._onInfo.bind(this));
|
||||
this._userVerifier.connect('problem', this._onProblem.bind(this));
|
||||
this._userVerifier.connect('info-query', this._onInfoQuery.bind(this));
|
||||
this._userVerifier.connect('secret-info-query', this._onSecretInfoQuery.bind(this));
|
||||
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: function() {
|
||||
_getForegroundService() {
|
||||
if (this._preemptingService)
|
||||
return this._preemptingService;
|
||||
|
||||
return this._defaultService;
|
||||
},
|
||||
|
||||
serviceIsForeground: function(serviceName) {
|
||||
serviceIsForeground(serviceName) {
|
||||
return serviceName == this._getForegroundService();
|
||||
},
|
||||
|
||||
serviceIsDefault: function(serviceName) {
|
||||
serviceIsDefault(serviceName) {
|
||||
return serviceName == this._defaultService;
|
||||
},
|
||||
|
||||
_updateDefaultService: function() {
|
||||
_updateDefaultService() {
|
||||
if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY))
|
||||
this._defaultService = PASSWORD_SERVICE_NAME;
|
||||
else if (this._settings.get_boolean(SMARTCARD_AUTHENTICATION_KEY))
|
||||
this._defaultService = SMARTCARD_SERVICE_NAME;
|
||||
else if (this._haveFingerprintReader)
|
||||
this._defaultService = FINGERPRINT_SERVICE_NAME;
|
||||
|
||||
if (!this._defaultService) {
|
||||
log("no authentication service is enabled, using password authentication");
|
||||
this._defaultService = PASSWORD_SERVICE_NAME;
|
||||
}
|
||||
},
|
||||
|
||||
_startService: function(serviceName) {
|
||||
_startService(serviceName) {
|
||||
this._hold.acquire();
|
||||
if (this._userName) {
|
||||
this._userVerifier.call_begin_verification_for_user(serviceName,
|
||||
this._userName,
|
||||
this._cancellable,
|
||||
Lang.bind(this, function(obj, result) {
|
||||
(obj, result) => {
|
||||
try {
|
||||
obj.call_begin_verification_for_user_finish(result);
|
||||
} catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
|
||||
return;
|
||||
} catch(e) {
|
||||
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||
return;
|
||||
this._reportInitError('Failed to start verification for user', e);
|
||||
return;
|
||||
}
|
||||
|
||||
this._hold.release();
|
||||
}));
|
||||
});
|
||||
} else {
|
||||
this._userVerifier.call_begin_verification(serviceName,
|
||||
this._cancellable,
|
||||
Lang.bind(this, function(obj, result) {
|
||||
(obj, result) => {
|
||||
try {
|
||||
obj.call_begin_verification_finish(result);
|
||||
} catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
|
||||
return;
|
||||
} catch(e) {
|
||||
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||
return;
|
||||
this._reportInitError('Failed to start verification', e);
|
||||
return;
|
||||
}
|
||||
|
||||
this._hold.release();
|
||||
}));
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_beginVerification: function() {
|
||||
_beginVerification() {
|
||||
this._startService(this._getForegroundService());
|
||||
|
||||
if (this._userName && this._haveFingerprintReader && !this.serviceIsForeground(FINGERPRINT_SERVICE_NAME))
|
||||
this._startService(FINGERPRINT_SERVICE_NAME);
|
||||
},
|
||||
|
||||
_onInfo: function(client, serviceName, info) {
|
||||
_onInfo(client, serviceName, info) {
|
||||
if (this.serviceIsForeground(serviceName)) {
|
||||
this._queueMessage(info, MessageType.INFO);
|
||||
} else if (serviceName == FINGERPRINT_SERVICE_NAME &&
|
||||
@@ -479,21 +486,21 @@ var ShellUserVerifier = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_onProblem: function(client, serviceName, problem) {
|
||||
_onProblem(client, serviceName, problem) {
|
||||
if (!this.serviceIsForeground(serviceName))
|
||||
return;
|
||||
|
||||
this._queueMessage(problem, MessageType.ERROR);
|
||||
},
|
||||
|
||||
_onInfoQuery: function(client, serviceName, question) {
|
||||
_onInfoQuery(client, serviceName, question) {
|
||||
if (!this.serviceIsForeground(serviceName))
|
||||
return;
|
||||
|
||||
this.emit('ask-question', serviceName, question, '');
|
||||
},
|
||||
|
||||
_onSecretInfoQuery: function(client, serviceName, secretQuestion) {
|
||||
_onSecretInfoQuery(client, serviceName, secretQuestion) {
|
||||
if (!this.serviceIsForeground(serviceName))
|
||||
return;
|
||||
|
||||
@@ -506,7 +513,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this.emit('ask-question', serviceName, secretQuestion, '\u25cf');
|
||||
},
|
||||
|
||||
_onReset: function() {
|
||||
_onReset() {
|
||||
// Clear previous attempts to authenticate
|
||||
this._failCounter = 0;
|
||||
this._updateDefaultService();
|
||||
@@ -514,56 +521,55 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this.emit('reset');
|
||||
},
|
||||
|
||||
_onVerificationComplete: function() {
|
||||
_onVerificationComplete() {
|
||||
this.emit('verification-complete');
|
||||
},
|
||||
|
||||
_cancelAndReset: function() {
|
||||
_cancelAndReset() {
|
||||
this.cancel();
|
||||
this._onReset();
|
||||
},
|
||||
|
||||
_retry: function() {
|
||||
_retry() {
|
||||
this.begin(this._userName, new Batch.Hold());
|
||||
},
|
||||
|
||||
_verificationFailed: function(retry) {
|
||||
_verificationFailed(retry) {
|
||||
// For Not Listed / enterprise logins, immediately reset
|
||||
// the dialog
|
||||
// Otherwise, we allow ALLOWED_FAILURES attempts. After that, we
|
||||
// go back to the welcome screen.
|
||||
// Otherwise, when in login mode we allow ALLOWED_FAILURES attempts.
|
||||
// After that, we go back to the welcome screen.
|
||||
|
||||
this._failCounter++;
|
||||
let canRetry = retry && this._userName &&
|
||||
this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY);
|
||||
(this._reauthOnly ||
|
||||
this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY));
|
||||
|
||||
if (canRetry) {
|
||||
if (!this.hasPendingMessages) {
|
||||
this._retry();
|
||||
} else {
|
||||
let signalId = this.connect('no-more-messages',
|
||||
Lang.bind(this, function() {
|
||||
this.disconnect(signalId);
|
||||
if (this._cancellable && !this._cancellable.is_cancelled())
|
||||
this._retry();
|
||||
}));
|
||||
let signalId = this.connect('no-more-messages', () => {
|
||||
this.disconnect(signalId);
|
||||
if (this._cancellable && !this._cancellable.is_cancelled())
|
||||
this._retry();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (!this.hasPendingMessages) {
|
||||
this._cancelAndReset();
|
||||
} else {
|
||||
let signalId = this.connect('no-more-messages',
|
||||
Lang.bind(this, function() {
|
||||
this.disconnect(signalId);
|
||||
this._cancelAndReset();
|
||||
}));
|
||||
let signalId = this.connect('no-more-messages', () => {
|
||||
this.disconnect(signalId);
|
||||
this._cancelAndReset();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.emit('verification-failed');
|
||||
this.emit('verification-failed', canRetry);
|
||||
},
|
||||
|
||||
_onConversationStopped: function(client, serviceName) {
|
||||
_onConversationStopped(client, serviceName) {
|
||||
// If the login failed with the preauthenticated oVirt credentials
|
||||
// then discard the credentials and revert to default authentication
|
||||
// mechanism.
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
<file>gdm/realmd.js</file>
|
||||
<file>gdm/util.js</file>
|
||||
|
||||
<file>extensionPrefs/main.js</file>
|
||||
|
||||
<file>misc/config.js</file>
|
||||
<file>misc/extensionUtils.js</file>
|
||||
<file>misc/fileUtils.js</file>
|
||||
@@ -33,8 +31,6 @@
|
||||
<file>perf/core.js</file>
|
||||
<file>perf/hwtest.js</file>
|
||||
|
||||
<file>portalHelper/main.js</file>
|
||||
|
||||
<file>ui/accessDialog.js</file>
|
||||
<file>ui/altTab.js</file>
|
||||
<file>ui/animation.js</file>
|
||||
@@ -43,6 +39,7 @@
|
||||
<file>ui/audioDeviceSelection.js</file>
|
||||
<file>ui/backgroundMenu.js</file>
|
||||
<file>ui/background.js</file>
|
||||
<file>ui/barLevel.js</file>
|
||||
<file>ui/boxpointer.js</file>
|
||||
<file>ui/calendar.js</file>
|
||||
<file>ui/checkBox.js</file>
|
||||
@@ -130,6 +127,7 @@
|
||||
<file>ui/status/rfkill.js</file>
|
||||
<file>ui/status/volume.js</file>
|
||||
<file>ui/status/bluetooth.js</file>
|
||||
<file>ui/status/remoteAccess.js</file>
|
||||
<file>ui/status/screencast.js</file>
|
||||
<file>ui/status/system.js</file>
|
||||
<file>ui/status/thunderbolt.js</file>
|
||||
|
||||
@@ -6,3 +6,17 @@ js_resources = gnome.compile_resources(
|
||||
c_name: 'shell_js_resources',
|
||||
dependencies: [config_js]
|
||||
)
|
||||
|
||||
portal_resources = gnome.compile_resources(
|
||||
'portal-resources', 'portal-resources.gresource.xml',
|
||||
source_dir: ['.', meson.current_build_dir()],
|
||||
c_name: 'portal_js_resources',
|
||||
dependencies: [config_js]
|
||||
)
|
||||
|
||||
prefs_resources = gnome.compile_resources(
|
||||
'prefs-resources', 'prefs-resources.gresource.xml',
|
||||
source_dir: ['.', meson.current_build_dir()],
|
||||
c_name: 'prefs_js_resources',
|
||||
dependencies: [config_js]
|
||||
)
|
||||
|
||||
@@ -112,6 +112,8 @@ function createExtensionObject(uuid, dir, type) {
|
||||
let metadataContents, success, tag;
|
||||
try {
|
||||
[success, metadataContents, tag] = metadataFile.load_contents(null);
|
||||
if (metadataContents instanceof Uint8Array)
|
||||
metadataContents = imports.byteArray.toString(metadataContents);
|
||||
} catch (e) {
|
||||
throw new Error('Failed to load metadata.json: ' + e);
|
||||
}
|
||||
@@ -161,7 +163,7 @@ function installImporter(extension) {
|
||||
var ExtensionFinder = new Lang.Class({
|
||||
Name: 'ExtensionFinder',
|
||||
|
||||
_loadExtension: function(extensionDir, info, perUserDir) {
|
||||
_loadExtension(extensionDir, info, perUserDir) {
|
||||
let fileType = info.get_file_type();
|
||||
if (fileType != Gio.FileType.DIRECTORY)
|
||||
return;
|
||||
@@ -184,9 +186,11 @@ var ExtensionFinder = new Lang.Class({
|
||||
this.emit('extension-found', extension);
|
||||
},
|
||||
|
||||
scanExtensions: function() {
|
||||
scanExtensions() {
|
||||
let perUserDir = Gio.File.new_for_path(global.userdatadir);
|
||||
FileUtils.collectFromDatadirs('extensions', true, Lang.bind(this, this._loadExtension, perUserDir));
|
||||
FileUtils.collectFromDatadirs('extensions', true, (dir, info) => {
|
||||
this._loadExtension(dir, info, perUserDir);
|
||||
});
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(ExtensionFinder.prototype);
|
||||
|
||||
@@ -4,17 +4,18 @@ const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const PresenceIface = '<node> \
|
||||
<interface name="org.gnome.SessionManager.Presence"> \
|
||||
<method name="SetStatus"> \
|
||||
<arg type="u" direction="in"/> \
|
||||
</method> \
|
||||
<property name="status" type="u" access="readwrite"/> \
|
||||
<signal name="StatusChanged"> \
|
||||
<arg type="u" direction="out"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const PresenceIface = `
|
||||
<node>
|
||||
<interface name="org.gnome.SessionManager.Presence">
|
||||
<method name="SetStatus">
|
||||
<arg type="u" direction="in"/>
|
||||
</method>
|
||||
<property name="status" type="u" access="readwrite"/>
|
||||
<signal name="StatusChanged">
|
||||
<arg type="u" direction="out"/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
var PresenceStatus = {
|
||||
AVAILABLE: 0,
|
||||
@@ -32,16 +33,17 @@ function Presence(initCallback, cancellable) {
|
||||
// Note inhibitors are immutable objects, so they don't
|
||||
// change at runtime (changes always come in the form
|
||||
// of new inhibitors)
|
||||
const InhibitorIface = '<node> \
|
||||
<interface name="org.gnome.SessionManager.Inhibitor"> \
|
||||
<method name="GetAppId"> \
|
||||
<arg type="s" direction="out" /> \
|
||||
</method> \
|
||||
<method name="GetReason"> \
|
||||
<arg type="s" direction="out" /> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const InhibitorIface = `
|
||||
<node>
|
||||
<interface name="org.gnome.SessionManager.Inhibitor">
|
||||
<method name="GetAppId">
|
||||
<arg type="s" direction="out" />
|
||||
</method>
|
||||
<method name="GetReason">
|
||||
<arg type="s" direction="out" />
|
||||
</method>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
var InhibitorProxy = Gio.DBusProxy.makeProxyWrapper(InhibitorIface);
|
||||
function Inhibitor(objectPath, initCallback, cancellable) {
|
||||
@@ -49,29 +51,30 @@ function Inhibitor(objectPath, initCallback, cancellable) {
|
||||
}
|
||||
|
||||
// Not the full interface, only the methods we use
|
||||
const SessionManagerIface = '<node> \
|
||||
<interface name="org.gnome.SessionManager"> \
|
||||
<method name="Logout"> \
|
||||
<arg type="u" direction="in" /> \
|
||||
</method> \
|
||||
<method name="Shutdown" /> \
|
||||
<method name="Reboot" /> \
|
||||
<method name="CanShutdown"> \
|
||||
<arg type="b" direction="out" /> \
|
||||
</method> \
|
||||
<method name="IsInhibited"> \
|
||||
<arg type="u" direction="in" /> \
|
||||
<arg type="b" direction="out" /> \
|
||||
</method> \
|
||||
<property name="SessionIsActive" type="b" access="read"/> \
|
||||
<signal name="InhibitorAdded"> \
|
||||
<arg type="o" direction="out"/> \
|
||||
</signal> \
|
||||
<signal name="InhibitorRemoved"> \
|
||||
<arg type="o" direction="out"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const SessionManagerIface = `
|
||||
<node>
|
||||
<interface name="org.gnome.SessionManager">
|
||||
<method name="Logout">
|
||||
<arg type="u" direction="in" />
|
||||
</method>
|
||||
<method name="Shutdown" />
|
||||
<method name="Reboot" />
|
||||
<method name="CanShutdown">
|
||||
<arg type="b" direction="out" />
|
||||
</method>
|
||||
<method name="IsInhibited">
|
||||
<arg type="u" direction="in" />
|
||||
<arg type="b" direction="out" />
|
||||
</method>
|
||||
<property name="SessionIsActive" type="b" access="read"/>
|
||||
<signal name="InhibitorAdded">
|
||||
<arg type="o" direction="out"/>
|
||||
</signal>
|
||||
<signal name="InhibitorRemoved">
|
||||
<arg type="o" direction="out"/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
var SessionManagerProxy = Gio.DBusProxy.makeProxyWrapper(SessionManagerIface);
|
||||
function SessionManager(initCallback, cancellable) {
|
||||
|
||||
@@ -10,7 +10,7 @@ var DEFAULT_LIMIT = 512;
|
||||
var HistoryManager = new Lang.Class({
|
||||
Name: 'HistoryManager',
|
||||
|
||||
_init: function(params) {
|
||||
_init(params) {
|
||||
params = Params.parse(params, { gsettingsKey: null,
|
||||
limit: DEFAULT_LIMIT,
|
||||
entry: null });
|
||||
@@ -22,7 +22,7 @@ var HistoryManager = new Lang.Class({
|
||||
if (this._key) {
|
||||
this._history = global.settings.get_strv(this._key);
|
||||
global.settings.connect('changed::' + this._key,
|
||||
Lang.bind(this, this._historyChanged));
|
||||
this._historyChanged.bind(this));
|
||||
|
||||
} else {
|
||||
this._history = [];
|
||||
@@ -32,16 +32,16 @@ var HistoryManager = new Lang.Class({
|
||||
|
||||
if (this._entry) {
|
||||
this._entry.connect('key-press-event',
|
||||
Lang.bind(this, this._onEntryKeyPress));
|
||||
this._onEntryKeyPress.bind(this));
|
||||
}
|
||||
},
|
||||
|
||||
_historyChanged: function() {
|
||||
_historyChanged() {
|
||||
this._history = global.settings.get_strv(this._key);
|
||||
this._historyIndex = this._history.length;
|
||||
},
|
||||
|
||||
_setPrevItem: function(text) {
|
||||
_setPrevItem(text) {
|
||||
if (this._historyIndex <= 0)
|
||||
return false;
|
||||
|
||||
@@ -52,7 +52,7 @@ var HistoryManager = new Lang.Class({
|
||||
return true;
|
||||
},
|
||||
|
||||
_setNextItem: function(text) {
|
||||
_setNextItem(text) {
|
||||
if (this._historyIndex >= this._history.length)
|
||||
return false;
|
||||
|
||||
@@ -63,7 +63,7 @@ var HistoryManager = new Lang.Class({
|
||||
return true;
|
||||
},
|
||||
|
||||
lastItem: function() {
|
||||
lastItem() {
|
||||
if (this._historyIndex != this._history.length) {
|
||||
this._historyIndex = this._history.length;
|
||||
this._indexChanged();
|
||||
@@ -72,7 +72,7 @@ var HistoryManager = new Lang.Class({
|
||||
return this._historyIndex ? this._history[this._historyIndex -1] : null;
|
||||
},
|
||||
|
||||
addItem: function(input) {
|
||||
addItem(input) {
|
||||
if (this._history.length == 0 ||
|
||||
this._history[this._history.length - 1] != input) {
|
||||
|
||||
@@ -82,7 +82,7 @@ var HistoryManager = new Lang.Class({
|
||||
this._historyIndex = this._history.length;
|
||||
},
|
||||
|
||||
_onEntryKeyPress: function(entry, event) {
|
||||
_onEntryKeyPress(entry, event) {
|
||||
let symbol = event.get_key_symbol();
|
||||
if (symbol == Clutter.KEY_Up) {
|
||||
return this._setPrevItem(entry.get_text());
|
||||
@@ -92,7 +92,7 @@ var HistoryManager = new Lang.Class({
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
},
|
||||
|
||||
_indexChanged: function() {
|
||||
_indexChanged() {
|
||||
let current = this._history[this._historyIndex] || '';
|
||||
this.emit('changed', current);
|
||||
|
||||
@@ -100,7 +100,7 @@ var HistoryManager = new Lang.Class({
|
||||
this._entry.set_text(current);
|
||||
},
|
||||
|
||||
_save: function() {
|
||||
_save() {
|
||||
if (this._history.length > this._limit)
|
||||
this._history.splice(0, this._history.length - this._limit);
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ var IBusManager = new Lang.Class({
|
||||
_MAX_INPUT_SOURCE_ACTIVATION_TIME: 4000, // ms
|
||||
_PRELOAD_ENGINES_DELAY_TIME: 30, // sec
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
IBus.init();
|
||||
|
||||
this._candidatePopup = new IBusCandidatePopup.CandidatePopup();
|
||||
@@ -53,16 +53,16 @@ var IBusManager = new Lang.Class({
|
||||
this._preloadEnginesId = 0;
|
||||
|
||||
this._ibus = IBus.Bus.new_async();
|
||||
this._ibus.connect('connected', Lang.bind(this, this._onConnected));
|
||||
this._ibus.connect('disconnected', Lang.bind(this, this._clear));
|
||||
this._ibus.connect('connected', this._onConnected.bind(this));
|
||||
this._ibus.connect('disconnected', this._clear.bind(this));
|
||||
// Need to set this to get 'global-engine-changed' emitions
|
||||
this._ibus.set_watch_ibus_signal(true);
|
||||
this._ibus.connect('global-engine-changed', Lang.bind(this, this._engineChanged));
|
||||
this._ibus.connect('global-engine-changed', this._engineChanged.bind(this));
|
||||
|
||||
this._spawn();
|
||||
},
|
||||
|
||||
_spawn: function() {
|
||||
_spawn() {
|
||||
try {
|
||||
Gio.Subprocess.new(['ibus-daemon', '--xim', '--panel', 'disable'],
|
||||
Gio.SubprocessFlags.NONE);
|
||||
@@ -71,7 +71,7 @@ var IBusManager = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_clear: function() {
|
||||
_clear() {
|
||||
if (this._panelService)
|
||||
this._panelService.destroy();
|
||||
|
||||
@@ -87,15 +87,15 @@ var IBusManager = new Lang.Class({
|
||||
this._spawn();
|
||||
},
|
||||
|
||||
_onConnected: function() {
|
||||
this._ibus.list_engines_async(-1, null, Lang.bind(this, this._initEngines));
|
||||
_onConnected() {
|
||||
this._ibus.list_engines_async(-1, null, this._initEngines.bind(this));
|
||||
this._ibus.request_name_async(IBus.SERVICE_PANEL,
|
||||
IBus.BusNameFlag.REPLACE_EXISTING,
|
||||
-1, null,
|
||||
Lang.bind(this, this._initPanelService));
|
||||
this._initPanelService.bind(this));
|
||||
},
|
||||
|
||||
_initEngines: function(ibus, result) {
|
||||
_initEngines(ibus, result) {
|
||||
let enginesList = this._ibus.list_engines_async_finish(result);
|
||||
if (enginesList) {
|
||||
for (let i = 0; i < enginesList.length; ++i) {
|
||||
@@ -108,13 +108,18 @@ var IBusManager = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_initPanelService: function(ibus, result) {
|
||||
_initPanelService(ibus, result) {
|
||||
let success = this._ibus.request_name_async_finish(result);
|
||||
if (success) {
|
||||
this._panelService = new IBus.PanelService({ connection: this._ibus.get_connection(),
|
||||
object_path: IBus.PATH_PANEL });
|
||||
this._candidatePopup.setPanelService(this._panelService);
|
||||
this._panelService.connect('update-property', Lang.bind(this, this._updateProperty));
|
||||
this._panelService.connect('update-property', this._updateProperty.bind(this));
|
||||
this._panelService.connect('set-cursor-location', (ps, x, y, w, h) => {
|
||||
let cursorLocation = { x, y, width: w, height: h };
|
||||
this.emit('set-cursor-location', cursorLocation);
|
||||
});
|
||||
|
||||
try {
|
||||
// IBus versions older than 1.5.10 have a bug which
|
||||
// causes spurious set-content-type emissions when
|
||||
@@ -122,11 +127,11 @@ var IBusManager = new Lang.Class({
|
||||
// and hints defeating its intended semantics and
|
||||
// confusing users. We thus don't use it in that case.
|
||||
_checkIBusVersion(1, 5, 10);
|
||||
this._panelService.connect('set-content-type', Lang.bind(this, this._setContentType));
|
||||
this._panelService.connect('set-content-type', this._setContentType.bind(this));
|
||||
} catch (e) {
|
||||
}
|
||||
// If an engine is already active we need to get its properties
|
||||
this._ibus.get_global_engine_async(-1, null, Lang.bind(this, function(i, result) {
|
||||
this._ibus.get_global_engine_async(-1, null, (i, result) => {
|
||||
let engine;
|
||||
try {
|
||||
engine = this._ibus.get_global_engine_async_finish(result);
|
||||
@@ -136,20 +141,20 @@ var IBusManager = new Lang.Class({
|
||||
return;
|
||||
}
|
||||
this._engineChanged(this._ibus, engine.get_name());
|
||||
}));
|
||||
});
|
||||
this._updateReadiness();
|
||||
} else {
|
||||
this._clear();
|
||||
}
|
||||
},
|
||||
|
||||
_updateReadiness: function() {
|
||||
_updateReadiness() {
|
||||
this._ready = (Object.keys(this._engines).length > 0 &&
|
||||
this._panelService != null);
|
||||
this.emit('ready', this._ready);
|
||||
},
|
||||
|
||||
_engineChanged: function(bus, engineName) {
|
||||
_engineChanged(bus, engineName) {
|
||||
if (!this._ready)
|
||||
return;
|
||||
|
||||
@@ -159,7 +164,7 @@ var IBusManager = new Lang.Class({
|
||||
return;
|
||||
|
||||
this._registerPropertiesId =
|
||||
this._panelService.connect('register-properties', Lang.bind(this, function(p, props) {
|
||||
this._panelService.connect('register-properties', (p, props) => {
|
||||
if (!props.get(0))
|
||||
return;
|
||||
|
||||
@@ -167,29 +172,29 @@ var IBusManager = new Lang.Class({
|
||||
this._registerPropertiesId = 0;
|
||||
|
||||
this.emit('properties-registered', this._currentEngineName, props);
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
_updateProperty: function(panel, prop) {
|
||||
_updateProperty(panel, prop) {
|
||||
this.emit('property-updated', this._currentEngineName, prop);
|
||||
},
|
||||
|
||||
_setContentType: function(panel, purpose, hints) {
|
||||
_setContentType(panel, purpose, hints) {
|
||||
this.emit('set-content-type', purpose, hints);
|
||||
},
|
||||
|
||||
activateProperty: function(key, state) {
|
||||
activateProperty(key, state) {
|
||||
this._panelService.property_activate(key, state);
|
||||
},
|
||||
|
||||
getEngineDesc: function(id) {
|
||||
getEngineDesc(id) {
|
||||
if (!this._ready || !this._engines.hasOwnProperty(id))
|
||||
return null;
|
||||
|
||||
return this._engines[id];
|
||||
},
|
||||
|
||||
setEngine: function(id, callback) {
|
||||
setEngine(id, callback) {
|
||||
// Send id even if id == this._currentEngineName
|
||||
// because 'properties-registered' signal can be emitted
|
||||
// while this._ibusSources == null on a lock screen.
|
||||
@@ -203,7 +208,7 @@ var IBusManager = new Lang.Class({
|
||||
null, callback);
|
||||
},
|
||||
|
||||
preloadEngines: function(ids) {
|
||||
preloadEngines(ids) {
|
||||
if (!this._ibus || ids.length == 0)
|
||||
return;
|
||||
|
||||
@@ -214,7 +219,7 @@ var IBusManager = new Lang.Class({
|
||||
|
||||
this._preloadEnginesId =
|
||||
Mainloop.timeout_add_seconds(this._PRELOAD_ENGINES_DELAY_TIME,
|
||||
Lang.bind(this, function() {
|
||||
() => {
|
||||
this._ibus.preload_engines_async(
|
||||
ids,
|
||||
-1,
|
||||
@@ -222,7 +227,7 @@ var IBusManager = new Lang.Class({
|
||||
null);
|
||||
this._preloadEnginesId = 0;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
}));
|
||||
});
|
||||
},
|
||||
});
|
||||
Signals.addSignalMethods(IBusManager.prototype);
|
||||
|
||||
@@ -9,22 +9,29 @@ var InputMethod = new Lang.Class({
|
||||
Name: 'InputMethod',
|
||||
Extends: Clutter.InputMethod,
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this.parent();
|
||||
this._hints = 0;
|
||||
this._purpose = 0;
|
||||
this._enabled = true;
|
||||
this._currentFocus = null;
|
||||
this._currentEvent = null;
|
||||
this._doForwardEvent = false;
|
||||
this._preeditStr = '';
|
||||
this._preeditPos = 0;
|
||||
this._ibus = IBus.Bus.new_async();
|
||||
this._ibus.connect('connected', Lang.bind(this, this._onConnected));
|
||||
this._ibus.connect('disconnected', Lang.bind(this, this._clear));
|
||||
this.connect('notify::can-show-preedit', Lang.bind(this, this._updateCapabilities));
|
||||
this._ibus.connect('connected', this._onConnected.bind(this));
|
||||
this._ibus.connect('disconnected', this._clear.bind(this));
|
||||
this.connect('notify::can-show-preedit', this._updateCapabilities.bind(this));
|
||||
|
||||
this._inputSourceManager = Keyboard.getInputSourceManager();
|
||||
this._sourceChangedId = this._inputSourceManager.connect('current-source-changed',
|
||||
Lang.bind(this, this._onSourceChanged));
|
||||
this._onSourceChanged.bind(this));
|
||||
this._currentSource = this._inputSourceManager.currentSource;
|
||||
|
||||
let deviceManager = Clutter.DeviceManager.get_default();
|
||||
this._virtualDevice = deviceManager.create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);
|
||||
|
||||
if (this._ibus.is_connected())
|
||||
this._onConnected();
|
||||
},
|
||||
@@ -33,7 +40,7 @@ var InputMethod = new Lang.Class({
|
||||
return this._currentFocus;
|
||||
},
|
||||
|
||||
_updateCapabilities: function() {
|
||||
_updateCapabilities() {
|
||||
let caps = 0;
|
||||
|
||||
if (this.can_show_preedit)
|
||||
@@ -48,55 +55,89 @@ var InputMethod = new Lang.Class({
|
||||
this._context.set_capabilities(caps);
|
||||
},
|
||||
|
||||
_onSourceChanged: function() {
|
||||
_onSourceChanged() {
|
||||
this._currentSource = this._inputSourceManager.currentSource;
|
||||
},
|
||||
|
||||
_onConnected: function() {
|
||||
_onConnected() {
|
||||
this._ibus.create_input_context_async ('gnome-shell', -1, null,
|
||||
Lang.bind(this, this._setContext));
|
||||
this._setContext.bind(this));
|
||||
},
|
||||
|
||||
_setContext: function(bus, res) {
|
||||
_setContext(bus, res) {
|
||||
this._context = this._ibus.create_input_context_async_finish(res);
|
||||
this._context.connect('enabled', Lang.bind(this, function () { this._enabled = true }));
|
||||
this._context.connect('disabled', Lang.bind(this, function () { this._enabled = false }));
|
||||
this._context.connect('commit-text', Lang.bind(this, this._onCommitText));
|
||||
this._context.connect('delete-surrounding-text', Lang.bind(this, this._onDeleteSurroundingText));
|
||||
this._context.connect('update-preedit-text', Lang.bind(this, this._onUpdatePreeditText));
|
||||
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));
|
||||
this._context.connect('show-preedit-text', this._onShowPreeditText.bind(this));
|
||||
this._context.connect('hide-preedit-text', this._onHidePreeditText.bind(this));
|
||||
this._context.connect('forward-key-event', this._onForwardKeyEvent.bind(this));
|
||||
|
||||
this._updateCapabilities();
|
||||
},
|
||||
|
||||
_clear: function() {
|
||||
_clear() {
|
||||
this._context = null;
|
||||
this._hints = 0;
|
||||
this._purpose = 0;
|
||||
this._enabled = false;
|
||||
this._preeditStr = ''
|
||||
this._preeditPos = 0;
|
||||
},
|
||||
|
||||
_emitRequestSurrounding: function() {
|
||||
_emitRequestSurrounding() {
|
||||
if (this._context.needs_surrounding_text())
|
||||
this.emit('request-surrounding');
|
||||
},
|
||||
|
||||
_onCommitText: function(context, text) {
|
||||
_onCommitText(context, text) {
|
||||
this.commit(text.get_text());
|
||||
},
|
||||
|
||||
_onDeleteSurroundingText: function (context) {
|
||||
_onDeleteSurroundingText(context) {
|
||||
this.delete_surrounding();
|
||||
},
|
||||
|
||||
_onUpdatePreeditText: function (context, text, pos, visible) {
|
||||
let str = null;
|
||||
if (visible && text != null)
|
||||
str = text.get_text();
|
||||
|
||||
this.set_preedit_text(str, pos);
|
||||
_onUpdatePreeditText(context, text, pos, visible) {
|
||||
if (text == null)
|
||||
return;
|
||||
this._preeditStr = text.get_text();
|
||||
this._preeditPos = pos;
|
||||
if (visible)
|
||||
this.set_preedit_text(this._preeditStr, pos);
|
||||
else
|
||||
this.set_preedit_text(null, pos);
|
||||
},
|
||||
|
||||
vfunc_focus_in: function(focus) {
|
||||
_onShowPreeditText(context) {
|
||||
this.set_preedit_text(this._preeditStr, this._preeditPos);
|
||||
},
|
||||
|
||||
_onHidePreeditText(context) {
|
||||
this.set_preedit_text(null, this._preeditPos);
|
||||
},
|
||||
|
||||
_onForwardKeyEvent(context, keyval, keycode, state) {
|
||||
let press = (state & IBus.ModifierType.RELEASE_MASK) == 0;
|
||||
|
||||
if (this._currentEvent) {
|
||||
// If we are handling this same event in filter_key_press(),
|
||||
// just let it go through, sending the same event again will
|
||||
// be silenced away because the key counts as pressed.
|
||||
if (this._currentEvent.get_key_symbol() == keyval &&
|
||||
(this._currentEvent.type() == Clutter.EventType.KEY_PRESS) == press) {
|
||||
this._doForwardEvent = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this._virtualDevice.notify_key(Clutter.get_current_event_time(), keycode,
|
||||
press ? Clutter.KeyState.PRESSED : Clutter.KeyState.RELEASED);
|
||||
},
|
||||
|
||||
vfunc_focus_in(focus) {
|
||||
this._currentFocus = focus;
|
||||
if (this._context) {
|
||||
this._context.focus_in();
|
||||
@@ -105,7 +146,7 @@ var InputMethod = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
vfunc_focus_out: function() {
|
||||
vfunc_focus_out() {
|
||||
this._currentFocus = null;
|
||||
if (this._context) {
|
||||
this._context.focus_out();
|
||||
@@ -116,7 +157,7 @@ var InputMethod = new Lang.Class({
|
||||
this.set_preedit_text(null, 0);
|
||||
},
|
||||
|
||||
vfunc_reset: function() {
|
||||
vfunc_reset() {
|
||||
if (this._context) {
|
||||
this._context.reset();
|
||||
this._emitRequestSurrounding();
|
||||
@@ -126,7 +167,7 @@ var InputMethod = new Lang.Class({
|
||||
this.set_preedit_text(null, 0);
|
||||
},
|
||||
|
||||
vfunc_set_cursor_location: function(rect) {
|
||||
vfunc_set_cursor_location(rect) {
|
||||
if (this._context) {
|
||||
this._context.set_cursor_location(rect.get_x(), rect.get_y(),
|
||||
rect.get_width(), rect.get_height());
|
||||
@@ -134,12 +175,12 @@ var InputMethod = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
vfunc_set_surrounding: function(text, cursor, anchor) {
|
||||
vfunc_set_surrounding(text, cursor, anchor) {
|
||||
if (this._context)
|
||||
this._context.set_surrounding_text(text, cursor, anchor);
|
||||
},
|
||||
|
||||
vfunc_update_content_hints: function(hints) {
|
||||
vfunc_update_content_hints(hints) {
|
||||
let ibusHints = 0;
|
||||
if (hints & Clutter.InputContentHintFlags.COMPLETION)
|
||||
ibusHints |= IBus.InputHints.WORD_COMPLETION;
|
||||
@@ -159,7 +200,7 @@ var InputMethod = new Lang.Class({
|
||||
this._context.set_content_type(this._purpose, this._hints);
|
||||
},
|
||||
|
||||
vfunc_update_content_purpose: function(purpose) {
|
||||
vfunc_update_content_purpose(purpose) {
|
||||
let ibusPurpose = 0;
|
||||
if (purpose == Clutter.InputContentPurpose.NORMAL)
|
||||
ibusPurpose = IBus.InputPurpose.FREE_FORM;
|
||||
@@ -185,11 +226,10 @@ var InputMethod = new Lang.Class({
|
||||
this._context.set_content_type(this._purpose, this._hints);
|
||||
},
|
||||
|
||||
vfunc_filter_key_event: function(event) {
|
||||
vfunc_filter_key_event(event) {
|
||||
if (!this._context || !this._enabled)
|
||||
return false;
|
||||
if (!this._currentSource ||
|
||||
this._currentSource.type == Keyboard.INPUT_SOURCE_TYPE_XKB)
|
||||
if (!this._currentSource)
|
||||
return false;
|
||||
|
||||
let state = event.get_state();
|
||||
@@ -198,17 +238,27 @@ var InputMethod = new Lang.Class({
|
||||
|
||||
if (event.type() == Clutter.EventType.KEY_RELEASE)
|
||||
state |= IBus.ModifierType.RELEASE_MASK;
|
||||
|
||||
this._currentEvent = event;
|
||||
this._doForwardEvent = false;
|
||||
|
||||
this._context.process_key_event_async(event.get_key_symbol(),
|
||||
event.get_key_code() - 8, // Convert XKB keycodes to evcodes
|
||||
state, -1, null,
|
||||
Lang.bind(this, (context, res) => {
|
||||
(context, res) => {
|
||||
try {
|
||||
let retval = context.process_key_event_async_finish(res);
|
||||
|
||||
if (this._doForwardEvent)
|
||||
retval = false;
|
||||
|
||||
this.notify_key_event(event, retval);
|
||||
this._doForwardEvent = false;
|
||||
this._currentEvent = null;
|
||||
} catch (e) {
|
||||
log('Error processing key on IM: ' + e.message);
|
||||
}
|
||||
}));
|
||||
});
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -23,9 +23,9 @@ function getCompletions(text, commandHeader, globalCompletionList) {
|
||||
if (matches) {
|
||||
[expr, base, attrHead] = matches;
|
||||
|
||||
methods = getPropertyNamesFromExpression(base, commandHeader).filter(function(attr) {
|
||||
return attr.slice(0, attrHead.length) == attrHead;
|
||||
});
|
||||
methods = getPropertyNamesFromExpression(base, commandHeader).filter(
|
||||
attr => attr.slice(0, attrHead.length) == attrHead
|
||||
);
|
||||
}
|
||||
|
||||
// Look for the empty expression or partially entered words
|
||||
@@ -33,9 +33,9 @@ function getCompletions(text, commandHeader, globalCompletionList) {
|
||||
matches = text.match(/^(\w*)$/);
|
||||
if (text == '' || matches) {
|
||||
[expr, attrHead] = matches;
|
||||
methods = globalCompletionList.filter(function(attr) {
|
||||
return attr.slice(0, attrHead.length) == attrHead;
|
||||
});
|
||||
methods = globalCompletionList.filter(
|
||||
attr => attr.slice(0, attrHead.length) == attrHead
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ function getPropertyNamesFromExpression(expr, commandHeader) {
|
||||
|
||||
// Make sure propsUnique contains one key for every
|
||||
// property so we end up with a unique list of properties
|
||||
allProps.map(function(p){ propsUnique[p] = null; });
|
||||
allProps.map(p => propsUnique[p] = null);
|
||||
}
|
||||
return Object.keys(propsUnique).sort();
|
||||
}
|
||||
@@ -233,7 +233,7 @@ function isUnsafeExpression(str) {
|
||||
// Returns a list of global keywords derived from str
|
||||
function getDeclaredConstants(str) {
|
||||
let ret = [];
|
||||
str.split(';').forEach(function(s) {
|
||||
str.split(';').forEach(s => {
|
||||
let base, keyword;
|
||||
let match = s.match(/const\s+(\w+)\s*=/);
|
||||
if (match) {
|
||||
|
||||
@@ -47,24 +47,24 @@ var KeyboardManager = new Lang.Class({
|
||||
// even as a Wayland compositor, we can't bump this.
|
||||
MAX_LAYOUTS_PER_GROUP: 4,
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._xkbInfo = getXkbInfo();
|
||||
this._current = null;
|
||||
this._localeLayoutInfo = this._getLocaleLayout();
|
||||
this._layoutInfos = {};
|
||||
},
|
||||
|
||||
_applyLayoutGroup: function(group) {
|
||||
_applyLayoutGroup(group) {
|
||||
let options = this._buildOptionsString();
|
||||
let [layouts, variants] = this._buildGroupStrings(group);
|
||||
Meta.get_backend().set_keymap(layouts, variants, options);
|
||||
},
|
||||
|
||||
_applyLayoutGroupIndex: function(idx) {
|
||||
_applyLayoutGroupIndex(idx) {
|
||||
Meta.get_backend().lock_layout_group(idx);
|
||||
},
|
||||
|
||||
apply: function(id) {
|
||||
apply(id) {
|
||||
let info = this._layoutInfos[id];
|
||||
if (!info)
|
||||
return;
|
||||
@@ -80,7 +80,7 @@ var KeyboardManager = new Lang.Class({
|
||||
this._current = info;
|
||||
},
|
||||
|
||||
reapply: function() {
|
||||
reapply() {
|
||||
if (!this._current)
|
||||
return;
|
||||
|
||||
@@ -88,7 +88,9 @@ var KeyboardManager = new Lang.Class({
|
||||
this._applyLayoutGroupIndex(this._current.groupIndex);
|
||||
},
|
||||
|
||||
setUserLayouts: function(ids) {
|
||||
setUserLayouts(ids) {
|
||||
let currentId = this._current ? this._current.id : null;
|
||||
let currentGroupIndex = this._current ? this._current.groupIndex : null;
|
||||
this._current = null;
|
||||
this._layoutInfos = {};
|
||||
|
||||
@@ -115,11 +117,14 @@ var KeyboardManager = new Lang.Class({
|
||||
info.group = group;
|
||||
info.groupIndex = groupIndex;
|
||||
|
||||
if (currentId == id && currentGroupIndex == groupIndex)
|
||||
this._current = info;
|
||||
|
||||
i += 1;
|
||||
}
|
||||
},
|
||||
|
||||
_getLocaleLayout: function() {
|
||||
_getLocaleLayout() {
|
||||
let locale = GLib.get_language_names()[0];
|
||||
if (locale.indexOf('_') == -1)
|
||||
locale = DEFAULT_LOCALE;
|
||||
@@ -136,18 +141,18 @@ var KeyboardManager = new Lang.Class({
|
||||
return { layout: DEFAULT_LAYOUT, variant: DEFAULT_VARIANT };
|
||||
},
|
||||
|
||||
_buildGroupStrings: function(_group) {
|
||||
_buildGroupStrings(_group) {
|
||||
let group = _group.concat(this._localeLayoutInfo);
|
||||
let layouts = group.map(function(g) { return g.layout; }).join(',');
|
||||
let variants = group.map(function(g) { return g.variant; }).join(',');
|
||||
let layouts = group.map(g => g.layout).join(',');
|
||||
let variants = group.map(g => g.variant).join(',');
|
||||
return [layouts, variants];
|
||||
},
|
||||
|
||||
setKeyboardOptions: function(options) {
|
||||
setKeyboardOptions(options) {
|
||||
this._xkbOptions = options;
|
||||
},
|
||||
|
||||
_buildOptionsString: function() {
|
||||
_buildOptionsString() {
|
||||
let options = this._xkbOptions.join(',');
|
||||
return options;
|
||||
}
|
||||
|
||||
@@ -7,47 +7,60 @@ const Mainloop = imports.mainloop;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const SystemdLoginManagerIface = '<node> \
|
||||
<interface name="org.freedesktop.login1.Manager"> \
|
||||
<method name="Suspend"> \
|
||||
<arg type="b" direction="in"/> \
|
||||
</method> \
|
||||
<method name="CanSuspend"> \
|
||||
<arg type="s" direction="out"/> \
|
||||
</method> \
|
||||
<method name="Inhibit"> \
|
||||
<arg type="s" direction="in"/> \
|
||||
<arg type="s" direction="in"/> \
|
||||
<arg type="s" direction="in"/> \
|
||||
<arg type="s" direction="in"/> \
|
||||
<arg type="h" direction="out"/> \
|
||||
</method> \
|
||||
<method name="GetSession"> \
|
||||
<arg type="s" direction="in"/> \
|
||||
<arg type="o" direction="out"/> \
|
||||
</method> \
|
||||
<method name="ListSessions"> \
|
||||
<arg name="sessions" type="a(susso)" direction="out"/> \
|
||||
</method> \
|
||||
<signal name="PrepareForSleep"> \
|
||||
<arg type="b" direction="out"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const SystemdLoginManagerIface = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.login1.Manager">
|
||||
<method name="Suspend">
|
||||
<arg type="b" direction="in"/>
|
||||
</method>
|
||||
<method name="CanSuspend">
|
||||
<arg type="s" direction="out"/>
|
||||
</method>
|
||||
<method name="Inhibit">
|
||||
<arg type="s" direction="in"/>
|
||||
<arg type="s" direction="in"/>
|
||||
<arg type="s" direction="in"/>
|
||||
<arg type="s" direction="in"/>
|
||||
<arg type="h" direction="out"/>
|
||||
</method>
|
||||
<method name="GetSession">
|
||||
<arg type="s" direction="in"/>
|
||||
<arg type="o" direction="out"/>
|
||||
</method>
|
||||
<method name="ListSessions">
|
||||
<arg name="sessions" type="a(susso)" direction="out"/>
|
||||
</method>
|
||||
<signal name="PrepareForSleep">
|
||||
<arg type="b" direction="out"/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const SystemdLoginSessionIface = '<node> \
|
||||
<interface name="org.freedesktop.login1.Session"> \
|
||||
<signal name="Lock" /> \
|
||||
<signal name="Unlock" /> \
|
||||
<property name="Active" type="b" access="read" /> \
|
||||
<method name="SetLockedHint"> \
|
||||
<arg type="b" direction="in"/> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const SystemdLoginSessionIface = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.login1.Session">
|
||||
<signal name="Lock" />
|
||||
<signal name="Unlock" />
|
||||
<property name="Active" type="b" access="read" />
|
||||
<property name="Class" type="s" access="read" />
|
||||
<property name="Id" type="s" access="read" />
|
||||
<method name="SetLockedHint">
|
||||
<arg type="b" direction="in"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const SystemdLoginUserIface = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.login1.User">
|
||||
<property name="Display" type="(so)" access="read" />
|
||||
<property name="Sessions" type="a(so)" access="read" />
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const SystemdLoginManager = Gio.DBusProxy.makeProxyWrapper(SystemdLoginManagerIface);
|
||||
const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface);
|
||||
const SystemdLoginUser = Gio.DBusProxy.makeProxyWrapper(SystemdLoginUserIface);
|
||||
|
||||
function haveSystemd() {
|
||||
return GLib.access("/run/systemd/seats", 0) >= 0;
|
||||
@@ -105,15 +118,18 @@ function getLoginManager() {
|
||||
var LoginManagerSystemd = new Lang.Class({
|
||||
Name: 'LoginManagerSystemd',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._proxy = new SystemdLoginManager(Gio.DBus.system,
|
||||
'org.freedesktop.login1',
|
||||
'/org/freedesktop/login1');
|
||||
this._userProxy = new SystemdLoginUser(Gio.DBus.system,
|
||||
'org.freedesktop.login1',
|
||||
'/org/freedesktop/login1/user/self');
|
||||
this._proxy.connectSignal('PrepareForSleep',
|
||||
Lang.bind(this, this._prepareForSleep));
|
||||
this._prepareForSleep.bind(this));
|
||||
},
|
||||
|
||||
getCurrentSessionProxy: function(callback) {
|
||||
getCurrentSessionProxy(callback) {
|
||||
if (this._currentSession) {
|
||||
callback (this._currentSession);
|
||||
return;
|
||||
@@ -121,25 +137,47 @@ var LoginManagerSystemd = new Lang.Class({
|
||||
|
||||
let sessionId = GLib.getenv('XDG_SESSION_ID');
|
||||
if (!sessionId) {
|
||||
log('Unset XDG_SESSION_ID, getCurrentSessionProxy() called outside a user session.');
|
||||
return;
|
||||
log('Unset XDG_SESSION_ID, getCurrentSessionProxy() called outside a user session. Asking logind directly.');
|
||||
let [session, objectPath] = this._userProxy.Display;
|
||||
if (session) {
|
||||
log(`Will monitor session ${session}`);
|
||||
sessionId = session;
|
||||
} else {
|
||||
log('Failed to find "Display" session; are we the greeter?');
|
||||
|
||||
for (let [session, objectPath] of this._userProxy.Sessions) {
|
||||
let sessionProxy = new SystemdLoginSession(Gio.DBus.system,
|
||||
'org.freedesktop.login1',
|
||||
objectPath);
|
||||
log(`Considering ${session}, class=${sessionProxy.Class}`);
|
||||
if (sessionProxy.Class == 'greeter') {
|
||||
log(`Yes, will monitor session ${session}`);
|
||||
sessionId = session;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sessionId) {
|
||||
log('No, failed to get session from logind.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._proxy.GetSessionRemote(sessionId, Lang.bind(this,
|
||||
function(result, error) {
|
||||
if (error) {
|
||||
logError(error, 'Could not get a proxy for the current session');
|
||||
} else {
|
||||
this._currentSession = new SystemdLoginSession(Gio.DBus.system,
|
||||
'org.freedesktop.login1',
|
||||
result[0]);
|
||||
callback(this._currentSession);
|
||||
}
|
||||
}));
|
||||
this._proxy.GetSessionRemote(sessionId, (result, error) => {
|
||||
if (error) {
|
||||
logError(error, 'Could not get a proxy for the current session');
|
||||
} else {
|
||||
this._currentSession = new SystemdLoginSession(Gio.DBus.system,
|
||||
'org.freedesktop.login1',
|
||||
result[0]);
|
||||
callback(this._currentSession);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
canSuspend: function(asyncCallback) {
|
||||
this._proxy.CanSuspendRemote(function(result, error) {
|
||||
canSuspend(asyncCallback) {
|
||||
this._proxy.CanSuspendRemote((result, error) => {
|
||||
if (error) {
|
||||
asyncCallback(false, false);
|
||||
} else {
|
||||
@@ -150,8 +188,8 @@ var LoginManagerSystemd = new Lang.Class({
|
||||
});
|
||||
},
|
||||
|
||||
listSessions: function(asyncCallback) {
|
||||
this._proxy.ListSessionsRemote(function(result, error) {
|
||||
listSessions(asyncCallback) {
|
||||
this._proxy.ListSessionsRemote((result, error) => {
|
||||
if (error)
|
||||
asyncCallback([]);
|
||||
else
|
||||
@@ -159,18 +197,18 @@ var LoginManagerSystemd = new Lang.Class({
|
||||
});
|
||||
},
|
||||
|
||||
suspend: function() {
|
||||
suspend() {
|
||||
this._proxy.SuspendRemote(true);
|
||||
},
|
||||
|
||||
inhibit: function(reason, callback) {
|
||||
inhibit(reason, callback) {
|
||||
let inVariant = GLib.Variant.new('(ssss)',
|
||||
['sleep',
|
||||
'GNOME Shell',
|
||||
reason,
|
||||
'delay']);
|
||||
this._proxy.call_with_unix_fd_list('Inhibit', inVariant, 0, -1, null, null,
|
||||
Lang.bind(this, function(proxy, result) {
|
||||
(proxy, result) => {
|
||||
let fd = -1;
|
||||
try {
|
||||
let [outVariant, fdList] = proxy.call_with_unix_fd_list_finish(result);
|
||||
@@ -180,10 +218,10 @@ var LoginManagerSystemd = new Lang.Class({
|
||||
logError(e, "Error getting systemd inhibitor");
|
||||
callback(null);
|
||||
}
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
_prepareForSleep: function(proxy, sender, [aboutToSuspend]) {
|
||||
_prepareForSleep(proxy, sender, [aboutToSuspend]) {
|
||||
this.emit('prepare-for-sleep', aboutToSuspend);
|
||||
}
|
||||
});
|
||||
@@ -192,26 +230,26 @@ Signals.addSignalMethods(LoginManagerSystemd.prototype);
|
||||
var LoginManagerDummy = new Lang.Class({
|
||||
Name: 'LoginManagerDummy',
|
||||
|
||||
getCurrentSessionProxy: function(callback) {
|
||||
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: function(asyncCallback) {
|
||||
canSuspend(asyncCallback) {
|
||||
asyncCallback(false, false);
|
||||
},
|
||||
|
||||
listSessions: function(asyncCallback) {
|
||||
listSessions(asyncCallback) {
|
||||
asyncCallback([]);
|
||||
},
|
||||
|
||||
suspend: function() {
|
||||
suspend() {
|
||||
this.emit('prepare-for-sleep', true);
|
||||
this.emit('prepare-for-sleep', false);
|
||||
},
|
||||
|
||||
inhibit: function(reason, callback) {
|
||||
inhibit(reason, callback) {
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -92,63 +92,65 @@ function _findProviderForSid(sid) {
|
||||
// The following are not the complete interfaces, just the methods we need
|
||||
// (or may need in the future)
|
||||
|
||||
const ModemGsmNetworkInterface = '<node> \
|
||||
<interface name="org.freedesktop.ModemManager.Modem.Gsm.Network"> \
|
||||
<method name="GetRegistrationInfo"> \
|
||||
<arg type="(uss)" direction="out" /> \
|
||||
</method> \
|
||||
<method name="GetSignalQuality"> \
|
||||
<arg type="u" direction="out" /> \
|
||||
</method> \
|
||||
<property name="AccessTechnology" type="u" access="read" /> \
|
||||
<signal name="SignalQuality"> \
|
||||
<arg type="u" direction="out" /> \
|
||||
</signal> \
|
||||
<signal name="RegistrationInfo"> \
|
||||
<arg type="u" direction="out" /> \
|
||||
<arg type="s" direction="out" /> \
|
||||
<arg type="s" direction="out" /> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ModemGsmNetworkInterface = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.ModemManager.Modem.Gsm.Network">
|
||||
<method name="GetRegistrationInfo">
|
||||
<arg type="(uss)" direction="out" />
|
||||
</method>
|
||||
<method name="GetSignalQuality">
|
||||
<arg type="u" direction="out" />
|
||||
</method>
|
||||
<property name="AccessTechnology" type="u" access="read" />
|
||||
<signal name="SignalQuality">
|
||||
<arg type="u" direction="out" />
|
||||
</signal>
|
||||
<signal name="RegistrationInfo">
|
||||
<arg type="u" direction="out" />
|
||||
<arg type="s" direction="out" />
|
||||
<arg type="s" direction="out" />
|
||||
</signal>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const ModemGsmNetworkProxy = Gio.DBusProxy.makeProxyWrapper(ModemGsmNetworkInterface);
|
||||
|
||||
const ModemCdmaInterface = '<node> \
|
||||
<interface name="org.freedesktop.ModemManager.Modem.Cdma"> \
|
||||
<method name="GetSignalQuality"> \
|
||||
<arg type="u" direction="out" /> \
|
||||
</method> \
|
||||
<method name="GetServingSystem"> \
|
||||
<arg type="(usu)" direction="out" /> \
|
||||
</method> \
|
||||
<signal name="SignalQuality"> \
|
||||
<arg type="u" direction="out" /> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ModemCdmaInterface = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.ModemManager.Modem.Cdma">
|
||||
<method name="GetSignalQuality">
|
||||
<arg type="u" direction="out" />
|
||||
</method>
|
||||
<method name="GetServingSystem">
|
||||
<arg type="(usu)" direction="out" />
|
||||
</method>
|
||||
<signal name="SignalQuality">
|
||||
<arg type="u" direction="out" />
|
||||
</signal>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface);
|
||||
|
||||
var ModemGsm = new Lang.Class({
|
||||
Name: 'ModemGsm',
|
||||
|
||||
_init: function(path) {
|
||||
_init(path) {
|
||||
this._proxy = new ModemGsmNetworkProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
|
||||
|
||||
this.signal_quality = 0;
|
||||
this.operator_name = null;
|
||||
|
||||
// Code is duplicated because the function have different signatures
|
||||
this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, [quality]) {
|
||||
this._proxy.connectSignal('SignalQuality', (proxy, sender, [quality]) => {
|
||||
this.signal_quality = quality;
|
||||
this.emit('notify::signal-quality');
|
||||
}));
|
||||
this._proxy.connectSignal('RegistrationInfo', Lang.bind(this, function(proxy, sender, [status, code, name]) {
|
||||
});
|
||||
this._proxy.connectSignal('RegistrationInfo', (proxy, sender, [status, code, name]) => {
|
||||
this.operator_name = _findProviderForMccMnc(name, code);
|
||||
this.emit('notify::operator-name');
|
||||
}));
|
||||
this._proxy.GetRegistrationInfoRemote(Lang.bind(this, function([result], err) {
|
||||
});
|
||||
this._proxy.GetRegistrationInfoRemote(([result], err) => {
|
||||
if (err) {
|
||||
log(err);
|
||||
return;
|
||||
@@ -157,8 +159,8 @@ var ModemGsm = new Lang.Class({
|
||||
let [status, code, name] = result;
|
||||
this.operator_name = _findProviderForMccMnc(name, code);
|
||||
this.emit('notify::operator-name');
|
||||
}));
|
||||
this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
|
||||
});
|
||||
this._proxy.GetSignalQualityRemote((result, err) => {
|
||||
if (err) {
|
||||
// it will return an error if the device is not connected
|
||||
this.signal_quality = 0;
|
||||
@@ -167,7 +169,7 @@ var ModemGsm = new Lang.Class({
|
||||
this.signal_quality = quality;
|
||||
}
|
||||
this.emit('notify::signal-quality');
|
||||
}));
|
||||
});
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(ModemGsm.prototype);
|
||||
@@ -175,12 +177,12 @@ Signals.addSignalMethods(ModemGsm.prototype);
|
||||
var ModemCdma = new Lang.Class({
|
||||
Name: 'ModemCdma',
|
||||
|
||||
_init: function(path) {
|
||||
_init(path) {
|
||||
this._proxy = new ModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
|
||||
|
||||
this.signal_quality = 0;
|
||||
this.operator_name = null;
|
||||
this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, params) {
|
||||
this._proxy.connectSignal('SignalQuality', (proxy, sender, params) => {
|
||||
this.signal_quality = params[0];
|
||||
this.emit('notify::signal-quality');
|
||||
|
||||
@@ -188,8 +190,8 @@ var ModemCdma = new Lang.Class({
|
||||
// and we can finally call GetServingSystem
|
||||
if (this.operator_name == null)
|
||||
this._refreshServingSystem();
|
||||
}));
|
||||
this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
|
||||
});
|
||||
this._proxy.GetSignalQualityRemote((result, err) => {
|
||||
if (err) {
|
||||
// it will return an error if the device is not connected
|
||||
this.signal_quality = 0;
|
||||
@@ -198,11 +200,11 @@ var ModemCdma = new Lang.Class({
|
||||
this.signal_quality = quality;
|
||||
}
|
||||
this.emit('notify::signal-quality');
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
_refreshServingSystem: function() {
|
||||
this._proxy.GetServingSystemRemote(Lang.bind(this, function([result], err) {
|
||||
_refreshServingSystem() {
|
||||
this._proxy.GetServingSystemRemote(([result], err) => {
|
||||
if (err) {
|
||||
// it will return an error if the device is not connected
|
||||
this.operator_name = null;
|
||||
@@ -212,7 +214,7 @@ var ModemCdma = new Lang.Class({
|
||||
this.operator_name = _findProviderForSid(sid)
|
||||
}
|
||||
this.emit('notify::operator-name');
|
||||
}));
|
||||
});
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(ModemCdma.prototype);
|
||||
@@ -222,65 +224,68 @@ Signals.addSignalMethods(ModemCdma.prototype);
|
||||
// Support for the new ModemManager1 interface (MM >= 0.7)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const BroadbandModemInterface = '<node> \
|
||||
<interface name="org.freedesktop.ModemManager1.Modem"> \
|
||||
<property name="SignalQuality" type="(ub)" access="read" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const BroadbandModemInterface = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.ModemManager1.Modem">
|
||||
<property name="SignalQuality" type="(ub)" access="read" />
|
||||
</interface>
|
||||
</node>`;
|
||||
const BroadbandModemProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemInterface);
|
||||
|
||||
const BroadbandModem3gppInterface = '<node> \
|
||||
<interface name="org.freedesktop.ModemManager1.Modem.Modem3gpp"> \
|
||||
<property name="OperatorCode" type="s" access="read" /> \
|
||||
<property name="OperatorName" type="s" access="read" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const BroadbandModem3gppInterface = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.ModemManager1.Modem.Modem3gpp">
|
||||
<property name="OperatorCode" type="s" access="read" />
|
||||
<property name="OperatorName" type="s" access="read" />
|
||||
</interface>
|
||||
</node>`;
|
||||
const BroadbandModem3gppProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModem3gppInterface);
|
||||
|
||||
const BroadbandModemCdmaInterface = '<node> \
|
||||
<interface name="org.freedesktop.ModemManager1.Modem.ModemCdma"> \
|
||||
<property name="Sid" type="u" access="read" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const BroadbandModemCdmaInterface = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.ModemManager1.Modem.ModemCdma">
|
||||
<property name="Sid" type="u" access="read" />
|
||||
</interface>
|
||||
</node>`;
|
||||
const BroadbandModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemCdmaInterface);
|
||||
|
||||
var BroadbandModem = new Lang.Class({
|
||||
Name: 'BroadbandModem',
|
||||
|
||||
_init: function(path, capabilities) {
|
||||
_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);
|
||||
this._capabilities = capabilities;
|
||||
|
||||
this._proxy.connect('g-properties-changed', Lang.bind(this, function(proxy, properties) {
|
||||
this._proxy.connect('g-properties-changed', (proxy, properties) => {
|
||||
if ('SignalQuality' in properties.deep_unpack())
|
||||
this._reloadSignalQuality();
|
||||
}));
|
||||
});
|
||||
this._reloadSignalQuality();
|
||||
|
||||
this._proxy_3gpp.connect('g-properties-changed', Lang.bind(this, function(proxy, properties) {
|
||||
this._proxy_3gpp.connect('g-properties-changed', (proxy, properties) => {
|
||||
let unpacked = properties.deep_unpack();
|
||||
if ('OperatorName' in unpacked || 'OperatorCode' in unpacked)
|
||||
this._reload3gppOperatorName();
|
||||
}));
|
||||
});
|
||||
this._reload3gppOperatorName();
|
||||
|
||||
this._proxy_cdma.connect('g-properties-changed', Lang.bind(this, function(proxy, properties) {
|
||||
this._proxy_cdma.connect('g-properties-changed', (proxy, properties) => {
|
||||
let unpacked = properties.deep_unpack();
|
||||
if ('Nid' in unpacked || 'Sid' in unpacked)
|
||||
this._reloadCdmaOperatorName();
|
||||
}));
|
||||
});
|
||||
this._reloadCdmaOperatorName();
|
||||
},
|
||||
|
||||
_reloadSignalQuality: function() {
|
||||
_reloadSignalQuality() {
|
||||
let [quality, recent] = this._proxy.SignalQuality;
|
||||
this.signal_quality = quality;
|
||||
this.emit('notify::signal-quality');
|
||||
},
|
||||
|
||||
_reloadOperatorName: function() {
|
||||
_reloadOperatorName() {
|
||||
let new_name = "";
|
||||
if (this.operator_name_3gpp && this.operator_name_3gpp.length > 0)
|
||||
new_name += this.operator_name_3gpp;
|
||||
@@ -295,14 +300,14 @@ var BroadbandModem = new Lang.Class({
|
||||
this.emit('notify::operator-name');
|
||||
},
|
||||
|
||||
_reload3gppOperatorName: function() {
|
||||
_reload3gppOperatorName() {
|
||||
let name = this._proxy_3gpp.OperatorName;
|
||||
let code = this._proxy_3gpp.OperatorCode;
|
||||
this.operator_name_3gpp = _findProviderForMccMnc(name, code);
|
||||
this._reloadOperatorName();
|
||||
},
|
||||
|
||||
_reloadCdmaOperatorName: function() {
|
||||
_reloadCdmaOperatorName() {
|
||||
let sid = this._proxy_cdma.Sid;
|
||||
this.operator_name_cdma = _findProviderForSid(sid);
|
||||
this._reloadOperatorName();
|
||||
|
||||
@@ -8,27 +8,28 @@ const Signals = imports.signals;
|
||||
|
||||
// Specified in the D-Bus specification here:
|
||||
// http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager
|
||||
const ObjectManagerIface = '<node> \
|
||||
<interface name="org.freedesktop.DBus.ObjectManager"> \
|
||||
<method name="GetManagedObjects"> \
|
||||
<arg name="objects" type="a{oa{sa{sv}}}" direction="out"/> \
|
||||
</method> \
|
||||
<signal name="InterfacesAdded"> \
|
||||
<arg name="objectPath" type="o"/> \
|
||||
<arg name="interfaces" type="a{sa{sv}}" /> \
|
||||
</signal> \
|
||||
<signal name="InterfacesRemoved"> \
|
||||
<arg name="objectPath" type="o"/> \
|
||||
<arg name="interfaces" type="as" /> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ObjectManagerIface = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.DBus.ObjectManager">
|
||||
<method name="GetManagedObjects">
|
||||
<arg name="objects" type="a{oa{sa{sv}}}" direction="out"/>
|
||||
</method>
|
||||
<signal name="InterfacesAdded">
|
||||
<arg name="objectPath" type="o"/>
|
||||
<arg name="interfaces" type="a{sa{sv}}" />
|
||||
</signal>
|
||||
<signal name="InterfacesRemoved">
|
||||
<arg name="objectPath" type="o"/>
|
||||
<arg name="interfaces" type="as" />
|
||||
</signal>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const ObjectManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ObjectManagerIface);
|
||||
|
||||
var ObjectManager = new Lang.Class({
|
||||
Name: 'ObjectManager',
|
||||
_init: function(params) {
|
||||
_init(params) {
|
||||
params = Params.parse(params, { connection: null,
|
||||
name: null,
|
||||
objectPath: null,
|
||||
@@ -61,10 +62,10 @@ var ObjectManager = new Lang.Class({
|
||||
this._numLoadInhibitors = 1;
|
||||
this._managerProxy.init_async(GLib.PRIORITY_DEFAULT,
|
||||
this._cancellable,
|
||||
Lang.bind(this, this._onManagerProxyLoaded));
|
||||
this._onManagerProxyLoaded.bind(this));
|
||||
},
|
||||
|
||||
_tryToCompleteLoad: function() {
|
||||
_tryToCompleteLoad() {
|
||||
if (this._numLoadInhibitors == 0)
|
||||
return;
|
||||
|
||||
@@ -75,7 +76,7 @@ var ObjectManager = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_addInterface: function(objectPath, interfaceName, onFinished) {
|
||||
_addInterface(objectPath, interfaceName, onFinished) {
|
||||
let info = this._interfaceInfos[interfaceName];
|
||||
|
||||
if (!info) {
|
||||
@@ -93,7 +94,7 @@ var ObjectManager = new Lang.Class({
|
||||
|
||||
proxy.init_async(GLib.PRIORITY_DEFAULT,
|
||||
this._cancellable,
|
||||
Lang.bind(this, function(initable, result) {
|
||||
(initable, result) => {
|
||||
let error = null;
|
||||
try {
|
||||
initable.init_finish(result);
|
||||
@@ -127,10 +128,10 @@ var ObjectManager = new Lang.Class({
|
||||
|
||||
if (onFinished)
|
||||
onFinished();
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
_removeInterface: function(objectPath, interfaceName) {
|
||||
_removeInterface(objectPath, interfaceName) {
|
||||
if (!this._objects[objectPath])
|
||||
return;
|
||||
|
||||
@@ -156,7 +157,7 @@ var ObjectManager = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_onManagerProxyLoaded: function(initable, result) {
|
||||
_onManagerProxyLoaded(initable, result) {
|
||||
let error = null;
|
||||
try {
|
||||
initable.init_finish(result);
|
||||
@@ -168,35 +169,35 @@ var ObjectManager = new Lang.Class({
|
||||
}
|
||||
|
||||
this._managerProxy.connectSignal('InterfacesAdded',
|
||||
Lang.bind(this, function(objectManager, sender, [objectPath, interfaces]) {
|
||||
(objectManager, sender, [objectPath, interfaces]) => {
|
||||
let interfaceNames = Object.keys(interfaces);
|
||||
for (let i = 0; i < interfaceNames.length; i++)
|
||||
this._addInterface(objectPath, interfaceNames[i]);
|
||||
}));
|
||||
});
|
||||
this._managerProxy.connectSignal('InterfacesRemoved',
|
||||
Lang.bind(this, function(objectManager, sender, [objectPath, interfaceNames]) {
|
||||
(objectManager, sender, [objectPath, interfaceNames]) => {
|
||||
for (let i = 0; i < interfaceNames.length; i++)
|
||||
this._removeInterface(objectPath, interfaceNames[i]);
|
||||
}));
|
||||
});
|
||||
|
||||
if (Object.keys(this._interfaceInfos).length == 0) {
|
||||
this._tryToCompleteLoad();
|
||||
return;
|
||||
}
|
||||
|
||||
this._managerProxy.connect('notify::g-name-owner', Lang.bind(this, function() {
|
||||
this._managerProxy.connect('notify::g-name-owner', () => {
|
||||
if (this._managerProxy.g_name_owner)
|
||||
this._onNameAppeared();
|
||||
else
|
||||
this._onNameVanished();
|
||||
}));
|
||||
});
|
||||
|
||||
if (this._managerProxy.g_name_owner)
|
||||
this._onNameAppeared();
|
||||
},
|
||||
|
||||
_onNameAppeared: function() {
|
||||
this._managerProxy.GetManagedObjectsRemote(Lang.bind(this, function(result, error) {
|
||||
_onNameAppeared() {
|
||||
this._managerProxy.GetManagedObjectsRemote((result, error) => {
|
||||
if (!result) {
|
||||
if (error) {
|
||||
logError(error, 'could not get remote objects for service ' + this._serviceName + ' path ' + this._managerPath);
|
||||
@@ -226,21 +227,22 @@ var ObjectManager = new Lang.Class({
|
||||
this._numLoadInhibitors++;
|
||||
this._addInterface(objectPath,
|
||||
interfaceName,
|
||||
Lang.bind(this, this._tryToCompleteLoad));
|
||||
this._tryToCompleteLoad.bind(this));
|
||||
}
|
||||
}
|
||||
this._tryToCompleteLoad();
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
_onNameVanished: function() {
|
||||
_onNameVanished() {
|
||||
let objectPaths = Object.keys(this._objects);
|
||||
for (let i = 0; i < objectPaths.length; i++) {
|
||||
let object = this._objects[objectPaths];
|
||||
let objectPath = objectPaths[i];
|
||||
let object = this._objects[objectPath];
|
||||
|
||||
let interfaceNames = Object.keys(object);
|
||||
for (let j = 0; i < interfaceNames.length; i++) {
|
||||
let interfaceName = interfaceNames[i];
|
||||
for (let j = 0; j < interfaceNames.length; j++) {
|
||||
let interfaceName = interfaceNames[j];
|
||||
|
||||
if (object[interfaceName])
|
||||
this._removeInterface(objectPath, interfaceName);
|
||||
@@ -248,14 +250,14 @@ var ObjectManager = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_registerInterfaces: function(interfaces) {
|
||||
_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: function(objectPath, interfaceName) {
|
||||
getProxy(objectPath, interfaceName) {
|
||||
let object = this._objects[objectPath];
|
||||
|
||||
if (!object)
|
||||
@@ -264,7 +266,7 @@ var ObjectManager = new Lang.Class({
|
||||
return object[interfaceName];
|
||||
},
|
||||
|
||||
getProxiesForInterface: function(interfaceName) {
|
||||
getProxiesForInterface(interfaceName) {
|
||||
let proxyList = this._interfaces[interfaceName];
|
||||
|
||||
if (!proxyList)
|
||||
@@ -273,7 +275,7 @@ var ObjectManager = new Lang.Class({
|
||||
return proxyList;
|
||||
},
|
||||
|
||||
getAllProxies: function() {
|
||||
getAllProxies() {
|
||||
let proxies = [];
|
||||
|
||||
let objectPaths = Object.keys(this._objects);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// parse:
|
||||
// @params: caller-provided parameter object, or %null
|
||||
// @defaults: function-provided defaults object
|
||||
// @defaults-provided defaults object
|
||||
// @allowExtras: whether or not to allow properties not in @default
|
||||
//
|
||||
// Examines @params and fills in default values from @defaults for
|
||||
|
||||
@@ -2,30 +2,31 @@
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
|
||||
const PermissionStoreIface = '<node> \
|
||||
<interface name="org.freedesktop.impl.portal.PermissionStore"> \
|
||||
<method name="Lookup"> \
|
||||
<arg name="table" type="s" direction="in"/> \
|
||||
<arg name="id" type="s" direction="in"/> \
|
||||
<arg name="permissions" type="a{sas}" direction="out"/> \
|
||||
<arg name="data" type="v" direction="out"/> \
|
||||
</method> \
|
||||
<method name="Set"> \
|
||||
<arg name="table" type="s" direction="in"/> \
|
||||
<arg name="create" type="b" direction="in"/> \
|
||||
<arg name="id" type="s" direction="in"/> \
|
||||
<arg name="app_permissions" type="a{sas}" direction="in"/> \
|
||||
<arg name="data" type="v" direction="in"/> \
|
||||
</method> \
|
||||
<signal name="Changed"> \
|
||||
<arg name="table" type="s" direction="out"/> \
|
||||
<arg name="id" type="s" direction="out"/> \
|
||||
<arg name="deleted" type="b" direction="out"/> \
|
||||
<arg name="data" type="v" direction="out"/> \
|
||||
<arg name="permissions" type="a{sas}" direction="out"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const PermissionStoreIface = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.impl.portal.PermissionStore">
|
||||
<method name="Lookup">
|
||||
<arg name="table" type="s" direction="in"/>
|
||||
<arg name="id" type="s" direction="in"/>
|
||||
<arg name="permissions" type="a{sas}" direction="out"/>
|
||||
<arg name="data" type="v" direction="out"/>
|
||||
</method>
|
||||
<method name="Set">
|
||||
<arg name="table" type="s" direction="in"/>
|
||||
<arg name="create" type="b" direction="in"/>
|
||||
<arg name="id" type="s" direction="in"/>
|
||||
<arg name="app_permissions" type="a{sas}" direction="in"/>
|
||||
<arg name="data" type="v" direction="in"/>
|
||||
</method>
|
||||
<signal name="Changed">
|
||||
<arg name="table" type="s" direction="out"/>
|
||||
<arg name="id" type="s" direction="out"/>
|
||||
<arg name="deleted" type="b" direction="out"/>
|
||||
<arg name="data" type="v" direction="out"/>
|
||||
<arg name="permissions" type="a{sas}" direction="out"/>
|
||||
</signal>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const PermissionStoreProxy = Gio.DBusProxy.makeProxyWrapper(PermissionStoreIface);
|
||||
|
||||
|
||||
@@ -7,14 +7,15 @@ const Signals = imports.signals;
|
||||
|
||||
const ObjectManager = imports.misc.objectManager;
|
||||
|
||||
const SmartcardTokenIface = '<node> \
|
||||
<interface name="org.gnome.SettingsDaemon.Smartcard.Token"> \
|
||||
<property name="Name" type="s" access="read"/> \
|
||||
<property name="Driver" type="o" access="read"/> \
|
||||
<property name="IsInserted" type="b" access="read"/> \
|
||||
<property name="UsedToLogin" type="b" access="read"/> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const SmartcardTokenIface = `
|
||||
<node>
|
||||
<interface name="org.gnome.SettingsDaemon.Smartcard.Token">
|
||||
<property name="Name" type="s" access="read"/>
|
||||
<property name="Driver" type="o" access="read"/>
|
||||
<property name="IsInserted" type="b" access="read"/>
|
||||
<property name="UsedToLogin" type="b" access="read"/>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
let _smartcardManager = null;
|
||||
|
||||
@@ -27,34 +28,34 @@ function getSmartcardManager() {
|
||||
|
||||
var SmartcardManager = new Lang.Class({
|
||||
Name: 'SmartcardManager',
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._objectManager = new ObjectManager.ObjectManager({ connection: Gio.DBus.session,
|
||||
name: "org.gnome.SettingsDaemon.Smartcard",
|
||||
objectPath: '/org/gnome/SettingsDaemon/Smartcard',
|
||||
knownInterfaces: [ SmartcardTokenIface ],
|
||||
onLoaded: Lang.bind(this, this._onLoaded) });
|
||||
onLoaded: this._onLoaded.bind(this) });
|
||||
this._insertedTokens = {};
|
||||
this._loginToken = null;
|
||||
},
|
||||
|
||||
_onLoaded: function() {
|
||||
_onLoaded() {
|
||||
let tokens = this._objectManager.getProxiesForInterface('org.gnome.SettingsDaemon.Smartcard.Token');
|
||||
|
||||
for (let i = 0; i < tokens.length; i++)
|
||||
this._addToken(tokens[i]);
|
||||
|
||||
this._objectManager.connect('interface-added', Lang.bind(this, function(objectManager, interfaceName, proxy) {
|
||||
this._objectManager.connect('interface-added', (objectManager, interfaceName, proxy) => {
|
||||
if (interfaceName == 'org.gnome.SettingsDaemon.Smartcard.Token')
|
||||
this._addToken(proxy);
|
||||
}));
|
||||
});
|
||||
|
||||
this._objectManager.connect('interface-removed', Lang.bind(this, function(objectManager, interfaceName, proxy) {
|
||||
this._objectManager.connect('interface-removed', (objectManager, interfaceName, proxy) => {
|
||||
if (interfaceName == 'org.gnome.SettingsDaemon.Smartcard.Token')
|
||||
this._removeToken(proxy);
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
_updateToken: function(token) {
|
||||
_updateToken(token) {
|
||||
let objectPath = token.get_object_path();
|
||||
|
||||
delete this._insertedTokens[objectPath];
|
||||
@@ -66,28 +67,27 @@ var SmartcardManager = new Lang.Class({
|
||||
this._loginToken = token;
|
||||
},
|
||||
|
||||
_addToken: function(token) {
|
||||
_addToken(token) {
|
||||
this._updateToken(token);
|
||||
|
||||
token.connect('g-properties-changed',
|
||||
Lang.bind(this, function(proxy, properties) {
|
||||
if ('IsInserted' in properties.deep_unpack()) {
|
||||
this._updateToken(token);
|
||||
token.connect('g-properties-changed', (proxy, properties) => {
|
||||
if ('IsInserted' in properties.deep_unpack()) {
|
||||
this._updateToken(token);
|
||||
|
||||
if (token.IsInserted) {
|
||||
this.emit('smartcard-inserted', token);
|
||||
} else {
|
||||
this.emit('smartcard-removed', token);
|
||||
}
|
||||
}
|
||||
}));
|
||||
if (token.IsInserted) {
|
||||
this.emit('smartcard-inserted', token);
|
||||
} else {
|
||||
this.emit('smartcard-removed', token);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Emit a smartcard-inserted at startup if it's already plugged in
|
||||
if (token.IsInserted)
|
||||
this.emit('smartcard-inserted', token);
|
||||
},
|
||||
|
||||
_removeToken: function(token) {
|
||||
_removeToken(token) {
|
||||
let objectPath = token.get_object_path();
|
||||
|
||||
if (this._insertedTokens[objectPath] == token) {
|
||||
@@ -101,11 +101,11 @@ var SmartcardManager = new Lang.Class({
|
||||
token.disconnectAll();
|
||||
},
|
||||
|
||||
hasInsertedTokens: function() {
|
||||
hasInsertedTokens() {
|
||||
return Object.keys(this._insertedTokens).length > 0;
|
||||
},
|
||||
|
||||
hasInsertedLoginToken: function() {
|
||||
hasInsertedLoginToken() {
|
||||
if (!this._loginToken)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -22,11 +22,12 @@ const ALWAYS_SHOW_LOG_OUT_KEY = 'always-show-log-out';
|
||||
const SENSOR_BUS_NAME = 'net.hadess.SensorProxy';
|
||||
const SENSOR_OBJECT_PATH = '/net/hadess/SensorProxy';
|
||||
|
||||
const SensorProxyInterface = '<node> \
|
||||
<interface name="net.hadess.SensorProxy"> \
|
||||
<property name="HasAccelerometer" type="b" access="read"/> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const SensorProxyInterface = `
|
||||
<node>
|
||||
<interface name="net.hadess.SensorProxy">
|
||||
<property name="HasAccelerometer" type="b" access="read"/>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const POWER_OFF_ACTION_ID = 'power-off';
|
||||
const LOCK_SCREEN_ACTION_ID = 'lock-screen';
|
||||
@@ -87,7 +88,7 @@ const SystemActions = new Lang.Class({
|
||||
null)
|
||||
},
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this.parent();
|
||||
|
||||
this._canHavePowerOff = true;
|
||||
@@ -218,7 +219,7 @@ const SystemActions = new Lang.Class({
|
||||
return this._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName;
|
||||
},
|
||||
|
||||
_sensorProxyAppeared: function() {
|
||||
_sensorProxyAppeared() {
|
||||
this._sensorProxy = new SensorProxy(Gio.DBus.system, SENSOR_BUS_NAME, SENSOR_OBJECT_PATH,
|
||||
(proxy, error) => {
|
||||
if (error) {
|
||||
@@ -231,7 +232,7 @@ const SystemActions = new Lang.Class({
|
||||
});
|
||||
},
|
||||
|
||||
_updateOrientationLock: function() {
|
||||
_updateOrientationLock() {
|
||||
let available = false;
|
||||
if (this._sensorProxy)
|
||||
available = this._sensorProxy.HasAccelerometer &&
|
||||
@@ -242,7 +243,7 @@ const SystemActions = new Lang.Class({
|
||||
this.notify('can-lock-orientation');
|
||||
},
|
||||
|
||||
_updateOrientationLockIcon: function() {
|
||||
_updateOrientationLockIcon() {
|
||||
let locked = this._orientationSettings.get_boolean('orientation-lock');
|
||||
let iconName = locked ? 'rotation-locked-symbolic'
|
||||
: 'rotation-allowed-symbolic';
|
||||
@@ -251,14 +252,14 @@ const SystemActions = new Lang.Class({
|
||||
this.notify('orientation-lock-icon');
|
||||
},
|
||||
|
||||
_sessionUpdated: function() {
|
||||
_sessionUpdated() {
|
||||
this._updateLockScreen();
|
||||
this._updatePowerOff();
|
||||
this._updateSuspend();
|
||||
this._updateMultiUser();
|
||||
},
|
||||
|
||||
forceUpdate: function() {
|
||||
forceUpdate() {
|
||||
// Whether those actions are available or not depends on both lockdown
|
||||
// settings and Polkit policy - we don't get change notifications for the
|
||||
// latter, so their value may be outdated; force an update now
|
||||
@@ -266,7 +267,7 @@ const SystemActions = new Lang.Class({
|
||||
this._updateHaveSuspend();
|
||||
},
|
||||
|
||||
getMatchingActions: function(terms) {
|
||||
getMatchingActions(terms) {
|
||||
// terms is a list of strings
|
||||
terms = terms.map((term) => { return term.toLowerCase(); });
|
||||
|
||||
@@ -279,15 +280,15 @@ const SystemActions = new Lang.Class({
|
||||
return results;
|
||||
},
|
||||
|
||||
getName: function(id) {
|
||||
getName(id) {
|
||||
return this._actions.get(id).name;
|
||||
},
|
||||
|
||||
getIconName: function(id) {
|
||||
getIconName(id) {
|
||||
return this._actions.get(id).iconName;
|
||||
},
|
||||
|
||||
activateAction: function(id) {
|
||||
activateAction(id) {
|
||||
switch (id) {
|
||||
case POWER_OFF_ACTION_ID:
|
||||
this.activatePowerOff();
|
||||
@@ -317,7 +318,7 @@ const SystemActions = new Lang.Class({
|
||||
this.notify('can-lock-screen');
|
||||
},
|
||||
|
||||
_updateHaveShutdown: function() {
|
||||
_updateHaveShutdown() {
|
||||
this._session.CanShutdownRemote((result, error) => {
|
||||
if (error)
|
||||
return;
|
||||
@@ -327,7 +328,7 @@ const SystemActions = new Lang.Class({
|
||||
});
|
||||
},
|
||||
|
||||
_updatePowerOff: function() {
|
||||
_updatePowerOff() {
|
||||
let disabled = Main.sessionMode.isLocked ||
|
||||
(Main.sessionMode.isGreeter &&
|
||||
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
|
||||
@@ -335,7 +336,7 @@ const SystemActions = new Lang.Class({
|
||||
this.notify('can-power-off');
|
||||
},
|
||||
|
||||
_updateHaveSuspend: function() {
|
||||
_updateHaveSuspend() {
|
||||
this._loginManager.canSuspend(
|
||||
(canSuspend, needsAuth) => {
|
||||
this._canHaveSuspend = canSuspend;
|
||||
@@ -344,7 +345,7 @@ const SystemActions = new Lang.Class({
|
||||
});
|
||||
},
|
||||
|
||||
_updateSuspend: function() {
|
||||
_updateSuspend() {
|
||||
let disabled = (Main.sessionMode.isLocked &&
|
||||
this._suspendNeedsAuth) ||
|
||||
(Main.sessionMode.isGreeter &&
|
||||
@@ -353,12 +354,12 @@ const SystemActions = new Lang.Class({
|
||||
this.notify('can-suspend');
|
||||
},
|
||||
|
||||
_updateMultiUser: function() {
|
||||
_updateMultiUser() {
|
||||
this._updateLogout();
|
||||
this._updateSwitchUser();
|
||||
},
|
||||
|
||||
_updateSwitchUser: function() {
|
||||
_updateSwitchUser() {
|
||||
let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY);
|
||||
let multiUser = this._userManager.can_switch() && this._userManager.has_multiple_users;
|
||||
let shouldShowInMode = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
|
||||
@@ -370,7 +371,7 @@ const SystemActions = new Lang.Class({
|
||||
return visible;
|
||||
},
|
||||
|
||||
_updateLogout: function() {
|
||||
_updateLogout() {
|
||||
let user = this._userManager.get_user(GLib.get_user_name());
|
||||
|
||||
let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY);
|
||||
@@ -388,7 +389,7 @@ const SystemActions = new Lang.Class({
|
||||
return visible;
|
||||
},
|
||||
|
||||
activateLockOrientation: function() {
|
||||
activateLockOrientation() {
|
||||
if (!this._actions.get(LOCK_ORIENTATION_ACTION_ID).available)
|
||||
throw new Error('The lock-orientation action is not available!');
|
||||
|
||||
@@ -396,27 +397,27 @@ const SystemActions = new Lang.Class({
|
||||
this._orientationSettings.set_boolean('orientation-lock', !locked);
|
||||
},
|
||||
|
||||
activateLockScreen: function() {
|
||||
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: function() {
|
||||
activateSwitchUser() {
|
||||
if (!this._actions.get(SWITCH_USER_ACTION_ID).available)
|
||||
throw new Error('The switch-user action is not available!');
|
||||
|
||||
if (Main.screenShield)
|
||||
Main.screenShield.lock(false);
|
||||
|
||||
Clutter.threads_add_repaint_func_full(Clutter.RepaintFlags.POST_PAINT, function() {
|
||||
Clutter.threads_add_repaint_func_full(Clutter.RepaintFlags.POST_PAINT, () => {
|
||||
Gdm.goto_login_session_sync(null);
|
||||
return false;
|
||||
});
|
||||
},
|
||||
|
||||
activateLogout: function() {
|
||||
activateLogout() {
|
||||
if (!this._actions.get(LOGOUT_ACTION_ID).available)
|
||||
throw new Error('The logout action is not available!');
|
||||
|
||||
@@ -424,14 +425,14 @@ const SystemActions = new Lang.Class({
|
||||
this._session.LogoutRemote(0);
|
||||
},
|
||||
|
||||
activatePowerOff: function() {
|
||||
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: function() {
|
||||
activateSuspend() {
|
||||
if (!this._actions.get(SUSPEND_ACTION_ID).available)
|
||||
throw new Error('The suspend action is not available!');
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ const Params = imports.misc.params;
|
||||
var SCROLL_TIME = 0.1;
|
||||
|
||||
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
||||
const _balancedParens = '\\((?:[^\\s()<>]+|(?:\\(?:[^\\s()<>]+\\)))*\\)';
|
||||
const _balancedParens = '\\([^\\s()<>]+\\)';
|
||||
const _leadingJunk = '[\\s`(\\[{\'\\"<\u00AB\u201C\u2018]';
|
||||
const _notTrailingJunk = '[^\\s`!()\\[\\]{};:\'\\".,<>?\u00AB\u00BB\u201C\u201D\u2018\u2019]';
|
||||
|
||||
@@ -136,7 +136,7 @@ function trySpawn(argv)
|
||||
// Dummy child watch; we don't want to double-fork internally
|
||||
// because then we lose the parent-child relationship, which
|
||||
// can break polkit. See https://bugzilla.redhat.com//show_bug.cgi?id=819275
|
||||
GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function () {});
|
||||
GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, () => {});
|
||||
}
|
||||
|
||||
// trySpawnCommandLine:
|
||||
@@ -291,12 +291,10 @@ function createTimeLabel(date, params) {
|
||||
_desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
|
||||
|
||||
let label = new St.Label({ text: formatTime(date, params) });
|
||||
let id = _desktopSettings.connect('changed::clock-format', function() {
|
||||
let id = _desktopSettings.connect('changed::clock-format', () => {
|
||||
label.text = formatTime(date, params);
|
||||
});
|
||||
label.connect('destroy', function() {
|
||||
_desktopSettings.disconnect(id);
|
||||
});
|
||||
label.connect('destroy', () => { _desktopSettings.disconnect(id); });
|
||||
return label;
|
||||
}
|
||||
|
||||
@@ -316,7 +314,7 @@ function createTimeLabel(date, params) {
|
||||
|
||||
function lowerBound(array, val, cmp) {
|
||||
let min, max, mid, v;
|
||||
cmp = cmp || function(a, b) { return a - b; };
|
||||
cmp = cmp || ((a, b) => a - b);
|
||||
|
||||
if (array.length == 0)
|
||||
return 0;
|
||||
@@ -354,7 +352,7 @@ var CloseButton = new Lang.Class({
|
||||
Name: 'CloseButton',
|
||||
Extends: St.Button,
|
||||
|
||||
_init: function(boxpointer) {
|
||||
_init(boxpointer) {
|
||||
this.parent({ style_class: 'notification-close'});
|
||||
|
||||
// This is a bit tricky. St.Bin has its own x-align/y-align properties
|
||||
@@ -371,10 +369,10 @@ var CloseButton = new Lang.Class({
|
||||
|
||||
this._boxPointer = boxpointer;
|
||||
if (boxpointer)
|
||||
this._boxPointer.connect('arrow-side-changed', Lang.bind(this, this._sync));
|
||||
this._boxPointer.connect('arrow-side-changed', this._sync.bind(this));
|
||||
},
|
||||
|
||||
_computeBoxPointerOffset: function() {
|
||||
_computeBoxPointerOffset() {
|
||||
if (!this._boxPointer || !this._boxPointer.actor.get_stage())
|
||||
return 0;
|
||||
|
||||
@@ -385,7 +383,7 @@ var CloseButton = new Lang.Class({
|
||||
return 0;
|
||||
},
|
||||
|
||||
_sync: function() {
|
||||
_sync() {
|
||||
let themeNode = this.get_theme_node();
|
||||
|
||||
let offY = this._computeBoxPointerOffset();
|
||||
@@ -393,7 +391,7 @@ var CloseButton = new Lang.Class({
|
||||
this.translation_y = themeNode.get_length('-shell-close-overlap-y') + offY;
|
||||
},
|
||||
|
||||
vfunc_style_changed: function() {
|
||||
vfunc_style_changed() {
|
||||
this._sync();
|
||||
this.parent();
|
||||
},
|
||||
@@ -442,7 +440,7 @@ function ensureActorVisibleInScrollView(scrollView, actor) {
|
||||
var AppSettingsMonitor = new Lang.Class({
|
||||
Name: 'AppSettingsMonitor',
|
||||
|
||||
_init: function(appId, schemaId) {
|
||||
_init(appId, schemaId) {
|
||||
this._appId = appId;
|
||||
this._schemaId = schemaId;
|
||||
|
||||
@@ -454,7 +452,7 @@ var AppSettingsMonitor = new Lang.Class({
|
||||
|
||||
this._appSystem = Shell.AppSystem.get_default();
|
||||
this._appSystem.connect('installed-changed',
|
||||
Lang.bind(this, this._onInstalledChanged));
|
||||
this._onInstalledChanged.bind(this));
|
||||
this._onInstalledChanged();
|
||||
},
|
||||
|
||||
@@ -462,19 +460,19 @@ var AppSettingsMonitor = new Lang.Class({
|
||||
return this._app != null && this._settings != null;
|
||||
},
|
||||
|
||||
activateApp: function() {
|
||||
activateApp() {
|
||||
if (this._app)
|
||||
this._app.activate();
|
||||
},
|
||||
|
||||
watchSetting: function(key, callback) {
|
||||
watchSetting(key, callback) {
|
||||
let handler = { id: 0, key: key, callback: callback };
|
||||
this._handlers.push(handler);
|
||||
|
||||
this._connectHandler(handler);
|
||||
},
|
||||
|
||||
_connectHandler: function(handler) {
|
||||
_connectHandler(handler) {
|
||||
if (!this._settings || handler.id > 0)
|
||||
return;
|
||||
|
||||
@@ -483,13 +481,13 @@ var AppSettingsMonitor = new Lang.Class({
|
||||
handler.callback(this._settings, handler.key);
|
||||
},
|
||||
|
||||
_disconnectHandler: function(handler) {
|
||||
_disconnectHandler(handler) {
|
||||
if (this._settings && handler.id > 0)
|
||||
this._settings.disconnect(handler.id);
|
||||
handler.id = 0;
|
||||
},
|
||||
|
||||
_onInstalledChanged: function() {
|
||||
_onInstalledChanged() {
|
||||
let hadApp = (this._app != null);
|
||||
this._app = this._appSystem.lookup_app(this._appId);
|
||||
let haveApp = (this._app != null);
|
||||
@@ -503,7 +501,7 @@ var AppSettingsMonitor = new Lang.Class({
|
||||
this._setSettings(null);
|
||||
},
|
||||
|
||||
_setSettings: function(settings) {
|
||||
_setSettings(settings) {
|
||||
this._handlers.forEach((handler) => { this._disconnectHandler(handler); });
|
||||
|
||||
let hadSettings = (this._settings != null);
|
||||
@@ -516,7 +514,7 @@ var AppSettingsMonitor = new Lang.Class({
|
||||
this.emit('available-changed');
|
||||
},
|
||||
|
||||
_checkSettings: function() {
|
||||
_checkSettings() {
|
||||
let schema = this._schemaSource.lookup(this._schemaId, true);
|
||||
if (schema) {
|
||||
this._setSettings(new Gio.Settings({ settings_schema: schema }));
|
||||
|
||||
@@ -16,7 +16,7 @@ var UPDATE_THRESHOLD = 10 * GLib.TIME_SPAN_MINUTE;
|
||||
var WeatherClient = new Lang.Class({
|
||||
Name: 'WeatherClient',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._loading = false;
|
||||
this._locationValid = false;
|
||||
this._lastUpdate = GLib.DateTime.new_from_unix_local(0);
|
||||
@@ -46,11 +46,11 @@ var WeatherClient = new Lang.Class({
|
||||
});
|
||||
});
|
||||
this._permStore.connectSignal('Changed',
|
||||
Lang.bind(this, this._onPermStoreChanged));
|
||||
this._onPermStoreChanged.bind(this));
|
||||
|
||||
this._locationSettings = new Gio.Settings({ schema_id: 'org.gnome.system.location' });
|
||||
this._locationSettings.connect('changed::enabled',
|
||||
Lang.bind(this, this._updateAutoLocation));
|
||||
this._updateAutoLocation.bind(this));
|
||||
|
||||
this._world = GWeather.Location.get_world();
|
||||
|
||||
@@ -68,9 +68,9 @@ var WeatherClient = new Lang.Class({
|
||||
'org.gnome.Weather.Application');
|
||||
this._weatherAppMon.connect('available-changed', () => { this.emit('changed'); });
|
||||
this._weatherAppMon.watchSetting('automatic-location',
|
||||
Lang.bind(this, this._onAutomaticLocationChanged));
|
||||
this._onAutomaticLocationChanged.bind(this));
|
||||
this._weatherAppMon.watchSetting('locations',
|
||||
Lang.bind(this, this._onLocationsChanged));
|
||||
this._onLocationsChanged.bind(this));
|
||||
},
|
||||
|
||||
get available() {
|
||||
@@ -89,11 +89,11 @@ var WeatherClient = new Lang.Class({
|
||||
return this._weatherInfo;
|
||||
},
|
||||
|
||||
activateApp: function() {
|
||||
activateApp() {
|
||||
this._weatherAppMon.activateApp();
|
||||
},
|
||||
|
||||
update: function() {
|
||||
update() {
|
||||
if (!this._locationValid)
|
||||
return;
|
||||
|
||||
@@ -112,7 +112,7 @@ var WeatherClient = new Lang.Class({
|
||||
this._weatherAuthorized;
|
||||
},
|
||||
|
||||
_loadInfo: function() {
|
||||
_loadInfo() {
|
||||
let id = this._weatherInfo.connect('updated', () => {
|
||||
this._weatherInfo.disconnect(id);
|
||||
this._loading = false;
|
||||
@@ -124,7 +124,7 @@ var WeatherClient = new Lang.Class({
|
||||
this._weatherInfo.update();
|
||||
},
|
||||
|
||||
_locationsEqual: function(loc1, loc2) {
|
||||
_locationsEqual(loc1, loc2) {
|
||||
if (loc1 == loc2)
|
||||
return true;
|
||||
|
||||
@@ -134,7 +134,7 @@ var WeatherClient = new Lang.Class({
|
||||
return loc1.equal(loc2);
|
||||
},
|
||||
|
||||
_setLocation: function(location) {
|
||||
_setLocation(location) {
|
||||
if (this._locationsEqual(this._weatherInfo.location, location))
|
||||
return;
|
||||
|
||||
@@ -150,14 +150,14 @@ var WeatherClient = new Lang.Class({
|
||||
this.emit('changed');
|
||||
},
|
||||
|
||||
_updateLocationMonitoring: function() {
|
||||
_updateLocationMonitoring() {
|
||||
if (this._useAutoLocation) {
|
||||
if (this._gclueLocationChangedId != 0 || this._gclueService == null)
|
||||
return;
|
||||
|
||||
this._gclueLocationChangedId =
|
||||
this._gclueService.connect('notify::location',
|
||||
Lang.bind(this, this._onGClueLocationChanged));
|
||||
this._onGClueLocationChanged.bind(this));
|
||||
this._onGClueLocationChanged();
|
||||
} else {
|
||||
if (this._gclueLocationChangedId)
|
||||
@@ -166,7 +166,7 @@ var WeatherClient = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_startGClueService: function() {
|
||||
_startGClueService() {
|
||||
if (this._gclueStarting)
|
||||
return;
|
||||
|
||||
@@ -187,7 +187,7 @@ var WeatherClient = new Lang.Class({
|
||||
});
|
||||
},
|
||||
|
||||
_onGClueLocationChanged: function() {
|
||||
_onGClueLocationChanged() {
|
||||
let geoLocation = this._gclueService.location;
|
||||
let location = GWeather.Location.new_detached(geoLocation.description,
|
||||
null,
|
||||
@@ -196,7 +196,7 @@ var WeatherClient = new Lang.Class({
|
||||
this._setLocation(location);
|
||||
},
|
||||
|
||||
_onAutomaticLocationChanged: function(settings, key) {
|
||||
_onAutomaticLocationChanged(settings, key) {
|
||||
let useAutoLocation = settings.get_boolean(key);
|
||||
if (this._autoLocationRequested == useAutoLocation)
|
||||
return;
|
||||
@@ -206,7 +206,7 @@ var WeatherClient = new Lang.Class({
|
||||
this._updateAutoLocation();
|
||||
},
|
||||
|
||||
_updateAutoLocation: function() {
|
||||
_updateAutoLocation() {
|
||||
this._updateLocationMonitoring();
|
||||
|
||||
if (this._useAutoLocation)
|
||||
@@ -215,7 +215,7 @@ var WeatherClient = new Lang.Class({
|
||||
this._setLocation(this._mostRecentLocation);
|
||||
},
|
||||
|
||||
_onLocationsChanged: function(settings, key) {
|
||||
_onLocationsChanged(settings, key) {
|
||||
let serialized = settings.get_value(key).deep_unpack().shift();
|
||||
let mostRecentLocation = null;
|
||||
|
||||
@@ -231,7 +231,7 @@ var WeatherClient = new Lang.Class({
|
||||
this._setLocation(this._mostRecentLocation);
|
||||
},
|
||||
|
||||
_onPermStoreChanged: function(proxy, sender, params) {
|
||||
_onPermStoreChanged(proxy, sender, params) {
|
||||
let [table, id, deleted, data, perms] = params;
|
||||
|
||||
if (table != 'gnome' || id != 'geolocation')
|
||||
|
||||
@@ -75,9 +75,9 @@ function run() {
|
||||
// Enable recording of timestamps for different points in the frame cycle
|
||||
global.frame_timestamps = true;
|
||||
|
||||
Main.overview.connect('shown', function() {
|
||||
Scripting.scriptEvent('overviewShowDone');
|
||||
});
|
||||
Main.overview.connect('shown', () => {
|
||||
Scripting.scriptEvent('overviewShowDone');
|
||||
});
|
||||
|
||||
yield Scripting.sleep(1000);
|
||||
|
||||
|
||||
@@ -42,35 +42,29 @@ function waitAndDraw(milliseconds) {
|
||||
let timeline = new Clutter.Timeline({ duration: milliseconds });
|
||||
timeline.start();
|
||||
|
||||
timeline.connect('new-frame',
|
||||
function(timeline, frame) {
|
||||
global.stage.queue_redraw();
|
||||
});
|
||||
timeline.connect('new-frame', (timeline, frame) => {
|
||||
global.stage.queue_redraw();
|
||||
});
|
||||
|
||||
timeline.connect('completed',
|
||||
function() {
|
||||
timeline.stop();
|
||||
if (cb)
|
||||
cb();
|
||||
});
|
||||
timeline.connect('completed', () => {
|
||||
timeline.stop();
|
||||
if (cb)
|
||||
cb();
|
||||
});
|
||||
|
||||
return function(callback) {
|
||||
cb = callback;
|
||||
};
|
||||
return callback => { cb = callback; };
|
||||
}
|
||||
|
||||
function waitSignal(object, signal) {
|
||||
let cb;
|
||||
|
||||
let id = object.connect(signal, function() {
|
||||
let id = object.connect(signal, () => {
|
||||
object.disconnect(id);
|
||||
if (cb)
|
||||
cb();
|
||||
});
|
||||
|
||||
return function(callback) {
|
||||
cb = callback;
|
||||
};
|
||||
return callback => { cb = callback; };
|
||||
}
|
||||
|
||||
function extractBootTimestamp() {
|
||||
@@ -142,8 +136,7 @@ function run() {
|
||||
global.frame_finish_timestamp = true;
|
||||
|
||||
for (let k = 0; k < 5; k++)
|
||||
yield Scripting.createTestWindow(640, 480,
|
||||
{ maximized: true });
|
||||
yield Scripting.createTestWindow({ maximized: true });
|
||||
yield Scripting.waitTestWindows();
|
||||
|
||||
yield Scripting.sleep(1000);
|
||||
@@ -164,8 +157,7 @@ function run() {
|
||||
yield Scripting.destroyTestWindows();
|
||||
Main.overview.hide();
|
||||
|
||||
yield Scripting.createTestWindow(640, 480,
|
||||
{ maximized: true,
|
||||
yield Scripting.createTestWindow({ maximized: true,
|
||||
redraws: true});
|
||||
yield Scripting.waitTestWindows();
|
||||
|
||||
@@ -270,7 +262,7 @@ function script_redrawTestDone(time) {
|
||||
function script_collectTimings(time) {
|
||||
for (let timing in redrawTimes) {
|
||||
let times = redrawTimes[timing];
|
||||
times.sort(function(a, b) { return a - b });
|
||||
times.sort((a, b) => a - b);
|
||||
|
||||
let len = times.length;
|
||||
let median;
|
||||
|
||||
7
js/portal-resources.gresource.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gnome/shell">
|
||||
<file>misc/config.js</file>
|
||||
<file>portalHelper/main.js</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
@@ -30,31 +30,32 @@ const CONNECTIVITY_CHECK_HOST = 'nmcheck.gnome.org';
|
||||
const CONNECTIVITY_CHECK_URI = 'http://' + CONNECTIVITY_CHECK_HOST;
|
||||
const CONNECTIVITY_RECHECK_RATELIMIT_TIMEOUT = 30 * GLib.USEC_PER_SEC;
|
||||
|
||||
const HelperDBusInterface = '<node> \
|
||||
<interface name="org.gnome.Shell.PortalHelper"> \
|
||||
<method name="Authenticate"> \
|
||||
<arg type="o" direction="in" name="connection" /> \
|
||||
<arg type="s" direction="in" name="url" /> \
|
||||
<arg type="u" direction="in" name="timestamp" /> \
|
||||
</method> \
|
||||
<method name="Close"> \
|
||||
<arg type="o" direction="in" name="connection" /> \
|
||||
</method> \
|
||||
<method name="Refresh"> \
|
||||
<arg type="o" direction="in" name="connection" /> \
|
||||
</method> \
|
||||
<signal name="Done"> \
|
||||
<arg type="o" name="connection" /> \
|
||||
<arg type="u" name="result" /> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const HelperDBusInterface = `
|
||||
<node>
|
||||
<interface name="org.gnome.Shell.PortalHelper">
|
||||
<method name="Authenticate">
|
||||
<arg type="o" direction="in" name="connection" />
|
||||
<arg type="s" direction="in" name="url" />
|
||||
<arg type="u" direction="in" name="timestamp" />
|
||||
</method>
|
||||
<method name="Close">
|
||||
<arg type="o" direction="in" name="connection" />
|
||||
</method>
|
||||
<method name="Refresh">
|
||||
<arg type="o" direction="in" name="connection" />
|
||||
</method>
|
||||
<signal name="Done">
|
||||
<arg type="o" name="connection" />
|
||||
<arg type="u" name="result" />
|
||||
</signal>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
var PortalHeaderBar = new Lang.Class({
|
||||
Name: 'PortalHeaderBar',
|
||||
Extends: Gtk.HeaderBar,
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this.parent({ show_close_button: true });
|
||||
|
||||
// See ephy-title-box.c in epiphany for the layout
|
||||
@@ -92,11 +93,11 @@ var PortalHeaderBar = new Lang.Class({
|
||||
vbox.show_all();
|
||||
},
|
||||
|
||||
setSubtitle: function(label) {
|
||||
setSubtitle(label) {
|
||||
this.subtitleLabel.set_text(label);
|
||||
},
|
||||
|
||||
setSecurityIcon: function(securityLevel) {
|
||||
setSecurityIcon(securityLevel) {
|
||||
switch (securityLevel) {
|
||||
case PortalHelperSecurityLevel.NOT_YET_DETERMINED:
|
||||
this._lockImage.hide();
|
||||
@@ -119,10 +120,10 @@ var PortalWindow = new Lang.Class({
|
||||
Name: 'PortalWindow',
|
||||
Extends: Gtk.ApplicationWindow,
|
||||
|
||||
_init: function(application, url, timestamp, doneCallback) {
|
||||
_init(application, url, timestamp, doneCallback) {
|
||||
this.parent({ application: application });
|
||||
|
||||
this.connect('delete-event', Lang.bind(this, this.destroyWindow));
|
||||
this.connect('delete-event', this.destroyWindow.bind(this));
|
||||
this._headerBar = new PortalHeaderBar();
|
||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.NOT_YET_DETERMINED);
|
||||
this.set_titlebar(this._headerBar);
|
||||
@@ -146,12 +147,12 @@ var PortalWindow = new Lang.Class({
|
||||
this._webContext.set_network_proxy_settings(WebKit.NetworkProxyMode.NO_PROXY, null);
|
||||
|
||||
this._webView = WebKit.WebView.new_with_context(this._webContext);
|
||||
this._webView.connect('decide-policy', Lang.bind(this, this._onDecidePolicy));
|
||||
this._webView.connect('load-changed', Lang.bind(this, this._onLoadChanged));
|
||||
this._webView.connect('insecure-content-detected', Lang.bind(this, this._onInsecureContentDetected));
|
||||
this._webView.connect('load-failed-with-tls-errors', Lang.bind(this, this._onLoadFailedWithTlsErrors));
|
||||
this._webView.connect('decide-policy', this._onDecidePolicy.bind(this));
|
||||
this._webView.connect('load-changed', this._onLoadChanged.bind(this));
|
||||
this._webView.connect('insecure-content-detected', this._onInsecureContentDetected.bind(this));
|
||||
this._webView.connect('load-failed-with-tls-errors', this._onLoadFailedWithTlsErrors.bind(this));
|
||||
this._webView.load_uri(url);
|
||||
this._webView.connect('notify::uri', Lang.bind(this, this._syncUri));
|
||||
this._webView.connect('notify::uri', this._syncUri.bind(this));
|
||||
this._syncUri();
|
||||
|
||||
this.add(this._webView);
|
||||
@@ -163,11 +164,11 @@ var PortalWindow = new Lang.Class({
|
||||
this.application.set_accels_for_action('app.quit', ['<Primary>q', '<Primary>w']);
|
||||
},
|
||||
|
||||
destroyWindow: function() {
|
||||
destroyWindow() {
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
_syncUri: function() {
|
||||
_syncUri() {
|
||||
let uri = this._webView.uri;
|
||||
if (uri)
|
||||
this._headerBar.setSubtitle(GLib.uri_unescape_string(uri, null));
|
||||
@@ -175,12 +176,12 @@ var PortalWindow = new Lang.Class({
|
||||
this._headerBar.setSubtitle('');
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
refresh() {
|
||||
this._everSeenRedirect = false;
|
||||
this._webView.load_uri(this._originalUrl);
|
||||
},
|
||||
|
||||
vfunc_delete_event: function(event) {
|
||||
vfunc_delete_event(event) {
|
||||
if (this._recheckAtExit)
|
||||
this._doneCallback(PortalHelperResult.RECHECK);
|
||||
else
|
||||
@@ -188,7 +189,7 @@ var PortalWindow = new Lang.Class({
|
||||
return false;
|
||||
},
|
||||
|
||||
_onLoadChanged: function(view, loadEvent) {
|
||||
_onLoadChanged(view, loadEvent) {
|
||||
if (loadEvent == WebKit.LoadEvent.STARTED) {
|
||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.NOT_YET_DETERMINED);
|
||||
} else if (loadEvent == WebKit.LoadEvent.COMMITTED) {
|
||||
@@ -202,11 +203,11 @@ var PortalWindow = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_onInsecureContentDetected: function () {
|
||||
_onInsecureContentDetected() {
|
||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
||||
},
|
||||
|
||||
_onLoadFailedWithTlsErrors: function (view, failingURI, certificate, errors) {
|
||||
_onLoadFailedWithTlsErrors(view, failingURI, certificate, errors) {
|
||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
||||
let uri = new Soup.URI(failingURI);
|
||||
this._webContext.allow_tls_certificate_for_host(certificate, uri.get_host());
|
||||
@@ -214,7 +215,7 @@ var PortalWindow = new Lang.Class({
|
||||
return true;
|
||||
},
|
||||
|
||||
_onDecidePolicy: function(view, decision, type) {
|
||||
_onDecidePolicy(view, decision, type) {
|
||||
if (type == WebKit.PolicyDecisionType.NEW_WINDOW_ACTION) {
|
||||
let navigationAction = decision.get_navigation_action();
|
||||
if (navigationAction.is_user_gesture()) {
|
||||
@@ -286,7 +287,7 @@ var WebPortalHelper = new Lang.Class({
|
||||
Name: 'WebPortalHelper',
|
||||
Extends: Gtk.Application,
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this.parent({ application_id: 'org.gnome.Shell.PortalHelper',
|
||||
flags: Gio.ApplicationFlags.IS_SERVICE,
|
||||
inactivity_timeout: 30000 });
|
||||
@@ -299,30 +300,30 @@ var WebPortalHelper = new Lang.Class({
|
||||
this.add_action(action);
|
||||
},
|
||||
|
||||
vfunc_dbus_register: function(connection, path) {
|
||||
vfunc_dbus_register(connection, path) {
|
||||
this._dbusImpl.export(connection, path);
|
||||
this.parent(connection, path);
|
||||
return true;
|
||||
},
|
||||
|
||||
vfunc_dbus_unregister: function(connection, path) {
|
||||
vfunc_dbus_unregister(connection, path) {
|
||||
this._dbusImpl.unexport_from_connection(connection);
|
||||
this.parent(connection, path);
|
||||
},
|
||||
|
||||
vfunc_activate: function() {
|
||||
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: function(connection, url, timestamp) {
|
||||
Authenticate(connection, url, timestamp) {
|
||||
this._queue.push({ connection: connection, url: url, timestamp: timestamp });
|
||||
|
||||
this._processQueue();
|
||||
},
|
||||
|
||||
Close: function(connection) {
|
||||
Close(connection) {
|
||||
for (let i = 0; i < this._queue.length; i++) {
|
||||
let obj = this._queue[i];
|
||||
|
||||
@@ -337,7 +338,7 @@ var WebPortalHelper = new Lang.Class({
|
||||
this._processQueue();
|
||||
},
|
||||
|
||||
Refresh: function(connection) {
|
||||
Refresh(connection) {
|
||||
for (let i = 0; i < this._queue.length; i++) {
|
||||
let obj = this._queue[i];
|
||||
|
||||
@@ -349,7 +350,7 @@ var WebPortalHelper = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_processQueue: function() {
|
||||
_processQueue() {
|
||||
if (this._queue.length == 0)
|
||||
return;
|
||||
|
||||
@@ -357,9 +358,9 @@ var WebPortalHelper = new Lang.Class({
|
||||
if (top.window != null)
|
||||
return;
|
||||
|
||||
top.window = new PortalWindow(this, top.url, top.timestamp, Lang.bind(this, function(result) {
|
||||
top.window = new PortalWindow(this, top.url, top.timestamp, result => {
|
||||
this._dbusImpl.emit_signal('Done', new GLib.Variant('(ou)', [top.connection, result]));
|
||||
}));
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
11
js/prefs-resources.gresource.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gnome/shell">
|
||||
<file>extensionPrefs/main.js</file>
|
||||
|
||||
<file>misc/config.js</file>
|
||||
<file>misc/extensionUtils.js</file>
|
||||
<file>misc/fileUtils.js</file>
|
||||
<file>misc/params.js</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
@@ -10,27 +10,29 @@ const CheckBox = imports.ui.checkBox;
|
||||
const Dialog = imports.ui.dialog;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
|
||||
const RequestIface = '<node> \
|
||||
<interface name="org.freedesktop.impl.portal.Request"> \
|
||||
<method name="Close"/> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const RequestIface = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.impl.portal.Request">
|
||||
<method name="Close"/>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const AccessIface = '<node> \
|
||||
<interface name="org.freedesktop.impl.portal.Access"> \
|
||||
<method name="AccessDialog"> \
|
||||
<arg type="o" name="handle" direction="in"/> \
|
||||
<arg type="s" name="app_id" direction="in"/> \
|
||||
<arg type="s" name="parent_window" direction="in"/> \
|
||||
<arg type="s" name="title" direction="in"/> \
|
||||
<arg type="s" name="subtitle" direction="in"/> \
|
||||
<arg type="s" name="body" direction="in"/> \
|
||||
<arg type="a{sv}" name="options" direction="in"/> \
|
||||
<arg type="u" name="response" direction="out"/> \
|
||||
<arg type="a{sv}" name="results" direction="out"/> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const AccessIface = `
|
||||
<node>
|
||||
<interface name="org.freedesktop.impl.portal.Access">
|
||||
<method name="AccessDialog">
|
||||
<arg type="o" name="handle" direction="in"/>
|
||||
<arg type="s" name="app_id" direction="in"/>
|
||||
<arg type="s" name="parent_window" direction="in"/>
|
||||
<arg type="s" name="title" direction="in"/>
|
||||
<arg type="s" name="subtitle" direction="in"/>
|
||||
<arg type="s" name="body" direction="in"/>
|
||||
<arg type="a{sv}" name="options" direction="in"/>
|
||||
<arg type="u" name="response" direction="out"/>
|
||||
<arg type="a{sv}" name="results" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
var DialogResponse = {
|
||||
OK: 0,
|
||||
@@ -42,7 +44,7 @@ var AccessDialog = new Lang.Class({
|
||||
Name: 'AccessDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
|
||||
_init: function(invocation, handle, title, subtitle, body, options) {
|
||||
_init(invocation, handle, title, subtitle, body, options) {
|
||||
this.parent({ styleClass: 'access-dialog' });
|
||||
|
||||
this._invocation = invocation;
|
||||
@@ -57,7 +59,7 @@ var AccessDialog = new Lang.Class({
|
||||
this._buildLayout(title, subtitle, body, options);
|
||||
},
|
||||
|
||||
_buildLayout: function(title, subtitle, body, options) {
|
||||
_buildLayout(title, subtitle, body, options) {
|
||||
// No support for non-modal system dialogs, so ignore the option
|
||||
//let modal = options['modal'] || true;
|
||||
let denyLabel = options['deny_label'] || _("Deny Access");
|
||||
@@ -97,14 +99,14 @@ var AccessDialog = new Lang.Class({
|
||||
}});
|
||||
},
|
||||
|
||||
open: function() {
|
||||
open() {
|
||||
this.parent();
|
||||
|
||||
let connection = this._invocation.get_connection();
|
||||
this._requestExported = this._request.export(connection, this._handle);
|
||||
},
|
||||
|
||||
CloseAsync: function(invocation, params) {
|
||||
CloseAsync(invocation, params) {
|
||||
if (this._invocation.get_sender() != invocation.get_sender()) {
|
||||
invocation.return_error_literal(Gio.DBusError,
|
||||
Gio.DBusError.ACCESS_DENIED,
|
||||
@@ -115,7 +117,7 @@ var AccessDialog = new Lang.Class({
|
||||
this._sendResponse(DialogResponse.CLOSED);
|
||||
},
|
||||
|
||||
_sendResponse: function(response) {
|
||||
_sendResponse(response) {
|
||||
if (this._requestExported)
|
||||
this._request.unexport();
|
||||
this._requestExported = false;
|
||||
@@ -140,7 +142,7 @@ var AccessDialog = new Lang.Class({
|
||||
var AccessDialogDBus = new Lang.Class({
|
||||
Name: 'AccessDialogDBus',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._accessDialog = null;
|
||||
|
||||
this._windowTracker = Shell.WindowTracker.get_default();
|
||||
@@ -151,7 +153,7 @@ var AccessDialogDBus = new Lang.Class({
|
||||
Gio.DBus.session.own_name('org.freedesktop.impl.portal.desktop.gnome', Gio.BusNameOwnerFlags.REPLACE, null, null);
|
||||
},
|
||||
|
||||
AccessDialogAsync: function(params, invocation) {
|
||||
AccessDialogAsync(params, invocation) {
|
||||
if (this._accessDialog) {
|
||||
invocation.return_error_literal(Gio.DBusError,
|
||||
Gio.DBusError.LIMITS_EXCEEDED,
|
||||
|
||||
207
js/ui/altTab.js
@@ -62,7 +62,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
Name: 'AppSwitcherPopup',
|
||||
Extends: SwitcherPopup.SwitcherPopup,
|
||||
|
||||
_init : function() {
|
||||
_init() {
|
||||
this.parent();
|
||||
|
||||
this._thumbnails = null;
|
||||
@@ -80,7 +80,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
this._items = this._switcherList.icons;
|
||||
},
|
||||
|
||||
_allocate: function (actor, box, flags) {
|
||||
_allocate(actor, box, flags) {
|
||||
this.parent(actor, box, flags);
|
||||
|
||||
// Allocate the thumbnails
|
||||
@@ -118,7 +118,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_initialSelection: function(backward, binding) {
|
||||
_initialSelection(backward, binding) {
|
||||
if (binding == 'switch-group') {
|
||||
if (backward) {
|
||||
this._select(0, this._items[0].cachedWindows.length - 1);
|
||||
@@ -141,14 +141,14 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_nextWindow : function() {
|
||||
_nextWindow() {
|
||||
// We actually want the second window if we're in the unset state
|
||||
if (this._currentWindow == -1)
|
||||
this._currentWindow = 0;
|
||||
return SwitcherPopup.mod(this._currentWindow + 1,
|
||||
this._items[this._selectedIndex].cachedWindows.length);
|
||||
},
|
||||
_previousWindow : function() {
|
||||
_previousWindow() {
|
||||
// Also assume second window here
|
||||
if (this._currentWindow == -1)
|
||||
this._currentWindow = 1;
|
||||
@@ -156,7 +156,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
this._items[this._selectedIndex].cachedWindows.length);
|
||||
},
|
||||
|
||||
_closeAppWindow: function(appIndex, windowIndex) {
|
||||
_closeAppWindow(appIndex, windowIndex) {
|
||||
let appIcon = this._items[appIndex];
|
||||
if (!appIcon)
|
||||
return;
|
||||
@@ -168,7 +168,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
window.delete(global.get_current_time());
|
||||
},
|
||||
|
||||
_quitApplication: function(appIndex) {
|
||||
_quitApplication(appIndex) {
|
||||
let appIcon = this._items[appIndex];
|
||||
if (!appIcon)
|
||||
return;
|
||||
@@ -176,7 +176,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
appIcon.app.request_quit();
|
||||
},
|
||||
|
||||
_keyPressHandler: function(keysym, action) {
|
||||
_keyPressHandler(keysym, action) {
|
||||
if (action == Meta.KeyBindingAction.SWITCH_GROUP) {
|
||||
if (!this._thumbnailsFocused)
|
||||
this._select(this._selectedIndex, 0);
|
||||
@@ -215,7 +215,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
return Clutter.EVENT_STOP;
|
||||
},
|
||||
|
||||
_scrollHandler: function(direction) {
|
||||
_scrollHandler(direction) {
|
||||
if (direction == Clutter.ScrollDirection.UP) {
|
||||
if (this._thumbnailsFocused) {
|
||||
if (this._currentWindow == 0 || this._currentWindow == -1)
|
||||
@@ -245,7 +245,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_itemActivatedHandler: function(n) {
|
||||
_itemActivatedHandler(n) {
|
||||
// If the user clicks on the selected app, activate the
|
||||
// selected window; otherwise (eg, they click on an app while
|
||||
// !mouseActive) activate the clicked-on app.
|
||||
@@ -255,24 +255,24 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
this._select(n);
|
||||
},
|
||||
|
||||
_itemEnteredHandler: function(n) {
|
||||
_itemEnteredHandler(n) {
|
||||
this._select(n);
|
||||
},
|
||||
|
||||
_windowActivated : function(thumbnailList, n) {
|
||||
_windowActivated(thumbnailList, n) {
|
||||
let appIcon = this._items[this._selectedIndex];
|
||||
Main.activateWindow(appIcon.cachedWindows[n]);
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
_windowEntered : function(thumbnailList, n) {
|
||||
_windowEntered(thumbnailList, n) {
|
||||
if (!this.mouseActive)
|
||||
return;
|
||||
|
||||
this._select(this._selectedIndex, n);
|
||||
},
|
||||
|
||||
_windowRemoved : function(thumbnailList, n) {
|
||||
_windowRemoved(thumbnailList, n) {
|
||||
let appIcon = this._items[this._selectedIndex];
|
||||
if (!appIcon)
|
||||
return;
|
||||
@@ -283,7 +283,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_finish : function(timestamp) {
|
||||
_finish(timestamp) {
|
||||
let appIcon = this._items[this._selectedIndex];
|
||||
if (this._currentWindow < 0)
|
||||
appIcon.app.activate_window(appIcon.cachedWindows[0], timestamp);
|
||||
@@ -293,7 +293,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
this.parent();
|
||||
},
|
||||
|
||||
_onDestroy : function() {
|
||||
_onDestroy() {
|
||||
this.parent();
|
||||
|
||||
if (this._thumbnails)
|
||||
@@ -327,7 +327,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
* then @app will be highlighted, and @window outlined, and the
|
||||
* app list will have the keyboard focus.
|
||||
*/
|
||||
_select : function(app, window, forceAppFocus) {
|
||||
_select(app, window, forceAppFocus) {
|
||||
if (app != this._selectedIndex || window == null) {
|
||||
if (this._thumbnails)
|
||||
this._destroyThumbnails();
|
||||
@@ -353,12 +353,12 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
!forceAppFocus) {
|
||||
this._thumbnailTimeoutId = Mainloop.timeout_add (
|
||||
THUMBNAIL_POPUP_TIME,
|
||||
Lang.bind(this, this._timeoutPopupThumbnails));
|
||||
this._timeoutPopupThumbnails.bind(this));
|
||||
GLib.Source.set_name_by_id(this._thumbnailTimeoutId, '[gnome-shell] this._timeoutPopupThumbnails');
|
||||
}
|
||||
},
|
||||
|
||||
_timeoutPopupThumbnails: function() {
|
||||
_timeoutPopupThumbnails() {
|
||||
if (!this._thumbnails)
|
||||
this._createThumbnails();
|
||||
this._thumbnailTimeoutId = 0;
|
||||
@@ -366,27 +366,27 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
return GLib.SOURCE_REMOVE;
|
||||
},
|
||||
|
||||
_destroyThumbnails : function() {
|
||||
_destroyThumbnails() {
|
||||
let thumbnailsActor = this._thumbnails.actor;
|
||||
Tweener.addTween(thumbnailsActor,
|
||||
{ opacity: 0,
|
||||
time: THUMBNAIL_FADE_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: Lang.bind(this, function() {
|
||||
thumbnailsActor.destroy();
|
||||
this.thumbnailsVisible = false;
|
||||
})
|
||||
onComplete: () => {
|
||||
thumbnailsActor.destroy();
|
||||
this.thumbnailsVisible = false;
|
||||
}
|
||||
});
|
||||
this._thumbnails = null;
|
||||
if (this._switcherList._items[this._selectedIndex])
|
||||
this._switcherList._items[this._selectedIndex].remove_accessible_state (Atk.StateType.EXPANDED);
|
||||
},
|
||||
|
||||
_createThumbnails : function() {
|
||||
_createThumbnails() {
|
||||
this._thumbnails = new ThumbnailList (this._items[this._selectedIndex].cachedWindows);
|
||||
this._thumbnails.connect('item-activated', Lang.bind(this, this._windowActivated));
|
||||
this._thumbnails.connect('item-entered', Lang.bind(this, this._windowEntered));
|
||||
this._thumbnails.connect('item-removed', Lang.bind(this, this._windowRemoved));
|
||||
this._thumbnails.connect('item-activated', this._windowActivated.bind(this));
|
||||
this._thumbnails.connect('item-entered', this._windowEntered.bind(this));
|
||||
this._thumbnails.connect('item-removed', this._windowRemoved.bind(this));
|
||||
this._thumbnails.actor.connect('destroy', () => {
|
||||
this._thumbnails = null;
|
||||
this._thumbnailsFocused = false;
|
||||
@@ -403,7 +403,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
{ opacity: 255,
|
||||
time: THUMBNAIL_FADE_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: Lang.bind(this, function () { this.thumbnailsVisible = true; })
|
||||
onComplete: () => { this.thumbnailsVisible = true; }
|
||||
});
|
||||
|
||||
this._switcherList._items[this._selectedIndex].add_accessible_state (Atk.StateType.EXPANDED);
|
||||
@@ -413,7 +413,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
var CyclerHighlight = new Lang.Class({
|
||||
Name: 'CyclerHighlight',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._window = null;
|
||||
|
||||
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||
@@ -431,8 +431,8 @@ var CyclerHighlight = new Lang.Class({
|
||||
this.actor.add_constraint(constraint);
|
||||
|
||||
this.actor.connect('notify::allocation',
|
||||
Lang.bind(this, this._onAllocationChanged));
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
this._onAllocationChanged.bind(this));
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
},
|
||||
|
||||
set window(w) {
|
||||
@@ -453,7 +453,7 @@ var CyclerHighlight = new Lang.Class({
|
||||
this._clone.source = windowActor;
|
||||
},
|
||||
|
||||
_onAllocationChanged: function() {
|
||||
_onAllocationChanged() {
|
||||
if (!this._window) {
|
||||
this._highlight.set_size(0, 0);
|
||||
this._highlight.hide();
|
||||
@@ -466,7 +466,7 @@ var CyclerHighlight = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
_onDestroy() {
|
||||
this.window = null;
|
||||
}
|
||||
});
|
||||
@@ -476,7 +476,7 @@ var CyclerPopup = new Lang.Class({
|
||||
Extends: SwitcherPopup.SwitcherPopup,
|
||||
Abstract: true,
|
||||
|
||||
_init : function() {
|
||||
_init() {
|
||||
this.parent();
|
||||
|
||||
this._items = this._getWindows();
|
||||
@@ -490,19 +490,20 @@ var CyclerPopup = new Lang.Class({
|
||||
// We don't show an actual popup, so just provide what SwitcherPopup
|
||||
// expects instead of inheriting from SwitcherList
|
||||
this._switcherList = { actor: new St.Widget(),
|
||||
highlight: Lang.bind(this, this._highlightItem),
|
||||
connect: function() {} };
|
||||
highlight: this._highlightItem.bind(this),
|
||||
connect() {} };
|
||||
},
|
||||
|
||||
_highlightItem: function(index, justOutline) {
|
||||
_highlightItem(index, justOutline) {
|
||||
this._highlight.window = this._items[index];
|
||||
global.window_group.set_child_above_sibling(this._highlight.actor, null);
|
||||
},
|
||||
|
||||
_finish: function() {
|
||||
_finish() {
|
||||
let window = this._items[this._selectedIndex];
|
||||
let ws = window.get_workspace();
|
||||
let activeWs = global.screen.get_active_workspace();
|
||||
let workspaceManager = global.workspace_manager;
|
||||
let activeWs = workspaceManager.get_active_workspace();
|
||||
|
||||
if (window.minimized) {
|
||||
Main.wm.skipNextEffect(window.get_compositor_private());
|
||||
@@ -524,7 +525,7 @@ var CyclerPopup = new Lang.Class({
|
||||
this.parent();
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
_onDestroy() {
|
||||
this._highlight.actor.destroy();
|
||||
|
||||
this.parent();
|
||||
@@ -536,12 +537,12 @@ var GroupCyclerPopup = new Lang.Class({
|
||||
Name: 'GroupCyclerPopup',
|
||||
Extends: CyclerPopup,
|
||||
|
||||
_getWindows: function() {
|
||||
_getWindows() {
|
||||
let app = Shell.WindowTracker.get_default().focus_app;
|
||||
return app ? app.get_windows() : [];
|
||||
},
|
||||
|
||||
_keyPressHandler: function(keysym, action) {
|
||||
_keyPressHandler(keysym, action) {
|
||||
if (action == Meta.KeyBindingAction.CYCLE_GROUP)
|
||||
this._select(this._next());
|
||||
else if (action == Meta.KeyBindingAction.CYCLE_GROUP_BACKWARD)
|
||||
@@ -557,7 +558,7 @@ var WindowSwitcherPopup = new Lang.Class({
|
||||
Name: 'WindowSwitcherPopup',
|
||||
Extends: SwitcherPopup.SwitcherPopup,
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this.parent();
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
|
||||
|
||||
@@ -571,12 +572,19 @@ var WindowSwitcherPopup = new Lang.Class({
|
||||
this._items = this._switcherList.icons;
|
||||
},
|
||||
|
||||
_getWindowList: function() {
|
||||
let workspace = this._settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() : null;
|
||||
_getWindowList() {
|
||||
let workspace = null;
|
||||
|
||||
if (this._settings.get_boolean('current-workspace-only')) {
|
||||
let workspaceManager = global.workspace_manager;
|
||||
|
||||
workspace = workspaceManager.get_active_workspace();
|
||||
}
|
||||
|
||||
return getWindows(workspace);
|
||||
},
|
||||
|
||||
_closeWindow: function(windowIndex) {
|
||||
_closeWindow(windowIndex) {
|
||||
let windowIcon = this._items[windowIndex];
|
||||
if (!windowIcon)
|
||||
return;
|
||||
@@ -584,7 +592,7 @@ var WindowSwitcherPopup = new Lang.Class({
|
||||
windowIcon.window.delete(global.get_current_time());
|
||||
},
|
||||
|
||||
_keyPressHandler: function(keysym, action) {
|
||||
_keyPressHandler(keysym, action) {
|
||||
if (action == Meta.KeyBindingAction.SWITCH_WINDOWS) {
|
||||
this._select(this._next());
|
||||
} else if (action == Meta.KeyBindingAction.SWITCH_WINDOWS_BACKWARD) {
|
||||
@@ -603,7 +611,7 @@ var WindowSwitcherPopup = new Lang.Class({
|
||||
return Clutter.EVENT_STOP;
|
||||
},
|
||||
|
||||
_finish: function() {
|
||||
_finish() {
|
||||
Main.activateWindow(this._items[this._selectedIndex].window);
|
||||
|
||||
this.parent();
|
||||
@@ -614,17 +622,24 @@ var WindowCyclerPopup = new Lang.Class({
|
||||
Name: 'WindowCyclerPopup',
|
||||
Extends: CyclerPopup,
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
|
||||
this.parent();
|
||||
},
|
||||
|
||||
_getWindows: function() {
|
||||
let workspace = this._settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() : null;
|
||||
_getWindows() {
|
||||
let workspace = null;
|
||||
|
||||
if (this._settings.get_boolean('current-workspace-only')) {
|
||||
let workspaceManager = global.workspace_manager;
|
||||
|
||||
workspace = workspaceManager.get_active_workspace();
|
||||
}
|
||||
|
||||
return getWindows(workspace);
|
||||
},
|
||||
|
||||
_keyPressHandler: function(keysym, action) {
|
||||
_keyPressHandler(keysym, action) {
|
||||
if (action == Meta.KeyBindingAction.CYCLE_WINDOWS)
|
||||
this._select(this._next());
|
||||
else if (action == Meta.KeyBindingAction.CYCLE_WINDOWS_BACKWARD)
|
||||
@@ -639,7 +654,7 @@ var WindowCyclerPopup = new Lang.Class({
|
||||
var AppIcon = new Lang.Class({
|
||||
Name: 'AppIcon',
|
||||
|
||||
_init: function(app) {
|
||||
_init(app) {
|
||||
this.app = app;
|
||||
this.actor = new St.BoxLayout({ style_class: 'alt-tab-app',
|
||||
vertical: true });
|
||||
@@ -651,7 +666,7 @@ var AppIcon = new Lang.Class({
|
||||
this.actor.add(this.label, { x_fill: false });
|
||||
},
|
||||
|
||||
set_size: function(size) {
|
||||
set_size(size) {
|
||||
this.icon = this.app.create_icon_texture(size);
|
||||
this._iconBin.child = this.icon;
|
||||
}
|
||||
@@ -661,7 +676,7 @@ var AppSwitcher = new Lang.Class({
|
||||
Name: 'AppSwitcher',
|
||||
Extends: SwitcherPopup.SwitcherList,
|
||||
|
||||
_init : function(apps, altTabPopup) {
|
||||
_init(apps, altTabPopup) {
|
||||
this.parent(true);
|
||||
|
||||
this.icons = [];
|
||||
@@ -669,8 +684,14 @@ var AppSwitcher = new Lang.Class({
|
||||
|
||||
let windowTracker = Shell.WindowTracker.get_default();
|
||||
let settings = new Gio.Settings({ schema_id: 'org.gnome.shell.app-switcher' });
|
||||
let workspace = settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace()
|
||||
: null;
|
||||
|
||||
let workspace = null;
|
||||
if (settings.get_boolean('current-workspace-only')) {
|
||||
let workspaceManager = global.workspace_manager;
|
||||
|
||||
workspace = workspaceManager.get_active_workspace();
|
||||
}
|
||||
|
||||
let allWindows = global.display.get_tab_list(Meta.TabList.NORMAL, workspace);
|
||||
|
||||
// Construct the AppIcons, add to the popup
|
||||
@@ -678,9 +699,9 @@ var AppSwitcher = new Lang.Class({
|
||||
let appIcon = new AppIcon(apps[i]);
|
||||
// Cache the window list now; we don't handle dynamic changes here,
|
||||
// and we don't want to be continually retrieving it
|
||||
appIcon.cachedWindows = allWindows.filter(function(w) {
|
||||
return windowTracker.get_window_app (w) == appIcon.app;
|
||||
});
|
||||
appIcon.cachedWindows = allWindows.filter(
|
||||
w => windowTracker.get_window_app (w) == appIcon.app
|
||||
);
|
||||
if (appIcon.cachedWindows.length > 0)
|
||||
this._addIcon(appIcon);
|
||||
}
|
||||
@@ -690,10 +711,10 @@ var AppSwitcher = new Lang.Class({
|
||||
this._altTabPopup = altTabPopup;
|
||||
this._mouseTimeOutId = 0;
|
||||
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
_onDestroy() {
|
||||
if (this._mouseTimeOutId != 0)
|
||||
Mainloop.source_remove(this._mouseTimeOutId);
|
||||
|
||||
@@ -702,7 +723,7 @@ var AppSwitcher = new Lang.Class({
|
||||
});
|
||||
},
|
||||
|
||||
_setIconSize: function() {
|
||||
_setIconSize() {
|
||||
let j = 0;
|
||||
while(this._items.length > 1 && this._items[j].style_class != 'item-box') {
|
||||
j++;
|
||||
@@ -721,9 +742,7 @@ var AppSwitcher = new Lang.Class({
|
||||
let availWidth = primary.width - parentPadding - this.actor.get_theme_node().get_horizontal_padding();
|
||||
|
||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
let iconSizes = baseIconSizes.map(function(s) {
|
||||
return s * scaleFactor;
|
||||
});
|
||||
let iconSizes = baseIconSizes.map(s => s * scaleFactor);
|
||||
|
||||
if (this._items.length == 1) {
|
||||
this._iconSize = baseIconSizes[0];
|
||||
@@ -744,12 +763,12 @@ var AppSwitcher = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_getPreferredHeight: function (actor, forWidth, alloc) {
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
this._setIconSize();
|
||||
this.parent(actor, forWidth, alloc);
|
||||
},
|
||||
|
||||
_allocate: function (actor, box, flags) {
|
||||
_allocate(actor, box, flags) {
|
||||
// Allocate the main list items
|
||||
this.parent(actor, box, flags);
|
||||
|
||||
@@ -770,22 +789,22 @@ var AppSwitcher = new Lang.Class({
|
||||
|
||||
// We override SwitcherList's _onItemEnter method to delay
|
||||
// activation when the thumbnail list is open
|
||||
_onItemEnter: function (index) {
|
||||
_onItemEnter(index) {
|
||||
if (this._mouseTimeOutId != 0)
|
||||
Mainloop.source_remove(this._mouseTimeOutId);
|
||||
if (this._altTabPopup.thumbnailsVisible) {
|
||||
this._mouseTimeOutId = Mainloop.timeout_add(APP_ICON_HOVER_TIMEOUT,
|
||||
Lang.bind(this, function () {
|
||||
this._enterItem(index);
|
||||
this._mouseTimeOutId = 0;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
}));
|
||||
() => {
|
||||
this._enterItem(index);
|
||||
this._mouseTimeOutId = 0;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(this._mouseTimeOutId, '[gnome-shell] this._enterItem');
|
||||
} else
|
||||
this._itemEntered(index);
|
||||
},
|
||||
|
||||
_enterItem: function(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))
|
||||
@@ -799,7 +818,7 @@ var AppSwitcher = new Lang.Class({
|
||||
// in justOutline mode). Apps with multiple windows will normally
|
||||
// show a dim arrow, but show a bright arrow when they are
|
||||
// highlighted.
|
||||
highlight : function(n, justOutline) {
|
||||
highlight(n, justOutline) {
|
||||
if (this.icons[this._curApp]) {
|
||||
if (this.icons[this._curApp].cachedWindows.length == 1)
|
||||
this._arrows[this._curApp].hide();
|
||||
@@ -818,7 +837,7 @@ var AppSwitcher = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_addIcon : function(appIcon) {
|
||||
_addIcon(appIcon) {
|
||||
this.icons.push(appIcon);
|
||||
let item = this.addItem(appIcon.actor, appIcon.label);
|
||||
|
||||
@@ -829,7 +848,7 @@ var AppSwitcher = new Lang.Class({
|
||||
|
||||
let n = this._arrows.length;
|
||||
let arrow = new St.DrawingArea({ style_class: 'switcher-arrow' });
|
||||
arrow.connect('repaint', function() { SwitcherPopup.drawArrow(arrow, St.Side.BOTTOM); });
|
||||
arrow.connect('repaint', () => { SwitcherPopup.drawArrow(arrow, St.Side.BOTTOM); });
|
||||
this._list.add_actor(arrow);
|
||||
this._arrows.push(arrow);
|
||||
|
||||
@@ -839,7 +858,7 @@ var AppSwitcher = new Lang.Class({
|
||||
item.add_accessible_state (Atk.StateType.EXPANDABLE);
|
||||
},
|
||||
|
||||
_removeIcon: function(app) {
|
||||
_removeIcon(app) {
|
||||
let index = this.icons.findIndex(icon => {
|
||||
return icon.app == app;
|
||||
});
|
||||
@@ -855,7 +874,7 @@ var ThumbnailList = new Lang.Class({
|
||||
Name: 'ThumbnailList',
|
||||
Extends: SwitcherPopup.SwitcherList,
|
||||
|
||||
_init : function(windows) {
|
||||
_init(windows) {
|
||||
this.parent(false);
|
||||
|
||||
this._labels = new Array();
|
||||
@@ -891,7 +910,7 @@ var ThumbnailList = new Lang.Class({
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
},
|
||||
|
||||
addClones : function (availHeight) {
|
||||
addClones(availHeight) {
|
||||
if (!this._thumbnailBins.length)
|
||||
return;
|
||||
let totalPadding = this._items[0].get_theme_node().get_horizontal_padding() + this._items[0].get_theme_node().get_vertical_padding();
|
||||
@@ -914,7 +933,9 @@ var ThumbnailList = new Lang.Class({
|
||||
this._thumbnailBins[i].set_height(binHeight);
|
||||
this._thumbnailBins[i].add_actor(clone);
|
||||
|
||||
clone._destroyId = mutterWindow.connect('destroy', Lang.bind(this, this._removeThumbnail, clone));
|
||||
clone._destroyId = mutterWindow.connect('destroy', source => {
|
||||
this._removeThumbnail(source, clone);
|
||||
});
|
||||
this._clones.push(clone);
|
||||
}
|
||||
|
||||
@@ -922,7 +943,7 @@ var ThumbnailList = new Lang.Class({
|
||||
this._thumbnailBins = new Array();
|
||||
},
|
||||
|
||||
_removeThumbnail: function(source, clone) {
|
||||
_removeThumbnail(source, clone) {
|
||||
let index = this._clones.indexOf(clone);
|
||||
if (index === -1)
|
||||
return;
|
||||
@@ -938,7 +959,7 @@ var ThumbnailList = new Lang.Class({
|
||||
this.actor.destroy();
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
_onDestroy() {
|
||||
this._clones.forEach(clone => {
|
||||
if (clone.source)
|
||||
clone.source.disconnect(clone._destroyId);
|
||||
@@ -950,7 +971,7 @@ var ThumbnailList = new Lang.Class({
|
||||
var WindowIcon = new Lang.Class({
|
||||
Name: 'WindowIcon',
|
||||
|
||||
_init: function(window, mode) {
|
||||
_init(window, mode) {
|
||||
this.window = window;
|
||||
|
||||
this.actor = new St.BoxLayout({ style_class: 'alt-tab-app',
|
||||
@@ -993,7 +1014,7 @@ var WindowIcon = new Lang.Class({
|
||||
this._icon.set_size(size * scaleFactor, size * scaleFactor);
|
||||
},
|
||||
|
||||
_createAppIcon: function(app, size) {
|
||||
_createAppIcon(app, size) {
|
||||
let appIcon = app ? app.create_icon_texture(size)
|
||||
: new St.Icon({ icon_name: 'icon-missing',
|
||||
icon_size: size });
|
||||
@@ -1008,7 +1029,7 @@ var WindowList = new Lang.Class({
|
||||
Name: 'WindowList',
|
||||
Extends: SwitcherPopup.SwitcherList,
|
||||
|
||||
_init : function(windows, mode) {
|
||||
_init(windows, mode) {
|
||||
this.parent(true);
|
||||
|
||||
this._label = new St.Label({ x_align: Clutter.ActorAlign.CENTER,
|
||||
@@ -1033,13 +1054,13 @@ var WindowList = new Lang.Class({
|
||||
this.actor.connect('destroy', () => { this._onDestroy(); });
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
_onDestroy() {
|
||||
this.icons.forEach(icon => {
|
||||
icon.window.disconnect(icon._unmanagedSignalId);
|
||||
});
|
||||
},
|
||||
|
||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
this.parent(actor, forWidth, alloc);
|
||||
|
||||
let spacing = this.actor.get_theme_node().get_padding(St.Side.BOTTOM);
|
||||
@@ -1048,7 +1069,7 @@ var WindowList = new Lang.Class({
|
||||
alloc.natural_size += labelNat + spacing;
|
||||
},
|
||||
|
||||
_allocateTop: function(actor, box, flags) {
|
||||
_allocateTop(actor, box, flags) {
|
||||
let childBox = new Clutter.ActorBox();
|
||||
childBox.x1 = box.x1;
|
||||
childBox.x2 = box.x2;
|
||||
@@ -1061,13 +1082,13 @@ var WindowList = new Lang.Class({
|
||||
this.parent(actor, box, flags);
|
||||
},
|
||||
|
||||
highlight: function(index, justOutline) {
|
||||
highlight(index, justOutline) {
|
||||
this.parent(index, justOutline);
|
||||
|
||||
this._label.set_text(index == -1 ? '' : this.icons[index].label.text);
|
||||
},
|
||||
|
||||
_removeWindow: function(window) {
|
||||
_removeWindow(window) {
|
||||
let index = this.icons.findIndex(icon => {
|
||||
return icon.window == window;
|
||||
});
|
||||
|
||||
@@ -12,9 +12,9 @@ var ANIMATED_ICON_UPDATE_TIMEOUT = 16;
|
||||
var Animation = new Lang.Class({
|
||||
Name: 'Animation',
|
||||
|
||||
_init: function(file, width, height, speed) {
|
||||
_init(file, width, height, speed) {
|
||||
this.actor = new St.Bin();
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this._speed = speed;
|
||||
|
||||
this._isLoaded = false;
|
||||
@@ -24,23 +24,23 @@ var Animation = new Lang.Class({
|
||||
|
||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
this._animations = St.TextureCache.get_default().load_sliced_image (file, width, height, scaleFactor,
|
||||
Lang.bind(this, this._animationsLoaded));
|
||||
this._animationsLoaded.bind(this));
|
||||
this.actor.set_child(this._animations);
|
||||
},
|
||||
|
||||
play: function() {
|
||||
play() {
|
||||
if (this._isLoaded && this._timeoutId == 0) {
|
||||
if (this._frame == 0)
|
||||
this._showFrame(0);
|
||||
|
||||
this._timeoutId = GLib.timeout_add(GLib.PRIORITY_LOW, this._speed, Lang.bind(this, this._update));
|
||||
this._timeoutId = GLib.timeout_add(GLib.PRIORITY_LOW, this._speed, this._update.bind(this));
|
||||
GLib.Source.set_name_by_id(this._timeoutId, '[gnome-shell] this._update');
|
||||
}
|
||||
|
||||
this._isPlaying = true;
|
||||
},
|
||||
|
||||
stop: function() {
|
||||
stop() {
|
||||
if (this._timeoutId > 0) {
|
||||
Mainloop.source_remove(this._timeoutId);
|
||||
this._timeoutId = 0;
|
||||
@@ -49,7 +49,7 @@ var Animation = new Lang.Class({
|
||||
this._isPlaying = false;
|
||||
},
|
||||
|
||||
_showFrame: function(frame) {
|
||||
_showFrame(frame) {
|
||||
let oldFrameActor = this._animations.get_child_at_index(this._frame);
|
||||
if (oldFrameActor)
|
||||
oldFrameActor.hide();
|
||||
@@ -61,19 +61,19 @@ var Animation = new Lang.Class({
|
||||
newFrameActor.show();
|
||||
},
|
||||
|
||||
_update: function() {
|
||||
_update() {
|
||||
this._showFrame(this._frame + 1);
|
||||
return GLib.SOURCE_CONTINUE;
|
||||
},
|
||||
|
||||
_animationsLoaded: function() {
|
||||
_animationsLoaded() {
|
||||
this._isLoaded = this._animations.get_n_children() > 0;
|
||||
|
||||
if (this._isPlaying)
|
||||
this.play();
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
_onDestroy() {
|
||||
this.stop();
|
||||
}
|
||||
});
|
||||
@@ -82,7 +82,7 @@ var AnimatedIcon = new Lang.Class({
|
||||
Name: 'AnimatedIcon',
|
||||
Extends: Animation,
|
||||
|
||||
_init: function(file, size) {
|
||||
_init(file, size) {
|
||||
this.parent(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -13,6 +13,7 @@ const RENAMED_DESKTOP_IDS = {
|
||||
'dconf-editor.desktop': 'ca.desrt.dconf-editor.desktop',
|
||||
'empathy.desktop': 'org.gnome.Empathy.desktop',
|
||||
'epiphany.desktop': 'org.gnome.Epiphany.desktop',
|
||||
'evolution.desktop': 'org.gnome.Evolution.desktop',
|
||||
'file-roller.desktop': 'org.gnome.FileRoller.desktop',
|
||||
'gcalctool.desktop': 'org.gnome.Calculator.desktop',
|
||||
'geary.desktop': 'org.gnome.Geary.desktop',
|
||||
@@ -34,6 +35,7 @@ const RENAMED_DESKTOP_IDS = {
|
||||
'gnome-screenshot.desktop': 'org.gnome.Screenshot.desktop',
|
||||
'gnome-software.desktop': 'org.gnome.Software.desktop',
|
||||
'gnome-terminal.desktop': 'org.gnome.Terminal.desktop',
|
||||
'gnome-tweaks.desktop': 'org.gnome.tweaks.desktop',
|
||||
'gnome-weather.desktop': 'org.gnome.Weather.Application.desktop',
|
||||
'gnomine.desktop': 'gnome-mines.desktop',
|
||||
'gnotravex.desktop': 'gnome-tetravex.desktop',
|
||||
@@ -49,24 +51,24 @@ var AppFavorites = new Lang.Class({
|
||||
|
||||
FAVORITE_APPS_KEY: 'favorite-apps',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._favorites = {};
|
||||
global.settings.connect('changed::' + this.FAVORITE_APPS_KEY, Lang.bind(this, this._onFavsChanged));
|
||||
global.settings.connect('changed::' + this.FAVORITE_APPS_KEY, this._onFavsChanged.bind(this));
|
||||
this.reload();
|
||||
},
|
||||
|
||||
_onFavsChanged: function() {
|
||||
_onFavsChanged() {
|
||||
this.reload();
|
||||
this.emit('changed');
|
||||
},
|
||||
|
||||
reload: function() {
|
||||
reload() {
|
||||
let ids = global.settings.get_strv(this.FAVORITE_APPS_KEY);
|
||||
let appSys = Shell.AppSystem.get_default();
|
||||
|
||||
// Map old desktop file names to the current ones
|
||||
let updated = false;
|
||||
ids = ids.map(function (id) {
|
||||
ids = ids.map(id => {
|
||||
let newId = RENAMED_DESKTOP_IDS[id];
|
||||
if (newId !== undefined &&
|
||||
appSys.lookup_app(newId) != null) {
|
||||
@@ -79,11 +81,8 @@ var AppFavorites = new Lang.Class({
|
||||
if (updated)
|
||||
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
|
||||
|
||||
let apps = ids.map(function (id) {
|
||||
return appSys.lookup_app(id);
|
||||
}).filter(function (app) {
|
||||
return app != null;
|
||||
});
|
||||
let apps = ids.map(id => appSys.lookup_app(id))
|
||||
.filter(app => app != null);
|
||||
this._favorites = {};
|
||||
for (let i = 0; i < apps.length; i++) {
|
||||
let app = apps[i];
|
||||
@@ -91,29 +90,29 @@ var AppFavorites = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_getIds: function() {
|
||||
_getIds() {
|
||||
let ret = [];
|
||||
for (let id in this._favorites)
|
||||
ret.push(id);
|
||||
return ret;
|
||||
},
|
||||
|
||||
getFavoriteMap: function() {
|
||||
getFavoriteMap() {
|
||||
return this._favorites;
|
||||
},
|
||||
|
||||
getFavorites: function() {
|
||||
getFavorites() {
|
||||
let ret = [];
|
||||
for (let id in this._favorites)
|
||||
ret.push(this._favorites[id]);
|
||||
return ret;
|
||||
},
|
||||
|
||||
isFavorite: function(appId) {
|
||||
isFavorite(appId) {
|
||||
return appId in this._favorites;
|
||||
},
|
||||
|
||||
_addFavorite: function(appId, pos) {
|
||||
_addFavorite(appId, pos) {
|
||||
if (appId in this._favorites)
|
||||
return false;
|
||||
|
||||
@@ -132,7 +131,7 @@ var AppFavorites = new Lang.Class({
|
||||
return true;
|
||||
},
|
||||
|
||||
addFavoriteAtPos: function(appId, pos) {
|
||||
addFavoriteAtPos(appId, pos) {
|
||||
if (!this._addFavorite(appId, pos))
|
||||
return;
|
||||
|
||||
@@ -140,31 +139,31 @@ var AppFavorites = new Lang.Class({
|
||||
|
||||
Main.overview.setMessage(_("%s has been added to your favorites.").format(app.get_name()),
|
||||
{ forFeedback: true,
|
||||
undoCallback: Lang.bind(this, function () {
|
||||
this._removeFavorite(appId);
|
||||
})
|
||||
undoCallback: () => {
|
||||
this._removeFavorite(appId);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
addFavorite: function(appId) {
|
||||
addFavorite(appId) {
|
||||
this.addFavoriteAtPos(appId, -1);
|
||||
},
|
||||
|
||||
moveFavoriteToPos: function(appId, pos) {
|
||||
moveFavoriteToPos(appId, pos) {
|
||||
this._removeFavorite(appId);
|
||||
this._addFavorite(appId, pos);
|
||||
},
|
||||
|
||||
_removeFavorite: function(appId) {
|
||||
_removeFavorite(appId) {
|
||||
if (!appId in this._favorites)
|
||||
return false;
|
||||
|
||||
let ids = this._getIds().filter(function (id) { return id != appId; });
|
||||
let ids = this._getIds().filter(id => id != appId);
|
||||
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
|
||||
return true;
|
||||
},
|
||||
|
||||
removeFavorite: function(appId) {
|
||||
removeFavorite(appId) {
|
||||
let ids = this._getIds();
|
||||
let pos = ids.indexOf(appId);
|
||||
|
||||
@@ -174,9 +173,9 @@ var AppFavorites = new Lang.Class({
|
||||
|
||||
Main.overview.setMessage(_("%s has been removed from your favorites.").format(app.get_name()),
|
||||
{ forFeedback: true,
|
||||
undoCallback: Lang.bind(this, function () {
|
||||
this._addFavorite(appId, pos);
|
||||
})
|
||||
undoCallback: () => {
|
||||
this._addFavorite(appId, pos);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -15,24 +15,25 @@ var AudioDevice = {
|
||||
MICROPHONE: 1 << 2
|
||||
};
|
||||
|
||||
const AudioDeviceSelectionIface = '<node> \
|
||||
<interface name="org.gnome.Shell.AudioDeviceSelection"> \
|
||||
<method name="Open"> \
|
||||
<arg name="devices" direction="in" type="as" /> \
|
||||
</method> \
|
||||
<method name="Close"> \
|
||||
</method> \
|
||||
<signal name="DeviceSelected"> \
|
||||
<arg name="device" type="s" /> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const AudioDeviceSelectionIface = `
|
||||
<node>
|
||||
<interface name="org.gnome.Shell.AudioDeviceSelection">
|
||||
<method name="Open">
|
||||
<arg name="devices" direction="in" type="as" />
|
||||
</method>
|
||||
<method name="Close">
|
||||
</method>
|
||||
<signal name="DeviceSelected">
|
||||
<arg name="device" type="s" />
|
||||
</signal>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
var AudioDeviceSelectionDialog = new Lang.Class({
|
||||
Name: 'AudioDeviceSelectionDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
|
||||
_init: function(devices) {
|
||||
_init(devices) {
|
||||
this.parent({ styleClass: 'audio-device-selection-dialog' });
|
||||
|
||||
this._deviceItems = {};
|
||||
@@ -50,11 +51,11 @@ var AudioDeviceSelectionDialog = new Lang.Class({
|
||||
throw new Error('Too few devices for a selection');
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
destroy() {
|
||||
this.parent();
|
||||
},
|
||||
|
||||
_buildLayout: function(devices) {
|
||||
_buildLayout(devices) {
|
||||
let title = new St.Label({ style_class: 'audio-selection-title',
|
||||
text: _("Select Audio Device"),
|
||||
x_align: Clutter.ActorAlign.CENTER });
|
||||
@@ -65,14 +66,14 @@ var AudioDeviceSelectionDialog = new Lang.Class({
|
||||
this._selectionBox = new St.BoxLayout({ style_class: 'audio-selection-box' });
|
||||
this.contentLayout.add(this._selectionBox, { expand: true });
|
||||
|
||||
this.addButton({ action: Lang.bind(this, this._openSettings),
|
||||
this.addButton({ action: this._openSettings.bind(this),
|
||||
label: _("Sound Settings") });
|
||||
this.addButton({ action: Lang.bind(this, this.close),
|
||||
this.addButton({ action: this.close.bind(this),
|
||||
label: _("Cancel"),
|
||||
key: Clutter.Escape });
|
||||
},
|
||||
|
||||
_getDeviceLabel: function(device) {
|
||||
_getDeviceLabel(device) {
|
||||
switch(device) {
|
||||
case AudioDevice.HEADPHONES:
|
||||
return _("Headphones");
|
||||
@@ -85,7 +86,7 @@ var AudioDeviceSelectionDialog = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_getDeviceIcon: function(device) {
|
||||
_getDeviceIcon(device) {
|
||||
switch(device) {
|
||||
case AudioDevice.HEADPHONES:
|
||||
return 'audio-headphones-symbolic';
|
||||
@@ -98,16 +99,14 @@ var AudioDeviceSelectionDialog = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_addDevice: function(device) {
|
||||
_addDevice(device) {
|
||||
let box = new St.BoxLayout({ style_class: 'audio-selection-device-box',
|
||||
vertical: true });
|
||||
box.connect('notify::height',
|
||||
function() {
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
|
||||
function() {
|
||||
box.width = box.height;
|
||||
});
|
||||
box.connect('notify::height', () => {
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
box.width = box.height;
|
||||
});
|
||||
});
|
||||
|
||||
let icon = new St.Icon({ style_class: 'audio-selection-device-icon',
|
||||
icon_name: this._getDeviceIcon(device) });
|
||||
@@ -123,15 +122,14 @@ var AudioDeviceSelectionDialog = new Lang.Class({
|
||||
child: box });
|
||||
this._selectionBox.add(button);
|
||||
|
||||
button.connect('clicked', Lang.bind(this,
|
||||
function() {
|
||||
this.emit('device-selected', device);
|
||||
this.close();
|
||||
Main.overview.hide();
|
||||
}));
|
||||
button.connect('clicked', () => {
|
||||
this.emit('device-selected', device);
|
||||
this.close();
|
||||
Main.overview.hide();
|
||||
});
|
||||
},
|
||||
|
||||
_openSettings: function() {
|
||||
_openSettings() {
|
||||
let desktopFile = 'gnome-sound-panel.desktop'
|
||||
let app = Shell.AppSystem.get_default().lookup_app(desktopFile);
|
||||
|
||||
@@ -149,7 +147,7 @@ var AudioDeviceSelectionDialog = new Lang.Class({
|
||||
var AudioDeviceSelectionDBus = new Lang.Class({
|
||||
Name: 'AudioDeviceSelectionDBus',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._audioSelectionDialog = null;
|
||||
|
||||
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(AudioDeviceSelectionIface, this);
|
||||
@@ -158,17 +156,16 @@ var AudioDeviceSelectionDBus = new Lang.Class({
|
||||
Gio.DBus.session.own_name('org.gnome.Shell.AudioDeviceSelection', Gio.BusNameOwnerFlags.REPLACE, null, null);
|
||||
},
|
||||
|
||||
_onDialogClosed: function() {
|
||||
_onDialogClosed() {
|
||||
this._audioSelectionDialog = null;
|
||||
},
|
||||
|
||||
_onDeviceSelected: function(dialog, device) {
|
||||
_onDeviceSelected(dialog, device) {
|
||||
let connection = this._dbusImpl.get_connection();
|
||||
let info = this._dbusImpl.get_info();
|
||||
let deviceName = Object.keys(AudioDevice).filter(
|
||||
function(dev) {
|
||||
return AudioDevice[dev] == device;
|
||||
})[0].toLowerCase();
|
||||
dev => AudioDevice[dev] == device
|
||||
)[0].toLowerCase();
|
||||
connection.emit_signal(this._audioSelectionDialog._sender,
|
||||
this._dbusImpl.get_object_path(),
|
||||
info ? info.name : null,
|
||||
@@ -176,7 +173,7 @@ var AudioDeviceSelectionDBus = new Lang.Class({
|
||||
GLib.Variant.new('(s)', [deviceName]));
|
||||
},
|
||||
|
||||
OpenAsync: function(params, invocation) {
|
||||
OpenAsync(params, invocation) {
|
||||
if (this._audioSelectionDialog) {
|
||||
invocation.return_value(null);
|
||||
return;
|
||||
@@ -184,9 +181,7 @@ var AudioDeviceSelectionDBus = new Lang.Class({
|
||||
|
||||
let [deviceNames] = params;
|
||||
let devices = 0;
|
||||
deviceNames.forEach(function(n) {
|
||||
devices |= AudioDevice[n.toUpperCase()];
|
||||
});
|
||||
deviceNames.forEach(n => { devices |= AudioDevice[n.toUpperCase()]; });
|
||||
|
||||
let dialog;
|
||||
try {
|
||||
@@ -197,16 +192,16 @@ var AudioDeviceSelectionDBus = new Lang.Class({
|
||||
}
|
||||
dialog._sender = invocation.get_sender();
|
||||
|
||||
dialog.connect('closed', Lang.bind(this, this._onDialogClosed));
|
||||
dialog.connect('closed', this._onDialogClosed.bind(this));
|
||||
dialog.connect('device-selected',
|
||||
Lang.bind(this, this._onDeviceSelected));
|
||||
this._onDeviceSelected.bind(this));
|
||||
dialog.open();
|
||||
|
||||
this._audioSelectionDialog = dialog;
|
||||
invocation.return_value(null);
|
||||
},
|
||||
|
||||
CloseAsync: function(params, invocation) {
|
||||
CloseAsync(params, invocation) {
|
||||
if (this._audioSelectionDialog &&
|
||||
this._audioSelectionDialog._sender == invocation.get_sender())
|
||||
this._audioSelectionDialog.close();
|
||||
|
||||
@@ -141,31 +141,31 @@ function _fileEqual0(file1, file2) {
|
||||
var BackgroundCache = new Lang.Class({
|
||||
Name: 'BackgroundCache',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._fileMonitors = {};
|
||||
this._backgroundSources = {};
|
||||
this._animations = {};
|
||||
},
|
||||
|
||||
monitorFile: function(file) {
|
||||
monitorFile(file) {
|
||||
let key = file.hash();
|
||||
if (this._fileMonitors[key])
|
||||
return;
|
||||
|
||||
let monitor = file.monitor(Gio.FileMonitorFlags.NONE, null);
|
||||
monitor.connect('changed',
|
||||
Lang.bind(this, function(obj, file, otherFile, eventType) {
|
||||
(obj, file, otherFile, eventType) => {
|
||||
// Ignore CHANGED and CREATED events, since in both cases
|
||||
// we'll get a CHANGES_DONE_HINT event when done.
|
||||
if (eventType != Gio.FileMonitorEvent.CHANGED &&
|
||||
eventType != Gio.FileMonitorEvent.CREATED)
|
||||
this.emit('file-changed', file);
|
||||
}));
|
||||
});
|
||||
|
||||
this._fileMonitors[key] = monitor;
|
||||
},
|
||||
|
||||
getAnimation: function(params) {
|
||||
getAnimation(params) {
|
||||
params = Params.parse(params, { file: null,
|
||||
settingsSchema: null,
|
||||
onLoaded: null });
|
||||
@@ -173,10 +173,10 @@ var BackgroundCache = new Lang.Class({
|
||||
let animation = this._animations[params.settingsSchema];
|
||||
if (animation && _fileEqual0(animation.file, params.file)) {
|
||||
if (params.onLoaded) {
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||
params.onLoaded(this._animations[params.settingsSchema]);
|
||||
return GLib.SOURCE_REMOVE;
|
||||
}));
|
||||
});
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] params.onLoaded');
|
||||
}
|
||||
return;
|
||||
@@ -184,20 +184,20 @@ var BackgroundCache = new Lang.Class({
|
||||
|
||||
animation = new Animation({ file: params.file });
|
||||
|
||||
animation.load(Lang.bind(this, function() {
|
||||
this._animations[params.settingsSchema] = animation;
|
||||
animation.load(() => {
|
||||
this._animations[params.settingsSchema] = animation;
|
||||
|
||||
if (params.onLoaded) {
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
|
||||
params.onLoaded(this._animations[params.settingsSchema]);
|
||||
return GLib.SOURCE_REMOVE;
|
||||
}));
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] params.onLoaded');
|
||||
}
|
||||
}));
|
||||
if (params.onLoaded) {
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||
params.onLoaded(this._animations[params.settingsSchema]);
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] params.onLoaded');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getBackgroundSource: function(layoutManager, settingsSchema) {
|
||||
getBackgroundSource(layoutManager, settingsSchema) {
|
||||
// The layoutManager is always the same one; we pass in it since
|
||||
// Main.layoutManager may not be set yet
|
||||
|
||||
@@ -211,7 +211,7 @@ var BackgroundCache = new Lang.Class({
|
||||
return this._backgroundSources[settingsSchema];
|
||||
},
|
||||
|
||||
releaseBackgroundSource: function(settingsSchema) {
|
||||
releaseBackgroundSource(settingsSchema) {
|
||||
if (settingsSchema in this._backgroundSources) {
|
||||
let source = this._backgroundSources[settingsSchema];
|
||||
source._useCount--;
|
||||
@@ -233,14 +233,14 @@ function getBackgroundCache() {
|
||||
var Background = new Lang.Class({
|
||||
Name: 'Background',
|
||||
|
||||
_init: function(params) {
|
||||
_init(params) {
|
||||
params = Params.parse(params, { monitorIndex: 0,
|
||||
layoutManager: Main.layoutManager,
|
||||
settings: null,
|
||||
file: null,
|
||||
style: null });
|
||||
|
||||
this.background = new Meta.Background({ meta_screen: global.screen });
|
||||
this.background = new Meta.Background({ meta_display: global.display });
|
||||
this.background._delegate = this;
|
||||
|
||||
this._settings = params.settings;
|
||||
@@ -254,10 +254,10 @@ var Background = new Lang.Class({
|
||||
|
||||
this._clock = new GnomeDesktop.WallClock();
|
||||
this._timezoneChangedId = this._clock.connect('notify::timezone',
|
||||
Lang.bind(this, function() {
|
||||
() => {
|
||||
if (this._animation)
|
||||
this._loadAnimation(this._animation.file);
|
||||
}));
|
||||
});
|
||||
|
||||
let loginManager = LoginManager.getLoginManager();
|
||||
this._prepareForSleepId = loginManager.connect('prepare-for-sleep',
|
||||
@@ -267,14 +267,14 @@ var Background = new Lang.Class({
|
||||
this._refreshAnimation();
|
||||
});
|
||||
|
||||
this._settingsChangedSignalId = this._settings.connect('changed', Lang.bind(this, function() {
|
||||
this.emit('changed');
|
||||
}));
|
||||
this._settingsChangedSignalId = this._settings.connect('changed', () => {
|
||||
this.emit('changed');
|
||||
});
|
||||
|
||||
this._load();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
destroy() {
|
||||
this._cancellable.cancel();
|
||||
this._removeAnimationTimeout();
|
||||
|
||||
@@ -300,12 +300,12 @@ var Background = new Lang.Class({
|
||||
this._settingsChangedSignalId = 0;
|
||||
},
|
||||
|
||||
updateResolution: function() {
|
||||
updateResolution() {
|
||||
if (this._animation)
|
||||
this._refreshAnimation();
|
||||
},
|
||||
|
||||
_refreshAnimation: function() {
|
||||
_refreshAnimation() {
|
||||
if (!this._animation)
|
||||
return;
|
||||
|
||||
@@ -313,20 +313,20 @@ var Background = new Lang.Class({
|
||||
this._updateAnimation();
|
||||
},
|
||||
|
||||
_setLoaded: function() {
|
||||
_setLoaded() {
|
||||
if (this.isLoaded)
|
||||
return;
|
||||
|
||||
this.isLoaded = true;
|
||||
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||
this.emit('loaded');
|
||||
return GLib.SOURCE_REMOVE;
|
||||
}));
|
||||
});
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] this.emit');
|
||||
},
|
||||
|
||||
_loadPattern: function() {
|
||||
_loadPattern() {
|
||||
let colorString, res, color, secondColor;
|
||||
|
||||
colorString = this._settings.get_string(PRIMARY_COLOR_KEY);
|
||||
@@ -342,37 +342,37 @@ var Background = new Lang.Class({
|
||||
this.background.set_gradient(shadingType, color, secondColor);
|
||||
},
|
||||
|
||||
_watchFile: function(file) {
|
||||
_watchFile(file) {
|
||||
let key = file.hash();
|
||||
if (this._fileWatches[key])
|
||||
return;
|
||||
|
||||
this._cache.monitorFile(file);
|
||||
let signalId = this._cache.connect('file-changed',
|
||||
Lang.bind(this, function(cache, changedFile) {
|
||||
(cache, changedFile) => {
|
||||
if (changedFile.equal(file)) {
|
||||
let imageCache = Meta.BackgroundImageCache.get_default();
|
||||
imageCache.purge(changedFile);
|
||||
this.emit('changed');
|
||||
}
|
||||
}));
|
||||
});
|
||||
this._fileWatches[key] = signalId;
|
||||
},
|
||||
|
||||
_removeAnimationTimeout: function() {
|
||||
_removeAnimationTimeout() {
|
||||
if (this._updateAnimationTimeoutId) {
|
||||
GLib.source_remove(this._updateAnimationTimeoutId);
|
||||
this._updateAnimationTimeoutId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
_updateAnimation: function() {
|
||||
_updateAnimation() {
|
||||
this._updateAnimationTimeoutId = 0;
|
||||
|
||||
this._animation.update(this._layoutManager.monitors[this._monitorIndex]);
|
||||
let files = this._animation.keyFrameFiles;
|
||||
|
||||
let finish = Lang.bind(this, function() {
|
||||
let finish = () => {
|
||||
this._setLoaded();
|
||||
if (files.length > 1) {
|
||||
this.background.set_blend(files[0], files[1],
|
||||
@@ -384,7 +384,7 @@ var Background = new Lang.Class({
|
||||
this.background.set_file(null, this._style);
|
||||
}
|
||||
this._queueUpdateAnimation();
|
||||
});
|
||||
};
|
||||
|
||||
let cache = Meta.BackgroundImageCache.get_default();
|
||||
let numPendingImages = files.length;
|
||||
@@ -396,18 +396,17 @@ var Background = new Lang.Class({
|
||||
if (numPendingImages == 0)
|
||||
finish();
|
||||
} else {
|
||||
let id = image.connect('loaded',
|
||||
Lang.bind(this, function() {
|
||||
image.disconnect(id);
|
||||
numPendingImages--;
|
||||
if (numPendingImages == 0)
|
||||
finish();
|
||||
}));
|
||||
let id = image.connect('loaded', () => {
|
||||
image.disconnect(id);
|
||||
numPendingImages--;
|
||||
if (numPendingImages == 0)
|
||||
finish();
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_queueUpdateAnimation: function() {
|
||||
_queueUpdateAnimation() {
|
||||
if (this._updateAnimationTimeoutId != 0)
|
||||
return;
|
||||
|
||||
@@ -428,18 +427,18 @@ var Background = new Lang.Class({
|
||||
|
||||
this._updateAnimationTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
|
||||
interval,
|
||||
Lang.bind(this, function() {
|
||||
this._updateAnimationTimeoutId = 0;
|
||||
this._updateAnimation();
|
||||
return GLib.SOURCE_REMOVE;
|
||||
}));
|
||||
() => {
|
||||
this._updateAnimationTimeoutId = 0;
|
||||
this._updateAnimation();
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(this._updateAnimationTimeoutId, '[gnome-shell] this._updateAnimation');
|
||||
},
|
||||
|
||||
_loadAnimation: function(file) {
|
||||
_loadAnimation(file) {
|
||||
this._cache.getAnimation({ file: file,
|
||||
settingsSchema: this._settings.schema_id,
|
||||
onLoaded: Lang.bind(this, function(animation) {
|
||||
onLoaded: animation => {
|
||||
this._animation = animation;
|
||||
|
||||
if (!this._animation || this._cancellable.is_cancelled()) {
|
||||
@@ -449,11 +448,11 @@ var Background = new Lang.Class({
|
||||
|
||||
this._updateAnimation();
|
||||
this._watchFile(file);
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_loadImage: function(file) {
|
||||
_loadImage(file) {
|
||||
this.background.set_file(file, this._style);
|
||||
this._watchFile(file);
|
||||
|
||||
@@ -462,22 +461,21 @@ var Background = new Lang.Class({
|
||||
if (image.is_loaded())
|
||||
this._setLoaded();
|
||||
else {
|
||||
let id = image.connect('loaded',
|
||||
Lang.bind(this, function() {
|
||||
this._setLoaded();
|
||||
image.disconnect(id);
|
||||
}));
|
||||
let id = image.connect('loaded', () => {
|
||||
this._setLoaded();
|
||||
image.disconnect(id);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_loadFile: function(file) {
|
||||
_loadFile(file) {
|
||||
if (file.get_basename().endsWith('.xml'))
|
||||
this._loadAnimation(file);
|
||||
else
|
||||
this._loadImage(file);
|
||||
},
|
||||
|
||||
_load: function () {
|
||||
_load() {
|
||||
this._cache = getBackgroundCache();
|
||||
|
||||
this._loadPattern();
|
||||
@@ -497,16 +495,16 @@ let _systemBackground;
|
||||
var SystemBackground = new Lang.Class({
|
||||
Name: 'SystemBackground',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png');
|
||||
|
||||
if (_systemBackground == null) {
|
||||
_systemBackground = new Meta.Background({ meta_screen: global.screen });
|
||||
_systemBackground = new Meta.Background({ meta_display: global.display });
|
||||
_systemBackground.set_color(DEFAULT_BACKGROUND_COLOR);
|
||||
_systemBackground.set_file(file, GDesktopEnums.BackgroundStyle.WALLPAPER);
|
||||
}
|
||||
|
||||
this.actor = new Meta.BackgroundActor({ meta_screen: global.screen,
|
||||
this.actor = new Meta.BackgroundActor({ meta_display: global.display,
|
||||
monitor: 0,
|
||||
background: _systemBackground });
|
||||
|
||||
@@ -514,18 +512,17 @@ var SystemBackground = new Lang.Class({
|
||||
let image = cache.load(file);
|
||||
if (image.is_loaded()) {
|
||||
image = null;
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||
this.emit('loaded');
|
||||
return GLib.SOURCE_REMOVE;
|
||||
}));
|
||||
});
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] SystemBackground.loaded');
|
||||
} else {
|
||||
let id = image.connect('loaded',
|
||||
Lang.bind(this, function() {
|
||||
this.emit('loaded');
|
||||
image.disconnect(id);
|
||||
image = null;
|
||||
}));
|
||||
let id = image.connect('loaded', () => {
|
||||
this.emit('loaded');
|
||||
image.disconnect(id);
|
||||
image = null;
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -534,18 +531,20 @@ Signals.addSignalMethods(SystemBackground.prototype);
|
||||
var BackgroundSource = new Lang.Class({
|
||||
Name: 'BackgroundSource',
|
||||
|
||||
_init: function(layoutManager, settingsSchema) {
|
||||
_init(layoutManager, settingsSchema) {
|
||||
// Allow override the background image setting for performance testing
|
||||
this._layoutManager = layoutManager;
|
||||
this._overrideImage = GLib.getenv('SHELL_BACKGROUND_IMAGE');
|
||||
this._settings = new Gio.Settings({ schema_id: settingsSchema });
|
||||
this._backgrounds = [];
|
||||
|
||||
this._monitorsChangedId = global.screen.connect('monitors-changed',
|
||||
Lang.bind(this, this._onMonitorsChanged));
|
||||
let monitorManager = Meta.MonitorManager.get();
|
||||
this._monitorsChangedId =
|
||||
monitorManager.connect('monitors-changed',
|
||||
this._onMonitorsChanged.bind(this));
|
||||
},
|
||||
|
||||
_onMonitorsChanged: function() {
|
||||
_onMonitorsChanged() {
|
||||
for (let monitorIndex in this._backgrounds) {
|
||||
let background = this._backgrounds[monitorIndex];
|
||||
|
||||
@@ -559,7 +558,7 @@ var BackgroundSource = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
getBackground: function(monitorIndex) {
|
||||
getBackground(monitorIndex) {
|
||||
let file = null;
|
||||
let style;
|
||||
|
||||
@@ -594,11 +593,11 @@ var BackgroundSource = new Lang.Class({
|
||||
style: style
|
||||
});
|
||||
|
||||
background._changedId = background.connect('changed', Lang.bind(this, function() {
|
||||
background._changedId = background.connect('changed', () => {
|
||||
background.disconnect(background._changedId);
|
||||
background.destroy();
|
||||
delete this._backgrounds[monitorIndex];
|
||||
}));
|
||||
});
|
||||
|
||||
this._backgrounds[monitorIndex] = background;
|
||||
}
|
||||
@@ -606,8 +605,9 @@ var BackgroundSource = new Lang.Class({
|
||||
return this._backgrounds[monitorIndex];
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
global.screen.disconnect(this._monitorsChangedId);
|
||||
destroy() {
|
||||
let monitorManager = Meta.MonitorManager.get();
|
||||
monitorManager.disconnect(this._monitorsChangedId);
|
||||
|
||||
for (let monitorIndex in this._backgrounds) {
|
||||
let background = this._backgrounds[monitorIndex];
|
||||
@@ -622,7 +622,7 @@ var BackgroundSource = new Lang.Class({
|
||||
var Animation = new Lang.Class({
|
||||
Name: 'Animation',
|
||||
|
||||
_init: function(params) {
|
||||
_init(params) {
|
||||
params = Params.parse(params, { file: null });
|
||||
|
||||
this.file = params.file;
|
||||
@@ -632,19 +632,17 @@ var Animation = new Lang.Class({
|
||||
this.loaded = false;
|
||||
},
|
||||
|
||||
load: function(callback) {
|
||||
load(callback) {
|
||||
this._show = new GnomeDesktop.BGSlideShow({ filename: this.file.get_path() });
|
||||
|
||||
this._show.load_async(null,
|
||||
Lang.bind(this,
|
||||
function(object, result) {
|
||||
this.loaded = true;
|
||||
if (callback)
|
||||
callback();
|
||||
}));
|
||||
this._show.load_async(null, (object, result) => {
|
||||
this.loaded = true;
|
||||
if (callback)
|
||||
callback();
|
||||
});
|
||||
},
|
||||
|
||||
update: function(monitor) {
|
||||
update(monitor) {
|
||||
this.keyFrameFiles = [];
|
||||
|
||||
if (!this._show)
|
||||
@@ -670,7 +668,7 @@ Signals.addSignalMethods(Animation.prototype);
|
||||
var BackgroundManager = new Lang.Class({
|
||||
Name: 'BackgroundManager',
|
||||
|
||||
_init: function(params) {
|
||||
_init(params) {
|
||||
params = Params.parse(params, { container: null,
|
||||
layoutManager: Main.layoutManager,
|
||||
monitorIndex: null,
|
||||
@@ -692,7 +690,7 @@ var BackgroundManager = new Lang.Class({
|
||||
this._newBackgroundActor = null;
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
destroy() {
|
||||
let cache = getBackgroundCache();
|
||||
cache.releaseBackgroundSource(this._settingsSchema);
|
||||
this._backgroundSource = null;
|
||||
@@ -708,7 +706,7 @@ var BackgroundManager = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_swapBackgroundActor: function() {
|
||||
_swapBackgroundActor() {
|
||||
let oldBackgroundActor = this.backgroundActor;
|
||||
this.backgroundActor = this._newBackgroundActor;
|
||||
this._newBackgroundActor = null;
|
||||
@@ -718,14 +716,14 @@ var BackgroundManager = new Lang.Class({
|
||||
{ opacity: 0,
|
||||
time: FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: function() {
|
||||
onComplete() {
|
||||
oldBackgroundActor.background.run_dispose();
|
||||
oldBackgroundActor.destroy();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_updateBackgroundActor: function() {
|
||||
_updateBackgroundActor() {
|
||||
if (this._newBackgroundActor) {
|
||||
/* Skip displaying existing background queued for load */
|
||||
this._newBackgroundActor.destroy();
|
||||
@@ -745,19 +743,18 @@ var BackgroundManager = new Lang.Class({
|
||||
this._swapBackgroundActor();
|
||||
} else {
|
||||
newBackgroundActor.loadedSignalId = background.connect('loaded',
|
||||
Lang.bind(this, function() {
|
||||
() => {
|
||||
background.disconnect(newBackgroundActor.loadedSignalId);
|
||||
newBackgroundActor.loadedSignalId = 0;
|
||||
|
||||
this._swapBackgroundActor();
|
||||
|
||||
}));
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_createBackgroundActor: function() {
|
||||
_createBackgroundActor() {
|
||||
let background = this._backgroundSource.getBackground(this._monitorIndex);
|
||||
let backgroundActor = new Meta.BackgroundActor({ meta_screen: global.screen,
|
||||
let backgroundActor = new Meta.BackgroundActor({ meta_display: global.display,
|
||||
monitor: this._monitorIndex,
|
||||
background: background.background,
|
||||
vignette: this._vignette,
|
||||
@@ -775,19 +772,19 @@ var BackgroundManager = new Lang.Class({
|
||||
backgroundActor.lower_bottom();
|
||||
}
|
||||
|
||||
let changeSignalId = background.connect('changed', Lang.bind(this, function() {
|
||||
let changeSignalId = background.connect('changed', () => {
|
||||
background.disconnect(changeSignalId);
|
||||
changeSignalId = null;
|
||||
this._updateBackgroundActor();
|
||||
}));
|
||||
});
|
||||
|
||||
backgroundActor.connect('destroy', Lang.bind(this, function() {
|
||||
backgroundActor.connect('destroy', () => {
|
||||
if (changeSignalId)
|
||||
background.disconnect(changeSignalId);
|
||||
|
||||
if (backgroundActor.loadedSignalId)
|
||||
background.disconnect(backgroundActor.loadedSignalId);
|
||||
}));
|
||||
});
|
||||
|
||||
return backgroundActor;
|
||||
},
|
||||
|
||||
@@ -13,7 +13,7 @@ var BackgroundMenu = new Lang.Class({
|
||||
Name: 'BackgroundMenu',
|
||||
Extends: PopupMenu.PopupMenu,
|
||||
|
||||
_init: function(layoutManager) {
|
||||
_init(layoutManager) {
|
||||
this.parent(layoutManager.dummyCursor, 0, St.Side.TOP);
|
||||
|
||||
this.addSettingsAction(_("Change Background…"), 'gnome-background-panel.desktop');
|
||||
@@ -40,7 +40,7 @@ function addBackgroundMenu(actor, layoutManager) {
|
||||
}
|
||||
|
||||
let clickAction = new Clutter.ClickAction();
|
||||
clickAction.connect('long-press', function(action, actor, state) {
|
||||
clickAction.connect('long-press', (action, actor, state) => {
|
||||
if (state == Clutter.LongPressState.QUERY)
|
||||
return ((action.get_button() == 0 ||
|
||||
action.get_button() == 1) &&
|
||||
@@ -52,7 +52,7 @@ function addBackgroundMenu(actor, layoutManager) {
|
||||
}
|
||||
return true;
|
||||
});
|
||||
clickAction.connect('clicked', function(action) {
|
||||
clickAction.connect('clicked', action => {
|
||||
if (action.get_button() == 3) {
|
||||
let [x, y] = action.get_coords();
|
||||
openMenu(x, y);
|
||||
@@ -60,11 +60,11 @@ function addBackgroundMenu(actor, layoutManager) {
|
||||
});
|
||||
actor.add_action(clickAction);
|
||||
|
||||
let grabOpBeginId = global.display.connect('grab-op-begin', function () {
|
||||
let grabOpBeginId = global.display.connect('grab-op-begin', () => {
|
||||
clickAction.release();
|
||||
});
|
||||
|
||||
actor.connect('destroy', function() {
|
||||
actor.connect('destroy', () => {
|
||||
actor._backgroundMenu.destroy();
|
||||
actor._backgroundMenu = null;
|
||||
actor._backgroundManager = null;
|
||||
|
||||
210
js/ui/barLevel.js
Normal file
@@ -0,0 +1,210 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
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 = 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');
|
||||
this._maxValue = 1;
|
||||
this._value = Math.max(Math.min(value, this._maxValue), 0);
|
||||
this._overdriveStart = 1;
|
||||
this._barLevelWidth = 0;
|
||||
|
||||
if (params == undefined)
|
||||
params = {}
|
||||
|
||||
this.actor = new St.DrawingArea({ styleClass: params['styleClass'] || 'barlevel',
|
||||
can_focus: params['canFocus'] || false,
|
||||
reactive: params['reactive'] || false,
|
||||
accessible_role: params['accessibleRole'] || Atk.Role.LEVEL_BAR });
|
||||
this.actor.connect('repaint', this._barLevelRepaint.bind(this));
|
||||
this.actor.connect('allocation-changed', (actor, box) => {
|
||||
this._barLevelWidth = box.get_width();
|
||||
});
|
||||
|
||||
this._customAccessible = St.GenericAccessible.new_for_actor(this.actor);
|
||||
this.actor.set_accessible(this._customAccessible);
|
||||
|
||||
this._customAccessible.connect('get-current-value', this._getCurrentValue.bind(this));
|
||||
this._customAccessible.connect('get-minimum-value', this._getMinimumValue.bind(this));
|
||||
this._customAccessible.connect('get-maximum-value', this._getMaximumValue.bind(this));
|
||||
this._customAccessible.connect('set-current-value', this._setCurrentValue.bind(this));
|
||||
|
||||
this.connect('value-changed', this._valueChanged.bind(this));
|
||||
},
|
||||
|
||||
setValue(value) {
|
||||
if (isNaN(value))
|
||||
throw TypeError('The bar level value must be a number');
|
||||
|
||||
this._value = Math.max(Math.min(value, this._maxValue), 0);
|
||||
this.actor.queue_repaint();
|
||||
},
|
||||
|
||||
setMaximumValue(value) {
|
||||
if (isNaN(value))
|
||||
throw TypeError('The bar level max value must be a number');
|
||||
|
||||
this._maxValue = Math.max(value, 1);
|
||||
this._overdriveStart = Math.min(this._overdriveStart, this._maxValue);
|
||||
this.actor.queue_repaint();
|
||||
},
|
||||
|
||||
setOverdriveStart(value) {
|
||||
if (isNaN(value))
|
||||
throw TypeError('The overdrive limit value must be a number');
|
||||
if (value > this._maxValue)
|
||||
throw new Error(`Tried to set overdrive value to ${value}, ` +
|
||||
`which is a number greater than the maximum allowed value ${this._maxValue}`);
|
||||
|
||||
this._overdriveStart = value;
|
||||
this._value = Math.max(Math.min(value, this._maxValue), 0);
|
||||
this.actor.queue_repaint();
|
||||
},
|
||||
|
||||
_barLevelRepaint(area) {
|
||||
let cr = area.get_context();
|
||||
let themeNode = area.get_theme_node();
|
||||
let [width, height] = area.get_surface_size();
|
||||
|
||||
let barLevelHeight = themeNode.get_length('-barlevel-height');
|
||||
let barLevelBorderRadius = Math.min(width, barLevelHeight) / 2;
|
||||
let fgColor = themeNode.get_foreground_color();
|
||||
|
||||
let barLevelColor = themeNode.get_color('-barlevel-background-color');
|
||||
let barLevelActiveColor = themeNode.get_color('-barlevel-active-background-color');
|
||||
let barLevelOverdriveColor = themeNode.get_color('-barlevel-overdrive-color');
|
||||
|
||||
let barLevelBorderWidth = Math.min(themeNode.get_length('-barlevel-border-width'), 1);
|
||||
let [hasBorderColor, barLevelBorderColor] =
|
||||
themeNode.lookup_color('-barlevel-border-color', false);
|
||||
if (!hasBorderColor)
|
||||
barLevelBorderColor = barLevelColor;
|
||||
let [hasActiveBorderColor, barLevelActiveBorderColor] =
|
||||
themeNode.lookup_color('-barlevel-active-border-color', false);
|
||||
if (!hasActiveBorderColor)
|
||||
barLevelActiveBorderColor = barLevelActiveColor;
|
||||
let [hasOverdriveBorderColor, barLevelOverdriveBorderColor] =
|
||||
themeNode.lookup_color('-barlevel-overdrive-border-color', false);
|
||||
if (!hasOverdriveBorderColor)
|
||||
barLevelOverdriveBorderColor = barLevelOverdriveColor;
|
||||
|
||||
const TAU = Math.PI * 2;
|
||||
|
||||
let endX = 0;
|
||||
if (this._maxValue > 0)
|
||||
endX = barLevelBorderRadius + (width - 2 * barLevelBorderRadius) * this._value / this._maxValue;
|
||||
|
||||
let overdriveSeparatorX = barLevelBorderRadius + (width - 2 * barLevelBorderRadius) * this._overdriveStart / this._maxValue;
|
||||
let overdriveActive = this._overdriveStart !== this._maxValue;
|
||||
let overdriveSeparatorWidth = 0;
|
||||
if (overdriveActive)
|
||||
overdriveSeparatorWidth = themeNode.get_length('-barlevel-overdrive-separator-width');
|
||||
|
||||
/* background bar */
|
||||
cr.arc(width - barLevelBorderRadius - barLevelBorderWidth, height / 2, barLevelBorderRadius, TAU * 3 / 4, TAU * 1 / 4);
|
||||
cr.lineTo(endX, (height + barLevelHeight) / 2);
|
||||
cr.lineTo(endX, (height - barLevelHeight) / 2);
|
||||
cr.lineTo(width - barLevelBorderRadius - barLevelBorderWidth, (height - barLevelHeight) / 2);
|
||||
Clutter.cairo_set_source_color(cr, barLevelColor);
|
||||
cr.fillPreserve();
|
||||
Clutter.cairo_set_source_color(cr, barLevelBorderColor);
|
||||
cr.setLineWidth(barLevelBorderWidth);
|
||||
cr.stroke();
|
||||
|
||||
/* normal progress bar */
|
||||
let x = Math.min(endX, overdriveSeparatorX - overdriveSeparatorWidth / 2);
|
||||
cr.arc(barLevelBorderRadius + barLevelBorderWidth, height / 2, barLevelBorderRadius, TAU * 1 / 4, TAU * 3 / 4);
|
||||
cr.lineTo(x, (height - barLevelHeight) / 2);
|
||||
cr.lineTo(x, (height + barLevelHeight) / 2);
|
||||
cr.lineTo(barLevelBorderRadius + barLevelBorderWidth, (height + barLevelHeight) / 2);
|
||||
Clutter.cairo_set_source_color(cr, barLevelActiveColor);
|
||||
cr.fillPreserve();
|
||||
Clutter.cairo_set_source_color(cr, barLevelActiveBorderColor);
|
||||
cr.setLineWidth(barLevelBorderWidth);
|
||||
cr.stroke();
|
||||
|
||||
/* overdrive progress barLevel */
|
||||
x = Math.min(endX, overdriveSeparatorX) + overdriveSeparatorWidth / 2;
|
||||
if (this._value > this._overdriveStart) {
|
||||
cr.moveTo(x, (height - barLevelHeight) / 2);
|
||||
cr.lineTo(endX, (height - barLevelHeight) / 2);
|
||||
cr.lineTo(endX, (height + barLevelHeight) / 2);
|
||||
cr.lineTo(x, (height + barLevelHeight) / 2);
|
||||
cr.lineTo(x, (height - barLevelHeight) / 2);
|
||||
Clutter.cairo_set_source_color(cr, barLevelOverdriveColor);
|
||||
cr.fillPreserve();
|
||||
Clutter.cairo_set_source_color(cr, barLevelOverdriveBorderColor);
|
||||
cr.setLineWidth(barLevelBorderWidth);
|
||||
cr.stroke();
|
||||
}
|
||||
|
||||
/* end progress bar arc */
|
||||
if (this._value <= this._overdriveStart)
|
||||
Clutter.cairo_set_source_color(cr, barLevelActiveColor);
|
||||
else
|
||||
Clutter.cairo_set_source_color(cr, barLevelOverdriveColor);
|
||||
cr.arc(endX, height / 2, barLevelBorderRadius, TAU * 3 / 4, TAU * 1 / 4);
|
||||
cr.lineTo(Math.floor(endX), (height + barLevelHeight) / 2);
|
||||
cr.lineTo(Math.floor(endX), (height - barLevelHeight) / 2);
|
||||
cr.lineTo(endX, (height - barLevelHeight) / 2);
|
||||
cr.fillPreserve();
|
||||
cr.setLineWidth(barLevelBorderWidth);
|
||||
cr.stroke();
|
||||
|
||||
/* draw overdrive separator */
|
||||
if (overdriveActive) {
|
||||
cr.moveTo(overdriveSeparatorX - overdriveSeparatorWidth / 2, (height - barLevelHeight) / 2);
|
||||
cr.lineTo(overdriveSeparatorX + overdriveSeparatorWidth / 2, (height - barLevelHeight) / 2);
|
||||
cr.lineTo(overdriveSeparatorX + overdriveSeparatorWidth / 2, (height + barLevelHeight) / 2);
|
||||
cr.lineTo(overdriveSeparatorX - overdriveSeparatorWidth / 2, (height + barLevelHeight) / 2);
|
||||
cr.lineTo(overdriveSeparatorX - overdriveSeparatorWidth / 2, (height - barLevelHeight) / 2);
|
||||
if (this._value <= this._overdriveStart)
|
||||
Clutter.cairo_set_source_color(cr, fgColor);
|
||||
else
|
||||
Clutter.cairo_set_source_color(cr, barLevelColor);
|
||||
cr.fill();
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -35,7 +35,7 @@ var POPUP_ANIMATION_TIME = 0.15;
|
||||
var BoxPointer = new Lang.Class({
|
||||
Name: 'BoxPointer',
|
||||
|
||||
_init: function(arrowSide, binProperties) {
|
||||
_init(arrowSide, binProperties) {
|
||||
this._arrowSide = arrowSide;
|
||||
this._userArrowSide = arrowSide;
|
||||
this._arrowOrigin = 0;
|
||||
@@ -44,13 +44,14 @@ var BoxPointer = new Lang.Class({
|
||||
y_fill: true });
|
||||
this._container = new Shell.GenericContainer();
|
||||
this.actor.set_child(this._container);
|
||||
this._container.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||
this._container.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||
this._container.connect('allocate', Lang.bind(this, this._allocate));
|
||||
this.actor.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
|
||||
this._container.connect('get-preferred-width', this._getPreferredWidth.bind(this));
|
||||
this._container.connect('get-preferred-height', this._getPreferredHeight.bind(this));
|
||||
this._container.connect('allocate', this._allocate.bind(this));
|
||||
this.bin = new St.Bin(binProperties);
|
||||
this._container.add_actor(this.bin);
|
||||
this._border = new St.DrawingArea();
|
||||
this._border.connect('repaint', Lang.bind(this, this._drawBorder));
|
||||
this._border.connect('repaint', this._drawBorder.bind(this));
|
||||
this._container.add_actor(this._border);
|
||||
this.bin.raise(this._border);
|
||||
this._xOffset = 0;
|
||||
@@ -66,20 +67,20 @@ var BoxPointer = new Lang.Class({
|
||||
return this._arrowSide;
|
||||
},
|
||||
|
||||
_muteInput: function() {
|
||||
_muteInput() {
|
||||
if (this._capturedEventId == 0)
|
||||
this._capturedEventId = this.actor.connect('captured-event',
|
||||
function() { return Clutter.EVENT_STOP; });
|
||||
() => Clutter.EVENT_STOP);
|
||||
},
|
||||
|
||||
_unmuteInput: function() {
|
||||
_unmuteInput() {
|
||||
if (this._capturedEventId != 0) {
|
||||
this.actor.disconnect(this._capturedEventId);
|
||||
this._capturedEventId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
show: function(animate, onComplete) {
|
||||
show(animate, onComplete) {
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
let rise = themeNode.get_length('-arrow-rise');
|
||||
let animationTime = (animate & PopupAnimation.FULL) ? POPUP_ANIMATION_TIME : 0;
|
||||
@@ -112,15 +113,15 @@ var BoxPointer = new Lang.Class({
|
||||
xOffset: 0,
|
||||
yOffset: 0,
|
||||
transition: 'linear',
|
||||
onComplete: Lang.bind(this, function() {
|
||||
onComplete: () => {
|
||||
this._unmuteInput();
|
||||
if (onComplete)
|
||||
onComplete();
|
||||
}),
|
||||
},
|
||||
time: animationTime });
|
||||
},
|
||||
|
||||
hide: function(animate, onComplete) {
|
||||
hide(animate, onComplete) {
|
||||
if (!this.actor.visible)
|
||||
return;
|
||||
|
||||
@@ -156,18 +157,18 @@ var BoxPointer = new Lang.Class({
|
||||
yOffset: yOffset,
|
||||
transition: 'linear',
|
||||
time: animationTime,
|
||||
onComplete: Lang.bind(this, function () {
|
||||
onComplete: () => {
|
||||
this.actor.hide();
|
||||
this.opacity = 0;
|
||||
this.xOffset = 0;
|
||||
this.yOffset = 0;
|
||||
if (onComplete)
|
||||
onComplete();
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_adjustAllocationForArrow: function(isWidth, alloc) {
|
||||
_adjustAllocationForArrow(isWidth, alloc) {
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
let borderWidth = themeNode.get_length('-arrow-border-width');
|
||||
alloc.min_size += borderWidth * 2;
|
||||
@@ -180,14 +181,14 @@ var BoxPointer = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_getPreferredWidth: function(actor, forHeight, alloc) {
|
||||
_getPreferredWidth(actor, forHeight, alloc) {
|
||||
let [minInternalSize, natInternalSize] = this.bin.get_preferred_width(forHeight);
|
||||
alloc.min_size = minInternalSize;
|
||||
alloc.natural_size = natInternalSize;
|
||||
this._adjustAllocationForArrow(true, alloc);
|
||||
},
|
||||
|
||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||
_getPreferredHeight(actor, forWidth, alloc) {
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
let borderWidth = themeNode.get_length('-arrow-border-width');
|
||||
let [minSize, naturalSize] = this.bin.get_preferred_height(forWidth - 2 * borderWidth);
|
||||
@@ -196,7 +197,7 @@ var BoxPointer = new Lang.Class({
|
||||
this._adjustAllocationForArrow(false, alloc);
|
||||
},
|
||||
|
||||
_allocate: function(actor, box, flags) {
|
||||
_allocate(actor, box, flags) {
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
let borderWidth = themeNode.get_length('-arrow-border-width');
|
||||
let rise = themeNode.get_length('-arrow-rise');
|
||||
@@ -236,7 +237,7 @@ var BoxPointer = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_drawBorder: function(area) {
|
||||
_drawBorder(area) {
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
|
||||
if (this._arrowActor) {
|
||||
@@ -418,7 +419,7 @@ var BoxPointer = new Lang.Class({
|
||||
cr.$dispose();
|
||||
},
|
||||
|
||||
setPosition: function(sourceActor, alignment) {
|
||||
setPosition(sourceActor, alignment) {
|
||||
// We need to show it now to force an allocation,
|
||||
// so that we can query the correct size.
|
||||
this.actor.show();
|
||||
@@ -430,7 +431,7 @@ var BoxPointer = new Lang.Class({
|
||||
this._updateFlip();
|
||||
},
|
||||
|
||||
setSourceAlignment: function(alignment) {
|
||||
setSourceAlignment(alignment) {
|
||||
this._sourceAlignment = alignment;
|
||||
|
||||
if (!this._sourceActor)
|
||||
@@ -439,7 +440,7 @@ var BoxPointer = new Lang.Class({
|
||||
this.setPosition(this._sourceActor, this._arrowAlignment);
|
||||
},
|
||||
|
||||
_reposition: function() {
|
||||
_reposition() {
|
||||
let sourceActor = this._sourceActor;
|
||||
let alignment = this._arrowAlignment;
|
||||
|
||||
@@ -556,7 +557,7 @@ var BoxPointer = new Lang.Class({
|
||||
// @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
|
||||
// the left for St.Side.TOP and St.Side.BOTTOM.
|
||||
setArrowOrigin: function(origin) {
|
||||
setArrowOrigin(origin) {
|
||||
if (this._arrowOrigin != origin) {
|
||||
this._arrowOrigin = origin;
|
||||
this._border.queue_repaint();
|
||||
@@ -566,14 +567,14 @@ var BoxPointer = new Lang.Class({
|
||||
// @actor: an actor relative to which the arrow is positioned.
|
||||
// Differently from setPosition, this will not move the boxpointer itself,
|
||||
// on the arrow
|
||||
setArrowActor: function(actor) {
|
||||
setArrowActor(actor) {
|
||||
if (this._arrowActor != actor) {
|
||||
this._arrowActor = actor;
|
||||
this._border.queue_repaint();
|
||||
}
|
||||
},
|
||||
|
||||
_shiftActor : function() {
|
||||
_shiftActor() {
|
||||
// Since the position of the BoxPointer depends on the allocated size
|
||||
// of the BoxPointer and the position of the source actor, trying
|
||||
// to position the BoxPointer via the x/y properties will result in
|
||||
@@ -584,7 +585,7 @@ var BoxPointer = new Lang.Class({
|
||||
-(this._yPosition + this._yOffset));
|
||||
},
|
||||
|
||||
_calculateArrowSide: function(arrowSide) {
|
||||
_calculateArrowSide(arrowSide) {
|
||||
let sourceAllocation = Shell.util_get_transformed_allocation(this._sourceActor);
|
||||
let [minWidth, minHeight, boxWidth, boxHeight] = this._container.get_preferred_size();
|
||||
let monitorActor = this.sourceActor;
|
||||
@@ -618,15 +619,15 @@ var BoxPointer = new Lang.Class({
|
||||
return arrowSide;
|
||||
},
|
||||
|
||||
_updateFlip: function() {
|
||||
_updateFlip() {
|
||||
let arrowSide = this._calculateArrowSide(this._userArrowSide);
|
||||
if (this._arrowSide != arrowSide) {
|
||||
this._arrowSide = arrowSide;
|
||||
this._reposition();
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
this._container.queue_relayout();
|
||||
return false;
|
||||
}));
|
||||
});
|
||||
|
||||
this.emit('arrow-side-changed');
|
||||
}
|
||||
@@ -658,18 +659,18 @@ var BoxPointer = new Lang.Class({
|
||||
return this.actor.opacity;
|
||||
},
|
||||
|
||||
updateArrowSide: function(side) {
|
||||
updateArrowSide(side) {
|
||||
this._arrowSide = side;
|
||||
this._border.queue_repaint();
|
||||
|
||||
this.emit('arrow-side-changed');
|
||||
},
|
||||
|
||||
getPadding: function(side) {
|
||||
getPadding(side) {
|
||||
return this.bin.get_theme_node().get_padding(side);
|
||||
},
|
||||
|
||||
getArrowHeight: function() {
|
||||
getArrowHeight() {
|
||||
return this.actor.get_theme_node().get_length('-arrow-rise');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -21,7 +21,7 @@ var ELLIPSIS_CHAR = '\u2026';
|
||||
|
||||
var MESSAGE_ICON_SIZE = -1; // pick up from CSS
|
||||
|
||||
var NC_ = function(context, str) { return context + '\u0004' + str; };
|
||||
var NC_ = (context, str) => context + '\u0004' + str;
|
||||
|
||||
function sameYear(dateA, dateB) {
|
||||
return (dateA.getYear() == dateB.getYear());
|
||||
@@ -92,7 +92,7 @@ function _getCalendarDayAbbreviation(dayNumber) {
|
||||
var CalendarEvent = new Lang.Class({
|
||||
Name: 'CalendarEvent',
|
||||
|
||||
_init: function(id, date, end, summary, allDay) {
|
||||
_init(id, date, end, summary, allDay) {
|
||||
this.id = id;
|
||||
this.date = date;
|
||||
this.end = end;
|
||||
@@ -108,44 +108,45 @@ var CalendarEvent = new Lang.Class({
|
||||
var EmptyEventSource = new Lang.Class({
|
||||
Name: 'EmptyEventSource',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this.isLoading = false;
|
||||
this.isDummy = true;
|
||||
this.hasCalendars = false;
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
destroy() {
|
||||
},
|
||||
|
||||
ignoreEvent: function(event) {
|
||||
ignoreEvent(event) {
|
||||
},
|
||||
|
||||
requestRange: function(begin, end) {
|
||||
requestRange(begin, end) {
|
||||
},
|
||||
|
||||
getEvents: function(begin, end) {
|
||||
getEvents(begin, end) {
|
||||
let result = [];
|
||||
return result;
|
||||
},
|
||||
|
||||
hasEvents: function(day) {
|
||||
hasEvents(day) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(EmptyEventSource.prototype);
|
||||
|
||||
const CalendarServerIface = '<node> \
|
||||
<interface name="org.gnome.Shell.CalendarServer"> \
|
||||
<method name="GetEvents"> \
|
||||
<arg type="x" direction="in" /> \
|
||||
<arg type="x" direction="in" /> \
|
||||
<arg type="b" direction="in" /> \
|
||||
<arg type="a(sssbxxa{sv})" direction="out" /> \
|
||||
</method> \
|
||||
<property name="HasCalendars" type="b" access="read" /> \
|
||||
<signal name="Changed" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const CalendarServerIface = `
|
||||
<node>
|
||||
<interface name="org.gnome.Shell.CalendarServer">
|
||||
<method name="GetEvents">
|
||||
<arg type="x" direction="in" />
|
||||
<arg type="x" direction="in" />
|
||||
<arg type="b" direction="in" />
|
||||
<arg type="a(sssbxxa{sv})" direction="out" />
|
||||
</method>
|
||||
<property name="HasCalendars" type="b" access="read" />
|
||||
<signal name="Changed" />
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const CalendarServerInfo = Gio.DBusInterfaceInfo.new_for_xml(CalendarServerIface);
|
||||
|
||||
@@ -179,7 +180,7 @@ function _dateIntervalsOverlap(a0, a1, b0, b1)
|
||||
var DBusEventSource = new Lang.Class({
|
||||
Name: 'DBusEventSource',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._resetCache();
|
||||
this.isLoading = false;
|
||||
this.isDummy = false;
|
||||
@@ -188,14 +189,13 @@ var DBusEventSource = new Lang.Class({
|
||||
|
||||
let savedState = global.get_persistent_state('as', 'ignored_events');
|
||||
if (savedState)
|
||||
savedState.deep_unpack().forEach(Lang.bind(this,
|
||||
function(eventId) {
|
||||
this._ignoredEvents.set(eventId, true);
|
||||
}));
|
||||
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, Lang.bind(this, function(object, result) {
|
||||
this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, (object, result) => {
|
||||
let loaded = false;
|
||||
|
||||
try {
|
||||
@@ -216,28 +216,28 @@ var DBusEventSource = new Lang.Class({
|
||||
}
|
||||
}
|
||||
|
||||
this._dbusProxy.connectSignal('Changed', Lang.bind(this, this._onChanged));
|
||||
this._dbusProxy.connectSignal('Changed', this._onChanged.bind(this));
|
||||
|
||||
this._dbusProxy.connect('notify::g-name-owner', Lang.bind(this, function() {
|
||||
this._dbusProxy.connect('notify::g-name-owner', () => {
|
||||
if (this._dbusProxy.g_name_owner)
|
||||
this._onNameAppeared();
|
||||
else
|
||||
this._onNameVanished();
|
||||
}));
|
||||
});
|
||||
|
||||
this._dbusProxy.connect('g-properties-changed', Lang.bind(this, function() {
|
||||
this._dbusProxy.connect('g-properties-changed', () => {
|
||||
this.emit('notify::has-calendars');
|
||||
}));
|
||||
});
|
||||
|
||||
this._initialized = loaded;
|
||||
if (loaded) {
|
||||
this.emit('notify::has-calendars');
|
||||
this._onNameAppeared();
|
||||
}
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
destroy() {
|
||||
this._dbusProxy.run_dispose();
|
||||
},
|
||||
|
||||
@@ -248,28 +248,28 @@ var DBusEventSource = new Lang.Class({
|
||||
return false;
|
||||
},
|
||||
|
||||
_resetCache: function() {
|
||||
_resetCache() {
|
||||
this._events = [];
|
||||
this._lastRequestBegin = null;
|
||||
this._lastRequestEnd = null;
|
||||
},
|
||||
|
||||
_onNameAppeared: function(owner) {
|
||||
_onNameAppeared(owner) {
|
||||
this._initialized = true;
|
||||
this._resetCache();
|
||||
this._loadEvents(true);
|
||||
},
|
||||
|
||||
_onNameVanished: function(oldOwner) {
|
||||
_onNameVanished(oldOwner) {
|
||||
this._resetCache();
|
||||
this.emit('changed');
|
||||
},
|
||||
|
||||
_onChanged: function() {
|
||||
_onChanged() {
|
||||
this._loadEvents(false);
|
||||
},
|
||||
|
||||
_onEventsReceived: function(results, error) {
|
||||
_onEventsReceived(results, error) {
|
||||
let newEvents = [];
|
||||
let appointments = results ? results[0] : null;
|
||||
if (appointments != null) {
|
||||
@@ -283,9 +283,7 @@ var DBusEventSource = new Lang.Class({
|
||||
let event = new CalendarEvent(id, date, end, summary, allDay);
|
||||
newEvents.push(event);
|
||||
}
|
||||
newEvents.sort(function(event1, event2) {
|
||||
return event1.date.getTime() - event2.date.getTime();
|
||||
});
|
||||
newEvents.sort((ev1, ev2) => ev1.date.getTime() - ev2.date.getTime());
|
||||
}
|
||||
|
||||
this._events = newEvents;
|
||||
@@ -293,7 +291,7 @@ var DBusEventSource = new Lang.Class({
|
||||
this.emit('changed');
|
||||
},
|
||||
|
||||
_loadEvents: function(forceReload) {
|
||||
_loadEvents(forceReload) {
|
||||
// Ignore while loading
|
||||
if (!this._initialized)
|
||||
return;
|
||||
@@ -302,12 +300,12 @@ var DBusEventSource = new Lang.Class({
|
||||
this._dbusProxy.GetEventsRemote(this._curRequestBegin.getTime() / 1000,
|
||||
this._curRequestEnd.getTime() / 1000,
|
||||
forceReload,
|
||||
Lang.bind(this, this._onEventsReceived),
|
||||
this._onEventsReceived.bind(this),
|
||||
Gio.DBusCallFlags.NONE);
|
||||
}
|
||||
},
|
||||
|
||||
ignoreEvent: function(event) {
|
||||
ignoreEvent(event) {
|
||||
if (this._ignoredEvents.get(event.id))
|
||||
return;
|
||||
|
||||
@@ -317,7 +315,7 @@ var DBusEventSource = new Lang.Class({
|
||||
this.emit('changed');
|
||||
},
|
||||
|
||||
requestRange: function(begin, end) {
|
||||
requestRange(begin, end) {
|
||||
if (!(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
|
||||
this.isLoading = true;
|
||||
this._lastRequestBegin = begin;
|
||||
@@ -328,7 +326,7 @@ var DBusEventSource = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
getEvents: function(begin, end) {
|
||||
getEvents(begin, end) {
|
||||
let result = [];
|
||||
for(let n = 0; n < this._events.length; n++) {
|
||||
let event = this._events[n];
|
||||
@@ -340,7 +338,7 @@ var DBusEventSource = new Lang.Class({
|
||||
result.push(event);
|
||||
}
|
||||
}
|
||||
result.sort(function(event1, event2) {
|
||||
result.sort((event1, event2) => {
|
||||
// sort events by end time on ending day
|
||||
let d1 = event1.date < begin && event1.end <= end ? event1.end : event1.date;
|
||||
let d2 = event2.date < begin && event2.end <= end ? event2.end : event2.date;
|
||||
@@ -349,7 +347,7 @@ var DBusEventSource = new Lang.Class({
|
||||
return result;
|
||||
},
|
||||
|
||||
hasEvents: function(day) {
|
||||
hasEvents(day) {
|
||||
let dayBegin = _getBeginningOfDay(day);
|
||||
let dayEnd = _getEndOfDay(day);
|
||||
|
||||
@@ -366,11 +364,11 @@ Signals.addSignalMethods(DBusEventSource.prototype);
|
||||
var Calendar = new Lang.Class({
|
||||
Name: 'Calendar',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._weekStart = Shell.util_get_week_start();
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.calendar' });
|
||||
|
||||
this._settings.connect('changed::' + SHOW_WEEKDATE_KEY, Lang.bind(this, this._onSettingsChange));
|
||||
this._settings.connect('changed::' + SHOW_WEEKDATE_KEY, this._onSettingsChange.bind(this));
|
||||
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
|
||||
|
||||
/**
|
||||
@@ -401,25 +399,25 @@ var Calendar = new Lang.Class({
|
||||
reactive: true });
|
||||
|
||||
this.actor.connect('scroll-event',
|
||||
Lang.bind(this, this._onScroll));
|
||||
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.
|
||||
setEventSource: function(eventSource) {
|
||||
setEventSource(eventSource) {
|
||||
this._eventSource = eventSource;
|
||||
this._eventSource.connect('changed', Lang.bind(this, function() {
|
||||
this._eventSource.connect('changed', () => {
|
||||
this._rebuildCalendar();
|
||||
this._update();
|
||||
}));
|
||||
});
|
||||
this._rebuildCalendar();
|
||||
this._update();
|
||||
},
|
||||
|
||||
// Sets the calendar to show a specific date
|
||||
setDate: function(date) {
|
||||
setDate(date) {
|
||||
if (sameDay(date, this._selectedDate))
|
||||
return;
|
||||
|
||||
@@ -428,14 +426,14 @@ var Calendar = new Lang.Class({
|
||||
this.emit('selected-date-changed', new Date(this._selectedDate));
|
||||
},
|
||||
|
||||
updateTimeZone: function() {
|
||||
updateTimeZone() {
|
||||
// The calendar need to be rebuilt after a time zone update because
|
||||
// the date might have changed.
|
||||
this._rebuildCalendar();
|
||||
this._update();
|
||||
},
|
||||
|
||||
_buildHeader: function() {
|
||||
_buildHeader() {
|
||||
let layout = this.actor.layout_manager;
|
||||
let offsetCols = this._useWeekdate ? 1 : 0;
|
||||
this.actor.destroy_all_children();
|
||||
@@ -449,7 +447,7 @@ var Calendar = new Lang.Class({
|
||||
accessible_name: _("Previous month"),
|
||||
can_focus: true });
|
||||
this._topBox.add(this._backButton);
|
||||
this._backButton.connect('clicked', Lang.bind(this, this._onPrevMonthButtonClicked));
|
||||
this._backButton.connect('clicked', this._onPrevMonthButtonClicked.bind(this));
|
||||
|
||||
this._monthLabel = new St.Label({style_class: 'calendar-month-label',
|
||||
can_focus: true });
|
||||
@@ -459,7 +457,7 @@ var Calendar = new Lang.Class({
|
||||
accessible_name: _("Next month"),
|
||||
can_focus: true });
|
||||
this._topBox.add(this._forwardButton);
|
||||
this._forwardButton.connect('clicked', Lang.bind(this, this._onNextMonthButtonClicked));
|
||||
this._forwardButton.connect('clicked', this._onNextMonthButtonClicked.bind(this));
|
||||
|
||||
// Add weekday labels...
|
||||
//
|
||||
@@ -490,7 +488,7 @@ var Calendar = new Lang.Class({
|
||||
this._firstDayIndex = this.actor.get_n_children();
|
||||
},
|
||||
|
||||
_onScroll : function(actor, event) {
|
||||
_onScroll(actor, event) {
|
||||
switch (event.get_scroll_direction()) {
|
||||
case Clutter.ScrollDirection.UP:
|
||||
case Clutter.ScrollDirection.LEFT:
|
||||
@@ -504,7 +502,7 @@ var Calendar = new Lang.Class({
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
},
|
||||
|
||||
_onPrevMonthButtonClicked: function() {
|
||||
_onPrevMonthButtonClicked() {
|
||||
let newDate = new Date(this._selectedDate);
|
||||
let oldMonth = newDate.getMonth();
|
||||
if (oldMonth == 0) {
|
||||
@@ -528,7 +526,7 @@ var Calendar = new Lang.Class({
|
||||
this.setDate(newDate);
|
||||
},
|
||||
|
||||
_onNextMonthButtonClicked: function() {
|
||||
_onNextMonthButtonClicked() {
|
||||
let newDate = new Date(this._selectedDate);
|
||||
let oldMonth = newDate.getMonth();
|
||||
if (oldMonth == 11) {
|
||||
@@ -552,14 +550,14 @@ var Calendar = new Lang.Class({
|
||||
this.setDate(newDate);
|
||||
},
|
||||
|
||||
_onSettingsChange: function() {
|
||||
_onSettingsChange() {
|
||||
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
|
||||
this._buildHeader();
|
||||
this._rebuildCalendar();
|
||||
this._update();
|
||||
},
|
||||
|
||||
_rebuildCalendar: function() {
|
||||
_rebuildCalendar() {
|
||||
let now = new Date();
|
||||
|
||||
// Remove everything but the topBox and the weekday labels
|
||||
@@ -617,11 +615,11 @@ var Calendar = new Lang.Class({
|
||||
button.reactive = false;
|
||||
|
||||
button._date = new Date(iter);
|
||||
button.connect('clicked', Lang.bind(this, function() {
|
||||
button.connect('clicked', () => {
|
||||
this._shouldDateGrabFocus = true;
|
||||
this.setDate(button._date);
|
||||
this._shouldDateGrabFocus = false;
|
||||
}));
|
||||
});
|
||||
|
||||
let hasEvents = this._eventSource.hasEvents(iter);
|
||||
let styleClass = 'calendar-day-base calendar-day';
|
||||
@@ -680,7 +678,7 @@ var Calendar = new Lang.Class({
|
||||
this._eventSource.requestRange(beginDate, iter);
|
||||
},
|
||||
|
||||
_update: function() {
|
||||
_update() {
|
||||
let now = new Date();
|
||||
|
||||
if (sameYear(this._selectedDate, now))
|
||||
@@ -691,7 +689,7 @@ var Calendar = new Lang.Class({
|
||||
if (!this._calendarBegin || !sameMonth(this._selectedDate, this._calendarBegin) || !sameDay(now, this._markedAsToday))
|
||||
this._rebuildCalendar();
|
||||
|
||||
this._buttons.forEach(Lang.bind(this, function(button) {
|
||||
this._buttons.forEach(button => {
|
||||
if (sameDay(button._date, this._selectedDate)) {
|
||||
button.add_style_pseudo_class('selected');
|
||||
if (this._shouldDateGrabFocus)
|
||||
@@ -699,7 +697,7 @@ var Calendar = new Lang.Class({
|
||||
}
|
||||
else
|
||||
button.remove_style_pseudo_class('selected');
|
||||
}));
|
||||
});
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(Calendar.prototype);
|
||||
@@ -708,7 +706,7 @@ var EventMessage = new Lang.Class({
|
||||
Name: 'EventMessage',
|
||||
Extends: MessageList.Message,
|
||||
|
||||
_init: function(event, date) {
|
||||
_init(event, date) {
|
||||
this._event = event;
|
||||
this._date = date;
|
||||
|
||||
@@ -723,7 +721,7 @@ var EventMessage = new Lang.Class({
|
||||
});
|
||||
},
|
||||
|
||||
_formatEventTime: function() {
|
||||
_formatEventTime() {
|
||||
let periodBegin = _getBeginningOfDay(this._date);
|
||||
let periodEnd = _getEndOfDay(this._date);
|
||||
let allDay = (this._event.allDay || (this._event.date <= periodBegin &&
|
||||
@@ -756,7 +754,7 @@ var EventMessage = new Lang.Class({
|
||||
return title;
|
||||
},
|
||||
|
||||
canClose: function() {
|
||||
canClose() {
|
||||
return isToday(this._date);
|
||||
}
|
||||
});
|
||||
@@ -765,7 +763,7 @@ var NotificationMessage = new Lang.Class({
|
||||
Name: 'NotificationMessage',
|
||||
Extends: MessageList.Message,
|
||||
|
||||
_init: function(notification) {
|
||||
_init(notification) {
|
||||
this.notification = notification;
|
||||
|
||||
this.parent(notification.title, notification.bannerBodyText);
|
||||
@@ -773,21 +771,19 @@ var NotificationMessage = new Lang.Class({
|
||||
|
||||
this.setIcon(this._getIcon());
|
||||
|
||||
this.connect('close', Lang.bind(this,
|
||||
function() {
|
||||
this._closed = true;
|
||||
this.notification.destroy(MessageTray.NotificationDestroyedReason.DISMISSED);
|
||||
}));
|
||||
this._destroyId = notification.connect('destroy', Lang.bind(this,
|
||||
function() {
|
||||
if (!this._closed)
|
||||
this.close();
|
||||
}));
|
||||
this.connect('close', () => {
|
||||
this._closed = true;
|
||||
this.notification.destroy(MessageTray.NotificationDestroyedReason.DISMISSED);
|
||||
});
|
||||
this._destroyId = notification.connect('destroy', () => {
|
||||
if (!this._closed)
|
||||
this.close();
|
||||
});
|
||||
this._updatedId = notification.connect('updated',
|
||||
Lang.bind(this, this._onUpdated));
|
||||
this._onUpdated.bind(this));
|
||||
},
|
||||
|
||||
_getIcon: function() {
|
||||
_getIcon() {
|
||||
if (this.notification.gicon)
|
||||
return new St.Icon({ gicon: this.notification.gicon,
|
||||
icon_size: MESSAGE_ICON_SIZE });
|
||||
@@ -795,18 +791,20 @@ var NotificationMessage = new Lang.Class({
|
||||
return this.notification.source.createIcon(MESSAGE_ICON_SIZE);
|
||||
},
|
||||
|
||||
_onUpdated: function(n, clear) {
|
||||
_onUpdated(n, clear) {
|
||||
this.setIcon(this._getIcon());
|
||||
this.setTitle(n.title);
|
||||
this.setBody(n.bannerBodyText);
|
||||
this.setUseBodyMarkup(n.bannerBodyMarkup);
|
||||
},
|
||||
|
||||
_onClicked: function() {
|
||||
_onClicked() {
|
||||
this.notification.activate();
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
_onDestroy() {
|
||||
this.parent();
|
||||
|
||||
if (this._updatedId)
|
||||
this.notification.disconnect(this._updatedId);
|
||||
this._updatedId = 0;
|
||||
@@ -821,11 +819,13 @@ var EventsSection = new Lang.Class({
|
||||
Name: 'EventsSection',
|
||||
Extends: MessageList.MessageListSection,
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
|
||||
this._desktopSettings.connect('changed', Lang.bind(this, this._reloadEvents));
|
||||
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',
|
||||
@@ -834,28 +834,28 @@ var EventsSection = new Lang.Class({
|
||||
can_focus: true });
|
||||
this.actor.insert_child_below(this._title, null);
|
||||
|
||||
this._title.connect('clicked', Lang.bind(this, this._onTitleClicked));
|
||||
this._title.connect('key-focus-in', Lang.bind(this, this._onKeyFocusIn));
|
||||
this._title.connect('clicked', this._onTitleClicked.bind(this));
|
||||
this._title.connect('key-focus-in', this._onKeyFocusIn.bind(this));
|
||||
|
||||
Shell.AppSystem.get_default().connect('installed-changed',
|
||||
Lang.bind(this, this._appInstalledChanged));
|
||||
this._appInstalledChanged.bind(this));
|
||||
this._appInstalledChanged();
|
||||
},
|
||||
|
||||
_ignoreEvent: function(event) {
|
||||
_ignoreEvent(event) {
|
||||
this._eventSource.ignoreEvent(event);
|
||||
},
|
||||
|
||||
setEventSource: function(eventSource) {
|
||||
setEventSource(eventSource) {
|
||||
this._eventSource = eventSource;
|
||||
this._eventSource.connect('changed', Lang.bind(this, this._reloadEvents));
|
||||
this._eventSource.connect('changed', this._reloadEvents.bind(this));
|
||||
},
|
||||
|
||||
get allowed() {
|
||||
return Main.sessionMode.showCalendarEvents;
|
||||
},
|
||||
|
||||
_updateTitle: function() {
|
||||
_updateTitle() {
|
||||
this._title.visible = !isToday(this._date);
|
||||
|
||||
if (!this._title.visible)
|
||||
@@ -874,45 +874,57 @@ var EventsSection = new Lang.Class({
|
||||
this._title.label = this._date.toLocaleFormat(dayFormat);
|
||||
},
|
||||
|
||||
_reloadEvents: function() {
|
||||
_reloadEvents() {
|
||||
if (this._eventSource.isLoading)
|
||||
return;
|
||||
|
||||
this._reloading = true;
|
||||
|
||||
this._list.destroy_all_children();
|
||||
|
||||
let periodBegin = _getBeginningOfDay(this._date);
|
||||
let periodEnd = _getEndOfDay(this._date);
|
||||
let events = this._eventSource.getEvents(periodBegin, periodEnd);
|
||||
|
||||
let ids = events.map(e => e.id);
|
||||
this._messageById.forEach((message, id) => {
|
||||
if (ids.includes(id))
|
||||
return;
|
||||
this._messageById.delete(id);
|
||||
this.removeMessage(message);
|
||||
});
|
||||
|
||||
for (let i = 0; i < events.length; i++) {
|
||||
let event = events[i];
|
||||
|
||||
let message = new EventMessage(event, this._date);
|
||||
message.connect('close', Lang.bind(this, function() {
|
||||
this._ignoreEvent(event);
|
||||
}));
|
||||
this.addMessage(message, false);
|
||||
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 {
|
||||
this.moveMessage(message, i, false);
|
||||
}
|
||||
}
|
||||
|
||||
this._reloading = false;
|
||||
this._sync();
|
||||
},
|
||||
|
||||
_appInstalledChanged: function() {
|
||||
_appInstalledChanged() {
|
||||
this._calendarApp = undefined;
|
||||
this._title.reactive = (this._getCalendarApp() != null);
|
||||
},
|
||||
|
||||
_getCalendarApp: function() {
|
||||
_getCalendarApp() {
|
||||
if (this._calendarApp !== undefined)
|
||||
return this._calendarApp;
|
||||
|
||||
let apps = Gio.AppInfo.get_recommended_for_type('text/calendar');
|
||||
if (apps && (apps.length > 0)) {
|
||||
let app = Gio.AppInfo.get_default_for_type('text/calendar', false);
|
||||
let defaultInRecommended = apps.some(function(a) { return a.equal(app); });
|
||||
let defaultInRecommended = apps.some(a => a.equal(app));
|
||||
this._calendarApp = defaultInRecommended ? app : apps[0];
|
||||
} else {
|
||||
this._calendarApp = null;
|
||||
@@ -920,7 +932,7 @@ var EventsSection = new Lang.Class({
|
||||
return this._calendarApp;
|
||||
},
|
||||
|
||||
_onTitleClicked: function() {
|
||||
_onTitleClicked() {
|
||||
Main.overview.hide();
|
||||
Main.panel.closeCalendar();
|
||||
|
||||
@@ -930,17 +942,17 @@ var EventsSection = new Lang.Class({
|
||||
app.launch([], global.create_app_launch_context(0, -1));
|
||||
},
|
||||
|
||||
setDate: function(date) {
|
||||
setDate(date) {
|
||||
this.parent(date);
|
||||
this._updateTitle();
|
||||
this._reloadEvents();
|
||||
},
|
||||
|
||||
_shouldShow: function() {
|
||||
_shouldShow() {
|
||||
return !this.empty || !isToday(this._date);
|
||||
},
|
||||
|
||||
_sync: function() {
|
||||
_sync() {
|
||||
if (this._reloading)
|
||||
return;
|
||||
|
||||
@@ -952,18 +964,18 @@ var NotificationSection = new Lang.Class({
|
||||
Name: 'NotificationSection',
|
||||
Extends: MessageList.MessageListSection,
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this.parent();
|
||||
|
||||
this._sources = new Map();
|
||||
this._nUrgent = 0;
|
||||
|
||||
Main.messageTray.connect('source-added', Lang.bind(this, this._sourceAdded));
|
||||
Main.messageTray.getSources().forEach(Lang.bind(this, function(source) {
|
||||
Main.messageTray.connect('source-added', this._sourceAdded.bind(this));
|
||||
Main.messageTray.getSources().forEach(source => {
|
||||
this._sourceAdded(Main.messageTray, source);
|
||||
}));
|
||||
});
|
||||
|
||||
this.actor.connect('notify::mapped', Lang.bind(this, this._onMapped));
|
||||
this.actor.connect('notify::mapped', this._onMapped.bind(this));
|
||||
},
|
||||
|
||||
get allowed() {
|
||||
@@ -971,7 +983,7 @@ var NotificationSection = new Lang.Class({
|
||||
!Main.sessionMode.isGreeter;
|
||||
},
|
||||
|
||||
_createTimeLabel: function(datetime) {
|
||||
_createTimeLabel(datetime) {
|
||||
let label = new St.Label({ style_class: 'event-time',
|
||||
x_align: Clutter.ActorAlign.START,
|
||||
y_align: Clutter.ActorAlign.END });
|
||||
@@ -982,39 +994,37 @@ var NotificationSection = new Lang.Class({
|
||||
return label;
|
||||
},
|
||||
|
||||
_sourceAdded: function(tray, source) {
|
||||
_sourceAdded(tray, source) {
|
||||
let obj = {
|
||||
destroyId: 0,
|
||||
notificationAddedId: 0,
|
||||
};
|
||||
|
||||
obj.destroyId = source.connect('destroy', Lang.bind(this, function(source) {
|
||||
obj.destroyId = source.connect('destroy', source => {
|
||||
this._onSourceDestroy(source, obj);
|
||||
}));
|
||||
});
|
||||
obj.notificationAddedId = source.connect('notification-added',
|
||||
Lang.bind(this, this._onNotificationAdded));
|
||||
this._onNotificationAdded.bind(this));
|
||||
|
||||
this._sources.set(source, obj);
|
||||
},
|
||||
|
||||
_onNotificationAdded: function(source, notification) {
|
||||
_onNotificationAdded(source, notification) {
|
||||
let message = new NotificationMessage(notification);
|
||||
message.setSecondaryActor(this._createTimeLabel(notification.datetime));
|
||||
|
||||
let isUrgent = notification.urgency == MessageTray.Urgency.CRITICAL;
|
||||
|
||||
let updatedId = notification.connect('updated', Lang.bind(this,
|
||||
function() {
|
||||
message.setSecondaryActor(this._createTimeLabel(notification.datetime));
|
||||
this.moveMessage(message, isUrgent ? 0 : this._nUrgent, this.actor.mapped);
|
||||
}));
|
||||
let destroyId = notification.connect('destroy', Lang.bind(this,
|
||||
function() {
|
||||
notification.disconnect(destroyId);
|
||||
notification.disconnect(updatedId);
|
||||
if (isUrgent)
|
||||
this._nUrgent--;
|
||||
}));
|
||||
let updatedId = notification.connect('updated', () => {
|
||||
message.setSecondaryActor(this._createTimeLabel(notification.datetime));
|
||||
this.moveMessage(message, isUrgent ? 0 : this._nUrgent, this.actor.mapped);
|
||||
});
|
||||
let destroyId = notification.connect('destroy', () => {
|
||||
notification.disconnect(destroyId);
|
||||
notification.disconnect(updatedId);
|
||||
if (isUrgent)
|
||||
this._nUrgent--;
|
||||
});
|
||||
|
||||
if (isUrgent) {
|
||||
// Keep track of urgent notifications to keep them on top
|
||||
@@ -1030,14 +1040,14 @@ var NotificationSection = new Lang.Class({
|
||||
this.addMessageAtIndex(message, index, this.actor.mapped);
|
||||
},
|
||||
|
||||
_onSourceDestroy: function(source, obj) {
|
||||
_onSourceDestroy(source, obj) {
|
||||
source.disconnect(obj.destroyId);
|
||||
source.disconnect(obj.notificationAddedId);
|
||||
|
||||
this._sources.delete(source);
|
||||
},
|
||||
|
||||
_onMapped: function() {
|
||||
_onMapped() {
|
||||
if (!this.actor.mapped)
|
||||
return;
|
||||
|
||||
@@ -1046,7 +1056,7 @@ var NotificationSection = new Lang.Class({
|
||||
message.notification.acknowledged = true;
|
||||
},
|
||||
|
||||
_shouldShow: function() {
|
||||
_shouldShow() {
|
||||
return !this.empty && isToday(this._date);
|
||||
}
|
||||
});
|
||||
@@ -1054,7 +1064,7 @@ var NotificationSection = new Lang.Class({
|
||||
var Placeholder = new Lang.Class({
|
||||
Name: 'Placeholder',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this.actor = new St.BoxLayout({ style_class: 'message-list-placeholder',
|
||||
vertical: true });
|
||||
|
||||
@@ -1074,14 +1084,14 @@ var Placeholder = new Lang.Class({
|
||||
this._sync();
|
||||
},
|
||||
|
||||
setDate: function(date) {
|
||||
setDate(date) {
|
||||
if (sameDay(this._date, date))
|
||||
return;
|
||||
this._date = date;
|
||||
this._sync();
|
||||
},
|
||||
|
||||
_sync: function() {
|
||||
_sync() {
|
||||
let today = isToday(this._date);
|
||||
if (today && this._icon.gicon == this._todayIcon)
|
||||
return;
|
||||
@@ -1101,7 +1111,7 @@ var Placeholder = new Lang.Class({
|
||||
var CalendarMessageList = new Lang.Class({
|
||||
Name: 'CalendarMessageList',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this.actor = new St.Widget({ style_class: 'message-list',
|
||||
layout_manager: new Clutter.BinLayout(),
|
||||
x_expand: true, y_expand: true });
|
||||
@@ -1146,10 +1156,10 @@ var CalendarMessageList = new Lang.Class({
|
||||
this._eventsSection = new EventsSection();
|
||||
this._addSection(this._eventsSection);
|
||||
|
||||
Main.sessionMode.connect('updated', Lang.bind(this, this._sync));
|
||||
Main.sessionMode.connect('updated', this._sync.bind(this));
|
||||
},
|
||||
|
||||
_addSection: function(section) {
|
||||
_addSection(section) {
|
||||
let obj = {
|
||||
destroyId: 0,
|
||||
visibleId: 0,
|
||||
@@ -1157,25 +1167,24 @@ var CalendarMessageList = new Lang.Class({
|
||||
canClearChangedId: 0,
|
||||
keyFocusId: 0
|
||||
};
|
||||
obj.destroyId = section.actor.connect('destroy', Lang.bind(this,
|
||||
function() {
|
||||
this._removeSection(section);
|
||||
}));
|
||||
obj.destroyId = section.actor.connect('destroy', () => {
|
||||
this._removeSection(section);
|
||||
});
|
||||
obj.visibleId = section.actor.connect('notify::visible',
|
||||
Lang.bind(this, this._sync));
|
||||
this._sync.bind(this));
|
||||
obj.emptyChangedId = section.connect('empty-changed',
|
||||
Lang.bind(this, this._sync));
|
||||
this._sync.bind(this));
|
||||
obj.canClearChangedId = section.connect('can-clear-changed',
|
||||
Lang.bind(this, this._sync));
|
||||
this._sync.bind(this));
|
||||
obj.keyFocusId = section.connect('key-focus-in',
|
||||
Lang.bind(this, this._onKeyFocusIn));
|
||||
this._onKeyFocusIn.bind(this));
|
||||
|
||||
this._sections.set(section, obj);
|
||||
this._sectionList.add_actor(section.actor);
|
||||
this._sync();
|
||||
},
|
||||
|
||||
_removeSection: function(section) {
|
||||
_removeSection(section) {
|
||||
let obj = this._sections.get(section);
|
||||
section.actor.disconnect(obj.destroyId);
|
||||
section.actor.disconnect(obj.visibleId);
|
||||
@@ -1188,36 +1197,30 @@ var CalendarMessageList = new Lang.Class({
|
||||
this._sync();
|
||||
},
|
||||
|
||||
_onKeyFocusIn: function(section, actor) {
|
||||
_onKeyFocusIn(section, actor) {
|
||||
Util.ensureActorVisibleInScrollView(this._scrollView, actor);
|
||||
},
|
||||
|
||||
_sync: function() {
|
||||
_sync() {
|
||||
let sections = [...this._sections.keys()];
|
||||
let visible = sections.some(function(s) {
|
||||
return s.allowed;
|
||||
});
|
||||
let visible = sections.some(s => s.allowed);
|
||||
this.actor.visible = visible;
|
||||
if (!visible)
|
||||
return;
|
||||
|
||||
let empty = sections.every(function(s) {
|
||||
return s.empty || !s.actor.visible;
|
||||
});
|
||||
let empty = sections.every(s => s.empty || !s.actor.visible);
|
||||
this._placeholder.actor.visible = empty;
|
||||
this._clearButton.visible = !empty;
|
||||
|
||||
let canClear = sections.some(function(s) {
|
||||
return s.canClear && s.actor.visible;
|
||||
});
|
||||
let canClear = sections.some(s => s.canClear && s.actor.visible);
|
||||
this._clearButton.reactive = canClear;
|
||||
},
|
||||
|
||||
setEventSource: function(eventSource) {
|
||||
setEventSource(eventSource) {
|
||||
this._eventsSection.setEventSource(eventSource);
|
||||
},
|
||||
|
||||
setDate: function(date) {
|
||||
setDate(date) {
|
||||
for (let section of this._sections.keys())
|
||||
section.setDate(date);
|
||||
this._placeholder.setDate(date);
|
||||
|
||||
@@ -7,7 +7,7 @@ const Lang = imports.lang;
|
||||
var CheckBox = new Lang.Class({
|
||||
Name: 'CheckBox',
|
||||
|
||||
_init: function(label) {
|
||||
_init(label) {
|
||||
let container = new St.BoxLayout();
|
||||
this.actor = new St.Button({ style_class: 'check-box',
|
||||
child: container,
|
||||
@@ -30,11 +30,11 @@ var CheckBox = new Lang.Class({
|
||||
this.setLabel(label);
|
||||
},
|
||||
|
||||
setLabel: function(label) {
|
||||
setLabel(label) {
|
||||
this._label.set_text(label);
|
||||
},
|
||||
|
||||
getLabelActor: function() {
|
||||
getLabelActor() {
|
||||
return this._label;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,6 +2,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;
|
||||
@@ -13,6 +14,7 @@ const Tweener = imports.ui.tweener;
|
||||
|
||||
var FROZEN_WINDOW_BRIGHTNESS = -0.3
|
||||
var DIALOG_TRANSITION_TIME = 0.15
|
||||
var ALIVE_TIMEOUT = 5000;
|
||||
|
||||
var CloseDialog = new Lang.Class({
|
||||
Name: 'CloseDialog',
|
||||
@@ -22,10 +24,11 @@ var CloseDialog = new Lang.Class({
|
||||
'window': GObject.ParamSpec.override('window', Meta.CloseDialog)
|
||||
},
|
||||
|
||||
_init: function (window) {
|
||||
_init(window) {
|
||||
this.parent();
|
||||
this._window = window;
|
||||
this._dialog = null;
|
||||
this._timeoutId = 0;
|
||||
},
|
||||
|
||||
get window() {
|
||||
@@ -36,7 +39,7 @@ var CloseDialog = new Lang.Class({
|
||||
this._window = window;
|
||||
},
|
||||
|
||||
_createDialogContent: function () {
|
||||
_createDialogContent() {
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
let windowApp = tracker.get_window_app(this._window);
|
||||
|
||||
@@ -48,7 +51,7 @@ var CloseDialog = new Lang.Class({
|
||||
return new Dialog.MessageDialogContent({ icon, title, subtitle });
|
||||
},
|
||||
|
||||
_initDialog: function () {
|
||||
_initDialog() {
|
||||
if (this._dialog)
|
||||
return;
|
||||
|
||||
@@ -59,16 +62,16 @@ var CloseDialog = new Lang.Class({
|
||||
|
||||
this._dialog.addContent(this._createDialogContent());
|
||||
this._dialog.addButton({ label: _('Force Quit'),
|
||||
action: Lang.bind(this, this._onClose),
|
||||
action: this._onClose.bind(this),
|
||||
default: true });
|
||||
this._dialog.addButton({ label: _('Wait'),
|
||||
action: Lang.bind(this, this._onWait),
|
||||
action: this._onWait.bind(this),
|
||||
key: Clutter.Escape });
|
||||
|
||||
global.focus_manager.add_group(this._dialog);
|
||||
},
|
||||
|
||||
_addWindowEffect: function () {
|
||||
_addWindowEffect() {
|
||||
// We set the effect on the surface actor, so the dialog itself
|
||||
// (which is a child of the MetaWindowActor) does not get the
|
||||
// effect applied itself.
|
||||
@@ -79,24 +82,32 @@ var CloseDialog = new Lang.Class({
|
||||
surfaceActor.add_effect_with_name("gnome-shell-frozen-window", effect);
|
||||
},
|
||||
|
||||
_removeWindowEffect: function () {
|
||||
_removeWindowEffect() {
|
||||
let windowActor = this._window.get_compositor_private();
|
||||
let surfaceActor = windowActor.get_first_child();
|
||||
surfaceActor.remove_effect_by_name("gnome-shell-frozen-window");
|
||||
},
|
||||
|
||||
_onWait: function () {
|
||||
_onWait() {
|
||||
this.response(Meta.CloseDialogResponse.WAIT);
|
||||
},
|
||||
|
||||
_onClose: function () {
|
||||
_onClose() {
|
||||
this.response(Meta.CloseDialogResponse.FORCE_CLOSE);
|
||||
},
|
||||
|
||||
vfunc_show: function () {
|
||||
vfunc_show() {
|
||||
if (this._dialog != null)
|
||||
return;
|
||||
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
|
||||
this._timeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, ALIVE_TIMEOUT,
|
||||
() => {
|
||||
this._window.check_alive(global.display.get_current_time_roundtrip());
|
||||
return GLib.SOURCE_CONTINUE;
|
||||
});
|
||||
|
||||
this._addWindowEffect();
|
||||
this._initDialog();
|
||||
|
||||
@@ -107,16 +118,21 @@ var CloseDialog = new Lang.Class({
|
||||
{ scale_y: 1,
|
||||
transition: 'linear',
|
||||
time: DIALOG_TRANSITION_TIME,
|
||||
onComplete: Lang.bind(this, function () {
|
||||
onComplete: () => {
|
||||
Main.layoutManager.trackChrome(this._dialog, { affectsInputRegion: true });
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
vfunc_hide: function () {
|
||||
vfunc_hide() {
|
||||
if (this._dialog == null)
|
||||
return;
|
||||
|
||||
Meta.enable_unredirect_for_display(global.display);
|
||||
|
||||
GLib.source_remove(this._timeoutId);
|
||||
this._timeoutId = 0;
|
||||
|
||||
let dialog = this._dialog;
|
||||
this._dialog = null;
|
||||
this._removeWindowEffect();
|
||||
@@ -125,13 +141,13 @@ var CloseDialog = new Lang.Class({
|
||||
{ scale_y: 0,
|
||||
transition: 'linear',
|
||||
time: DIALOG_TRANSITION_TIME,
|
||||
onComplete: Lang.bind(this, function () {
|
||||
onComplete: () => {
|
||||
dialog.destroy();
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
vfunc_focus: function () {
|
||||
vfunc_focus() {
|
||||
if (this._dialog)
|
||||
this._dialog.grab_key_focus();
|
||||
}
|
||||
|
||||
@@ -5,38 +5,38 @@ const Main = imports.ui.main;
|
||||
var ComponentManager = new Lang.Class({
|
||||
Name: 'ComponentManager',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._allComponents = {};
|
||||
this._enabledComponents = [];
|
||||
|
||||
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
|
||||
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
|
||||
this._sessionUpdated();
|
||||
},
|
||||
|
||||
_sessionUpdated: function() {
|
||||
_sessionUpdated() {
|
||||
let newEnabledComponents = Main.sessionMode.components;
|
||||
|
||||
newEnabledComponents.filter(Lang.bind(this, function(name) {
|
||||
return this._enabledComponents.indexOf(name) == -1;
|
||||
})).forEach(Lang.bind(this, function(name) {
|
||||
newEnabledComponents.filter(
|
||||
name => this._enabledComponents.indexOf(name) == -1
|
||||
).forEach(name => {
|
||||
this._enableComponent(name);
|
||||
}));
|
||||
});
|
||||
|
||||
this._enabledComponents.filter(Lang.bind(this, function(name) {
|
||||
return newEnabledComponents.indexOf(name) == -1;
|
||||
})).forEach(Lang.bind(this, function(name) {
|
||||
this._enabledComponents.filter(
|
||||
name => newEnabledComponents.indexOf(name) == -1
|
||||
).forEach(name => {
|
||||
this._disableComponent(name);
|
||||
}));
|
||||
});
|
||||
|
||||
this._enabledComponents = newEnabledComponents;
|
||||
},
|
||||
|
||||
_importComponent: function(name) {
|
||||
_importComponent(name) {
|
||||
let module = imports.ui.components[name];
|
||||
return module.Component;
|
||||
},
|
||||
|
||||
_ensureComponent: function(name) {
|
||||
_ensureComponent(name) {
|
||||
let component = this._allComponents[name];
|
||||
if (component)
|
||||
return component;
|
||||
@@ -50,13 +50,13 @@ var ComponentManager = new Lang.Class({
|
||||
return component;
|
||||
},
|
||||
|
||||
_enableComponent: function(name) {
|
||||
_enableComponent(name) {
|
||||
let component = this._ensureComponent(name);
|
||||
if (component)
|
||||
component.enable();
|
||||
},
|
||||
|
||||
_disableComponent: function(name) {
|
||||
_disableComponent(name) {
|
||||
let component = this._allComponents[name];
|
||||
if (component == null)
|
||||
return;
|
||||
|
||||
@@ -22,31 +22,31 @@ var AUTORUN_EXPIRE_TIMEOUT_SECS = 10;
|
||||
var AutomountManager = new Lang.Class({
|
||||
Name: 'AutomountManager',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
|
||||
this._volumeQueue = [];
|
||||
this._session = new GnomeSession.SessionManager();
|
||||
this._session.connectSignal('InhibitorAdded',
|
||||
Lang.bind(this, this._InhibitorsChanged));
|
||||
this._InhibitorsChanged.bind(this));
|
||||
this._session.connectSignal('InhibitorRemoved',
|
||||
Lang.bind(this, this._InhibitorsChanged));
|
||||
this._InhibitorsChanged.bind(this));
|
||||
this._inhibited = false;
|
||||
|
||||
this._volumeMonitor = Gio.VolumeMonitor.get();
|
||||
},
|
||||
|
||||
enable: function() {
|
||||
this._volumeAddedId = this._volumeMonitor.connect('volume-added', Lang.bind(this, this._onVolumeAdded));
|
||||
this._volumeRemovedId = this._volumeMonitor.connect('volume-removed', Lang.bind(this, this._onVolumeRemoved));
|
||||
this._driveConnectedId = this._volumeMonitor.connect('drive-connected', Lang.bind(this, this._onDriveConnected));
|
||||
this._driveDisconnectedId = this._volumeMonitor.connect('drive-disconnected', Lang.bind(this, this._onDriveDisconnected));
|
||||
this._driveEjectButtonId = this._volumeMonitor.connect('drive-eject-button', Lang.bind(this, this._onDriveEjectButton));
|
||||
enable() {
|
||||
this._volumeAddedId = this._volumeMonitor.connect('volume-added', this._onVolumeAdded.bind(this));
|
||||
this._volumeRemovedId = this._volumeMonitor.connect('volume-removed', this._onVolumeRemoved.bind(this));
|
||||
this._driveConnectedId = this._volumeMonitor.connect('drive-connected', this._onDriveConnected.bind(this));
|
||||
this._driveDisconnectedId = this._volumeMonitor.connect('drive-disconnected', this._onDriveDisconnected.bind(this));
|
||||
this._driveEjectButtonId = this._volumeMonitor.connect('drive-eject-button', this._onDriveEjectButton.bind(this));
|
||||
|
||||
this._mountAllId = Mainloop.idle_add(Lang.bind(this, this._startupMountAll));
|
||||
this._mountAllId = Mainloop.idle_add(this._startupMountAll.bind(this));
|
||||
GLib.Source.set_name_by_id(this._mountAllId, '[gnome-shell] this._startupMountAll');
|
||||
},
|
||||
|
||||
disable: function() {
|
||||
disable() {
|
||||
this._volumeMonitor.disconnect(this._volumeAddedId);
|
||||
this._volumeMonitor.disconnect(this._volumeRemovedId);
|
||||
this._volumeMonitor.disconnect(this._driveConnectedId);
|
||||
@@ -59,29 +59,28 @@ var AutomountManager = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_InhibitorsChanged: function(object, senderName, [inhibtor]) {
|
||||
_InhibitorsChanged(object, senderName, [inhibtor]) {
|
||||
this._session.IsInhibitedRemote(GNOME_SESSION_AUTOMOUNT_INHIBIT,
|
||||
Lang.bind(this,
|
||||
function(result, error) {
|
||||
if (!error) {
|
||||
this._inhibited = result[0];
|
||||
}
|
||||
}));
|
||||
(result, error) => {
|
||||
if (!error) {
|
||||
this._inhibited = result[0];
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_startupMountAll: function() {
|
||||
_startupMountAll() {
|
||||
let volumes = this._volumeMonitor.get_volumes();
|
||||
volumes.forEach(Lang.bind(this, function(volume) {
|
||||
volumes.forEach(volume => {
|
||||
this._checkAndMountVolume(volume, { checkSession: false,
|
||||
useMountOp: false,
|
||||
allowAutorun: false });
|
||||
}));
|
||||
});
|
||||
|
||||
this._mountAllId = 0;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
},
|
||||
|
||||
_onDriveConnected: function() {
|
||||
_onDriveConnected() {
|
||||
// if we're not in the current ConsoleKit session,
|
||||
// or screensaver is active, don't play sounds
|
||||
if (!this._session.SessionIsActive)
|
||||
@@ -92,7 +91,7 @@ var AutomountManager = new Lang.Class({
|
||||
null);
|
||||
},
|
||||
|
||||
_onDriveDisconnected: function() {
|
||||
_onDriveDisconnected() {
|
||||
// if we're not in the current ConsoleKit session,
|
||||
// or screensaver is active, don't play sounds
|
||||
if (!this._session.SessionIsActive)
|
||||
@@ -103,7 +102,7 @@ var AutomountManager = new Lang.Class({
|
||||
null);
|
||||
},
|
||||
|
||||
_onDriveEjectButton: function(monitor, drive) {
|
||||
_onDriveEjectButton(monitor, drive) {
|
||||
// TODO: this code path is not tested, as the GVfs volume monitor
|
||||
// doesn't emit this signal just yet.
|
||||
if (!this._session.SessionIsActive)
|
||||
@@ -114,31 +113,31 @@ var AutomountManager = new Lang.Class({
|
||||
if (drive.can_stop()) {
|
||||
drive.stop
|
||||
(Gio.MountUnmountFlags.FORCE, null, null,
|
||||
Lang.bind(this, function(drive, res) {
|
||||
(drive, res) => {
|
||||
try {
|
||||
drive.stop_finish(res);
|
||||
} catch (e) {
|
||||
log("Unable to stop the drive after drive-eject-button " + e.toString());
|
||||
}
|
||||
}));
|
||||
});
|
||||
} else if (drive.can_eject()) {
|
||||
drive.eject_with_operation
|
||||
(Gio.MountUnmountFlags.FORCE, null, null,
|
||||
Lang.bind(this, function(drive, res) {
|
||||
(drive, res) => {
|
||||
try {
|
||||
drive.eject_with_operation_finish(res);
|
||||
} catch (e) {
|
||||
log("Unable to eject the drive after drive-eject-button " + e.toString());
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_onVolumeAdded: function(monitor, volume) {
|
||||
_onVolumeAdded(monitor, volume) {
|
||||
this._checkAndMountVolume(volume);
|
||||
},
|
||||
|
||||
_checkAndMountVolume: function(volume, params) {
|
||||
_checkAndMountVolume(volume, params) {
|
||||
params = Params.parse(params, { checkSession: true,
|
||||
useMountOp: true,
|
||||
allowAutorun: true });
|
||||
@@ -178,7 +177,7 @@ var AutomountManager = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_mountVolume: function(volume, operation, allowAutorun) {
|
||||
_mountVolume(volume, operation, allowAutorun) {
|
||||
if (allowAutorun)
|
||||
this._allowAutorun(volume);
|
||||
|
||||
@@ -186,10 +185,10 @@ var AutomountManager = new Lang.Class({
|
||||
volume._operation = operation;
|
||||
|
||||
volume.mount(0, mountOp, null,
|
||||
Lang.bind(this, this._onVolumeMounted));
|
||||
this._onVolumeMounted.bind(this));
|
||||
},
|
||||
|
||||
_onVolumeMounted: function(volume, res) {
|
||||
_onVolumeMounted(volume, res) {
|
||||
this._allowAutorunExpire(volume);
|
||||
|
||||
try {
|
||||
@@ -210,14 +209,16 @@ var AutomountManager = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_onVolumeRemoved: function(monitor, volume) {
|
||||
_onVolumeRemoved(monitor, volume) {
|
||||
if (volume._allowAutorunExpireId && volume._allowAutorunExpireId > 0) {
|
||||
Mainloop.source_remove(volume._allowAutorunExpireId);
|
||||
delete volume._allowAutorunExpireId;
|
||||
}
|
||||
this._volumeQueue =
|
||||
this._volumeQueue.filter(function(element) {
|
||||
return (element != volume);
|
||||
});
|
||||
this._volumeQueue.filter(element => (element != volume));
|
||||
},
|
||||
|
||||
_reaskPassword: function(volume) {
|
||||
_reaskPassword(volume) {
|
||||
let existingDialog = volume._operation ? volume._operation.borrowDialog() : null;
|
||||
let operation =
|
||||
new ShellMountOperation.ShellMountOperation(volume,
|
||||
@@ -225,20 +226,22 @@ var AutomountManager = new Lang.Class({
|
||||
this._mountVolume(volume, operation);
|
||||
},
|
||||
|
||||
_closeOperation: function(volume) {
|
||||
_closeOperation(volume) {
|
||||
if (volume._operation)
|
||||
volume._operation.close();
|
||||
},
|
||||
|
||||
_allowAutorun: function(volume) {
|
||||
_allowAutorun(volume) {
|
||||
volume.allowAutorun = true;
|
||||
},
|
||||
|
||||
_allowAutorunExpire: function(volume) {
|
||||
let id = Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, function() {
|
||||
_allowAutorunExpire(volume) {
|
||||
let id = Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, () => {
|
||||
volume.allowAutorun = false;
|
||||
delete volume._allowAutorunExpireId;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
volume._allowAutorunExpireId = id;
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] volume.allowAutorun');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -74,14 +74,15 @@ function startAppForMount(app, mount) {
|
||||
|
||||
/******************************************/
|
||||
|
||||
const HotplugSnifferIface = '<node> \
|
||||
<interface name="org.gnome.Shell.HotplugSniffer"> \
|
||||
<method name="SniffURI"> \
|
||||
<arg type="s" direction="in" /> \
|
||||
<arg type="as" direction="out" /> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const HotplugSnifferIface = `
|
||||
<node>
|
||||
<interface name="org.gnome.Shell.HotplugSniffer">
|
||||
<method name="SniffURI">
|
||||
<arg type="s" direction="in" />
|
||||
<arg type="as" direction="out" />
|
||||
</method>
|
||||
</interface>
|
||||
</node>`;
|
||||
|
||||
const HotplugSnifferProxy = Gio.DBusProxy.makeProxyWrapper(HotplugSnifferIface);
|
||||
function HotplugSniffer() {
|
||||
@@ -93,26 +94,25 @@ function HotplugSniffer() {
|
||||
var ContentTypeDiscoverer = new Lang.Class({
|
||||
Name: 'ContentTypeDiscoverer',
|
||||
|
||||
_init: function(callback) {
|
||||
_init(callback) {
|
||||
this._callback = callback;
|
||||
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
|
||||
},
|
||||
|
||||
guessContentTypes: function(mount) {
|
||||
guessContentTypes(mount) {
|
||||
let autorunEnabled = !this._settings.get_boolean(SETTING_DISABLE_AUTORUN);
|
||||
let shouldScan = autorunEnabled && !isMountNonLocal(mount);
|
||||
|
||||
if (shouldScan) {
|
||||
// guess mount's content types using GIO
|
||||
mount.guess_content_type(false, null,
|
||||
Lang.bind(this,
|
||||
this._onContentTypeGuessed));
|
||||
this._onContentTypeGuessed.bind(this));
|
||||
} else {
|
||||
this._emitCallback(mount, []);
|
||||
}
|
||||
},
|
||||
|
||||
_onContentTypeGuessed: function(mount, res) {
|
||||
_onContentTypeGuessed(mount, res) {
|
||||
let contentTypes = [];
|
||||
|
||||
try {
|
||||
@@ -129,23 +129,23 @@ var ContentTypeDiscoverer = new Lang.Class({
|
||||
|
||||
let hotplugSniffer = new HotplugSniffer();
|
||||
hotplugSniffer.SniffURIRemote(root.get_uri(),
|
||||
Lang.bind(this, function([contentTypes]) {
|
||||
([contentTypes]) => {
|
||||
this._emitCallback(mount, contentTypes);
|
||||
}));
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_emitCallback: function(mount, contentTypes) {
|
||||
_emitCallback(mount, contentTypes) {
|
||||
if (!contentTypes)
|
||||
contentTypes = [];
|
||||
|
||||
// we're not interested in win32 software content types here
|
||||
contentTypes = contentTypes.filter(function(type) {
|
||||
return (type != 'x-content/win32-software');
|
||||
});
|
||||
contentTypes = contentTypes.filter(
|
||||
type => (type != 'x-content/win32-software')
|
||||
);
|
||||
|
||||
let apps = [];
|
||||
contentTypes.forEach(function(type) {
|
||||
contentTypes.forEach(type => {
|
||||
let app = Gio.app_info_get_default_for_type(type, false);
|
||||
|
||||
if (app)
|
||||
@@ -162,36 +162,36 @@ var ContentTypeDiscoverer = new Lang.Class({
|
||||
var AutorunManager = new Lang.Class({
|
||||
Name: 'AutorunManager',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._session = new GnomeSession.SessionManager();
|
||||
this._volumeMonitor = Gio.VolumeMonitor.get();
|
||||
|
||||
this._dispatcher = new AutorunDispatcher(this);
|
||||
},
|
||||
|
||||
enable: function() {
|
||||
this._mountAddedId = this._volumeMonitor.connect('mount-added', Lang.bind(this, this._onMountAdded));
|
||||
this._mountRemovedId = this._volumeMonitor.connect('mount-removed', Lang.bind(this, this._onMountRemoved));
|
||||
enable() {
|
||||
this._mountAddedId = this._volumeMonitor.connect('mount-added', this._onMountAdded.bind(this));
|
||||
this._mountRemovedId = this._volumeMonitor.connect('mount-removed', this._onMountRemoved.bind(this));
|
||||
},
|
||||
|
||||
disable: function() {
|
||||
disable() {
|
||||
this._volumeMonitor.disconnect(this._mountAddedId);
|
||||
this._volumeMonitor.disconnect(this._mountRemovedId);
|
||||
},
|
||||
|
||||
_onMountAdded: function(monitor, mount) {
|
||||
_onMountAdded(monitor, mount) {
|
||||
// don't do anything if our session is not the currently
|
||||
// active one
|
||||
if (!this._session.SessionIsActive)
|
||||
return;
|
||||
|
||||
let discoverer = new ContentTypeDiscoverer(Lang.bind(this, function(mount, apps, contentTypes) {
|
||||
let discoverer = new ContentTypeDiscoverer((mount, apps, contentTypes) => {
|
||||
this._dispatcher.addMount(mount, apps, contentTypes);
|
||||
}));
|
||||
});
|
||||
discoverer.guessContentTypes(mount);
|
||||
},
|
||||
|
||||
_onMountRemoved: function(monitor, mount) {
|
||||
_onMountRemoved(monitor, mount) {
|
||||
this._dispatcher.removeMount(mount);
|
||||
}
|
||||
});
|
||||
@@ -199,13 +199,13 @@ var AutorunManager = new Lang.Class({
|
||||
var AutorunDispatcher = new Lang.Class({
|
||||
Name: 'AutorunDispatcher',
|
||||
|
||||
_init: function(manager) {
|
||||
_init(manager) {
|
||||
this._manager = manager;
|
||||
this._sources = [];
|
||||
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
|
||||
},
|
||||
|
||||
_getAutorunSettingForType: function(contentType) {
|
||||
_getAutorunSettingForType(contentType) {
|
||||
let runApp = this._settings.get_strv(SETTING_START_APP);
|
||||
if (runApp.indexOf(contentType) != -1)
|
||||
return AutorunSetting.RUN;
|
||||
@@ -221,11 +221,8 @@ var AutorunDispatcher = new Lang.Class({
|
||||
return AutorunSetting.ASK;
|
||||
},
|
||||
|
||||
_getSourceForMount: function(mount) {
|
||||
let filtered =
|
||||
this._sources.filter(function (source) {
|
||||
return (source.mount == mount);
|
||||
});
|
||||
_getSourceForMount(mount) {
|
||||
let filtered = this._sources.filter(source => (source.mount == mount));
|
||||
|
||||
// we always make sure not to add two sources for the same
|
||||
// mount in addMount(), so it's safe to assume filtered.length
|
||||
@@ -236,7 +233,7 @@ var AutorunDispatcher = new Lang.Class({
|
||||
return null;
|
||||
},
|
||||
|
||||
_addSource: function(mount, apps) {
|
||||
_addSource(mount, apps) {
|
||||
// if we already have a source showing for this
|
||||
// mount, return
|
||||
if (this._getSourceForMount(mount))
|
||||
@@ -246,7 +243,7 @@ var AutorunDispatcher = new Lang.Class({
|
||||
this._sources.push(new AutorunSource(this._manager, mount, apps));
|
||||
},
|
||||
|
||||
addMount: function(mount, apps, contentTypes) {
|
||||
addMount(mount, apps, contentTypes) {
|
||||
// if autorun is disabled globally, return
|
||||
if (this._settings.get_boolean(SETTING_DISABLE_AUTORUN))
|
||||
return;
|
||||
@@ -284,7 +281,7 @@ var AutorunDispatcher = new Lang.Class({
|
||||
this._addSource(mount, apps);
|
||||
},
|
||||
|
||||
removeMount: function(mount) {
|
||||
removeMount(mount) {
|
||||
let source = this._getSourceForMount(mount);
|
||||
|
||||
// if we aren't tracking this mount, don't do anything
|
||||
@@ -300,7 +297,7 @@ var AutorunSource = new Lang.Class({
|
||||
Name: 'AutorunSource',
|
||||
Extends: MessageTray.Source,
|
||||
|
||||
_init: function(manager, mount, apps) {
|
||||
_init(manager, mount, apps) {
|
||||
this._manager = manager;
|
||||
this.mount = mount;
|
||||
this.apps = apps;
|
||||
@@ -314,11 +311,11 @@ var AutorunSource = new Lang.Class({
|
||||
this.notify(this._notification);
|
||||
},
|
||||
|
||||
getIcon: function() {
|
||||
getIcon() {
|
||||
return this.mount.get_icon();
|
||||
},
|
||||
|
||||
_createPolicy: function() {
|
||||
_createPolicy() {
|
||||
return new MessageTray.NotificationApplicationPolicy('org.gnome.Nautilus');
|
||||
}
|
||||
});
|
||||
@@ -327,27 +324,27 @@ var AutorunNotification = new Lang.Class({
|
||||
Name: 'AutorunNotification',
|
||||
Extends: MessageTray.Notification,
|
||||
|
||||
_init: function(manager, source) {
|
||||
_init(manager, source) {
|
||||
this.parent(source, source.title);
|
||||
|
||||
this._manager = manager;
|
||||
this._mount = source.mount;
|
||||
},
|
||||
|
||||
createBanner: function() {
|
||||
createBanner() {
|
||||
let banner = new MessageTray.NotificationBanner(this);
|
||||
|
||||
this.source.apps.forEach(Lang.bind(this, function (app) {
|
||||
this.source.apps.forEach(app => {
|
||||
let actor = this._buttonForApp(app);
|
||||
|
||||
if (actor)
|
||||
banner.addButton(actor);
|
||||
}));
|
||||
});
|
||||
|
||||
return banner;
|
||||
},
|
||||
|
||||
_buttonForApp: function(app) {
|
||||
_buttonForApp(app) {
|
||||
let box = new St.BoxLayout();
|
||||
let icon = new St.Icon({ gicon: app.get_icon(),
|
||||
style_class: 'hotplug-notification-item-icon' });
|
||||
@@ -366,15 +363,15 @@ var AutorunNotification = new Lang.Class({
|
||||
button_mask: St.ButtonMask.ONE,
|
||||
style_class: 'hotplug-notification-item button' });
|
||||
|
||||
button.connect('clicked', Lang.bind(this, function() {
|
||||
button.connect('clicked', () => {
|
||||
startAppForMount(app, this._mount);
|
||||
this.destroy();
|
||||
}));
|
||||
});
|
||||
|
||||
return button;
|
||||
},
|
||||
|
||||
activate: function() {
|
||||
activate() {
|
||||
this.parent();
|
||||
|
||||
let app = Gio.app_info_get_default_for_type('inode/directory', false);
|
||||
|
||||
@@ -24,13 +24,13 @@ var KeyringDialog = new Lang.Class({
|
||||
Name: 'KeyringDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this.parent({ styleClass: 'prompt-dialog' });
|
||||
|
||||
this.prompt = new Shell.KeyringPrompt();
|
||||
this.prompt.connect('show-password', Lang.bind(this, this._onShowPassword));
|
||||
this.prompt.connect('show-confirm', Lang.bind(this, this._onShowConfirm));
|
||||
this.prompt.connect('prompt-close', Lang.bind(this, this._onHidePrompt));
|
||||
this.prompt.connect('show-password', this._onShowPassword.bind(this));
|
||||
this.prompt.connect('show-confirm', this._onShowConfirm.bind(this));
|
||||
this.prompt.connect('prompt-close', this._onHidePrompt.bind(this));
|
||||
|
||||
let icon = new Gio.ThemedIcon({ name: 'dialog-password-symbolic' });
|
||||
this._content = new Dialog.MessageDialogContent({ icon });
|
||||
@@ -55,17 +55,17 @@ var KeyringDialog = new Lang.Class({
|
||||
this._controlTable = null;
|
||||
|
||||
this._cancelButton = this.addButton({ label: '',
|
||||
action: Lang.bind(this, this._onCancelButton),
|
||||
action: this._onCancelButton.bind(this),
|
||||
key: Clutter.Escape });
|
||||
this._continueButton = this.addButton({ label: '',
|
||||
action: Lang.bind(this, this._onContinueButton),
|
||||
action: this._onContinueButton.bind(this),
|
||||
default: true });
|
||||
|
||||
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: function(working) {
|
||||
_setWorking(working) {
|
||||
if (!this._workSpinner)
|
||||
return;
|
||||
|
||||
@@ -84,7 +84,7 @@ var KeyringDialog = new Lang.Class({
|
||||
time: WORK_SPINNER_ANIMATION_TIME,
|
||||
transition: 'linear',
|
||||
onCompleteScope: this,
|
||||
onComplete: function() {
|
||||
onComplete() {
|
||||
if (this._workSpinner)
|
||||
this._workSpinner.stop();
|
||||
}
|
||||
@@ -92,7 +92,7 @@ var KeyringDialog = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_buildControlTable: function() {
|
||||
_buildControlTable() {
|
||||
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
|
||||
let table = new St.Widget({ style_class: 'keyring-dialog-control-table',
|
||||
layout_manager: layout });
|
||||
@@ -112,7 +112,7 @@ var KeyringDialog = new Lang.Class({
|
||||
x_expand: true });
|
||||
this._passwordEntry.clutter_text.set_password_char('\u25cf'); // ● U+25CF BLACK CIRCLE
|
||||
ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true });
|
||||
this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onPasswordActivate));
|
||||
this._passwordEntry.clutter_text.connect('activate', this._onPasswordActivate.bind(this));
|
||||
|
||||
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);
|
||||
@@ -144,7 +144,7 @@ var KeyringDialog = new Lang.Class({
|
||||
x_expand: true });
|
||||
this._confirmEntry.clutter_text.set_password_char('\u25cf'); // ● U+25CF BLACK CIRCLE
|
||||
ShellEntry.addContextMenu(this._confirmEntry, { isPassword: true });
|
||||
this._confirmEntry.clutter_text.connect('activate', Lang.bind(this, this._onConfirmActivate));
|
||||
this._confirmEntry.clutter_text.connect('activate', this._onConfirmActivate.bind(this));
|
||||
if (rtl) {
|
||||
layout.attach(this._confirmEntry, 0, row, 1, 1);
|
||||
layout.attach(label, 1, row, 1, 1);
|
||||
@@ -185,7 +185,7 @@ var KeyringDialog = new Lang.Class({
|
||||
this._content.messageBox.add(table, { x_fill: true, y_fill: true });
|
||||
},
|
||||
|
||||
_updateSensitivity: function(sensitive) {
|
||||
_updateSensitivity(sensitive) {
|
||||
if (this._passwordEntry) {
|
||||
this._passwordEntry.reactive = sensitive;
|
||||
this._passwordEntry.clutter_text.editable = sensitive;
|
||||
@@ -201,7 +201,7 @@ var KeyringDialog = new Lang.Class({
|
||||
this._setWorking(!sensitive);
|
||||
},
|
||||
|
||||
_ensureOpen: function() {
|
||||
_ensureOpen() {
|
||||
// NOTE: ModalDialog.open() is safe to call if the dialog is
|
||||
// already open - it just returns true without side-effects
|
||||
if (this.open())
|
||||
@@ -219,41 +219,41 @@ var KeyringDialog = new Lang.Class({
|
||||
return false;
|
||||
},
|
||||
|
||||
_onShowPassword: function(prompt) {
|
||||
_onShowPassword(prompt) {
|
||||
this._buildControlTable();
|
||||
this._ensureOpen();
|
||||
this._updateSensitivity(true);
|
||||
this._passwordEntry.grab_key_focus();
|
||||
},
|
||||
|
||||
_onShowConfirm: function(prompt) {
|
||||
_onShowConfirm(prompt) {
|
||||
this._buildControlTable();
|
||||
this._ensureOpen();
|
||||
this._updateSensitivity(true);
|
||||
this._continueButton.grab_key_focus();
|
||||
},
|
||||
|
||||
_onHidePrompt: function(prompt) {
|
||||
_onHidePrompt(prompt) {
|
||||
this.close();
|
||||
},
|
||||
|
||||
_onPasswordActivate: function() {
|
||||
_onPasswordActivate() {
|
||||
if (this.prompt.confirm_visible)
|
||||
this._confirmEntry.grab_key_focus();
|
||||
else
|
||||
this._onContinueButton();
|
||||
},
|
||||
|
||||
_onConfirmActivate: function() {
|
||||
_onConfirmActivate() {
|
||||
this._onContinueButton();
|
||||
},
|
||||
|
||||
_onContinueButton: function() {
|
||||
_onContinueButton() {
|
||||
this._updateSensitivity(false);
|
||||
this.prompt.complete();
|
||||
},
|
||||
|
||||
_onCancelButton: function() {
|
||||
_onCancelButton() {
|
||||
this.prompt.cancel();
|
||||
},
|
||||
});
|
||||
@@ -261,15 +261,13 @@ var KeyringDialog = new Lang.Class({
|
||||
var KeyringDummyDialog = new Lang.Class({
|
||||
Name: 'KeyringDummyDialog',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this.prompt = new Shell.KeyringPrompt();
|
||||
this.prompt.connect('show-password',
|
||||
Lang.bind(this, this._cancelPrompt));
|
||||
this.prompt.connect('show-confirm', Lang.bind(this,
|
||||
this._cancelPrompt));
|
||||
this.prompt.connect('show-password', this._cancelPrompt.bind(this));
|
||||
this.prompt.connect('show-confirm', this._cancelPrompt.bind(this));
|
||||
},
|
||||
|
||||
_cancelPrompt: function() {
|
||||
_cancelPrompt() {
|
||||
this.prompt.cancel();
|
||||
}
|
||||
});
|
||||
@@ -277,22 +275,21 @@ var KeyringDummyDialog = new Lang.Class({
|
||||
var KeyringPrompter = new Lang.Class({
|
||||
Name: 'KeyringPrompter',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._prompter = new Gcr.SystemPrompter();
|
||||
this._prompter.connect('new-prompt', Lang.bind(this,
|
||||
function() {
|
||||
let dialog = this._enabled ? new KeyringDialog()
|
||||
: new KeyringDummyDialog();
|
||||
this._currentPrompt = dialog.prompt;
|
||||
return this._currentPrompt;
|
||||
}));
|
||||
this._prompter.connect('new-prompt', () => {
|
||||
let dialog = this._enabled ? new KeyringDialog()
|
||||
: new KeyringDummyDialog();
|
||||
this._currentPrompt = dialog.prompt;
|
||||
return this._currentPrompt;
|
||||
});
|
||||
this._dbusId = null;
|
||||
this._registered = false;
|
||||
this._enabled = false;
|
||||
this._currentPrompt = null;
|
||||
},
|
||||
|
||||
enable: function() {
|
||||
enable() {
|
||||
if (!this._registered) {
|
||||
this._prompter.register(Gio.DBus.session);
|
||||
this._dbusId = Gio.DBus.session.own_name('org.gnome.keyring.SystemPrompter',
|
||||
@@ -302,7 +299,7 @@ var KeyringPrompter = new Lang.Class({
|
||||
this._enabled = true;
|
||||
},
|
||||
|
||||
disable: function() {
|
||||
disable() {
|
||||
this._enabled = false;
|
||||
|
||||
if (this._prompter.prompting)
|
||||
|
||||
@@ -25,7 +25,7 @@ var NetworkSecretDialog = new Lang.Class({
|
||||
Name: 'NetworkSecretDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
|
||||
_init: function(agent, requestId, connection, settingName, hints, contentOverride) {
|
||||
_init(agent, requestId, connection, settingName, hints, contentOverride) {
|
||||
this.parent({ styleClass: 'prompt-dialog' });
|
||||
|
||||
this._agent = agent;
|
||||
@@ -82,15 +82,15 @@ var NetworkSecretDialog = new Lang.Class({
|
||||
initialFocusSet = true;
|
||||
}
|
||||
|
||||
secret.entry.clutter_text.connect('activate', Lang.bind(this, this._onOk));
|
||||
secret.entry.clutter_text.connect('text-changed', Lang.bind(this, function() {
|
||||
secret.entry.clutter_text.connect('activate', this._onOk.bind(this));
|
||||
secret.entry.clutter_text.connect('text-changed', () => {
|
||||
secret.value = secret.entry.get_text();
|
||||
if (secret.validate)
|
||||
secret.valid = secret.validate(secret);
|
||||
else
|
||||
secret.valid = secret.value.length > 0;
|
||||
this._updateOkButton();
|
||||
}));
|
||||
});
|
||||
} else
|
||||
secret.valid = true;
|
||||
|
||||
@@ -110,12 +110,12 @@ var NetworkSecretDialog = new Lang.Class({
|
||||
contentBox.messageBox.add(secretTable);
|
||||
|
||||
this._okButton = { label: _("Connect"),
|
||||
action: Lang.bind(this, this._onOk),
|
||||
action: this._onOk.bind(this),
|
||||
default: true
|
||||
};
|
||||
|
||||
this.setButtons([{ label: _("Cancel"),
|
||||
action: Lang.bind(this, this.cancel),
|
||||
action: this.cancel.bind(this),
|
||||
key: Clutter.KEY_Escape,
|
||||
},
|
||||
this._okButton]);
|
||||
@@ -123,7 +123,7 @@ var NetworkSecretDialog = new Lang.Class({
|
||||
this._updateOkButton();
|
||||
},
|
||||
|
||||
_updateOkButton: function() {
|
||||
_updateOkButton() {
|
||||
let valid = true;
|
||||
for (let i = 0; i < this._content.secrets.length; i++) {
|
||||
let secret = this._content.secrets[i];
|
||||
@@ -134,7 +134,7 @@ var NetworkSecretDialog = new Lang.Class({
|
||||
this._okButton.button.can_focus = valid;
|
||||
},
|
||||
|
||||
_onOk: function() {
|
||||
_onOk() {
|
||||
let valid = true;
|
||||
for (let i = 0; i < this._content.secrets.length; i++) {
|
||||
let secret = this._content.secrets[i];
|
||||
@@ -150,12 +150,12 @@ var NetworkSecretDialog = new Lang.Class({
|
||||
// do nothing if not valid
|
||||
},
|
||||
|
||||
cancel: function() {
|
||||
cancel() {
|
||||
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.USER_CANCELED);
|
||||
this.close(global.get_current_time());
|
||||
},
|
||||
|
||||
_validateWpaPsk: function(secret) {
|
||||
_validateWpaPsk(secret) {
|
||||
let value = secret.value;
|
||||
if (value.length == 64) {
|
||||
// must be composed of hexadecimal digits only
|
||||
@@ -171,7 +171,7 @@ var NetworkSecretDialog = new Lang.Class({
|
||||
return (value.length >= 8 && value.length <= 63);
|
||||
},
|
||||
|
||||
_validateStaticWep: function(secret) {
|
||||
_validateStaticWep(secret) {
|
||||
let value = secret.value;
|
||||
if (secret.wep_key_type == NM.WepKeyType.KEY) {
|
||||
if (value.length == 10 || value.length == 26) {
|
||||
@@ -196,7 +196,7 @@ var NetworkSecretDialog = new Lang.Class({
|
||||
return true;
|
||||
},
|
||||
|
||||
_getWirelessSecrets: function(secrets, wirelessSetting) {
|
||||
_getWirelessSecrets(secrets, wirelessSetting) {
|
||||
let wirelessSecuritySetting = this._connection.get_setting_wireless_security();
|
||||
switch (wirelessSecuritySetting.key_mgmt) {
|
||||
// First the easy ones
|
||||
@@ -227,7 +227,7 @@ var NetworkSecretDialog = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_get8021xSecrets: function(secrets) {
|
||||
_get8021xSecrets(secrets) {
|
||||
let ieee8021xSetting = this._connection.get_setting_802_1x();
|
||||
let phase2method;
|
||||
|
||||
@@ -256,7 +256,7 @@ var NetworkSecretDialog = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_getPPPoESecrets: function(secrets) {
|
||||
_getPPPoESecrets(secrets) {
|
||||
let pppoeSetting = this._connection.get_setting_pppoe();
|
||||
secrets.push({ label: _("Username: "), key: 'username',
|
||||
value: pppoeSetting.username || '', password: false });
|
||||
@@ -266,7 +266,7 @@ var NetworkSecretDialog = new Lang.Class({
|
||||
value: pppoeSetting.password || '', password: true });
|
||||
},
|
||||
|
||||
_getMobileSecrets: function(secrets, connectionType) {
|
||||
_getMobileSecrets(secrets, connectionType) {
|
||||
let setting;
|
||||
if (connectionType == 'bluetooth')
|
||||
setting = this._connection.get_setting_cdma() || this._connection.get_setting_gsm();
|
||||
@@ -276,7 +276,7 @@ var NetworkSecretDialog = new Lang.Class({
|
||||
value: setting.value || '', password: true });
|
||||
},
|
||||
|
||||
_getContent: function() {
|
||||
_getContent() {
|
||||
let connectionSetting = this._connection.get_setting_connection();
|
||||
let connectionType = connectionSetting.get_connection_type();
|
||||
let wirelessSetting;
|
||||
@@ -332,7 +332,7 @@ var NetworkSecretDialog = new Lang.Class({
|
||||
var VPNRequestHandler = new Lang.Class({
|
||||
Name: 'VPNRequestHandler',
|
||||
|
||||
_init: function(agent, requestId, authHelper, serviceType, connection, hints, flags) {
|
||||
_init(agent, requestId, authHelper, serviceType, connection, hints, flags) {
|
||||
this._agent = agent;
|
||||
this._requestId = requestId;
|
||||
this._connection = connection;
|
||||
@@ -384,7 +384,7 @@ var VPNRequestHandler = new Lang.Class({
|
||||
this._readStdoutOldStyle();
|
||||
|
||||
this._childWatch = GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid,
|
||||
Lang.bind(this, this._vpnChildFinished));
|
||||
this._vpnChildFinished.bind(this));
|
||||
|
||||
this._writeConnection();
|
||||
} catch(e) {
|
||||
@@ -394,7 +394,7 @@ var VPNRequestHandler = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
cancel: function(respond) {
|
||||
cancel(respond) {
|
||||
if (respond)
|
||||
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.USER_CANCELED);
|
||||
|
||||
@@ -410,7 +410,7 @@ var VPNRequestHandler = new Lang.Class({
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
destroy() {
|
||||
if (this._destroyed)
|
||||
return;
|
||||
|
||||
@@ -424,7 +424,7 @@ var VPNRequestHandler = new Lang.Class({
|
||||
this._destroyed = true;
|
||||
},
|
||||
|
||||
_vpnChildFinished: function(pid, status, requestObj) {
|
||||
_vpnChildFinished(pid, status, requestObj) {
|
||||
this._childWatch = 0;
|
||||
if (this._newStylePlugin) {
|
||||
// For new style plugin, all work is done in the async reading functions
|
||||
@@ -445,7 +445,7 @@ var VPNRequestHandler = new Lang.Class({
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
_vpnChildProcessLineOldStyle: function(line) {
|
||||
_vpnChildProcessLineOldStyle(line) {
|
||||
if (this._previousLine != undefined) {
|
||||
// Two consecutive newlines mean that the child should be closed
|
||||
// (the actual newlines are eaten by Gio.DataInputStream)
|
||||
@@ -463,8 +463,8 @@ var VPNRequestHandler = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_readStdoutOldStyle: function() {
|
||||
this._dataStdout.read_line_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(stream, result) {
|
||||
_readStdoutOldStyle() {
|
||||
this._dataStdout.read_line_async(GLib.PRIORITY_DEFAULT, null, (stream, result) => {
|
||||
let [line, len] = this._dataStdout.read_line_finish_utf8(result);
|
||||
|
||||
if (line == null) {
|
||||
@@ -477,11 +477,11 @@ var VPNRequestHandler = new Lang.Class({
|
||||
|
||||
// try to read more!
|
||||
this._readStdoutOldStyle();
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
_readStdoutNewStyle: function() {
|
||||
this._dataStdout.fill_async(-1, GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(stream, result) {
|
||||
_readStdoutNewStyle() {
|
||||
this._dataStdout.fill_async(-1, GLib.PRIORITY_DEFAULT, null, (stream, result) => {
|
||||
let cnt = this._dataStdout.fill_finish(result);
|
||||
|
||||
if (cnt == 0) {
|
||||
@@ -495,10 +495,10 @@ var VPNRequestHandler = new Lang.Class({
|
||||
// Try to read more
|
||||
this._dataStdout.set_buffer_size(2 * this._dataStdout.get_buffer_size());
|
||||
this._readStdoutNewStyle();
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
_showNewStyleDialog: function() {
|
||||
_showNewStyleDialog() {
|
||||
let keyfile = new GLib.KeyFile();
|
||||
let data;
|
||||
let contentOverride;
|
||||
@@ -506,8 +506,12 @@ var VPNRequestHandler = new Lang.Class({
|
||||
try {
|
||||
data = this._dataStdout.peek_buffer();
|
||||
|
||||
keyfile.load_from_data(data.toString(), data.length,
|
||||
GLib.KeyFileFlags.NONE);
|
||||
if (data instanceof Uint8Array)
|
||||
data = imports.byteArray.toGBytes(data);
|
||||
else
|
||||
data = data.toGBytes();
|
||||
|
||||
keyfile.load_from_bytes(data, GLib.KeyFileFlags.NONE);
|
||||
|
||||
if (keyfile.get_integer(VPN_UI_GROUP, 'Version') != 2)
|
||||
throw new Error('Invalid plugin keyfile version, is %d');
|
||||
@@ -558,18 +562,18 @@ var VPNRequestHandler = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_writeConnection: function() {
|
||||
_writeConnection() {
|
||||
let vpnSetting = this._connection.get_setting_vpn();
|
||||
|
||||
try {
|
||||
vpnSetting.foreach_data_item(Lang.bind(this, function(key, value) {
|
||||
vpnSetting.foreach_data_item((key, value) => {
|
||||
this._stdin.write('DATA_KEY=' + key + '\n', null);
|
||||
this._stdin.write('DATA_VAL=' + (value || '') + '\n\n', null);
|
||||
}));
|
||||
vpnSetting.foreach_secret(Lang.bind(this, function(key, value) {
|
||||
});
|
||||
vpnSetting.foreach_secret((key, value) => {
|
||||
this._stdin.write('SECRET_KEY=' + key + '\n', null);
|
||||
this._stdin.write('SECRET_VAL=' + (value || '') + '\n\n', null);
|
||||
}));
|
||||
});
|
||||
this._stdin.write('DONE\n\n', null);
|
||||
} catch(e) {
|
||||
logError(e, 'internal error while writing connection to helper');
|
||||
@@ -584,7 +588,7 @@ Signals.addSignalMethods(VPNRequestHandler.prototype);
|
||||
var NetworkAgent = new Lang.Class({
|
||||
Name: 'NetworkAgent',
|
||||
|
||||
_init: function() {
|
||||
_init() {
|
||||
this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent',
|
||||
capabilities: NM.SecretAgentCapabilities.VPN_HINTS,
|
||||
auto_register: false
|
||||
@@ -602,26 +606,31 @@ var NetworkAgent = new Lang.Class({
|
||||
log('Failed to create monitor for VPN plugin dir: ' + e.message);
|
||||
}
|
||||
|
||||
this._native.connect('new-request', Lang.bind(this, this._newRequest));
|
||||
this._native.connect('cancel-request', Lang.bind(this, this._cancelRequest));
|
||||
try {
|
||||
this._native.init(null);
|
||||
} catch(e) {
|
||||
this._native = null;
|
||||
logError(e, 'error initializing the NetworkManager Agent');
|
||||
}
|
||||
this._native.connect('new-request', this._newRequest.bind(this));
|
||||
this._native.connect('cancel-request', this._cancelRequest.bind(this));
|
||||
|
||||
this._initialized = false;
|
||||
this._native.init_async(GLib.PRIORITY_DEFAULT, null, (o, res) => {
|
||||
try {
|
||||
this._native.init_finish(res);
|
||||
this._initialized = true;
|
||||
} catch(e) {
|
||||
this._native = null;
|
||||
logError(e, 'error initializing the NetworkManager Agent');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
enable: function() {
|
||||
enable() {
|
||||
if (!this._native)
|
||||
return;
|
||||
|
||||
this._native.auto_register = true;
|
||||
if (!this._native.registered)
|
||||
if (this._initialized && !this._native.registered)
|
||||
this._native.register_async(null, null);
|
||||
},
|
||||
|
||||
disable: function() {
|
||||
disable() {
|
||||
let requestId;
|
||||
|
||||
for (requestId in this._dialogs)
|
||||
@@ -640,11 +649,11 @@ var NetworkAgent = new Lang.Class({
|
||||
return;
|
||||
|
||||
this._native.auto_register = false;
|
||||
if (this._native.registered)
|
||||
if (this._initialized && this._native.registered)
|
||||
this._native.unregister_async(null, null);
|
||||
},
|
||||
|
||||
_showNotification: function(requestId, connection, settingName, hints, flags) {
|
||||
_showNotification(requestId, connection, settingName, hints, flags) {
|
||||
let source = new MessageTray.Source(_("Network Manager"), 'network-transmit-receive');
|
||||
source.policy = new MessageTray.NotificationApplicationPolicy('gnome-network-panel');
|
||||
|
||||
@@ -655,7 +664,7 @@ var NetworkAgent = new Lang.Class({
|
||||
switch (connectionType) {
|
||||
case '802-11-wireless':
|
||||
let wirelessSetting = connection.get_setting_wireless();
|
||||
let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid());
|
||||
let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid().get_data());
|
||||
title = _("Authentication required by wireless network");
|
||||
body = _("Passwords or encryption keys are required to access the wireless network “%s”.").format(ssid);
|
||||
break;
|
||||
@@ -688,44 +697,44 @@ var NetworkAgent = new Lang.Class({
|
||||
|
||||
let notification = new MessageTray.Notification(source, title, body);
|
||||
|
||||
notification.connect('activated', Lang.bind(this, function() {
|
||||
notification.connect('activated', () => {
|
||||
notification.answered = true;
|
||||
this._handleRequest(requestId, connection, settingName, hints, flags);
|
||||
}));
|
||||
});
|
||||
|
||||
this._notifications[requestId] = notification;
|
||||
notification.connect('destroy', Lang.bind(this, function() {
|
||||
notification.connect('destroy', () => {
|
||||
if (!notification.answered)
|
||||
this._native.respond(requestId, Shell.NetworkAgentResponse.USER_CANCELED);
|
||||
delete this._notifications[requestId];
|
||||
}));
|
||||
});
|
||||
|
||||
Main.messageTray.add(source);
|
||||
source.notify(notification);
|
||||
},
|
||||
|
||||
_newRequest: function(agent, requestId, connection, settingName, hints, flags) {
|
||||
_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: function(requestId, connection, settingName, hints, flags) {
|
||||
_handleRequest(requestId, connection, settingName, hints, flags) {
|
||||
if (settingName == 'vpn') {
|
||||
this._vpnRequest(requestId, connection, hints, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
let dialog = new NetworkSecretDialog(this._native, requestId, connection, settingName, hints);
|
||||
dialog.connect('destroy', Lang.bind(this, function() {
|
||||
dialog.connect('destroy', () => {
|
||||
delete this._dialogs[requestId];
|
||||
}));
|
||||
});
|
||||
this._dialogs[requestId] = dialog;
|
||||
dialog.open(global.get_current_time());
|
||||
},
|
||||
|
||||
_cancelRequest: function(agent, requestId) {
|
||||
_cancelRequest(agent, requestId) {
|
||||
if (this._dialogs[requestId]) {
|
||||
this._dialogs[requestId].close(global.get_current_time());
|
||||
this._dialogs[requestId].destroy();
|
||||
@@ -736,7 +745,7 @@ var NetworkAgent = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_vpnRequest: function(requestId, connection, hints, flags) {
|
||||
_vpnRequest(requestId, connection, hints, flags) {
|
||||
let vpnSetting = connection.get_setting_vpn();
|
||||
let serviceType = vpnSetting.service_type;
|
||||
|
||||
@@ -752,70 +761,42 @@ var NetworkAgent = new Lang.Class({
|
||||
}
|
||||
|
||||
let vpnRequest = new VPNRequestHandler(this._native, requestId, binary, serviceType, connection, hints, flags);
|
||||
vpnRequest.connect('destroy', Lang.bind(this, function() {
|
||||
vpnRequest.connect('destroy', () => {
|
||||
delete this._vpnRequests[requestId];
|
||||
}));
|
||||
});
|
||||
this._vpnRequests[requestId] = vpnRequest;
|
||||
},
|
||||
|
||||
_buildVPNServiceCache: function() {
|
||||
_buildVPNServiceCache() {
|
||||
if (this._vpnCacheBuilt)
|
||||
return;
|
||||
|
||||
this._vpnCacheBuilt = true;
|
||||
this._vpnBinaries = { };
|
||||
|
||||
try {
|
||||
let fileEnum = this._pluginDir.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null);
|
||||
let info;
|
||||
NM.VpnPluginInfo.list_load().forEach(plugin => {
|
||||
let service = plugin.get_service();
|
||||
let fileName = plugin.get_auth_dialog();
|
||||
let supportsHints = plugin.supports_hints();
|
||||
let externalUIMode = false;
|
||||
|
||||
while ((info = fileEnum.next_file(null))) {
|
||||
let name = info.get_name();
|
||||
if (name.substr(-5) != '.name')
|
||||
continue;
|
||||
|
||||
try {
|
||||
let keyfile = new GLib.KeyFile();
|
||||
keyfile.load_from_file(this._pluginDir.get_child(name).get_path(), GLib.KeyFileFlags.NONE);
|
||||
let service = keyfile.get_string('VPN Connection', 'service');
|
||||
let binary = keyfile.get_string('GNOME', 'auth-dialog');
|
||||
let externalUIMode = false;
|
||||
let hints = false;
|
||||
|
||||
try {
|
||||
externalUIMode = keyfile.get_boolean('GNOME', 'supports-external-ui-mode');
|
||||
} catch(e) { } // ignore errors if key does not exist
|
||||
|
||||
try {
|
||||
hints = keyfile.get_boolean('GNOME', 'supports-hints');
|
||||
} catch(e) { } // ignore errors if key does not exist
|
||||
|
||||
let path = binary;
|
||||
if (!GLib.path_is_absolute(path)) {
|
||||
path = GLib.build_filenamev([Config.LIBEXECDIR, path]);
|
||||
}
|
||||
|
||||
if (GLib.file_test(path, GLib.FileTest.IS_EXECUTABLE)) {
|
||||
this._vpnBinaries[service] = { fileName: path, externalUIMode: externalUIMode, supportsHints: hints };
|
||||
try {
|
||||
let aliases = keyfile.get_string_list('VPN Connection', 'aliases');
|
||||
|
||||
for (let alias of aliases) {
|
||||
this._vpnBinaries[alias] = { fileName: path, externalUIMode: externalUIMode, supportsHints: hints };
|
||||
}
|
||||
} catch(e) { } // ignore errors if key does not exist
|
||||
} else {
|
||||
throw new Error('VPN plugin at %s is not executable'.format(path));
|
||||
}
|
||||
} catch(e) {
|
||||
log('Error \'%s\' while processing VPN keyfile \'%s\''.
|
||||
format(e.message, this._pluginDir.get_child(name).get_path()));
|
||||
continue;
|
||||
}
|
||||
let prop = plugin.lookup_property('GNOME', 'supports-external-ui-mode');
|
||||
if (prop) {
|
||||
prop = prop.trim().toLowerCase();
|
||||
externalUIMode = ['true', 'yes', 'on', '1'].includes(prop);
|
||||
}
|
||||
} catch(e) {
|
||||
logError(e, 'error while enumerating VPN auth helpers');
|
||||
}
|
||||
|
||||
if (GLib.file_test(fileName, GLib.FileTest.IS_EXECUTABLE)) {
|
||||
let binary = { fileName, externalUIMode, supportsHints };
|
||||
this._vpnBinaries[service] = binary;
|
||||
|
||||
plugin.get_aliases().forEach(alias => {
|
||||
this._vpnBinaries[alias] = binary;
|
||||
});
|
||||
} else {
|
||||
log('VPN plugin at %s is not executable'.format(fileName));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
var Component = NetworkAgent;
|
||||
|
||||