Compare commits
	
		
			2 Commits
		
	
	
		
			wip/jimmac
			...
			issue-36
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					735ce62e8b | ||
| 
						 | 
					cc028dd55a | 
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -1,3 +1,6 @@
 | 
			
		||||
[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,16 +1,19 @@
 | 
			
		||||
# 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
 | 
			
		||||
@@ -19,7 +22,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;
 | 
			
		||||
 | 
			
		||||
@@ -36,20 +39,22 @@ 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.
 | 
			
		||||
 | 
			
		||||
@@ -62,13 +67,14 @@ 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.
 | 
			
		||||
@@ -79,7 +85,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;
 | 
			
		||||
@@ -89,22 +95,23 @@ 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
 | 
			
		||||
    const MY_DBUS_INTERFACE = 'org.my.Interface';
 | 
			
		||||
 | 
			
		||||
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];
 | 
			
		||||
@@ -114,32 +121,31 @@ 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(icon, label) {
 | 
			
		||||
        _init: function(icon, label) {
 | 
			
		||||
            this.parent({ reactive: false });
 | 
			
		||||
            this.actor.add_child(icon);
 | 
			
		||||
            this.actor.add_child(label);
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        open() {
 | 
			
		||||
        open: function() {
 | 
			
		||||
            log("menu opened!");
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
* 'Name' is required. 'Extends' is optional. If you leave it out, you will
 | 
			
		||||
  automatically inherit from Object.
 | 
			
		||||
@@ -156,34 +162,35 @@ 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(actor, forHeight) {
 | 
			
		||||
        vfunc_get_preferred_width: function(actor, forHeight) {
 | 
			
		||||
             return [100, 100];
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        vfunc_get_preferred_height(actor, forWidth) {
 | 
			
		||||
        vfunc_get_preferred_height: function(actor, forWidth) {
 | 
			
		||||
             return [100, 100];
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        vfunc_paint(actor) {
 | 
			
		||||
        vfunc_paint: function(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
 | 
			
		||||
@@ -197,7 +204,8 @@ 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
 | 
			
		||||
@@ -206,22 +214,21 @@ 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() {
 | 
			
		||||
        _init: function() {
 | 
			
		||||
            this.actor = new St.Button({ text: "This is a button" });
 | 
			
		||||
            this.actor._delegate = this;
 | 
			
		||||
 | 
			
		||||
            this.actor.connect('clicked', this._onClicked.bind(this));
 | 
			
		||||
            this.actor.connect('clicked', Lang.bind(this, this._onClicked));
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        _onClicked(actor) {
 | 
			
		||||
        _onClicked: function(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
 | 
			
		||||
@@ -229,60 +236,57 @@ 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 Function.prototype.bind or use arrow
 | 
			
		||||
notation.
 | 
			
		||||
```javascript
 | 
			
		||||
All closures should be wrapped with a Lang.bind.
 | 
			
		||||
 | 
			
		||||
    const Lang = imports.lang;
 | 
			
		||||
 | 
			
		||||
    let closure1 = () => { this._fnorbate(); };
 | 
			
		||||
    let closure2 = this._fnorbate.bind(this);
 | 
			
		||||
```
 | 
			
		||||
    let closure = Lang.bind(this, function() { this._fnorbate(); });
 | 
			
		||||
 | 
			
		||||
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() {
 | 
			
		||||
        _init: function() {
 | 
			
		||||
            let fnorb = new FnorbLib.Fnorb();
 | 
			
		||||
            fnorb.connect('frobate', this._onFnorbFrobate.bind(this));
 | 
			
		||||
            fnorb.connect('frobate', Lang.bind(this, this._onFnorbFrobate));
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        _onFnorbFrobate(fnorb) {
 | 
			
		||||
        _onFnorbFrobate: function(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:
 | 
			
		||||
@@ -292,19 +296,20 @@ 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() {
 | 
			
		||||
        _init: function() {
 | 
			
		||||
            this.actor = new St.BoxLayout();
 | 
			
		||||
            this._position = 0;
 | 
			
		||||
        },
 | 
			
		||||
@@ -324,4 +329,3 @@ property.
 | 
			
		||||
                     { position: 100,
 | 
			
		||||
                       time: ANIMATION_TIME,
 | 
			
		||||
                       transition: 'easeOutQuad' });
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										7
									
								
								MAINTAINERS
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,7 @@
 | 
			
		||||
Owen Taylor
 | 
			
		||||
E-mail: otaylor@redhat.com
 | 
			
		||||
Userid: otaylor
 | 
			
		||||
 | 
			
		||||
Colin Walters
 | 
			
		||||
E-mail: walters@verbum.org
 | 
			
		||||
Userid: walters
 | 
			
		||||
							
								
								
									
										144
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						@@ -1,147 +1,3 @@
 | 
			
		||||
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,4 +1,3 @@
 | 
			
		||||
# 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
 | 
			
		||||
@@ -7,14 +6,15 @@ 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 the [project wiki][wiki]
 | 
			
		||||
see:
 | 
			
		||||
 | 
			
		||||
Bugs should be reported to the GNOME [bug tracking system][bug-tracker].
 | 
			
		||||
 https://wiki.gnome.org/Projects/GnomeShell
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
Bugs should be reported at http://bugzilla.gnome.org against the 'gnome-shell'
 | 
			
		||||
product.
 | 
			
		||||
 | 
			
		||||
License
 | 
			
		||||
=======
 | 
			
		||||
GNOME Shell is distributed under the terms of the GNU General Public License,
 | 
			
		||||
version 2 or later. See the [COPYING][license] file for details.
 | 
			
		||||
version 2 or later. See the COPYING 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 to the GNOME [bug tracking system][bug-tracker].
 | 
			
		||||
Bugs should be reported at http://bugzilla.gnome.org against the 'gnome-shell'
 | 
			
		||||
product.
 | 
			
		||||
 | 
			
		||||
## 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
 | 
			
		||||
@@ -19,12 +19,6 @@
 | 
			
		||||
    <file>filter-selected-rtl.svg</file>
 | 
			
		||||
    <file>gnome-shell.css</file>
 | 
			
		||||
    <file>gnome-shell-high-contrast.css</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>logged-in-indicator.svg</file>
 | 
			
		||||
    <file alias="icons/message-indicator-symbolic.svg">message-indicator-symbolic.svg</file>
 | 
			
		||||
    <file>no-events.svg</file>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=GNOME Shell (wayland sync point)
 | 
			
		||||
After=gnome-shell.service
 | 
			
		||||
BindsTo=gnome-shell.service
 | 
			
		||||
Conflicts=gnome-shell-x11.target
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=GNOME Shell (x11 sync point)
 | 
			
		||||
After=gnome-shell.service
 | 
			
		||||
BindsTo=gnome-shell.service
 | 
			
		||||
Conflicts=gnome-shell-wayland.target
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
[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
 | 
			
		||||
@@ -93,23 +93,6 @@ schema = configure_file(
 | 
			
		||||
  install_dir: schemadir
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
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',
 | 
			
		||||
  input: schema,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								data/theme/HACKING
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,3 @@
 | 
			
		||||
To generate the css files, from the project directory:
 | 
			
		||||
 | 
			
		||||
sass --sourcemap=none --update .
 | 
			
		||||
							
								
								
									
										34
									
								
								data/theme/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,34 @@
 | 
			
		||||
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.
 | 
			
		||||
@@ -1,32 +0,0 @@
 | 
			
		||||
## 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/
 | 
			
		||||
							
								
								
									
										1902
									
								
								data/theme/gnome-shell-high-contrast.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1
									
								
								data/theme/gnome-shell-sass
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						@@ -1,339 +0,0 @@
 | 
			
		||||
		    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.
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
# 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
 | 
			
		||||
@@ -1,44 +0,0 @@
 | 
			
		||||
// 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%);
 | 
			
		||||
@@ -1,221 +0,0 @@
 | 
			
		||||
// 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.5),
 | 
			
		||||
                          $osd_bg_color);
 | 
			
		||||
 | 
			
		||||
    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,10%));
 | 
			
		||||
 | 
			
		||||
    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: darken($_bg,5%);
 | 
			
		||||
    // 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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1,41 +0,0 @@
 | 
			
		||||
// 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%);
 | 
			
		||||
@@ -1,37 +0,0 @@
 | 
			
		||||
<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>
 | 
			
		||||
							
								
								
									
										1891
									
								
								data/theme/gnome-shell.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -1,109 +0,0 @@
 | 
			
		||||
<?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>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 4.1 KiB  | 
@@ -1,114 +0,0 @@
 | 
			
		||||
<?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>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 3.5 KiB  | 
@@ -1,129 +0,0 @@
 | 
			
		||||
<?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>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 4.2 KiB  | 
@@ -1,109 +0,0 @@
 | 
			
		||||
<?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>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 3.4 KiB  | 
@@ -1,104 +0,0 @@
 | 
			
		||||
<?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>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 3.1 KiB  | 
@@ -1,108 +0,0 @@
 | 
			
		||||
<?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>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 3.1 KiB  | 
@@ -7,19 +7,15 @@ theme_sources = files([
 | 
			
		||||
  'gnome-shell-sass/_high-contrast-colors.scss'
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
styles = [
 | 
			
		||||
  'gnome-shell-high-contrast',
 | 
			
		||||
  'gnome-shell'
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
theme_deps = []
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
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
 | 
			
		||||
 
 | 
			
		||||
@@ -13,102 +13,10 @@
 | 
			
		||||
   height="64px"
 | 
			
		||||
   id="svg3393"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.92.3 (2405546, 2018-03-11)"
 | 
			
		||||
   sodipodi:docname="no-notifications.svg">
 | 
			
		||||
   inkscape:version="0.48.5 r10040"
 | 
			
		||||
   sodipodi:docname="New document 2">
 | 
			
		||||
  <defs
 | 
			
		||||
     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>
 | 
			
		||||
     id="defs3395" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#ffffff"
 | 
			
		||||
@@ -116,17 +24,17 @@
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0.0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="1"
 | 
			
		||||
     inkscape:cx="125.08157"
 | 
			
		||||
     inkscape:cy="-13.805087"
 | 
			
		||||
     inkscape:zoom="5.5"
 | 
			
		||||
     inkscape:cx="32"
 | 
			
		||||
     inkscape:cy="32"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="true"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:grid-bbox="true"
 | 
			
		||||
     inkscape:window-width="1664"
 | 
			
		||||
     inkscape:window-height="1034"
 | 
			
		||||
     inkscape:window-x="1479"
 | 
			
		||||
     inkscape:window-y="252"
 | 
			
		||||
     inkscape:window-width="697"
 | 
			
		||||
     inkscape:window-height="613"
 | 
			
		||||
     inkscape:window-x="100"
 | 
			
		||||
     inkscape:window-y="77"
 | 
			
		||||
     inkscape:window-maximized="0" />
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata3398">
 | 
			
		||||
@@ -146,7 +54,7 @@
 | 
			
		||||
     inkscape:groupmode="layer">
 | 
			
		||||
    <g
 | 
			
		||||
       style="display:inline"
 | 
			
		||||
       transform="matrix(4,0,0,4,-79.702662,-0.35415646)"
 | 
			
		||||
       transform="matrix(4,0,0,4,0.29733827,-0.35415646)"
 | 
			
		||||
       id="g19245">
 | 
			
		||||
      <g
 | 
			
		||||
         id="g19247"
 | 
			
		||||
@@ -163,15 +71,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 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"
 | 
			
		||||
           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"
 | 
			
		||||
           id="path19253"
 | 
			
		||||
           sodipodi:nodetypes="csscsscccssssc"
 | 
			
		||||
           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" />
 | 
			
		||||
           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" />
 | 
			
		||||
        <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 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"
 | 
			
		||||
           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"
 | 
			
		||||
           id="path19255"
 | 
			
		||||
           style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;enable-background:accumulate" />
 | 
			
		||||
           style="color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
 | 
			
		||||
      </g>
 | 
			
		||||
      <g
 | 
			
		||||
         id="g19257"
 | 
			
		||||
@@ -202,22 +110,5 @@
 | 
			
		||||
         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: 11 KiB After Width: | Height: | Size: 6.1 KiB  | 
							
								
								
									
										10
									
								
								data/theme/parse-sass.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						@@ -0,0 +1,10 @@
 | 
			
		||||
#!/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
 | 
			
		||||
@@ -34,16 +34,16 @@ function stripPrefix(string, prefix) {
 | 
			
		||||
 | 
			
		||||
var Application = new Lang.Class({
 | 
			
		||||
    Name: 'Application',
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        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', this._onActivate.bind(this));
 | 
			
		||||
        this.application.connect('command-line', this._onCommandLine.bind(this));
 | 
			
		||||
        this.application.connect('startup', this._onStartup.bind(this));
 | 
			
		||||
        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._extensionPrefsModules = {};
 | 
			
		||||
 | 
			
		||||
@@ -52,7 +52,7 @@ var Application = new Lang.Class({
 | 
			
		||||
        this._skipMainWindow = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _extensionAvailable(uuid) {
 | 
			
		||||
    _extensionAvailable: function(uuid) {
 | 
			
		||||
        let extension = ExtensionUtils.extensions[uuid];
 | 
			
		||||
 | 
			
		||||
        if (!extension)
 | 
			
		||||
@@ -64,7 +64,7 @@ var Application = new Lang.Class({
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getExtensionPrefsModule(extension) {
 | 
			
		||||
    _getExtensionPrefsModule: function(extension) {
 | 
			
		||||
        let uuid = extension.metadata.uuid;
 | 
			
		||||
 | 
			
		||||
        if (this._extensionPrefsModules.hasOwnProperty(uuid))
 | 
			
		||||
@@ -79,7 +79,7 @@ var Application = new Lang.Class({
 | 
			
		||||
        return prefsModule;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _selectExtension(uuid) {
 | 
			
		||||
    _selectExtension: function(uuid) {
 | 
			
		||||
        if (!this._extensionAvailable(uuid))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -114,7 +114,7 @@ var Application = new Lang.Class({
 | 
			
		||||
        dialog.show();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _buildErrorUI(extension, exc) {
 | 
			
		||||
    _buildErrorUI: function(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,7 +127,9 @@ var Application = new Lang.Class({
 | 
			
		||||
        errortext += 'Stack trace:\n';
 | 
			
		||||
 | 
			
		||||
        // Indent stack trace.
 | 
			
		||||
        errortext += exc.stack.split('\n').map(line => '  ' + line).join('\n');
 | 
			
		||||
        errortext += exc.stack.split('\n').map(function(line) {
 | 
			
		||||
            return '  ' + line;
 | 
			
		||||
        }).join('\n');
 | 
			
		||||
 | 
			
		||||
        let scroll = new Gtk.ScrolledWindow({ vexpand: true });
 | 
			
		||||
        let buffer = new Gtk.TextBuffer({ text: errortext });
 | 
			
		||||
@@ -140,7 +142,7 @@ var Application = new Lang.Class({
 | 
			
		||||
        return box;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _buildUI(app) {
 | 
			
		||||
    _buildUI: function(app) {
 | 
			
		||||
        this._window = new Gtk.ApplicationWindow({ application: app,
 | 
			
		||||
                                                   window_position: Gtk.WindowPosition.CENTER });
 | 
			
		||||
 | 
			
		||||
@@ -162,28 +164,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(this._sortList.bind(this));
 | 
			
		||||
        this._extensionSelector.set_header_func(this._updateHeader.bind(this));
 | 
			
		||||
        this._extensionSelector.set_sort_func(Lang.bind(this, this._sortList));
 | 
			
		||||
        this._extensionSelector.set_header_func(Lang.bind(this, this._updateHeader));
 | 
			
		||||
 | 
			
		||||
        scroll.add(this._extensionSelector);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell');
 | 
			
		||||
        this._shellProxy.connectSignal('ExtensionStatusChanged', (proxy, senderName, [uuid, state, error]) => {
 | 
			
		||||
        this._shellProxy.connectSignal('ExtensionStatusChanged', Lang.bind(this, function(proxy, senderName, [uuid, state, error]) {
 | 
			
		||||
            if (ExtensionUtils.extensions[uuid] !== undefined)
 | 
			
		||||
                this._scanExtensions();
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._window.show_all();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sortList(row1, row2) {
 | 
			
		||||
    _sortList: function(row1, row2) {
 | 
			
		||||
        let name1 = ExtensionUtils.extensions[row1.uuid].metadata.name;
 | 
			
		||||
        let name2 = ExtensionUtils.extensions[row2.uuid].metadata.name;
 | 
			
		||||
        return name1.localeCompare(name2);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateHeader(row, before) {
 | 
			
		||||
    _updateHeader: function(row, before) {
 | 
			
		||||
        if (!before || row.get_header())
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -191,26 +193,27 @@ var Application = new Lang.Class({
 | 
			
		||||
        row.set_header(sep);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _scanExtensions() {
 | 
			
		||||
    _scanExtensions: function() {
 | 
			
		||||
        let finder = new ExtensionUtils.ExtensionFinder();
 | 
			
		||||
        finder.connect('extension-found', this._extensionFound.bind(this));
 | 
			
		||||
        finder.connect('extension-found', Lang.bind(this, this._extensionFound));
 | 
			
		||||
        finder.scanExtensions();
 | 
			
		||||
        this._extensionsLoaded();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _extensionFound(finder, extension) {
 | 
			
		||||
    _extensionFound: function(finder, extension) {
 | 
			
		||||
        let row = new ExtensionRow(extension.uuid);
 | 
			
		||||
 | 
			
		||||
        row.prefsButton.visible = this._extensionAvailable(row.uuid);
 | 
			
		||||
        row.prefsButton.connect('clicked', () => {
 | 
			
		||||
            this._selectExtension(row.uuid);
 | 
			
		||||
        });
 | 
			
		||||
        row.prefsButton.connect('clicked', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                this._selectExtension(row.uuid);
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        row.show_all();
 | 
			
		||||
        this._extensionSelector.add(row);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _extensionsLoaded() {
 | 
			
		||||
    _extensionsLoaded: function() {
 | 
			
		||||
        if (this._startupUuid && this._extensionAvailable(this._startupUuid))
 | 
			
		||||
            this._selectExtension(this._startupUuid);
 | 
			
		||||
        this._startupUuid = null;
 | 
			
		||||
@@ -218,16 +221,16 @@ var Application = new Lang.Class({
 | 
			
		||||
        this._loaded = true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onActivate() {
 | 
			
		||||
    _onActivate: function() {
 | 
			
		||||
        this._window.present();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onStartup(app) {
 | 
			
		||||
    _onStartup: function(app) {
 | 
			
		||||
        this._buildUI(app);
 | 
			
		||||
        this._scanExtensions();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onCommandLine(app, commandLine) {
 | 
			
		||||
    _onCommandLine: function(app, commandLine) {
 | 
			
		||||
        app.activate();
 | 
			
		||||
        let args = commandLine.get_arguments();
 | 
			
		||||
 | 
			
		||||
@@ -254,7 +257,7 @@ var DescriptionLabel = new Lang.Class({
 | 
			
		||||
    Name: 'DescriptionLabel',
 | 
			
		||||
    Extends: Gtk.Label,
 | 
			
		||||
 | 
			
		||||
    vfunc_get_preferred_height_for_width(width) {
 | 
			
		||||
    vfunc_get_preferred_height_for_width: function(width) {
 | 
			
		||||
        // Hack: Request the maximum height allowed by the line limit
 | 
			
		||||
        if (this.lines > 0)
 | 
			
		||||
            return this.parent(0);
 | 
			
		||||
@@ -266,28 +269,29 @@ var ExtensionRow = new Lang.Class({
 | 
			
		||||
    Name: 'ExtensionRow',
 | 
			
		||||
    Extends: Gtk.ListBoxRow,
 | 
			
		||||
 | 
			
		||||
    _init(uuid) {
 | 
			
		||||
    _init: function(uuid) {
 | 
			
		||||
        this.parent();
 | 
			
		||||
 | 
			
		||||
        this.uuid = uuid;
 | 
			
		||||
 | 
			
		||||
        this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
 | 
			
		||||
        this._settings.connect('changed::enabled-extensions', () => {
 | 
			
		||||
            this._switch.state = this._isEnabled();
 | 
			
		||||
        });
 | 
			
		||||
        this._settings.connect('changed::enabled-extensions', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                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() {
 | 
			
		||||
    _buildUI: function() {
 | 
			
		||||
        let extension = ExtensionUtils.extensions[this.uuid];
 | 
			
		||||
 | 
			
		||||
        let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
 | 
			
		||||
@@ -324,17 +328,18 @@ 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', () => {
 | 
			
		||||
            if (this._switch.active)
 | 
			
		||||
                this._enable();
 | 
			
		||||
            else
 | 
			
		||||
                this._disable();
 | 
			
		||||
        });
 | 
			
		||||
        this._switch.connect('state-set', () => true);
 | 
			
		||||
        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; });
 | 
			
		||||
        hbox.add(this._switch);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _canEnable() {
 | 
			
		||||
    _canEnable: function() {
 | 
			
		||||
        let extension = ExtensionUtils.extensions[this.uuid];
 | 
			
		||||
        let checkVersion = !this._settings.get_boolean('disable-extension-version-validation');
 | 
			
		||||
 | 
			
		||||
@@ -342,12 +347,12 @@ var ExtensionRow = new Lang.Class({
 | 
			
		||||
               !(checkVersion && ExtensionUtils.isOutOfDate(extension));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _isEnabled() {
 | 
			
		||||
    _isEnabled: function() {
 | 
			
		||||
        let extensions = this._settings.get_strv('enabled-extensions');
 | 
			
		||||
        return extensions.indexOf(this.uuid) != -1;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _enable() {
 | 
			
		||||
    _enable: function() {
 | 
			
		||||
        let extensions = this._settings.get_strv('enabled-extensions');
 | 
			
		||||
        if (extensions.indexOf(this.uuid) != -1)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -356,7 +361,7 @@ var ExtensionRow = new Lang.Class({
 | 
			
		||||
        this._settings.set_strv('enabled-extensions', extensions);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _disable() {
 | 
			
		||||
    _disable: function() {
 | 
			
		||||
        let extensions = this._settings.get_strv('enabled-extensions');
 | 
			
		||||
        let pos = extensions.indexOf(this.uuid);
 | 
			
		||||
        if (pos == -1)
 | 
			
		||||
@@ -373,11 +378,11 @@ function initEnvironment() {
 | 
			
		||||
    // Monkey-patch in a "global" object that fakes some Shell utilities
 | 
			
		||||
    // that ExtensionUtils depends on.
 | 
			
		||||
    window.global = {
 | 
			
		||||
        log() {
 | 
			
		||||
        log: function() {
 | 
			
		||||
            print([].join.call(arguments, ', '));
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        logError(s) {
 | 
			
		||||
        logError: function(s) {
 | 
			
		||||
            log('ERROR: ' + s);
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ var BeginRequestType = {
 | 
			
		||||
var AuthPrompt = new Lang.Class({
 | 
			
		||||
    Name: 'AuthPrompt',
 | 
			
		||||
 | 
			
		||||
    _init(gdmClient, mode) {
 | 
			
		||||
    _init: function(gdmClient, mode) {
 | 
			
		||||
        this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
 | 
			
		||||
 | 
			
		||||
        this._gdmClient = gdmClient;
 | 
			
		||||
@@ -55,33 +55,35 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly: reauthenticationOnly });
 | 
			
		||||
 | 
			
		||||
        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._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.smartcardDetected = this._userVerifier.smartcardDetected;
 | 
			
		||||
 | 
			
		||||
        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.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.actor = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
 | 
			
		||||
                                        vertical: true });
 | 
			
		||||
        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.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._userWell = new St.Bin({ x_fill: true,
 | 
			
		||||
                                      x_align: St.Align.START });
 | 
			
		||||
@@ -134,18 +136,21 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
        this._defaultButtonWell.add_child(this._spinner.actor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
        this._userVerifier.destroy();
 | 
			
		||||
        this._userVerifier = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _initButtons() {
 | 
			
		||||
    _initButtons: function() {
 | 
			
		||||
        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', () => { this.cancel(); });
 | 
			
		||||
        this.cancelButton.connect('clicked',
 | 
			
		||||
                                   Lang.bind(this, function() {
 | 
			
		||||
                                       this.cancel();
 | 
			
		||||
                                   }));
 | 
			
		||||
        this._buttonBox.add(this.cancelButton,
 | 
			
		||||
                            { expand: false,
 | 
			
		||||
                              x_fill: false,
 | 
			
		||||
@@ -164,7 +169,10 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
                                          reactive: true,
 | 
			
		||||
                                          can_focus: true,
 | 
			
		||||
                                          label: _("Next") });
 | 
			
		||||
        this.nextButton.connect('clicked', () => { this.emit('next'); });
 | 
			
		||||
        this.nextButton.connect('clicked',
 | 
			
		||||
                                 Lang.bind(this, function() {
 | 
			
		||||
                                     this.emit('next');
 | 
			
		||||
                                 }));
 | 
			
		||||
        this.nextButton.add_style_pseudo_class('default');
 | 
			
		||||
        this._buttonBox.add(this.nextButton,
 | 
			
		||||
                            { expand: false,
 | 
			
		||||
@@ -175,19 +183,20 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._updateNextButtonSensitivity(this._entry.text.length > 0);
 | 
			
		||||
 | 
			
		||||
        this._entry.clutter_text.connect('text-changed', () => {
 | 
			
		||||
            if (!this._userVerifier.hasPendingMessages)
 | 
			
		||||
                this._fadeOutMessage();
 | 
			
		||||
        this._entry.clutter_text.connect('text-changed',
 | 
			
		||||
                                         Lang.bind(this, function() {
 | 
			
		||||
                                             if (!this._userVerifier.hasPendingMessages)
 | 
			
		||||
                                                 this._fadeOutMessage();
 | 
			
		||||
 | 
			
		||||
            this._updateNextButtonSensitivity(this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING);
 | 
			
		||||
        });
 | 
			
		||||
        this._entry.clutter_text.connect('activate', () => {
 | 
			
		||||
                                             this._updateNextButtonSensitivity(this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING);
 | 
			
		||||
                                         }));
 | 
			
		||||
        this._entry.clutter_text.connect('activate', Lang.bind(this, function() {
 | 
			
		||||
            if (this.nextButton.reactive)
 | 
			
		||||
                this.emit('next');
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onAskQuestion(verifier, serviceName, question, passwordChar) {
 | 
			
		||||
    _onAskQuestion: function(verifier, serviceName, question, passwordChar) {
 | 
			
		||||
        if (this._queryingService)
 | 
			
		||||
            this.clear();
 | 
			
		||||
 | 
			
		||||
@@ -213,12 +222,12 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
        this.emit('prompted');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onOVirtUserAuthenticated() {
 | 
			
		||||
    _onOVirtUserAuthenticated: function() {
 | 
			
		||||
        if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
 | 
			
		||||
            this.reset();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSmartcardStatusChanged() {
 | 
			
		||||
    _onSmartcardStatusChanged: function() {
 | 
			
		||||
        this.smartcardDetected = this._userVerifier.smartcardDetected;
 | 
			
		||||
 | 
			
		||||
        // Most of the time we want to reset if the user inserts or removes
 | 
			
		||||
@@ -237,12 +246,12 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
            this.reset();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onShowMessage(userVerifier, message, type) {
 | 
			
		||||
    _onShowMessage: function(userVerifier, message, type) {
 | 
			
		||||
        this.setMessage(message, type);
 | 
			
		||||
        this.emit('prompted');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onVerificationFailed() {
 | 
			
		||||
    _onVerificationFailed: function() {
 | 
			
		||||
        this._queryingService = null;
 | 
			
		||||
        this.clear();
 | 
			
		||||
 | 
			
		||||
@@ -251,22 +260,22 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
        this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onVerificationComplete() {
 | 
			
		||||
    _onVerificationComplete: function() {
 | 
			
		||||
        this.setActorInDefaultButtonWell(null);
 | 
			
		||||
        this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED;
 | 
			
		||||
        this.cancelButton.reactive = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onReset() {
 | 
			
		||||
    _onReset: function() {
 | 
			
		||||
        this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
 | 
			
		||||
        this.reset();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addActorToDefaultButtonWell(actor) {
 | 
			
		||||
    addActorToDefaultButtonWell: function(actor) {
 | 
			
		||||
        this._defaultButtonWell.add_child(actor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setActorInDefaultButtonWell(actor, animate) {
 | 
			
		||||
    setActorInDefaultButtonWell: function(actor, animate) {
 | 
			
		||||
        if (!this._defaultButtonWellActor &&
 | 
			
		||||
            !actor)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -303,7 +312,7 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
                                   delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
 | 
			
		||||
                                   transition: 'linear',
 | 
			
		||||
                                   onCompleteScope: this,
 | 
			
		||||
                                   onComplete() {
 | 
			
		||||
                                   onComplete: function() {
 | 
			
		||||
                                      if (wasSpinner) {
 | 
			
		||||
                                          if (this._spinner)
 | 
			
		||||
                                              this._spinner.stop();
 | 
			
		||||
@@ -330,25 +339,25 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
        this._defaultButtonWellActor = actor;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    startSpinning() {
 | 
			
		||||
    startSpinning: function() {
 | 
			
		||||
        this.setActorInDefaultButtonWell(this._spinner.actor, true);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    stopSpinning() {
 | 
			
		||||
    stopSpinning: function() {
 | 
			
		||||
        this.setActorInDefaultButtonWell(null, false);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    clear() {
 | 
			
		||||
    clear: function() {
 | 
			
		||||
        this._entry.text = '';
 | 
			
		||||
        this.stopSpinning();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setPasswordChar(passwordChar) {
 | 
			
		||||
    setPasswordChar: function(passwordChar) {
 | 
			
		||||
        this._entry.clutter_text.set_password_char(passwordChar);
 | 
			
		||||
        this._entry.menu.isPassword = passwordChar != '';
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setQuestion(question) {
 | 
			
		||||
    setQuestion: function(question) {
 | 
			
		||||
        this._label.set_text(question);
 | 
			
		||||
 | 
			
		||||
        this._label.show();
 | 
			
		||||
@@ -357,7 +366,7 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
        this._entry.grab_key_focus();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getAnswer() {
 | 
			
		||||
    getAnswer: function() {
 | 
			
		||||
        let text;
 | 
			
		||||
 | 
			
		||||
        if (this._preemptiveAnswer) {
 | 
			
		||||
@@ -370,7 +379,7 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
        return text;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _fadeOutMessage() {
 | 
			
		||||
    _fadeOutMessage: function() {
 | 
			
		||||
        if (this._message.opacity == 0)
 | 
			
		||||
            return;
 | 
			
		||||
        Tweener.removeTweens(this._message);
 | 
			
		||||
@@ -381,7 +390,7 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
                         });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setMessage(message, type) {
 | 
			
		||||
    setMessage: function(message, type) {
 | 
			
		||||
        if (type == GdmUtil.MessageType.ERROR)
 | 
			
		||||
            this._message.add_style_class_name('login-dialog-message-warning');
 | 
			
		||||
        else
 | 
			
		||||
@@ -401,18 +410,18 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateNextButtonSensitivity(sensitive) {
 | 
			
		||||
    _updateNextButtonSensitivity: function(sensitive) {
 | 
			
		||||
        this.nextButton.reactive = sensitive;
 | 
			
		||||
        this.nextButton.can_focus = sensitive;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    updateSensitivity(sensitive) {
 | 
			
		||||
    updateSensitivity: function(sensitive) {
 | 
			
		||||
        this._updateNextButtonSensitivity(sensitive && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING));
 | 
			
		||||
        this._entry.reactive = sensitive;
 | 
			
		||||
        this._entry.clutter_text.editable = sensitive;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hide() {
 | 
			
		||||
    hide: function() {
 | 
			
		||||
        this.setActorInDefaultButtonWell(null, true);
 | 
			
		||||
        this.actor.hide();
 | 
			
		||||
        this._message.opacity = 0;
 | 
			
		||||
@@ -423,7 +432,7 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
        this._entry.set_text('');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setUser(user) {
 | 
			
		||||
    setUser: function(user) {
 | 
			
		||||
        let oldChild = this._userWell.get_child();
 | 
			
		||||
        if (oldChild)
 | 
			
		||||
            oldChild.destroy();
 | 
			
		||||
@@ -434,7 +443,7 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    reset() {
 | 
			
		||||
    reset: function() {
 | 
			
		||||
        let oldStatus = this.verificationStatus;
 | 
			
		||||
        this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
 | 
			
		||||
        this.cancelButton.reactive = true;
 | 
			
		||||
@@ -471,7 +480,7 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
        this.emit('reset', beginRequestType);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addCharacter(unichar) {
 | 
			
		||||
    addCharacter: function(unichar) {
 | 
			
		||||
        if (!this._entry.visible)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -479,7 +488,7 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
        this._entry.clutter_text.insert_unichar(unichar);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    begin(params) {
 | 
			
		||||
    begin: function(params) {
 | 
			
		||||
        params = Params.parse(params, { userName: null,
 | 
			
		||||
                                        hold: null });
 | 
			
		||||
 | 
			
		||||
@@ -493,21 +502,22 @@ var AuthPrompt = new Lang.Class({
 | 
			
		||||
        this.verificationStatus = AuthPromptStatus.VERIFYING;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    finish(onComplete) {
 | 
			
		||||
    finish: function(onComplete) {
 | 
			
		||||
        if (!this._userVerifier.hasPendingMessages) {
 | 
			
		||||
            this._userVerifier.clear();
 | 
			
		||||
            onComplete();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let signalId = this._userVerifier.connect('no-more-messages', () => {
 | 
			
		||||
            this._userVerifier.disconnect(signalId);
 | 
			
		||||
            this._userVerifier.clear();
 | 
			
		||||
            onComplete();
 | 
			
		||||
        });
 | 
			
		||||
        let signalId = this._userVerifier.connect('no-more-messages',
 | 
			
		||||
                                                  Lang.bind(this, function() {
 | 
			
		||||
                                                      this._userVerifier.disconnect(signalId);
 | 
			
		||||
                                                      this._userVerifier.clear();
 | 
			
		||||
                                                      onComplete();
 | 
			
		||||
                                                  }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    cancel() {
 | 
			
		||||
    cancel: function() {
 | 
			
		||||
        if (this.verificationStatus == AuthPromptStatus.VERIFICATION_SUCCEEDED) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,7 @@ const Signals = imports.signals;
 | 
			
		||||
var Task = new Lang.Class({
 | 
			
		||||
    Name: 'Task',
 | 
			
		||||
 | 
			
		||||
    _init(scope, handler) {
 | 
			
		||||
    _init: function(scope, handler) {
 | 
			
		||||
        if (scope)
 | 
			
		||||
            this.scope = scope;
 | 
			
		||||
        else
 | 
			
		||||
@@ -59,7 +59,7 @@ var Task = new Lang.Class({
 | 
			
		||||
        this.handler = handler;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    run() {
 | 
			
		||||
    run: function() {
 | 
			
		||||
        if (this.handler)
 | 
			
		||||
            return this.handler.call(this.scope);
 | 
			
		||||
 | 
			
		||||
@@ -72,37 +72,39 @@ var Hold = new Lang.Class({
 | 
			
		||||
    Name: 'Hold',
 | 
			
		||||
    Extends: Task,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
        this.parent(this, () => this);
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent(this, function () {
 | 
			
		||||
            return this;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._acquisitions = 1;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    acquire() {
 | 
			
		||||
    acquire: function() {
 | 
			
		||||
        if (this._acquisitions <= 0)
 | 
			
		||||
            throw new Error("Cannot acquire hold after it's been released");
 | 
			
		||||
        this._acquisitions++;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    acquireUntilAfter(hold) {
 | 
			
		||||
    acquireUntilAfter: function(hold) {
 | 
			
		||||
        if (!hold.isAcquired())
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this.acquire();
 | 
			
		||||
        let signalId = hold.connect('release', () => {
 | 
			
		||||
            hold.disconnect(signalId);
 | 
			
		||||
            this.release();
 | 
			
		||||
        });
 | 
			
		||||
        let signalId = hold.connect('release', Lang.bind(this, function() {
 | 
			
		||||
                                        hold.disconnect(signalId);
 | 
			
		||||
                                        this.release();
 | 
			
		||||
                                    }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    release() {
 | 
			
		||||
    release: function() {
 | 
			
		||||
        this._acquisitions--;
 | 
			
		||||
 | 
			
		||||
        if (this._acquisitions == 0)
 | 
			
		||||
            this.emit('release');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    isAcquired() {
 | 
			
		||||
    isAcquired: function() {
 | 
			
		||||
        return this._acquisitions > 0;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -112,7 +114,7 @@ var Batch = new Lang.Class({
 | 
			
		||||
    Name: 'Batch',
 | 
			
		||||
    Extends: Task,
 | 
			
		||||
 | 
			
		||||
    _init(scope, tasks) {
 | 
			
		||||
    _init: function(scope, tasks) {
 | 
			
		||||
        this.parent();
 | 
			
		||||
 | 
			
		||||
        this.tasks = [];
 | 
			
		||||
@@ -132,11 +134,11 @@ var Batch = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    process() {
 | 
			
		||||
    process: function() {
 | 
			
		||||
        throw new Error('Not implemented');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    runTask() {
 | 
			
		||||
    runTask: function() {
 | 
			
		||||
        if (!(this._currentTaskIndex in this.tasks)) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
@@ -144,11 +146,11 @@ var Batch = new Lang.Class({
 | 
			
		||||
        return this.tasks[this._currentTaskIndex].run();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _finish() {
 | 
			
		||||
    _finish: function() {
 | 
			
		||||
        this.hold.release();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    nextTask() {
 | 
			
		||||
    nextTask: function() {
 | 
			
		||||
        this._currentTaskIndex++;
 | 
			
		||||
 | 
			
		||||
        // if the entire batch of tasks is finished, release
 | 
			
		||||
@@ -161,7 +163,7 @@ var Batch = new Lang.Class({
 | 
			
		||||
        this.process();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _start() {
 | 
			
		||||
    _start: function() {
 | 
			
		||||
        // acquire a hold to get released when the entire
 | 
			
		||||
        // batch of tasks is finished
 | 
			
		||||
        this.hold = new Hold();
 | 
			
		||||
@@ -169,7 +171,7 @@ var Batch = new Lang.Class({
 | 
			
		||||
        this.process();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    run() {
 | 
			
		||||
    run: function() {
 | 
			
		||||
        this._start();
 | 
			
		||||
 | 
			
		||||
        // hold may be destroyed at this point
 | 
			
		||||
@@ -177,7 +179,7 @@ var Batch = new Lang.Class({
 | 
			
		||||
        return this.hold;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    cancel() {
 | 
			
		||||
    cancel: function() {
 | 
			
		||||
        this.tasks = this.tasks.splice(0, this._currentTaskIndex + 1);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -187,7 +189,7 @@ var ConcurrentBatch = new Lang.Class({
 | 
			
		||||
    Name: 'ConcurrentBatch',
 | 
			
		||||
    Extends: Batch,
 | 
			
		||||
 | 
			
		||||
    process() {
 | 
			
		||||
    process: function() {
 | 
			
		||||
       let hold = this.runTask();
 | 
			
		||||
 | 
			
		||||
       if (hold) {
 | 
			
		||||
@@ -206,16 +208,17 @@ var ConsecutiveBatch = new Lang.Class({
 | 
			
		||||
    Name: 'ConsecutiveBatch',
 | 
			
		||||
    Extends: Batch,
 | 
			
		||||
 | 
			
		||||
    process() {
 | 
			
		||||
    process: function() {
 | 
			
		||||
       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', () => {
 | 
			
		||||
               hold.disconnect(signalId);
 | 
			
		||||
               this.nextTask();
 | 
			
		||||
           });
 | 
			
		||||
           let signalId = hold.connect('release',
 | 
			
		||||
                                       Lang.bind(this, function() {
 | 
			
		||||
                                           hold.disconnect(signalId);
 | 
			
		||||
                                           this.nextTask();
 | 
			
		||||
                                       }));
 | 
			
		||||
           return;
 | 
			
		||||
       } else {
 | 
			
		||||
           // This task finished, process the next one
 | 
			
		||||
 
 | 
			
		||||
@@ -29,28 +29,28 @@ function OVirtCredentials() {
 | 
			
		||||
 | 
			
		||||
var OVirtCredentialsManager = new Lang.Class({
 | 
			
		||||
    Name: 'OVirtCredentialsManager',
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._token = null;
 | 
			
		||||
 | 
			
		||||
        this._credentials = new OVirtCredentials();
 | 
			
		||||
        this._credentials.connectSignal('UserAuthenticated',
 | 
			
		||||
                                        this._onUserAuthenticated.bind(this));
 | 
			
		||||
                                        Lang.bind(this, this._onUserAuthenticated));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onUserAuthenticated(proxy, sender, [token]) {
 | 
			
		||||
    _onUserAuthenticated: function(proxy, sender, [token]) {
 | 
			
		||||
        this._token = token;
 | 
			
		||||
        this.emit('user-authenticated', token);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hasToken() {
 | 
			
		||||
    hasToken: function() {
 | 
			
		||||
        return this._token != null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getToken() {
 | 
			
		||||
    getToken: function() {
 | 
			
		||||
        return this._token;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    resetToken() {
 | 
			
		||||
    resetToken: function() {
 | 
			
		||||
        this._token = null;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -62,21 +62,21 @@ const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface);
 | 
			
		||||
var Manager = new Lang.Class({
 | 
			
		||||
    Name: 'Manager',
 | 
			
		||||
 | 
			
		||||
    _init(parentActor) {
 | 
			
		||||
    _init: function(parentActor) {
 | 
			
		||||
        this._aggregateProvider = Provider(Gio.DBus.system,
 | 
			
		||||
                                           'org.freedesktop.realmd',
 | 
			
		||||
                                           '/org/freedesktop/realmd',
 | 
			
		||||
                                           this._reloadRealms.bind(this))
 | 
			
		||||
                                           Lang.bind(this, this._reloadRealms))
 | 
			
		||||
        this._realms = {};
 | 
			
		||||
 | 
			
		||||
        this._signalId = this._aggregateProvider.connect('g-properties-changed',
 | 
			
		||||
            (proxy, properties) => {
 | 
			
		||||
                if ('Realms' in properties.deep_unpack())
 | 
			
		||||
                    this._reloadRealms();
 | 
			
		||||
            });
 | 
			
		||||
                                        Lang.bind(this, function(proxy, properties) {
 | 
			
		||||
                                            if ('Realms' in properties.deep_unpack())
 | 
			
		||||
                                                this._reloadRealms();
 | 
			
		||||
                                        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _reloadRealms() {
 | 
			
		||||
    _reloadRealms: function() {
 | 
			
		||||
        let realmPaths = this._aggregateProvider.Realms;
 | 
			
		||||
 | 
			
		||||
        if (!realmPaths)
 | 
			
		||||
@@ -86,11 +86,11 @@ var Manager = new Lang.Class({
 | 
			
		||||
            let realm = Realm(Gio.DBus.system,
 | 
			
		||||
                              'org.freedesktop.realmd',
 | 
			
		||||
                              realmPaths[i],
 | 
			
		||||
                              this._onRealmLoaded.bind(this));
 | 
			
		||||
                              Lang.bind(this, this._onRealmLoaded));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _reloadRealm(realm) {
 | 
			
		||||
    _reloadRealm: function(realm) {
 | 
			
		||||
        if (!realm.Configured) {
 | 
			
		||||
            if (this._realms[realm.get_object_path()])
 | 
			
		||||
                delete this._realms[realm.get_object_path()];
 | 
			
		||||
@@ -103,19 +103,20 @@ var Manager = new Lang.Class({
 | 
			
		||||
        this._updateLoginFormat();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onRealmLoaded(realm, error) {
 | 
			
		||||
    _onRealmLoaded: function(realm, error) {
 | 
			
		||||
        if (error)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._reloadRealm(realm);
 | 
			
		||||
 | 
			
		||||
        realm.connect('g-properties-changed', (proxy, properties) => {
 | 
			
		||||
            if ('Configured' in properties.deep_unpack())
 | 
			
		||||
                this._reloadRealm(realm);
 | 
			
		||||
        });
 | 
			
		||||
        realm.connect('g-properties-changed',
 | 
			
		||||
                      Lang.bind(this, function(proxy, properties) {
 | 
			
		||||
                                if ('Configured' in properties.deep_unpack())
 | 
			
		||||
                                    this._reloadRealm(realm);
 | 
			
		||||
                                }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateLoginFormat() {
 | 
			
		||||
    _updateLoginFormat: function() {
 | 
			
		||||
        let newLoginFormat;
 | 
			
		||||
 | 
			
		||||
        for (let realmPath in this._realms) {
 | 
			
		||||
@@ -141,11 +142,13 @@ var Manager = new Lang.Class({
 | 
			
		||||
        return this._loginFormat;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    release() {
 | 
			
		||||
    release: function() {
 | 
			
		||||
        Service(Gio.DBus.system,
 | 
			
		||||
                'org.freedesktop.realmd',
 | 
			
		||||
                '/org/freedesktop/realmd',
 | 
			
		||||
                service => { service.ReleaseRemote(); });
 | 
			
		||||
                function(service) {
 | 
			
		||||
                    service.ReleaseRemote();
 | 
			
		||||
                });
 | 
			
		||||
        this._aggregateProvider.disconnect(this._signalId);
 | 
			
		||||
        this._realms = { };
 | 
			
		||||
        this._updateLoginFormat();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										187
									
								
								js/gdm/util.js
									
									
									
									
									
								
							
							
						
						@@ -60,7 +60,7 @@ function fadeInActor(actor) {
 | 
			
		||||
                       height: naturalHeight,
 | 
			
		||||
                       time: FADE_ANIMATION_TIME,
 | 
			
		||||
                       transition: 'easeOutQuad',
 | 
			
		||||
                       onComplete() {
 | 
			
		||||
                       onComplete: function() {
 | 
			
		||||
                           this.set_height(-1);
 | 
			
		||||
                           hold.release();
 | 
			
		||||
                       },
 | 
			
		||||
@@ -82,7 +82,7 @@ function fadeOutActor(actor) {
 | 
			
		||||
                       height: 0,
 | 
			
		||||
                       time: FADE_ANIMATION_TIME,
 | 
			
		||||
                       transition: 'easeOutQuad',
 | 
			
		||||
                       onComplete() {
 | 
			
		||||
                       onComplete: function() {
 | 
			
		||||
                           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() {
 | 
			
		||||
                       onComplete: function() {
 | 
			
		||||
                           clone.destroy();
 | 
			
		||||
                           hold.release();
 | 
			
		||||
                       }
 | 
			
		||||
@@ -122,7 +122,7 @@ function cloneAndFadeOutActor(actor) {
 | 
			
		||||
var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
    Name: 'ShellUserVerifier',
 | 
			
		||||
 | 
			
		||||
    _init(client, params) {
 | 
			
		||||
    _init: function(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',
 | 
			
		||||
                               this._updateDefaultService.bind(this));
 | 
			
		||||
                               Lang.bind(this, this._updateDefaultService));
 | 
			
		||||
        this._updateDefaultService();
 | 
			
		||||
 | 
			
		||||
        this._fprintManager = Fprint.FprintManager();
 | 
			
		||||
@@ -147,9 +147,9 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
        this._checkForSmartcard();
 | 
			
		||||
 | 
			
		||||
        this._smartcardInsertedId = this._smartcardManager.connect('smartcard-inserted',
 | 
			
		||||
                                                                   this._checkForSmartcard.bind(this));
 | 
			
		||||
                                                                   Lang.bind(this, this._checkForSmartcard));
 | 
			
		||||
        this._smartcardRemovedId = this._smartcardManager.connect('smartcard-removed',
 | 
			
		||||
                                                                  this._checkForSmartcard.bind(this));
 | 
			
		||||
                                                                  Lang.bind(this, this._checkForSmartcard));
 | 
			
		||||
 | 
			
		||||
        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',
 | 
			
		||||
                                                                               this._oVirtUserAuthenticated.bind(this));
 | 
			
		||||
                                                                               Lang.bind(this, this._oVirtUserAuthenticated));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    begin(userName, hold) {
 | 
			
		||||
    begin: function(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,
 | 
			
		||||
                                                       this._reauthenticationChannelOpened.bind(this));
 | 
			
		||||
                                                       Lang.bind(this, this._reauthenticationChannelOpened));
 | 
			
		||||
        } else {
 | 
			
		||||
            this._client.get_user_verifier(this._cancellable, this._userVerifierGot.bind(this));
 | 
			
		||||
            this._client.get_user_verifier(this._cancellable, Lang.bind(this, this._userVerifierGot));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    cancel() {
 | 
			
		||||
    cancel: function() {
 | 
			
		||||
        if (this._cancellable)
 | 
			
		||||
            this._cancellable.cancel();
 | 
			
		||||
 | 
			
		||||
@@ -195,14 +195,14 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _clearUserVerifier() {
 | 
			
		||||
    _clearUserVerifier: function() {
 | 
			
		||||
        if (this._userVerifier) {
 | 
			
		||||
            this._userVerifier.run_dispose();
 | 
			
		||||
            this._userVerifier = null;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    clear() {
 | 
			
		||||
    clear: function() {
 | 
			
		||||
        if (this._cancellable) {
 | 
			
		||||
            this._cancellable.cancel();
 | 
			
		||||
            this._cancellable = null;
 | 
			
		||||
@@ -212,7 +212,7 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
        this._clearMessageQueue();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
    destroy: function() {
 | 
			
		||||
        this.clear();
 | 
			
		||||
 | 
			
		||||
        this._settings.run_dispose();
 | 
			
		||||
@@ -226,23 +226,24 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
        this._oVirtCredentialsManager = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    answerQuery(serviceName, answer) {
 | 
			
		||||
    answerQuery: function(serviceName, answer) {
 | 
			
		||||
        if (!this.hasPendingMessages) {
 | 
			
		||||
            this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
 | 
			
		||||
        } else {
 | 
			
		||||
            let signalId = this.connect('no-more-messages', () => {
 | 
			
		||||
                this.disconnect(signalId);
 | 
			
		||||
                this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
 | 
			
		||||
            });
 | 
			
		||||
            let signalId = this.connect('no-more-messages',
 | 
			
		||||
                                        Lang.bind(this, function() {
 | 
			
		||||
                                            this.disconnect(signalId);
 | 
			
		||||
                                            this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
 | 
			
		||||
                                        }));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getIntervalForMessage(message) {
 | 
			
		||||
    _getIntervalForMessage: function(message) {
 | 
			
		||||
        // We probably could be smarter here
 | 
			
		||||
        return message.length * USER_READ_TIME;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    finishMessageQueue() {
 | 
			
		||||
    finishMessageQueue: function() {
 | 
			
		||||
        if (!this.hasPendingMessages)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -252,7 +253,7 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
        this.emit('no-more-messages');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _queueMessageTimeout() {
 | 
			
		||||
    _queueMessageTimeout: function() {
 | 
			
		||||
        if (this._messageQueue.length == 0) {
 | 
			
		||||
            this.finishMessageQueue();
 | 
			
		||||
            return;
 | 
			
		||||
@@ -267,15 +268,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(message, messageType) {
 | 
			
		||||
    _queueMessage: function(message, messageType) {
 | 
			
		||||
        let interval = this._getIntervalForMessage(message);
 | 
			
		||||
 | 
			
		||||
        this.hasPendingMessages = true;
 | 
			
		||||
@@ -283,7 +284,7 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
        this._queueMessageTimeout();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _clearMessageQueue() {
 | 
			
		||||
    _clearMessageQueue: function() {
 | 
			
		||||
        this.finishMessageQueue();
 | 
			
		||||
 | 
			
		||||
        if (this._messageQueueTimeoutId != 0) {
 | 
			
		||||
@@ -293,7 +294,7 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
        this.emit('show-message', null, MessageType.NONE);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _checkForFingerprintReader() {
 | 
			
		||||
    _checkForFingerprintReader: function() {
 | 
			
		||||
        this._haveFingerprintReader = false;
 | 
			
		||||
 | 
			
		||||
        if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY) ||
 | 
			
		||||
@@ -302,21 +303,21 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, this._cancellable,
 | 
			
		||||
            (device, error) => {
 | 
			
		||||
        this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, this._cancellable, Lang.bind(this,
 | 
			
		||||
            function(device, error) {
 | 
			
		||||
                if (!error && device) {
 | 
			
		||||
                    this._haveFingerprintReader = true;
 | 
			
		||||
                    this._updateDefaultService();
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _oVirtUserAuthenticated(token) {
 | 
			
		||||
    _oVirtUserAuthenticated: function(token) {
 | 
			
		||||
        this._preemptingService = OVIRT_SERVICE_NAME;
 | 
			
		||||
        this.emit('ovirt-user-authenticated');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _checkForSmartcard() {
 | 
			
		||||
    _checkForSmartcard: function() {
 | 
			
		||||
        let smartcardDetected;
 | 
			
		||||
 | 
			
		||||
        if (!this._settings.get_boolean(SMARTCARD_AUTHENTICATION_KEY))
 | 
			
		||||
@@ -338,7 +339,7 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _reportInitError(where, error) {
 | 
			
		||||
    _reportInitError: function(where, error) {
 | 
			
		||||
        logError(error, where);
 | 
			
		||||
        this._hold.release();
 | 
			
		||||
 | 
			
		||||
@@ -346,23 +347,20 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
        this._verificationFailed(false);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _reauthenticationChannelOpened(client, result) {
 | 
			
		||||
    _reauthenticationChannelOpened: function(client, result) {
 | 
			
		||||
        try {
 | 
			
		||||
            this._clearUserVerifier();
 | 
			
		||||
            this._userVerifier = client.open_reauthentication_channel_finish(result);
 | 
			
		||||
        } catch(e) {
 | 
			
		||||
            if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
 | 
			
		||||
                return;
 | 
			
		||||
            if (e.matches(Gio.DBusError, Gio.DBusError.ACCESS_DENIED) &&
 | 
			
		||||
        } 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,
 | 
			
		||||
                                         this._userVerifierGot.bind(this));
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 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) {
 | 
			
		||||
            this._reportInitError('Failed to open reauthentication channel', e);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -373,13 +371,13 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
        this._hold.release();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _userVerifierGot(client, result) {
 | 
			
		||||
    _userVerifierGot: function(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;
 | 
			
		||||
        }
 | 
			
		||||
@@ -389,89 +387,84 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
        this._hold.release();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _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));
 | 
			
		||||
    _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));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getForegroundService() {
 | 
			
		||||
    _getForegroundService: function() {
 | 
			
		||||
        if (this._preemptingService)
 | 
			
		||||
            return this._preemptingService;
 | 
			
		||||
 | 
			
		||||
        return this._defaultService;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    serviceIsForeground(serviceName) {
 | 
			
		||||
    serviceIsForeground: function(serviceName) {
 | 
			
		||||
        return serviceName == this._getForegroundService();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    serviceIsDefault(serviceName) {
 | 
			
		||||
    serviceIsDefault: function(serviceName) {
 | 
			
		||||
        return serviceName == this._defaultService;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateDefaultService() {
 | 
			
		||||
    _updateDefaultService: function() {
 | 
			
		||||
        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(serviceName) {
 | 
			
		||||
    _startService: function(serviceName) {
 | 
			
		||||
        this._hold.acquire();
 | 
			
		||||
        if (this._userName) {
 | 
			
		||||
           this._userVerifier.call_begin_verification_for_user(serviceName,
 | 
			
		||||
                                                               this._userName,
 | 
			
		||||
                                                               this._cancellable,
 | 
			
		||||
                                                               (obj, result) => {
 | 
			
		||||
                                                               Lang.bind(this, function(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,
 | 
			
		||||
                                                      (obj, result) => {
 | 
			
		||||
                                                      Lang.bind(this, function(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() {
 | 
			
		||||
    _beginVerification: function() {
 | 
			
		||||
        this._startService(this._getForegroundService());
 | 
			
		||||
 | 
			
		||||
        if (this._userName && this._haveFingerprintReader && !this.serviceIsForeground(FINGERPRINT_SERVICE_NAME))
 | 
			
		||||
            this._startService(FINGERPRINT_SERVICE_NAME);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onInfo(client, serviceName, info) {
 | 
			
		||||
    _onInfo: function(client, serviceName, info) {
 | 
			
		||||
        if (this.serviceIsForeground(serviceName)) {
 | 
			
		||||
            this._queueMessage(info, MessageType.INFO);
 | 
			
		||||
        } else if (serviceName == FINGERPRINT_SERVICE_NAME &&
 | 
			
		||||
@@ -486,21 +479,21 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onProblem(client, serviceName, problem) {
 | 
			
		||||
    _onProblem: function(client, serviceName, problem) {
 | 
			
		||||
        if (!this.serviceIsForeground(serviceName))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._queueMessage(problem, MessageType.ERROR);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onInfoQuery(client, serviceName, question) {
 | 
			
		||||
    _onInfoQuery: function(client, serviceName, question) {
 | 
			
		||||
        if (!this.serviceIsForeground(serviceName))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this.emit('ask-question', serviceName, question, '');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSecretInfoQuery(client, serviceName, secretQuestion) {
 | 
			
		||||
    _onSecretInfoQuery: function(client, serviceName, secretQuestion) {
 | 
			
		||||
        if (!this.serviceIsForeground(serviceName))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -513,7 +506,7 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
        this.emit('ask-question', serviceName, secretQuestion, '\u25cf');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onReset() {
 | 
			
		||||
    _onReset: function() {
 | 
			
		||||
        // Clear previous attempts to authenticate
 | 
			
		||||
        this._failCounter = 0;
 | 
			
		||||
        this._updateDefaultService();
 | 
			
		||||
@@ -521,20 +514,20 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
        this.emit('reset');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onVerificationComplete() {
 | 
			
		||||
    _onVerificationComplete: function() {
 | 
			
		||||
        this.emit('verification-complete');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _cancelAndReset() {
 | 
			
		||||
    _cancelAndReset: function() {
 | 
			
		||||
        this.cancel();
 | 
			
		||||
        this._onReset();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _retry() {
 | 
			
		||||
    _retry: function() {
 | 
			
		||||
        this.begin(this._userName, new Batch.Hold());
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _verificationFailed(retry) {
 | 
			
		||||
    _verificationFailed: function(retry) {
 | 
			
		||||
        // For Not Listed / enterprise logins, immediately reset
 | 
			
		||||
        // the dialog
 | 
			
		||||
        // Otherwise, we allow ALLOWED_FAILURES attempts. After that, we
 | 
			
		||||
@@ -548,27 +541,29 @@ var ShellUserVerifier = new Lang.Class({
 | 
			
		||||
            if (!this.hasPendingMessages) {
 | 
			
		||||
                this._retry();
 | 
			
		||||
            } else {
 | 
			
		||||
                let signalId = this.connect('no-more-messages', () => {
 | 
			
		||||
                    this.disconnect(signalId);
 | 
			
		||||
                    if (this._cancellable && !this._cancellable.is_cancelled())
 | 
			
		||||
                        this._retry();
 | 
			
		||||
                });
 | 
			
		||||
                let signalId = this.connect('no-more-messages',
 | 
			
		||||
                                            Lang.bind(this, function() {
 | 
			
		||||
                                                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', () => {
 | 
			
		||||
                    this.disconnect(signalId);
 | 
			
		||||
                    this._cancelAndReset();
 | 
			
		||||
                });
 | 
			
		||||
                let signalId = this.connect('no-more-messages',
 | 
			
		||||
                                            Lang.bind(this, function() {
 | 
			
		||||
                                                this.disconnect(signalId);
 | 
			
		||||
                                                this._cancelAndReset();
 | 
			
		||||
                                            }));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.emit('verification-failed');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onConversationStopped(client, serviceName) {
 | 
			
		||||
    _onConversationStopped: function(client, serviceName) {
 | 
			
		||||
        // If the login failed with the preauthenticated oVirt credentials
 | 
			
		||||
        // then discard the credentials and revert to default authentication
 | 
			
		||||
        // mechanism.
 | 
			
		||||
 
 | 
			
		||||
@@ -130,7 +130,6 @@
 | 
			
		||||
    <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>
 | 
			
		||||
 
 | 
			
		||||
@@ -161,7 +161,7 @@ function installImporter(extension) {
 | 
			
		||||
var ExtensionFinder = new Lang.Class({
 | 
			
		||||
    Name: 'ExtensionFinder',
 | 
			
		||||
 | 
			
		||||
    _loadExtension(extensionDir, info, perUserDir) {
 | 
			
		||||
    _loadExtension: function(extensionDir, info, perUserDir) {
 | 
			
		||||
        let fileType = info.get_file_type();
 | 
			
		||||
        if (fileType != Gio.FileType.DIRECTORY)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -184,11 +184,9 @@ var ExtensionFinder = new Lang.Class({
 | 
			
		||||
        this.emit('extension-found', extension);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    scanExtensions() {
 | 
			
		||||
    scanExtensions: function() {
 | 
			
		||||
        let perUserDir = Gio.File.new_for_path(global.userdatadir);
 | 
			
		||||
        FileUtils.collectFromDatadirs('extensions', true, (dir, info) => {
 | 
			
		||||
            this._loadExtension(dir, info, perUserDir);
 | 
			
		||||
        });
 | 
			
		||||
        FileUtils.collectFromDatadirs('extensions', true, Lang.bind(this, this._loadExtension, perUserDir));
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
Signals.addSignalMethods(ExtensionFinder.prototype);
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ var DEFAULT_LIMIT = 512;
 | 
			
		||||
var HistoryManager = new Lang.Class({
 | 
			
		||||
    Name: 'HistoryManager',
 | 
			
		||||
 | 
			
		||||
    _init(params) {
 | 
			
		||||
    _init: function(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,
 | 
			
		||||
                                    this._historyChanged.bind(this));
 | 
			
		||||
                                    Lang.bind(this, this._historyChanged));
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
            this._history = [];
 | 
			
		||||
@@ -32,16 +32,16 @@ var HistoryManager = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        if (this._entry) {
 | 
			
		||||
            this._entry.connect('key-press-event', 
 | 
			
		||||
                                this._onEntryKeyPress.bind(this));
 | 
			
		||||
                                Lang.bind(this, this._onEntryKeyPress));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _historyChanged() {
 | 
			
		||||
    _historyChanged: function() {
 | 
			
		||||
        this._history = global.settings.get_strv(this._key);
 | 
			
		||||
        this._historyIndex = this._history.length;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setPrevItem(text) {
 | 
			
		||||
    _setPrevItem: function(text) {
 | 
			
		||||
        if (this._historyIndex <= 0)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
@@ -52,7 +52,7 @@ var HistoryManager = new Lang.Class({
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setNextItem(text) {
 | 
			
		||||
    _setNextItem: function(text) {
 | 
			
		||||
        if (this._historyIndex >= this._history.length)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
@@ -63,7 +63,7 @@ var HistoryManager = new Lang.Class({
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    lastItem() {
 | 
			
		||||
    lastItem: function() {
 | 
			
		||||
        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(input) {
 | 
			
		||||
    addItem: function(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(entry, event) {
 | 
			
		||||
    _onEntryKeyPress: function(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() {
 | 
			
		||||
    _indexChanged: function() {
 | 
			
		||||
        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() {
 | 
			
		||||
    _save: function() {
 | 
			
		||||
        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() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        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', this._onConnected.bind(this));
 | 
			
		||||
        this._ibus.connect('disconnected', this._clear.bind(this));
 | 
			
		||||
        this._ibus.connect('connected', Lang.bind(this, this._onConnected));
 | 
			
		||||
        this._ibus.connect('disconnected', Lang.bind(this, this._clear));
 | 
			
		||||
        // Need to set this to get 'global-engine-changed' emitions
 | 
			
		||||
        this._ibus.set_watch_ibus_signal(true);
 | 
			
		||||
        this._ibus.connect('global-engine-changed', this._engineChanged.bind(this));
 | 
			
		||||
        this._ibus.connect('global-engine-changed', Lang.bind(this, this._engineChanged));
 | 
			
		||||
 | 
			
		||||
        this._spawn();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _spawn() {
 | 
			
		||||
    _spawn: function() {
 | 
			
		||||
        try {
 | 
			
		||||
            Gio.Subprocess.new(['ibus-daemon', '--xim', '--panel', 'disable'],
 | 
			
		||||
                               Gio.SubprocessFlags.NONE);
 | 
			
		||||
@@ -71,7 +71,7 @@ var IBusManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _clear() {
 | 
			
		||||
    _clear: function() {
 | 
			
		||||
        if (this._panelService)
 | 
			
		||||
            this._panelService.destroy();
 | 
			
		||||
 | 
			
		||||
@@ -87,15 +87,15 @@ var IBusManager = new Lang.Class({
 | 
			
		||||
        this._spawn();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onConnected() {
 | 
			
		||||
        this._ibus.list_engines_async(-1, null, this._initEngines.bind(this));
 | 
			
		||||
    _onConnected: function() {
 | 
			
		||||
        this._ibus.list_engines_async(-1, null, Lang.bind(this, this._initEngines));
 | 
			
		||||
        this._ibus.request_name_async(IBus.SERVICE_PANEL,
 | 
			
		||||
                                      IBus.BusNameFlag.REPLACE_EXISTING,
 | 
			
		||||
                                      -1, null,
 | 
			
		||||
                                      this._initPanelService.bind(this));
 | 
			
		||||
                                      Lang.bind(this, this._initPanelService));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _initEngines(ibus, result) {
 | 
			
		||||
    _initEngines: function(ibus, result) {
 | 
			
		||||
        let enginesList = this._ibus.list_engines_async_finish(result);
 | 
			
		||||
        if (enginesList) {
 | 
			
		||||
            for (let i = 0; i < enginesList.length; ++i) {
 | 
			
		||||
@@ -108,18 +108,13 @@ var IBusManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _initPanelService(ibus, result) {
 | 
			
		||||
    _initPanelService: function(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', 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);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            this._panelService.connect('update-property', Lang.bind(this, this._updateProperty));
 | 
			
		||||
            try {
 | 
			
		||||
                // IBus versions older than 1.5.10 have a bug which
 | 
			
		||||
                // causes spurious set-content-type emissions when
 | 
			
		||||
@@ -127,11 +122,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', this._setContentType.bind(this));
 | 
			
		||||
                this._panelService.connect('set-content-type', Lang.bind(this, this._setContentType));
 | 
			
		||||
            } catch (e) {
 | 
			
		||||
            }
 | 
			
		||||
            // If an engine is already active we need to get its properties
 | 
			
		||||
            this._ibus.get_global_engine_async(-1, null, (i, result) => {
 | 
			
		||||
            this._ibus.get_global_engine_async(-1, null, Lang.bind(this, function(i, result) {
 | 
			
		||||
                let engine;
 | 
			
		||||
                try {
 | 
			
		||||
                    engine = this._ibus.get_global_engine_async_finish(result);
 | 
			
		||||
@@ -141,20 +136,20 @@ var IBusManager = new Lang.Class({
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                this._engineChanged(this._ibus, engine.get_name());
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
            this._updateReadiness();
 | 
			
		||||
        } else {
 | 
			
		||||
            this._clear();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateReadiness() {
 | 
			
		||||
    _updateReadiness: function() {
 | 
			
		||||
        this._ready = (Object.keys(this._engines).length > 0 &&
 | 
			
		||||
                       this._panelService != null);
 | 
			
		||||
        this.emit('ready', this._ready);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _engineChanged(bus, engineName) {
 | 
			
		||||
    _engineChanged: function(bus, engineName) {
 | 
			
		||||
        if (!this._ready)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -164,7 +159,7 @@ var IBusManager = new Lang.Class({
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._registerPropertiesId =
 | 
			
		||||
            this._panelService.connect('register-properties', (p, props) => {
 | 
			
		||||
            this._panelService.connect('register-properties', Lang.bind(this, function(p, props) {
 | 
			
		||||
                if (!props.get(0))
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
@@ -172,29 +167,29 @@ var IBusManager = new Lang.Class({
 | 
			
		||||
                this._registerPropertiesId = 0;
 | 
			
		||||
 | 
			
		||||
                this.emit('properties-registered', this._currentEngineName, props);
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateProperty(panel, prop) {
 | 
			
		||||
    _updateProperty: function(panel, prop) {
 | 
			
		||||
        this.emit('property-updated', this._currentEngineName, prop);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setContentType(panel, purpose, hints) {
 | 
			
		||||
    _setContentType: function(panel, purpose, hints) {
 | 
			
		||||
        this.emit('set-content-type', purpose, hints);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateProperty(key, state) {
 | 
			
		||||
    activateProperty: function(key, state) {
 | 
			
		||||
        this._panelService.property_activate(key, state);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getEngineDesc(id) {
 | 
			
		||||
    getEngineDesc: function(id) {
 | 
			
		||||
        if (!this._ready || !this._engines.hasOwnProperty(id))
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
        return this._engines[id];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setEngine(id, callback) {
 | 
			
		||||
    setEngine: function(id, callback) {
 | 
			
		||||
        // Send id even if id == this._currentEngineName
 | 
			
		||||
        // because 'properties-registered' signal can be emitted
 | 
			
		||||
        // while this._ibusSources == null on a lock screen.
 | 
			
		||||
@@ -208,7 +203,7 @@ var IBusManager = new Lang.Class({
 | 
			
		||||
                                           null, callback);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    preloadEngines(ids) {
 | 
			
		||||
    preloadEngines: function(ids) {
 | 
			
		||||
        if (!this._ibus || ids.length == 0)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -219,7 +214,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,
 | 
			
		||||
@@ -227,7 +222,7 @@ var IBusManager = new Lang.Class({
 | 
			
		||||
                                                 null);
 | 
			
		||||
                                             this._preloadEnginesId = 0;
 | 
			
		||||
                                             return GLib.SOURCE_REMOVE;
 | 
			
		||||
                                         });
 | 
			
		||||
                                         }));
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
Signals.addSignalMethods(IBusManager.prototype);
 | 
			
		||||
 
 | 
			
		||||
@@ -9,27 +9,22 @@ var InputMethod = new Lang.Class({
 | 
			
		||||
    Name: 'InputMethod',
 | 
			
		||||
    Extends: Clutter.InputMethod,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent();
 | 
			
		||||
        this._hints = 0;
 | 
			
		||||
        this._purpose = 0;
 | 
			
		||||
        this._enabled = true;
 | 
			
		||||
        this._currentFocus = null;
 | 
			
		||||
        this._currentEvent = null;
 | 
			
		||||
        this._doForwardEvent = false;
 | 
			
		||||
        this._ibus = IBus.Bus.new_async();
 | 
			
		||||
        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._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._inputSourceManager = Keyboard.getInputSourceManager();
 | 
			
		||||
        this._sourceChangedId = this._inputSourceManager.connect('current-source-changed',
 | 
			
		||||
                                                                 this._onSourceChanged.bind(this));
 | 
			
		||||
                                                                 Lang.bind(this, this._onSourceChanged));
 | 
			
		||||
        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();
 | 
			
		||||
    },
 | 
			
		||||
@@ -38,7 +33,7 @@ var InputMethod = new Lang.Class({
 | 
			
		||||
        return this._currentFocus;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateCapabilities() {
 | 
			
		||||
    _updateCapabilities: function() {
 | 
			
		||||
        let caps = 0;
 | 
			
		||||
 | 
			
		||||
        if (this.can_show_preedit)
 | 
			
		||||
@@ -53,48 +48,47 @@ var InputMethod = new Lang.Class({
 | 
			
		||||
            this._context.set_capabilities(caps);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSourceChanged() {
 | 
			
		||||
    _onSourceChanged: function() {
 | 
			
		||||
        this._currentSource = this._inputSourceManager.currentSource;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onConnected() {
 | 
			
		||||
    _onConnected: function() {
 | 
			
		||||
        this._ibus.create_input_context_async ('gnome-shell', -1, null,
 | 
			
		||||
                                               this._setContext.bind(this));
 | 
			
		||||
                                               Lang.bind(this, this._setContext));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setContext(bus, res) {
 | 
			
		||||
    _setContext: function(bus, res) {
 | 
			
		||||
        this._context = this._ibus.create_input_context_async_finish(res);
 | 
			
		||||
        this._context.connect('enabled', () => { this._enabled = true });
 | 
			
		||||
        this._context.connect('disabled', () => { this._enabled = false });
 | 
			
		||||
        this._context.connect('commit-text', this._onCommitText.bind(this));
 | 
			
		||||
        this._context.connect('delete-surrounding-text', this._onDeleteSurroundingText.bind(this));
 | 
			
		||||
        this._context.connect('update-preedit-text', this._onUpdatePreeditText.bind(this));
 | 
			
		||||
        this._context.connect('forward-key-event', this._onForwardKeyEvent.bind(this));
 | 
			
		||||
        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._updateCapabilities();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _clear() {
 | 
			
		||||
    _clear: function() {
 | 
			
		||||
        this._context = null;
 | 
			
		||||
        this._hints = 0;
 | 
			
		||||
        this._purpose = 0;
 | 
			
		||||
        this._enabled = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _emitRequestSurrounding() {
 | 
			
		||||
    _emitRequestSurrounding: function() {
 | 
			
		||||
        if (this._context.needs_surrounding_text())
 | 
			
		||||
            this.emit('request-surrounding');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onCommitText(context, text) {
 | 
			
		||||
    _onCommitText: function(context, text) {
 | 
			
		||||
        this.commit(text.get_text());
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDeleteSurroundingText(context) {
 | 
			
		||||
    _onDeleteSurroundingText: function (context) {
 | 
			
		||||
        this.delete_surrounding();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onUpdatePreeditText(context, text, pos, visible) {
 | 
			
		||||
    _onUpdatePreeditText: function (context, text, pos, visible) {
 | 
			
		||||
        let str = null;
 | 
			
		||||
        if (visible && text != null)
 | 
			
		||||
            str = text.get_text();
 | 
			
		||||
@@ -102,25 +96,7 @@ var InputMethod = new Lang.Class({
 | 
			
		||||
        this.set_preedit_text(str, pos);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _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) {
 | 
			
		||||
    vfunc_focus_in: function(focus) {
 | 
			
		||||
        this._currentFocus = focus;
 | 
			
		||||
        if (this._context) {
 | 
			
		||||
            this._context.focus_in();
 | 
			
		||||
@@ -129,7 +105,7 @@ var InputMethod = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_focus_out() {
 | 
			
		||||
    vfunc_focus_out: function() {
 | 
			
		||||
        this._currentFocus = null;
 | 
			
		||||
        if (this._context) {
 | 
			
		||||
            this._context.focus_out();
 | 
			
		||||
@@ -140,7 +116,7 @@ var InputMethod = new Lang.Class({
 | 
			
		||||
        this.set_preedit_text(null, 0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_reset() {
 | 
			
		||||
    vfunc_reset: function() {
 | 
			
		||||
        if (this._context) {
 | 
			
		||||
            this._context.reset();
 | 
			
		||||
            this._emitRequestSurrounding();
 | 
			
		||||
@@ -150,7 +126,7 @@ var InputMethod = new Lang.Class({
 | 
			
		||||
        this.set_preedit_text(null, 0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_set_cursor_location(rect) {
 | 
			
		||||
    vfunc_set_cursor_location: function(rect) {
 | 
			
		||||
        if (this._context) {
 | 
			
		||||
            this._context.set_cursor_location(rect.get_x(), rect.get_y(),
 | 
			
		||||
                                              rect.get_width(), rect.get_height());
 | 
			
		||||
@@ -158,12 +134,12 @@ var InputMethod = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_set_surrounding(text, cursor, anchor) {
 | 
			
		||||
    vfunc_set_surrounding: function(text, cursor, anchor) {
 | 
			
		||||
        if (this._context)
 | 
			
		||||
            this._context.set_surrounding_text(text, cursor, anchor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_update_content_hints(hints) {
 | 
			
		||||
    vfunc_update_content_hints: function(hints) {
 | 
			
		||||
        let ibusHints = 0;
 | 
			
		||||
        if (hints & Clutter.InputContentHintFlags.COMPLETION)
 | 
			
		||||
            ibusHints |= IBus.InputHints.WORD_COMPLETION;
 | 
			
		||||
@@ -183,7 +159,7 @@ var InputMethod = new Lang.Class({
 | 
			
		||||
            this._context.set_content_type(this._purpose, this._hints);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_update_content_purpose(purpose) {
 | 
			
		||||
    vfunc_update_content_purpose: function(purpose) {
 | 
			
		||||
        let ibusPurpose = 0;
 | 
			
		||||
        if (purpose == Clutter.InputContentPurpose.NORMAL)
 | 
			
		||||
            ibusPurpose = IBus.InputPurpose.FREE_FORM;
 | 
			
		||||
@@ -209,10 +185,11 @@ var InputMethod = new Lang.Class({
 | 
			
		||||
            this._context.set_content_type(this._purpose, this._hints);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_filter_key_event(event) {
 | 
			
		||||
    vfunc_filter_key_event: function(event) {
 | 
			
		||||
        if (!this._context || !this._enabled)
 | 
			
		||||
            return false;
 | 
			
		||||
        if (!this._currentSource)
 | 
			
		||||
        if (!this._currentSource ||
 | 
			
		||||
            this._currentSource.type == Keyboard.INPUT_SOURCE_TYPE_XKB)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        let state = event.get_state();
 | 
			
		||||
@@ -221,27 +198,17 @@ 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,
 | 
			
		||||
                                              (context, res) => {
 | 
			
		||||
                                              Lang.bind(this, (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(
 | 
			
		||||
                attr => attr.slice(0, attrHead.length) == attrHead
 | 
			
		||||
            );
 | 
			
		||||
            methods = getPropertyNamesFromExpression(base, commandHeader).filter(function(attr) {
 | 
			
		||||
                return 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(
 | 
			
		||||
                attr => attr.slice(0, attrHead.length) == attrHead
 | 
			
		||||
            );
 | 
			
		||||
            methods = globalCompletionList.filter(function(attr) {
 | 
			
		||||
                return 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(p => propsUnique[p] = null);
 | 
			
		||||
        allProps.map(function(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(s => {
 | 
			
		||||
    str.split(';').forEach(function(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() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._xkbInfo = getXkbInfo();
 | 
			
		||||
        this._current = null;
 | 
			
		||||
        this._localeLayoutInfo = this._getLocaleLayout();
 | 
			
		||||
        this._layoutInfos = {};
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _applyLayoutGroup(group) {
 | 
			
		||||
    _applyLayoutGroup: function(group) {
 | 
			
		||||
        let options = this._buildOptionsString();
 | 
			
		||||
        let [layouts, variants] = this._buildGroupStrings(group);
 | 
			
		||||
        Meta.get_backend().set_keymap(layouts, variants, options);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _applyLayoutGroupIndex(idx) {
 | 
			
		||||
    _applyLayoutGroupIndex: function(idx) {
 | 
			
		||||
        Meta.get_backend().lock_layout_group(idx);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    apply(id) {
 | 
			
		||||
    apply: function(id) {
 | 
			
		||||
        let info = this._layoutInfos[id];
 | 
			
		||||
        if (!info)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -80,7 +80,7 @@ var KeyboardManager = new Lang.Class({
 | 
			
		||||
        this._current = info;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    reapply() {
 | 
			
		||||
    reapply: function() {
 | 
			
		||||
        if (!this._current)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -88,9 +88,7 @@ var KeyboardManager = new Lang.Class({
 | 
			
		||||
        this._applyLayoutGroupIndex(this._current.groupIndex);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setUserLayouts(ids) {
 | 
			
		||||
        let currentId = this._current ? this._current.id : null;
 | 
			
		||||
        let currentGroupIndex = this._current ? this._current.groupIndex : null;
 | 
			
		||||
    setUserLayouts: function(ids) {
 | 
			
		||||
        this._current = null;
 | 
			
		||||
        this._layoutInfos = {};
 | 
			
		||||
 | 
			
		||||
@@ -117,14 +115,11 @@ var KeyboardManager = new Lang.Class({
 | 
			
		||||
            info.group = group;
 | 
			
		||||
            info.groupIndex = groupIndex;
 | 
			
		||||
 | 
			
		||||
            if (currentId == id && currentGroupIndex == groupIndex)
 | 
			
		||||
                this._current = info;
 | 
			
		||||
 | 
			
		||||
            i += 1;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getLocaleLayout() {
 | 
			
		||||
    _getLocaleLayout: function() {
 | 
			
		||||
        let locale = GLib.get_language_names()[0];
 | 
			
		||||
        if (locale.indexOf('_') == -1)
 | 
			
		||||
            locale = DEFAULT_LOCALE;
 | 
			
		||||
@@ -141,18 +136,18 @@ var KeyboardManager = new Lang.Class({
 | 
			
		||||
            return { layout: DEFAULT_LAYOUT, variant: DEFAULT_VARIANT };
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _buildGroupStrings(_group) {
 | 
			
		||||
    _buildGroupStrings: function(_group) {
 | 
			
		||||
        let group = _group.concat(this._localeLayoutInfo);
 | 
			
		||||
        let layouts = group.map(g => g.layout).join(',');
 | 
			
		||||
        let variants = group.map(g => g.variant).join(',');
 | 
			
		||||
        let layouts = group.map(function(g) { return g.layout; }).join(',');
 | 
			
		||||
        let variants = group.map(function(g) { return g.variant; }).join(',');
 | 
			
		||||
        return [layouts, variants];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setKeyboardOptions(options) {
 | 
			
		||||
    setKeyboardOptions: function(options) {
 | 
			
		||||
        this._xkbOptions = options;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _buildOptionsString() {
 | 
			
		||||
    _buildOptionsString: function() {
 | 
			
		||||
        let options = this._xkbOptions.join(',');
 | 
			
		||||
        return options;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -40,24 +40,14 @@ const SystemdLoginSessionIface = '<node> \
 | 
			
		||||
<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;
 | 
			
		||||
@@ -115,18 +105,15 @@ function getLoginManager() {
 | 
			
		||||
var LoginManagerSystemd = new Lang.Class({
 | 
			
		||||
    Name: 'LoginManagerSystemd',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        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',
 | 
			
		||||
                                  this._prepareForSleep.bind(this));
 | 
			
		||||
                                  Lang.bind(this, this._prepareForSleep));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getCurrentSessionProxy(callback) {
 | 
			
		||||
    getCurrentSessionProxy: function(callback) {
 | 
			
		||||
        if (this._currentSession) {
 | 
			
		||||
            callback (this._currentSession);
 | 
			
		||||
            return;
 | 
			
		||||
@@ -134,47 +121,25 @@ 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. 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;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            log('Unset XDG_SESSION_ID, getCurrentSessionProxy() called outside a user session.');
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        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);
 | 
			
		||||
                }
 | 
			
		||||
            }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    canSuspend(asyncCallback) {
 | 
			
		||||
        this._proxy.CanSuspendRemote((result, error) => {
 | 
			
		||||
    canSuspend: function(asyncCallback) {
 | 
			
		||||
        this._proxy.CanSuspendRemote(function(result, error) {
 | 
			
		||||
            if (error) {
 | 
			
		||||
                asyncCallback(false, false);
 | 
			
		||||
            } else {
 | 
			
		||||
@@ -185,8 +150,8 @@ var LoginManagerSystemd = new Lang.Class({
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    listSessions(asyncCallback) {
 | 
			
		||||
        this._proxy.ListSessionsRemote((result, error) => {
 | 
			
		||||
    listSessions: function(asyncCallback) {
 | 
			
		||||
        this._proxy.ListSessionsRemote(function(result, error) {
 | 
			
		||||
            if (error)
 | 
			
		||||
                asyncCallback([]);
 | 
			
		||||
            else
 | 
			
		||||
@@ -194,18 +159,18 @@ var LoginManagerSystemd = new Lang.Class({
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    suspend() {
 | 
			
		||||
    suspend: function() {
 | 
			
		||||
        this._proxy.SuspendRemote(true);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    inhibit(reason, callback) {
 | 
			
		||||
    inhibit: function(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,
 | 
			
		||||
            (proxy, result) => {
 | 
			
		||||
            Lang.bind(this, function(proxy, result) {
 | 
			
		||||
                let fd = -1;
 | 
			
		||||
                try {
 | 
			
		||||
                    let [outVariant, fdList] = proxy.call_with_unix_fd_list_finish(result);
 | 
			
		||||
@@ -215,10 +180,10 @@ var LoginManagerSystemd = new Lang.Class({
 | 
			
		||||
                    logError(e, "Error getting systemd inhibitor");
 | 
			
		||||
                    callback(null);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _prepareForSleep(proxy, sender, [aboutToSuspend]) {
 | 
			
		||||
    _prepareForSleep: function(proxy, sender, [aboutToSuspend]) {
 | 
			
		||||
        this.emit('prepare-for-sleep', aboutToSuspend);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -227,26 +192,26 @@ Signals.addSignalMethods(LoginManagerSystemd.prototype);
 | 
			
		||||
var LoginManagerDummy = new Lang.Class({
 | 
			
		||||
    Name: 'LoginManagerDummy',
 | 
			
		||||
 | 
			
		||||
    getCurrentSessionProxy(callback) {
 | 
			
		||||
    getCurrentSessionProxy: function(callback) {
 | 
			
		||||
        // we could return a DummySession object that fakes whatever callers
 | 
			
		||||
        // expect (at the time of writing: connect() and connectSignal()
 | 
			
		||||
        // methods), but just never calling the callback should be safer
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    canSuspend(asyncCallback) {
 | 
			
		||||
    canSuspend: function(asyncCallback) {
 | 
			
		||||
        asyncCallback(false, false);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    listSessions(asyncCallback) {
 | 
			
		||||
    listSessions: function(asyncCallback) {
 | 
			
		||||
        asyncCallback([]);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    suspend() {
 | 
			
		||||
    suspend: function() {
 | 
			
		||||
        this.emit('prepare-for-sleep', true);
 | 
			
		||||
        this.emit('prepare-for-sleep', false);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    inhibit(reason, callback) {
 | 
			
		||||
    inhibit: function(reason, callback) {
 | 
			
		||||
        callback(null);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -133,22 +133,22 @@ const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface);
 | 
			
		||||
var ModemGsm = new Lang.Class({
 | 
			
		||||
    Name: 'ModemGsm',
 | 
			
		||||
 | 
			
		||||
    _init(path) {
 | 
			
		||||
    _init: function(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', (proxy, sender, [quality]) => {
 | 
			
		||||
        this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, [quality]) {
 | 
			
		||||
            this.signal_quality = quality;
 | 
			
		||||
            this.emit('notify::signal-quality');
 | 
			
		||||
        });
 | 
			
		||||
        this._proxy.connectSignal('RegistrationInfo', (proxy, sender, [status, code, name]) => {
 | 
			
		||||
        }));
 | 
			
		||||
        this._proxy.connectSignal('RegistrationInfo', Lang.bind(this, function(proxy, sender, [status, code, name]) {
 | 
			
		||||
            this.operator_name = _findProviderForMccMnc(name, code);
 | 
			
		||||
            this.emit('notify::operator-name');
 | 
			
		||||
        });
 | 
			
		||||
        this._proxy.GetRegistrationInfoRemote(([result], err) => {
 | 
			
		||||
        }));
 | 
			
		||||
        this._proxy.GetRegistrationInfoRemote(Lang.bind(this, function([result], err) {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                log(err);
 | 
			
		||||
                return;
 | 
			
		||||
@@ -157,8 +157,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((result, err) => {
 | 
			
		||||
        }));
 | 
			
		||||
        this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                // it will return an error if the device is not connected
 | 
			
		||||
                this.signal_quality = 0;
 | 
			
		||||
@@ -167,7 +167,7 @@ var ModemGsm = new Lang.Class({
 | 
			
		||||
                this.signal_quality = quality;
 | 
			
		||||
            }
 | 
			
		||||
            this.emit('notify::signal-quality');
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
Signals.addSignalMethods(ModemGsm.prototype);
 | 
			
		||||
@@ -175,12 +175,12 @@ Signals.addSignalMethods(ModemGsm.prototype);
 | 
			
		||||
var ModemCdma = new Lang.Class({
 | 
			
		||||
    Name: 'ModemCdma',
 | 
			
		||||
 | 
			
		||||
    _init(path) {
 | 
			
		||||
    _init: function(path) {
 | 
			
		||||
        this._proxy = new ModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
 | 
			
		||||
 | 
			
		||||
        this.signal_quality = 0;
 | 
			
		||||
        this.operator_name = null;
 | 
			
		||||
        this._proxy.connectSignal('SignalQuality', (proxy, sender, params) => {
 | 
			
		||||
        this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, params) {
 | 
			
		||||
            this.signal_quality = params[0];
 | 
			
		||||
            this.emit('notify::signal-quality');
 | 
			
		||||
 | 
			
		||||
@@ -188,8 +188,8 @@ var ModemCdma = new Lang.Class({
 | 
			
		||||
            // and we can finally call GetServingSystem
 | 
			
		||||
            if (this.operator_name == null)
 | 
			
		||||
                this._refreshServingSystem();
 | 
			
		||||
        });
 | 
			
		||||
        this._proxy.GetSignalQualityRemote((result, err) => {
 | 
			
		||||
        }));
 | 
			
		||||
        this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                // it will return an error if the device is not connected
 | 
			
		||||
                this.signal_quality = 0;
 | 
			
		||||
@@ -198,11 +198,11 @@ var ModemCdma = new Lang.Class({
 | 
			
		||||
                this.signal_quality = quality;
 | 
			
		||||
            }
 | 
			
		||||
            this.emit('notify::signal-quality');
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _refreshServingSystem() {
 | 
			
		||||
        this._proxy.GetServingSystemRemote(([result], err) => {
 | 
			
		||||
    _refreshServingSystem: function() {
 | 
			
		||||
        this._proxy.GetServingSystemRemote(Lang.bind(this, function([result], err) {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                // it will return an error if the device is not connected
 | 
			
		||||
                this.operator_name = null;
 | 
			
		||||
@@ -212,7 +212,7 @@ var ModemCdma = new Lang.Class({
 | 
			
		||||
                this.operator_name = _findProviderForSid(sid)
 | 
			
		||||
            }
 | 
			
		||||
            this.emit('notify::operator-name');
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
Signals.addSignalMethods(ModemCdma.prototype);
 | 
			
		||||
@@ -247,40 +247,40 @@ const BroadbandModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemCdm
 | 
			
		||||
var BroadbandModem = new Lang.Class({
 | 
			
		||||
    Name: 'BroadbandModem',
 | 
			
		||||
 | 
			
		||||
    _init(path, capabilities) {
 | 
			
		||||
    _init: function(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', (proxy, properties) => {
 | 
			
		||||
        this._proxy.connect('g-properties-changed', Lang.bind(this, function(proxy, properties) {
 | 
			
		||||
            if ('SignalQuality' in properties.deep_unpack())
 | 
			
		||||
                this._reloadSignalQuality();
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
        this._reloadSignalQuality();
 | 
			
		||||
 | 
			
		||||
        this._proxy_3gpp.connect('g-properties-changed', (proxy, properties) => {
 | 
			
		||||
        this._proxy_3gpp.connect('g-properties-changed', Lang.bind(this, function(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', (proxy, properties) => {
 | 
			
		||||
        this._proxy_cdma.connect('g-properties-changed', Lang.bind(this, function(proxy, properties) {
 | 
			
		||||
            let unpacked = properties.deep_unpack();
 | 
			
		||||
            if ('Nid' in unpacked || 'Sid' in unpacked)
 | 
			
		||||
                this._reloadCdmaOperatorName();
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
        this._reloadCdmaOperatorName();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _reloadSignalQuality() {
 | 
			
		||||
    _reloadSignalQuality: function() {
 | 
			
		||||
        let [quality, recent] = this._proxy.SignalQuality;
 | 
			
		||||
        this.signal_quality = quality;
 | 
			
		||||
        this.emit('notify::signal-quality');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _reloadOperatorName() {
 | 
			
		||||
    _reloadOperatorName: function() {
 | 
			
		||||
        let new_name = "";
 | 
			
		||||
        if (this.operator_name_3gpp && this.operator_name_3gpp.length > 0)
 | 
			
		||||
            new_name += this.operator_name_3gpp;
 | 
			
		||||
@@ -295,14 +295,14 @@ var BroadbandModem = new Lang.Class({
 | 
			
		||||
        this.emit('notify::operator-name');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _reload3gppOperatorName() {
 | 
			
		||||
    _reload3gppOperatorName: function() {
 | 
			
		||||
        let name = this._proxy_3gpp.OperatorName;
 | 
			
		||||
        let code = this._proxy_3gpp.OperatorCode;
 | 
			
		||||
        this.operator_name_3gpp = _findProviderForMccMnc(name, code);
 | 
			
		||||
        this._reloadOperatorName();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _reloadCdmaOperatorName() {
 | 
			
		||||
    _reloadCdmaOperatorName: function() {
 | 
			
		||||
        let sid = this._proxy_cdma.Sid;
 | 
			
		||||
        this.operator_name_cdma = _findProviderForSid(sid);
 | 
			
		||||
        this._reloadOperatorName();
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ const ObjectManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ObjectManagerIface);
 | 
			
		||||
 | 
			
		||||
var ObjectManager = new Lang.Class({
 | 
			
		||||
    Name: 'ObjectManager',
 | 
			
		||||
    _init(params) {
 | 
			
		||||
    _init: function(params) {
 | 
			
		||||
        params = Params.parse(params, { connection: null,
 | 
			
		||||
                                        name: null,
 | 
			
		||||
                                        objectPath: null,
 | 
			
		||||
@@ -61,10 +61,10 @@ var ObjectManager = new Lang.Class({
 | 
			
		||||
        this._numLoadInhibitors = 1;
 | 
			
		||||
        this._managerProxy.init_async(GLib.PRIORITY_DEFAULT,
 | 
			
		||||
                                      this._cancellable,
 | 
			
		||||
                                      this._onManagerProxyLoaded.bind(this));
 | 
			
		||||
                                      Lang.bind(this, this._onManagerProxyLoaded));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _tryToCompleteLoad() {
 | 
			
		||||
    _tryToCompleteLoad: function() {
 | 
			
		||||
        if (this._numLoadInhibitors == 0)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -75,7 +75,7 @@ var ObjectManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _addInterface(objectPath, interfaceName, onFinished) {
 | 
			
		||||
    _addInterface: function(objectPath, interfaceName, onFinished) {
 | 
			
		||||
        let info = this._interfaceInfos[interfaceName];
 | 
			
		||||
 | 
			
		||||
        if (!info) {
 | 
			
		||||
@@ -93,7 +93,7 @@ var ObjectManager = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        proxy.init_async(GLib.PRIORITY_DEFAULT,
 | 
			
		||||
                         this._cancellable,
 | 
			
		||||
                         (initable, result) => {
 | 
			
		||||
                         Lang.bind(this, function(initable, result) {
 | 
			
		||||
               let error = null;
 | 
			
		||||
               try {
 | 
			
		||||
                   initable.init_finish(result);
 | 
			
		||||
@@ -127,10 +127,10 @@ var ObjectManager = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
               if (onFinished)
 | 
			
		||||
                   onFinished();
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _removeInterface(objectPath, interfaceName) {
 | 
			
		||||
    _removeInterface: function(objectPath, interfaceName) {
 | 
			
		||||
        if (!this._objects[objectPath])
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -156,7 +156,7 @@ var ObjectManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onManagerProxyLoaded(initable, result) {
 | 
			
		||||
    _onManagerProxyLoaded: function(initable, result) {
 | 
			
		||||
        let error = null;
 | 
			
		||||
        try {
 | 
			
		||||
            initable.init_finish(result);
 | 
			
		||||
@@ -168,35 +168,35 @@ var ObjectManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._managerProxy.connectSignal('InterfacesAdded',
 | 
			
		||||
                                         (objectManager, sender, [objectPath, interfaces]) => {
 | 
			
		||||
                                         Lang.bind(this, function(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',
 | 
			
		||||
                                         (objectManager, sender, [objectPath, interfaceNames]) => {
 | 
			
		||||
                                         Lang.bind(this, function(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', () => {
 | 
			
		||||
        this._managerProxy.connect('notify::g-name-owner', Lang.bind(this, function() {
 | 
			
		||||
            if (this._managerProxy.g_name_owner)
 | 
			
		||||
                this._onNameAppeared();
 | 
			
		||||
            else
 | 
			
		||||
                this._onNameVanished();
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        if (this._managerProxy.g_name_owner)
 | 
			
		||||
            this._onNameAppeared();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onNameAppeared() {
 | 
			
		||||
        this._managerProxy.GetManagedObjectsRemote((result, error) => {
 | 
			
		||||
    _onNameAppeared: function() {
 | 
			
		||||
        this._managerProxy.GetManagedObjectsRemote(Lang.bind(this, function(result, error) {
 | 
			
		||||
            if (!result) {
 | 
			
		||||
                if (error) {
 | 
			
		||||
                   logError(error, 'could not get remote objects for service ' + this._serviceName + ' path ' + this._managerPath);
 | 
			
		||||
@@ -226,14 +226,14 @@ var ObjectManager = new Lang.Class({
 | 
			
		||||
                    this._numLoadInhibitors++;
 | 
			
		||||
                    this._addInterface(objectPath,
 | 
			
		||||
                                       interfaceName,
 | 
			
		||||
                                       this._tryToCompleteLoad.bind(this));
 | 
			
		||||
                                       Lang.bind(this, this._tryToCompleteLoad));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            this._tryToCompleteLoad();
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onNameVanished() {
 | 
			
		||||
    _onNameVanished: function() {
 | 
			
		||||
        let objectPaths = Object.keys(this._objects);
 | 
			
		||||
        for (let i = 0; i < objectPaths.length; i++) {
 | 
			
		||||
            let object = this._objects[objectPaths];
 | 
			
		||||
@@ -248,14 +248,14 @@ var ObjectManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _registerInterfaces(interfaces) {
 | 
			
		||||
    _registerInterfaces: function(interfaces) {
 | 
			
		||||
        for (let i = 0; i < interfaces.length; i++) {
 | 
			
		||||
            let info = Gio.DBusInterfaceInfo.new_for_xml(interfaces[i]);
 | 
			
		||||
            this._interfaceInfos[info.name] = info;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getProxy(objectPath, interfaceName) {
 | 
			
		||||
    getProxy: function(objectPath, interfaceName) {
 | 
			
		||||
        let object = this._objects[objectPath];
 | 
			
		||||
 | 
			
		||||
        if (!object)
 | 
			
		||||
@@ -264,7 +264,7 @@ var ObjectManager = new Lang.Class({
 | 
			
		||||
        return object[interfaceName];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getProxiesForInterface(interfaceName) {
 | 
			
		||||
    getProxiesForInterface: function(interfaceName) {
 | 
			
		||||
        let proxyList = this._interfaces[interfaceName];
 | 
			
		||||
 | 
			
		||||
        if (!proxyList)
 | 
			
		||||
@@ -273,7 +273,7 @@ var ObjectManager = new Lang.Class({
 | 
			
		||||
        return proxyList;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getAllProxies() {
 | 
			
		||||
    getAllProxies: function() {
 | 
			
		||||
        let proxies = [];
 | 
			
		||||
 | 
			
		||||
        let objectPaths = Object.keys(this._objects);
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
// parse:
 | 
			
		||||
// @params: caller-provided parameter object, or %null
 | 
			
		||||
// @defaults-provided defaults object
 | 
			
		||||
// @defaults: function-provided defaults object
 | 
			
		||||
// @allowExtras: whether or not to allow properties not in @default
 | 
			
		||||
//
 | 
			
		||||
// Examines @params and fills in default values from @defaults for
 | 
			
		||||
 
 | 
			
		||||
@@ -27,34 +27,34 @@ function getSmartcardManager() {
 | 
			
		||||
 | 
			
		||||
var SmartcardManager = new Lang.Class({
 | 
			
		||||
    Name: 'SmartcardManager',
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._objectManager = new ObjectManager.ObjectManager({ connection: Gio.DBus.session,
 | 
			
		||||
                                                                name: "org.gnome.SettingsDaemon.Smartcard",
 | 
			
		||||
                                                                objectPath: '/org/gnome/SettingsDaemon/Smartcard',
 | 
			
		||||
                                                                knownInterfaces: [ SmartcardTokenIface ],
 | 
			
		||||
                                                                onLoaded: this._onLoaded.bind(this) });
 | 
			
		||||
                                                                onLoaded: Lang.bind(this, this._onLoaded) });
 | 
			
		||||
        this._insertedTokens = {};
 | 
			
		||||
        this._loginToken = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onLoaded() {
 | 
			
		||||
    _onLoaded: function() {
 | 
			
		||||
        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', (objectManager, interfaceName, proxy) => {
 | 
			
		||||
        this._objectManager.connect('interface-added', Lang.bind(this, function(objectManager, interfaceName, proxy) {
 | 
			
		||||
            if (interfaceName == 'org.gnome.SettingsDaemon.Smartcard.Token')
 | 
			
		||||
                this._addToken(proxy);
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._objectManager.connect('interface-removed', (objectManager, interfaceName, proxy) => {
 | 
			
		||||
        this._objectManager.connect('interface-removed', Lang.bind(this, function(objectManager, interfaceName, proxy) {
 | 
			
		||||
            if (interfaceName == 'org.gnome.SettingsDaemon.Smartcard.Token')
 | 
			
		||||
                this._removeToken(proxy);
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateToken(token) {
 | 
			
		||||
    _updateToken: function(token) {
 | 
			
		||||
        let objectPath = token.get_object_path();
 | 
			
		||||
 | 
			
		||||
        delete this._insertedTokens[objectPath];
 | 
			
		||||
@@ -66,27 +66,28 @@ var SmartcardManager = new Lang.Class({
 | 
			
		||||
            this._loginToken = token;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _addToken(token) {
 | 
			
		||||
    _addToken: function(token) {
 | 
			
		||||
        this._updateToken(token);
 | 
			
		||||
 | 
			
		||||
        token.connect('g-properties-changed', (proxy, properties) => {
 | 
			
		||||
            if ('IsInserted' in properties.deep_unpack()) {
 | 
			
		||||
                this._updateToken(token);
 | 
			
		||||
        token.connect('g-properties-changed',
 | 
			
		||||
                      Lang.bind(this, function(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(token) {
 | 
			
		||||
    _removeToken: function(token) {
 | 
			
		||||
        let objectPath = token.get_object_path();
 | 
			
		||||
 | 
			
		||||
        if (this._insertedTokens[objectPath] == token) {
 | 
			
		||||
@@ -100,11 +101,11 @@ var SmartcardManager = new Lang.Class({
 | 
			
		||||
        token.disconnectAll();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hasInsertedTokens() {
 | 
			
		||||
    hasInsertedTokens: function() {
 | 
			
		||||
        return Object.keys(this._insertedTokens).length > 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hasInsertedLoginToken() {
 | 
			
		||||
    hasInsertedLoginToken: function() {
 | 
			
		||||
        if (!this._loginToken)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -87,7 +87,7 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
                                                          null)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent();
 | 
			
		||||
 | 
			
		||||
        this._canHavePowerOff = true;
 | 
			
		||||
@@ -218,7 +218,7 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
        return this._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sensorProxyAppeared() {
 | 
			
		||||
    _sensorProxyAppeared: function() {
 | 
			
		||||
        this._sensorProxy = new SensorProxy(Gio.DBus.system, SENSOR_BUS_NAME, SENSOR_OBJECT_PATH,
 | 
			
		||||
            (proxy, error)  => {
 | 
			
		||||
                if (error) {
 | 
			
		||||
@@ -231,7 +231,7 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
            });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateOrientationLock() {
 | 
			
		||||
    _updateOrientationLock: function() {
 | 
			
		||||
        let available = false;
 | 
			
		||||
        if (this._sensorProxy)
 | 
			
		||||
            available = this._sensorProxy.HasAccelerometer &&
 | 
			
		||||
@@ -242,7 +242,7 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
        this.notify('can-lock-orientation');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateOrientationLockIcon() {
 | 
			
		||||
    _updateOrientationLockIcon: function() {
 | 
			
		||||
        let locked = this._orientationSettings.get_boolean('orientation-lock');
 | 
			
		||||
        let iconName = locked ? 'rotation-locked-symbolic'
 | 
			
		||||
                              : 'rotation-allowed-symbolic';
 | 
			
		||||
@@ -251,14 +251,14 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
        this.notify('orientation-lock-icon');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sessionUpdated() {
 | 
			
		||||
    _sessionUpdated: function() {
 | 
			
		||||
        this._updateLockScreen();
 | 
			
		||||
        this._updatePowerOff();
 | 
			
		||||
        this._updateSuspend();
 | 
			
		||||
        this._updateMultiUser();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    forceUpdate() {
 | 
			
		||||
    forceUpdate: function() {
 | 
			
		||||
        // 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 +266,7 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
        this._updateHaveSuspend();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getMatchingActions(terms) {
 | 
			
		||||
    getMatchingActions: function(terms) {
 | 
			
		||||
        // terms is a list of strings
 | 
			
		||||
        terms = terms.map((term) => { return term.toLowerCase(); });
 | 
			
		||||
 | 
			
		||||
@@ -279,15 +279,15 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
        return results;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getName(id) {
 | 
			
		||||
    getName: function(id) {
 | 
			
		||||
        return this._actions.get(id).name;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getIconName(id) {
 | 
			
		||||
    getIconName: function(id) {
 | 
			
		||||
        return this._actions.get(id).iconName;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateAction(id) {
 | 
			
		||||
    activateAction: function(id) {
 | 
			
		||||
        switch (id) {
 | 
			
		||||
            case POWER_OFF_ACTION_ID:
 | 
			
		||||
                this.activatePowerOff();
 | 
			
		||||
@@ -317,7 +317,7 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
        this.notify('can-lock-screen');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateHaveShutdown() {
 | 
			
		||||
    _updateHaveShutdown: function() {
 | 
			
		||||
        this._session.CanShutdownRemote((result, error) => {
 | 
			
		||||
            if (error)
 | 
			
		||||
                return;
 | 
			
		||||
@@ -327,7 +327,7 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updatePowerOff() {
 | 
			
		||||
    _updatePowerOff: function() {
 | 
			
		||||
        let disabled = Main.sessionMode.isLocked ||
 | 
			
		||||
                       (Main.sessionMode.isGreeter &&
 | 
			
		||||
                        this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
 | 
			
		||||
@@ -335,7 +335,7 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
        this.notify('can-power-off');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateHaveSuspend() {
 | 
			
		||||
    _updateHaveSuspend: function() {
 | 
			
		||||
        this._loginManager.canSuspend(
 | 
			
		||||
            (canSuspend, needsAuth) => {
 | 
			
		||||
                this._canHaveSuspend = canSuspend;
 | 
			
		||||
@@ -344,7 +344,7 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
            });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateSuspend() {
 | 
			
		||||
    _updateSuspend: function() {
 | 
			
		||||
        let disabled = (Main.sessionMode.isLocked &&
 | 
			
		||||
                        this._suspendNeedsAuth) ||
 | 
			
		||||
                       (Main.sessionMode.isGreeter &&
 | 
			
		||||
@@ -353,12 +353,12 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
        this.notify('can-suspend');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateMultiUser() {
 | 
			
		||||
    _updateMultiUser: function() {
 | 
			
		||||
        this._updateLogout();
 | 
			
		||||
        this._updateSwitchUser();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateSwitchUser() {
 | 
			
		||||
    _updateSwitchUser: function() {
 | 
			
		||||
        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 +370,7 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
        return visible;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateLogout() {
 | 
			
		||||
    _updateLogout: function() {
 | 
			
		||||
        let user = this._userManager.get_user(GLib.get_user_name());
 | 
			
		||||
 | 
			
		||||
        let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY);
 | 
			
		||||
@@ -388,7 +388,7 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
        return visible;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateLockOrientation() {
 | 
			
		||||
    activateLockOrientation: function() {
 | 
			
		||||
        if (!this._actions.get(LOCK_ORIENTATION_ACTION_ID).available)
 | 
			
		||||
            throw new Error('The lock-orientation action is not available!');
 | 
			
		||||
 | 
			
		||||
@@ -396,27 +396,27 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
        this._orientationSettings.set_boolean('orientation-lock', !locked);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateLockScreen() {
 | 
			
		||||
    activateLockScreen: function() {
 | 
			
		||||
        if (!this._actions.get(LOCK_SCREEN_ACTION_ID).available)
 | 
			
		||||
            throw new Error('The lock-screen action is not available!');
 | 
			
		||||
 | 
			
		||||
        Main.screenShield.lock(true);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateSwitchUser() {
 | 
			
		||||
    activateSwitchUser: function() {
 | 
			
		||||
        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, () => {
 | 
			
		||||
        Clutter.threads_add_repaint_func_full(Clutter.RepaintFlags.POST_PAINT, function() {
 | 
			
		||||
            Gdm.goto_login_session_sync(null);
 | 
			
		||||
            return false;
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateLogout() {
 | 
			
		||||
    activateLogout: function() {
 | 
			
		||||
        if (!this._actions.get(LOGOUT_ACTION_ID).available)
 | 
			
		||||
            throw new Error('The logout action is not available!');
 | 
			
		||||
 | 
			
		||||
@@ -424,14 +424,14 @@ const SystemActions = new Lang.Class({
 | 
			
		||||
        this._session.LogoutRemote(0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activatePowerOff() {
 | 
			
		||||
    activatePowerOff: function() {
 | 
			
		||||
        if (!this._actions.get(POWER_OFF_ACTION_ID).available)
 | 
			
		||||
            throw new Error('The power-off action is not available!');
 | 
			
		||||
 | 
			
		||||
        this._session.ShutdownRemote(0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateSuspend() {
 | 
			
		||||
    activateSuspend: function() {
 | 
			
		||||
        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()<>]+\\)';
 | 
			
		||||
const _balancedParens = '\\((?:[^\\s()<>]+|(?:\\(?:[^\\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, () => {});
 | 
			
		||||
    GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function () {});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// trySpawnCommandLine:
 | 
			
		||||
@@ -291,10 +291,12 @@ 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', () => {
 | 
			
		||||
    let id = _desktopSettings.connect('changed::clock-format', function() {
 | 
			
		||||
        label.text = formatTime(date, params);
 | 
			
		||||
    });
 | 
			
		||||
    label.connect('destroy', () => { _desktopSettings.disconnect(id); });
 | 
			
		||||
    label.connect('destroy', function() {
 | 
			
		||||
        _desktopSettings.disconnect(id);
 | 
			
		||||
    });
 | 
			
		||||
    return label;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -314,7 +316,7 @@ function createTimeLabel(date, params) {
 | 
			
		||||
 | 
			
		||||
function lowerBound(array, val, cmp) {
 | 
			
		||||
    let min, max, mid, v;
 | 
			
		||||
    cmp = cmp || ((a, b) => a - b);
 | 
			
		||||
    cmp = cmp || function(a, b) { return a - b; };
 | 
			
		||||
 | 
			
		||||
    if (array.length == 0)
 | 
			
		||||
        return 0;
 | 
			
		||||
@@ -352,7 +354,7 @@ var CloseButton = new Lang.Class({
 | 
			
		||||
    Name: 'CloseButton',
 | 
			
		||||
    Extends: St.Button,
 | 
			
		||||
 | 
			
		||||
    _init(boxpointer) {
 | 
			
		||||
    _init: function(boxpointer) {
 | 
			
		||||
        this.parent({ style_class: 'notification-close'});
 | 
			
		||||
 | 
			
		||||
        // This is a bit tricky. St.Bin has its own x-align/y-align properties
 | 
			
		||||
@@ -369,10 +371,10 @@ var CloseButton = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._boxPointer = boxpointer;
 | 
			
		||||
        if (boxpointer)
 | 
			
		||||
            this._boxPointer.connect('arrow-side-changed', this._sync.bind(this));
 | 
			
		||||
            this._boxPointer.connect('arrow-side-changed', Lang.bind(this, this._sync));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _computeBoxPointerOffset() {
 | 
			
		||||
    _computeBoxPointerOffset: function() {
 | 
			
		||||
        if (!this._boxPointer || !this._boxPointer.actor.get_stage())
 | 
			
		||||
            return 0;
 | 
			
		||||
 | 
			
		||||
@@ -383,7 +385,7 @@ var CloseButton = new Lang.Class({
 | 
			
		||||
            return 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sync() {
 | 
			
		||||
    _sync: function() {
 | 
			
		||||
        let themeNode = this.get_theme_node();
 | 
			
		||||
 | 
			
		||||
        let offY = this._computeBoxPointerOffset();
 | 
			
		||||
@@ -391,7 +393,7 @@ var CloseButton = new Lang.Class({
 | 
			
		||||
        this.translation_y = themeNode.get_length('-shell-close-overlap-y') + offY;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_style_changed() {
 | 
			
		||||
    vfunc_style_changed: function() {
 | 
			
		||||
        this._sync();
 | 
			
		||||
        this.parent();
 | 
			
		||||
    },
 | 
			
		||||
@@ -440,7 +442,7 @@ function ensureActorVisibleInScrollView(scrollView, actor) {
 | 
			
		||||
var AppSettingsMonitor = new Lang.Class({
 | 
			
		||||
    Name: 'AppSettingsMonitor',
 | 
			
		||||
 | 
			
		||||
    _init(appId, schemaId) {
 | 
			
		||||
    _init: function(appId, schemaId) {
 | 
			
		||||
        this._appId = appId;
 | 
			
		||||
        this._schemaId = schemaId;
 | 
			
		||||
 | 
			
		||||
@@ -452,7 +454,7 @@ var AppSettingsMonitor = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._appSystem = Shell.AppSystem.get_default();
 | 
			
		||||
        this._appSystem.connect('installed-changed',
 | 
			
		||||
                                this._onInstalledChanged.bind(this));
 | 
			
		||||
                                Lang.bind(this, this._onInstalledChanged));
 | 
			
		||||
        this._onInstalledChanged();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -460,19 +462,19 @@ var AppSettingsMonitor = new Lang.Class({
 | 
			
		||||
        return this._app != null && this._settings != null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateApp() {
 | 
			
		||||
    activateApp: function() {
 | 
			
		||||
        if (this._app)
 | 
			
		||||
            this._app.activate();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    watchSetting(key, callback) {
 | 
			
		||||
    watchSetting: function(key, callback) {
 | 
			
		||||
        let handler = { id: 0, key: key, callback: callback };
 | 
			
		||||
        this._handlers.push(handler);
 | 
			
		||||
 | 
			
		||||
        this._connectHandler(handler);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _connectHandler(handler) {
 | 
			
		||||
    _connectHandler: function(handler) {
 | 
			
		||||
        if (!this._settings || handler.id > 0)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -481,13 +483,13 @@ var AppSettingsMonitor = new Lang.Class({
 | 
			
		||||
        handler.callback(this._settings, handler.key);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _disconnectHandler(handler) {
 | 
			
		||||
    _disconnectHandler: function(handler) {
 | 
			
		||||
        if (this._settings && handler.id > 0)
 | 
			
		||||
            this._settings.disconnect(handler.id);
 | 
			
		||||
        handler.id = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onInstalledChanged() {
 | 
			
		||||
    _onInstalledChanged: function() {
 | 
			
		||||
        let hadApp = (this._app != null);
 | 
			
		||||
        this._app = this._appSystem.lookup_app(this._appId);
 | 
			
		||||
        let haveApp = (this._app != null);
 | 
			
		||||
@@ -501,7 +503,7 @@ var AppSettingsMonitor = new Lang.Class({
 | 
			
		||||
            this._setSettings(null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setSettings(settings) {
 | 
			
		||||
    _setSettings: function(settings) {
 | 
			
		||||
        this._handlers.forEach((handler) => { this._disconnectHandler(handler); });
 | 
			
		||||
 | 
			
		||||
        let hadSettings = (this._settings != null);
 | 
			
		||||
@@ -514,7 +516,7 @@ var AppSettingsMonitor = new Lang.Class({
 | 
			
		||||
            this.emit('available-changed');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _checkSettings() {
 | 
			
		||||
    _checkSettings: function() {
 | 
			
		||||
        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() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        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',
 | 
			
		||||
                                      this._onPermStoreChanged.bind(this));
 | 
			
		||||
                                      Lang.bind(this, this._onPermStoreChanged));
 | 
			
		||||
 | 
			
		||||
        this._locationSettings = new Gio.Settings({ schema_id: 'org.gnome.system.location' });
 | 
			
		||||
        this._locationSettings.connect('changed::enabled',
 | 
			
		||||
                                       this._updateAutoLocation.bind(this));
 | 
			
		||||
                                       Lang.bind(this, this._updateAutoLocation));
 | 
			
		||||
 | 
			
		||||
        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',
 | 
			
		||||
                                         this._onAutomaticLocationChanged.bind(this));
 | 
			
		||||
                                         Lang.bind(this, this._onAutomaticLocationChanged));
 | 
			
		||||
        this._weatherAppMon.watchSetting('locations',
 | 
			
		||||
                                         this._onLocationsChanged.bind(this));
 | 
			
		||||
                                         Lang.bind(this, this._onLocationsChanged));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get available() {
 | 
			
		||||
@@ -89,11 +89,11 @@ var WeatherClient = new Lang.Class({
 | 
			
		||||
        return this._weatherInfo;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateApp() {
 | 
			
		||||
    activateApp: function() {
 | 
			
		||||
        this._weatherAppMon.activateApp();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    update() {
 | 
			
		||||
    update: function() {
 | 
			
		||||
        if (!this._locationValid)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -112,7 +112,7 @@ var WeatherClient = new Lang.Class({
 | 
			
		||||
               this._weatherAuthorized;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _loadInfo() {
 | 
			
		||||
    _loadInfo: function() {
 | 
			
		||||
        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(loc1, loc2) {
 | 
			
		||||
    _locationsEqual: function(loc1, loc2) {
 | 
			
		||||
        if (loc1 == loc2)
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
@@ -134,7 +134,7 @@ var WeatherClient = new Lang.Class({
 | 
			
		||||
        return loc1.equal(loc2);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setLocation(location) {
 | 
			
		||||
    _setLocation: function(location) {
 | 
			
		||||
        if (this._locationsEqual(this._weatherInfo.location, location))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -150,14 +150,14 @@ var WeatherClient = new Lang.Class({
 | 
			
		||||
            this.emit('changed');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateLocationMonitoring() {
 | 
			
		||||
    _updateLocationMonitoring: function() {
 | 
			
		||||
        if (this._useAutoLocation) {
 | 
			
		||||
            if (this._gclueLocationChangedId != 0 || this._gclueService == null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            this._gclueLocationChangedId =
 | 
			
		||||
                this._gclueService.connect('notify::location',
 | 
			
		||||
                                           this._onGClueLocationChanged.bind(this));
 | 
			
		||||
                                           Lang.bind(this, this._onGClueLocationChanged));
 | 
			
		||||
            this._onGClueLocationChanged();
 | 
			
		||||
        } else {
 | 
			
		||||
            if (this._gclueLocationChangedId)
 | 
			
		||||
@@ -166,7 +166,7 @@ var WeatherClient = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _startGClueService() {
 | 
			
		||||
    _startGClueService: function() {
 | 
			
		||||
        if (this._gclueStarting)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -187,7 +187,7 @@ var WeatherClient = new Lang.Class({
 | 
			
		||||
            });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onGClueLocationChanged() {
 | 
			
		||||
    _onGClueLocationChanged: function() {
 | 
			
		||||
        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(settings, key) {
 | 
			
		||||
    _onAutomaticLocationChanged: function(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() {
 | 
			
		||||
    _updateAutoLocation: function() {
 | 
			
		||||
        this._updateLocationMonitoring();
 | 
			
		||||
 | 
			
		||||
        if (this._useAutoLocation)
 | 
			
		||||
@@ -215,7 +215,7 @@ var WeatherClient = new Lang.Class({
 | 
			
		||||
            this._setLocation(this._mostRecentLocation);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onLocationsChanged(settings, key) {
 | 
			
		||||
    _onLocationsChanged: function(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(proxy, sender, params) {
 | 
			
		||||
    _onPermStoreChanged: function(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', () => {
 | 
			
		||||
        Scripting.scriptEvent('overviewShowDone');
 | 
			
		||||
    });
 | 
			
		||||
    Main.overview.connect('shown', function() {
 | 
			
		||||
                              Scripting.scriptEvent('overviewShowDone');
 | 
			
		||||
                          });
 | 
			
		||||
 | 
			
		||||
    yield Scripting.sleep(1000);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -42,29 +42,35 @@ function waitAndDraw(milliseconds) {
 | 
			
		||||
    let timeline = new Clutter.Timeline({ duration: milliseconds });
 | 
			
		||||
    timeline.start();
 | 
			
		||||
 | 
			
		||||
    timeline.connect('new-frame', (timeline, frame) => {
 | 
			
		||||
        global.stage.queue_redraw();
 | 
			
		||||
    });
 | 
			
		||||
    timeline.connect('new-frame',
 | 
			
		||||
        function(timeline, frame) {
 | 
			
		||||
            global.stage.queue_redraw();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    timeline.connect('completed', () => {
 | 
			
		||||
        timeline.stop();
 | 
			
		||||
        if (cb)
 | 
			
		||||
            cb();
 | 
			
		||||
    });
 | 
			
		||||
    timeline.connect('completed',
 | 
			
		||||
        function() {
 | 
			
		||||
            timeline.stop();
 | 
			
		||||
            if (cb)
 | 
			
		||||
                cb();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    return callback => { cb = callback; };
 | 
			
		||||
    return function(callback) {
 | 
			
		||||
        cb = callback;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function waitSignal(object, signal) {
 | 
			
		||||
    let cb;
 | 
			
		||||
 | 
			
		||||
    let id = object.connect(signal, () => {
 | 
			
		||||
    let id = object.connect(signal, function() {
 | 
			
		||||
        object.disconnect(id);
 | 
			
		||||
        if (cb)
 | 
			
		||||
            cb();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return callback => { cb = callback; };
 | 
			
		||||
    return function(callback) {
 | 
			
		||||
        cb = callback;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function extractBootTimestamp() {
 | 
			
		||||
@@ -136,7 +142,8 @@ function run() {
 | 
			
		||||
    global.frame_finish_timestamp = true;
 | 
			
		||||
 | 
			
		||||
    for (let k = 0; k < 5; k++)
 | 
			
		||||
        yield Scripting.createTestWindow({ maximized: true });
 | 
			
		||||
        yield Scripting.createTestWindow(640, 480,
 | 
			
		||||
                                         { maximized: true });
 | 
			
		||||
    yield Scripting.waitTestWindows();
 | 
			
		||||
 | 
			
		||||
    yield Scripting.sleep(1000);
 | 
			
		||||
@@ -157,7 +164,8 @@ function run() {
 | 
			
		||||
    yield Scripting.destroyTestWindows();
 | 
			
		||||
    Main.overview.hide();
 | 
			
		||||
 | 
			
		||||
    yield Scripting.createTestWindow({ maximized: true,
 | 
			
		||||
    yield Scripting.createTestWindow(640, 480,
 | 
			
		||||
                                     { maximized: true,
 | 
			
		||||
                                       redraws: true});
 | 
			
		||||
    yield Scripting.waitTestWindows();
 | 
			
		||||
 | 
			
		||||
@@ -262,7 +270,7 @@ function script_redrawTestDone(time) {
 | 
			
		||||
function script_collectTimings(time) {
 | 
			
		||||
    for (let timing in redrawTimes) {
 | 
			
		||||
        let times = redrawTimes[timing];
 | 
			
		||||
        times.sort((a, b) => a - b);
 | 
			
		||||
        times.sort(function(a, b) { return a - b });
 | 
			
		||||
 | 
			
		||||
        let len = times.length;
 | 
			
		||||
        let median;
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,7 @@ var PortalHeaderBar = new Lang.Class({
 | 
			
		||||
    Name: 'PortalHeaderBar',
 | 
			
		||||
    Extends: Gtk.HeaderBar,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent({ show_close_button: true });
 | 
			
		||||
 | 
			
		||||
        // See ephy-title-box.c in epiphany for the layout
 | 
			
		||||
@@ -92,11 +92,11 @@ var PortalHeaderBar = new Lang.Class({
 | 
			
		||||
        vbox.show_all();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setSubtitle(label) {
 | 
			
		||||
    setSubtitle: function(label) {
 | 
			
		||||
        this.subtitleLabel.set_text(label);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setSecurityIcon(securityLevel) {
 | 
			
		||||
    setSecurityIcon: function(securityLevel) {
 | 
			
		||||
        switch (securityLevel) {
 | 
			
		||||
        case PortalHelperSecurityLevel.NOT_YET_DETERMINED:
 | 
			
		||||
            this._lockImage.hide();
 | 
			
		||||
@@ -119,10 +119,10 @@ var PortalWindow = new Lang.Class({
 | 
			
		||||
    Name: 'PortalWindow',
 | 
			
		||||
    Extends: Gtk.ApplicationWindow,
 | 
			
		||||
 | 
			
		||||
    _init(application, url, timestamp, doneCallback) {
 | 
			
		||||
    _init: function(application, url, timestamp, doneCallback) {
 | 
			
		||||
        this.parent({ application: application });
 | 
			
		||||
 | 
			
		||||
        this.connect('delete-event', this.destroyWindow.bind(this));
 | 
			
		||||
        this.connect('delete-event', Lang.bind(this, this.destroyWindow));
 | 
			
		||||
        this._headerBar = new PortalHeaderBar();
 | 
			
		||||
        this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.NOT_YET_DETERMINED);
 | 
			
		||||
        this.set_titlebar(this._headerBar);
 | 
			
		||||
@@ -146,12 +146,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', 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.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.load_uri(url);
 | 
			
		||||
        this._webView.connect('notify::uri', this._syncUri.bind(this));
 | 
			
		||||
        this._webView.connect('notify::uri', Lang.bind(this, this._syncUri));
 | 
			
		||||
        this._syncUri();
 | 
			
		||||
 | 
			
		||||
        this.add(this._webView);
 | 
			
		||||
@@ -163,11 +163,11 @@ var PortalWindow = new Lang.Class({
 | 
			
		||||
        this.application.set_accels_for_action('app.quit', ['<Primary>q', '<Primary>w']);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroyWindow() {
 | 
			
		||||
    destroyWindow: function() {
 | 
			
		||||
        this.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _syncUri() {
 | 
			
		||||
    _syncUri: function() {
 | 
			
		||||
        let uri = this._webView.uri;
 | 
			
		||||
        if (uri)
 | 
			
		||||
            this._headerBar.setSubtitle(GLib.uri_unescape_string(uri, null));
 | 
			
		||||
@@ -175,12 +175,12 @@ var PortalWindow = new Lang.Class({
 | 
			
		||||
            this._headerBar.setSubtitle('');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    refresh() {
 | 
			
		||||
    refresh: function() {
 | 
			
		||||
        this._everSeenRedirect = false;
 | 
			
		||||
        this._webView.load_uri(this._originalUrl);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_delete_event(event) {
 | 
			
		||||
    vfunc_delete_event: function(event) {
 | 
			
		||||
        if (this._recheckAtExit)
 | 
			
		||||
            this._doneCallback(PortalHelperResult.RECHECK);
 | 
			
		||||
        else
 | 
			
		||||
@@ -188,7 +188,7 @@ var PortalWindow = new Lang.Class({
 | 
			
		||||
        return false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onLoadChanged(view, loadEvent) {
 | 
			
		||||
    _onLoadChanged: function(view, loadEvent) {
 | 
			
		||||
        if (loadEvent == WebKit.LoadEvent.STARTED) {
 | 
			
		||||
            this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.NOT_YET_DETERMINED);
 | 
			
		||||
        } else if (loadEvent == WebKit.LoadEvent.COMMITTED) {
 | 
			
		||||
@@ -202,11 +202,11 @@ var PortalWindow = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onInsecureContentDetected() {
 | 
			
		||||
    _onInsecureContentDetected: function () {
 | 
			
		||||
        this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onLoadFailedWithTlsErrors(view, failingURI, certificate, errors) {
 | 
			
		||||
    _onLoadFailedWithTlsErrors: function (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 +214,7 @@ var PortalWindow = new Lang.Class({
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDecidePolicy(view, decision, type) {
 | 
			
		||||
    _onDecidePolicy: function(view, decision, type) {
 | 
			
		||||
        if (type == WebKit.PolicyDecisionType.NEW_WINDOW_ACTION) {
 | 
			
		||||
            let navigationAction = decision.get_navigation_action();
 | 
			
		||||
            if (navigationAction.is_user_gesture()) {
 | 
			
		||||
@@ -286,7 +286,7 @@ var WebPortalHelper = new Lang.Class({
 | 
			
		||||
    Name: 'WebPortalHelper',
 | 
			
		||||
    Extends: Gtk.Application,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent({ application_id: 'org.gnome.Shell.PortalHelper',
 | 
			
		||||
                      flags: Gio.ApplicationFlags.IS_SERVICE,
 | 
			
		||||
                      inactivity_timeout: 30000 });
 | 
			
		||||
@@ -299,30 +299,30 @@ var WebPortalHelper = new Lang.Class({
 | 
			
		||||
        this.add_action(action);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_dbus_register(connection, path) {
 | 
			
		||||
    vfunc_dbus_register: function(connection, path) {
 | 
			
		||||
        this._dbusImpl.export(connection, path);
 | 
			
		||||
        this.parent(connection, path);
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_dbus_unregister(connection, path) {
 | 
			
		||||
    vfunc_dbus_unregister: function(connection, path) {
 | 
			
		||||
        this._dbusImpl.unexport_from_connection(connection);
 | 
			
		||||
        this.parent(connection, path);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_activate() {
 | 
			
		||||
    vfunc_activate: function() {
 | 
			
		||||
        // If launched manually (for example for testing), force a dummy authentication
 | 
			
		||||
        // session with the default url
 | 
			
		||||
        this.Authenticate('/org/gnome/dummy', '', 0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    Authenticate(connection, url, timestamp) {
 | 
			
		||||
    Authenticate: function(connection, url, timestamp) {
 | 
			
		||||
        this._queue.push({ connection: connection, url: url, timestamp: timestamp });
 | 
			
		||||
 | 
			
		||||
        this._processQueue();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    Close(connection) {
 | 
			
		||||
    Close: function(connection) {
 | 
			
		||||
        for (let i = 0; i < this._queue.length; i++) {
 | 
			
		||||
            let obj = this._queue[i];
 | 
			
		||||
 | 
			
		||||
@@ -337,7 +337,7 @@ var WebPortalHelper = new Lang.Class({
 | 
			
		||||
        this._processQueue();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    Refresh(connection) {
 | 
			
		||||
    Refresh: function(connection) {
 | 
			
		||||
        for (let i = 0; i < this._queue.length; i++) {
 | 
			
		||||
            let obj = this._queue[i];
 | 
			
		||||
 | 
			
		||||
@@ -349,7 +349,7 @@ var WebPortalHelper = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _processQueue() {
 | 
			
		||||
    _processQueue: function() {
 | 
			
		||||
        if (this._queue.length == 0)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -357,9 +357,9 @@ var WebPortalHelper = new Lang.Class({
 | 
			
		||||
        if (top.window != null)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        top.window = new PortalWindow(this, top.url, top.timestamp, result => {
 | 
			
		||||
        top.window = new PortalWindow(this, top.url, top.timestamp, Lang.bind(this, function(result) {
 | 
			
		||||
            this._dbusImpl.emit_signal('Done', new GLib.Variant('(ou)', [top.connection, result]));
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@ var AccessDialog = new Lang.Class({
 | 
			
		||||
    Name: 'AccessDialog',
 | 
			
		||||
    Extends: ModalDialog.ModalDialog,
 | 
			
		||||
 | 
			
		||||
    _init(invocation, handle, title, subtitle, body, options) {
 | 
			
		||||
    _init: function(invocation, handle, title, subtitle, body, options) {
 | 
			
		||||
        this.parent({ styleClass: 'access-dialog' });
 | 
			
		||||
 | 
			
		||||
        this._invocation = invocation;
 | 
			
		||||
@@ -57,7 +57,7 @@ var AccessDialog = new Lang.Class({
 | 
			
		||||
        this._buildLayout(title, subtitle, body, options);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _buildLayout(title, subtitle, body, options) {
 | 
			
		||||
    _buildLayout: function(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 +97,14 @@ var AccessDialog = new Lang.Class({
 | 
			
		||||
                         }});
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    open() {
 | 
			
		||||
    open: function() {
 | 
			
		||||
        this.parent();
 | 
			
		||||
 | 
			
		||||
        let connection = this._invocation.get_connection();
 | 
			
		||||
        this._requestExported = this._request.export(connection, this._handle);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    CloseAsync(invocation, params) {
 | 
			
		||||
    CloseAsync: function(invocation, params) {
 | 
			
		||||
        if (this._invocation.get_sender() != invocation.get_sender()) {
 | 
			
		||||
            invocation.return_error_literal(Gio.DBusError,
 | 
			
		||||
                                            Gio.DBusError.ACCESS_DENIED,
 | 
			
		||||
@@ -115,7 +115,7 @@ var AccessDialog = new Lang.Class({
 | 
			
		||||
        this._sendResponse(DialogResponse.CLOSED);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sendResponse(response) {
 | 
			
		||||
    _sendResponse: function(response) {
 | 
			
		||||
        if (this._requestExported)
 | 
			
		||||
            this._request.unexport();
 | 
			
		||||
        this._requestExported = false;
 | 
			
		||||
@@ -140,7 +140,7 @@ var AccessDialog = new Lang.Class({
 | 
			
		||||
var AccessDialogDBus = new Lang.Class({
 | 
			
		||||
    Name: 'AccessDialogDBus',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._accessDialog = null;
 | 
			
		||||
 | 
			
		||||
        this._windowTracker = Shell.WindowTracker.get_default();
 | 
			
		||||
@@ -151,7 +151,7 @@ var AccessDialogDBus = new Lang.Class({
 | 
			
		||||
        Gio.DBus.session.own_name('org.freedesktop.impl.portal.desktop.gnome', Gio.BusNameOwnerFlags.REPLACE, null, null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    AccessDialogAsync(params, invocation) {
 | 
			
		||||
    AccessDialogAsync: function(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() {
 | 
			
		||||
    _init : function() {
 | 
			
		||||
        this.parent();
 | 
			
		||||
 | 
			
		||||
        this._thumbnails = null;
 | 
			
		||||
@@ -80,7 +80,7 @@ var AppSwitcherPopup = new Lang.Class({
 | 
			
		||||
        this._items = this._switcherList.icons;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _allocate(actor, box, flags) {
 | 
			
		||||
    _allocate: function (actor, box, flags) {
 | 
			
		||||
        this.parent(actor, box, flags);
 | 
			
		||||
 | 
			
		||||
        // Allocate the thumbnails
 | 
			
		||||
@@ -118,7 +118,7 @@ var AppSwitcherPopup = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _initialSelection(backward, binding) {
 | 
			
		||||
    _initialSelection: function(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() {
 | 
			
		||||
    _nextWindow : function() {
 | 
			
		||||
        // 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() {
 | 
			
		||||
    _previousWindow : function() {
 | 
			
		||||
        // 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(appIndex, windowIndex) {
 | 
			
		||||
    _closeAppWindow: function(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(appIndex) {
 | 
			
		||||
    _quitApplication: function(appIndex) {
 | 
			
		||||
        let appIcon = this._items[appIndex];
 | 
			
		||||
        if (!appIcon)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -176,7 +176,7 @@ var AppSwitcherPopup = new Lang.Class({
 | 
			
		||||
        appIcon.app.request_quit();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _keyPressHandler(keysym, action) {
 | 
			
		||||
    _keyPressHandler: function(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(direction) {
 | 
			
		||||
    _scrollHandler: function(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(n) {
 | 
			
		||||
    _itemActivatedHandler: function(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(n) {
 | 
			
		||||
    _itemEnteredHandler: function(n) {
 | 
			
		||||
        this._select(n);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowActivated(thumbnailList, n) {
 | 
			
		||||
    _windowActivated : function(thumbnailList, n) {
 | 
			
		||||
        let appIcon = this._items[this._selectedIndex];
 | 
			
		||||
        Main.activateWindow(appIcon.cachedWindows[n]);
 | 
			
		||||
        this.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowEntered(thumbnailList, n) {
 | 
			
		||||
    _windowEntered : function(thumbnailList, n) {
 | 
			
		||||
        if (!this.mouseActive)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._select(this._selectedIndex, n);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowRemoved(thumbnailList, n) {
 | 
			
		||||
    _windowRemoved : function(thumbnailList, n) {
 | 
			
		||||
        let appIcon = this._items[this._selectedIndex];
 | 
			
		||||
        if (!appIcon)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -283,7 +283,7 @@ var AppSwitcherPopup = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _finish(timestamp) {
 | 
			
		||||
    _finish : function(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() {
 | 
			
		||||
    _onDestroy : function() {
 | 
			
		||||
        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(app, window, forceAppFocus) {
 | 
			
		||||
    _select : function(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,
 | 
			
		||||
                this._timeoutPopupThumbnails.bind(this));
 | 
			
		||||
                Lang.bind(this, this._timeoutPopupThumbnails));
 | 
			
		||||
            GLib.Source.set_name_by_id(this._thumbnailTimeoutId, '[gnome-shell] this._timeoutPopupThumbnails');
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _timeoutPopupThumbnails() {
 | 
			
		||||
    _timeoutPopupThumbnails: function() {
 | 
			
		||||
        if (!this._thumbnails)
 | 
			
		||||
            this._createThumbnails();
 | 
			
		||||
        this._thumbnailTimeoutId = 0;
 | 
			
		||||
@@ -366,27 +366,27 @@ var AppSwitcherPopup = new Lang.Class({
 | 
			
		||||
        return GLib.SOURCE_REMOVE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _destroyThumbnails() {
 | 
			
		||||
    _destroyThumbnails : function() {
 | 
			
		||||
        let thumbnailsActor = this._thumbnails.actor;
 | 
			
		||||
        Tweener.addTween(thumbnailsActor,
 | 
			
		||||
                         { opacity: 0,
 | 
			
		||||
                           time: THUMBNAIL_FADE_TIME,
 | 
			
		||||
                           transition: 'easeOutQuad',
 | 
			
		||||
                           onComplete: () => {
 | 
			
		||||
                               thumbnailsActor.destroy();
 | 
			
		||||
                               this.thumbnailsVisible = false;
 | 
			
		||||
                           }
 | 
			
		||||
                           onComplete: Lang.bind(this, function() {
 | 
			
		||||
                                                            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() {
 | 
			
		||||
    _createThumbnails : function() {
 | 
			
		||||
        this._thumbnails = new ThumbnailList (this._items[this._selectedIndex].cachedWindows);
 | 
			
		||||
        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.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.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: () => { this.thumbnailsVisible = true; }
 | 
			
		||||
                           onComplete: Lang.bind(this, function () { 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() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        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',
 | 
			
		||||
                           this._onAllocationChanged.bind(this));
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
                           Lang.bind(this, this._onAllocationChanged));
 | 
			
		||||
        this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    set window(w) {
 | 
			
		||||
@@ -453,7 +453,7 @@ var CyclerHighlight = new Lang.Class({
 | 
			
		||||
        this._clone.source = windowActor;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onAllocationChanged() {
 | 
			
		||||
    _onAllocationChanged: function() {
 | 
			
		||||
        if (!this._window) {
 | 
			
		||||
            this._highlight.set_size(0, 0);
 | 
			
		||||
            this._highlight.hide();
 | 
			
		||||
@@ -466,7 +466,7 @@ var CyclerHighlight = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
        this.window = null;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -476,7 +476,7 @@ var CyclerPopup = new Lang.Class({
 | 
			
		||||
    Extends: SwitcherPopup.SwitcherPopup,
 | 
			
		||||
    Abstract: true,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init : function() {
 | 
			
		||||
        this.parent();
 | 
			
		||||
 | 
			
		||||
        this._items = this._getWindows();
 | 
			
		||||
@@ -490,20 +490,19 @@ 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: this._highlightItem.bind(this),
 | 
			
		||||
                               connect() {} };
 | 
			
		||||
                               highlight: Lang.bind(this, this._highlightItem),
 | 
			
		||||
                               connect: function() {} };
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _highlightItem(index, justOutline) {
 | 
			
		||||
    _highlightItem: function(index, justOutline) {
 | 
			
		||||
        this._highlight.window = this._items[index];
 | 
			
		||||
        global.window_group.set_child_above_sibling(this._highlight.actor, null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _finish() {
 | 
			
		||||
    _finish: function() {
 | 
			
		||||
        let window = this._items[this._selectedIndex];
 | 
			
		||||
        let ws = window.get_workspace();
 | 
			
		||||
        let workspaceManager = global.workspace_manager;
 | 
			
		||||
        let activeWs = workspaceManager.get_active_workspace();
 | 
			
		||||
        let activeWs = global.screen.get_active_workspace();
 | 
			
		||||
 | 
			
		||||
        if (window.minimized) {
 | 
			
		||||
            Main.wm.skipNextEffect(window.get_compositor_private());
 | 
			
		||||
@@ -525,7 +524,7 @@ var CyclerPopup = new Lang.Class({
 | 
			
		||||
        this.parent();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
        this._highlight.actor.destroy();
 | 
			
		||||
 | 
			
		||||
        this.parent();
 | 
			
		||||
@@ -537,12 +536,12 @@ var GroupCyclerPopup = new Lang.Class({
 | 
			
		||||
    Name: 'GroupCyclerPopup',
 | 
			
		||||
    Extends: CyclerPopup,
 | 
			
		||||
 | 
			
		||||
    _getWindows() {
 | 
			
		||||
    _getWindows: function() {
 | 
			
		||||
        let app = Shell.WindowTracker.get_default().focus_app;
 | 
			
		||||
        return app ? app.get_windows() : [];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _keyPressHandler(keysym, action) {
 | 
			
		||||
    _keyPressHandler: function(keysym, action) {
 | 
			
		||||
        if (action == Meta.KeyBindingAction.CYCLE_GROUP)
 | 
			
		||||
            this._select(this._next());
 | 
			
		||||
        else if (action == Meta.KeyBindingAction.CYCLE_GROUP_BACKWARD)
 | 
			
		||||
@@ -558,7 +557,7 @@ var WindowSwitcherPopup = new Lang.Class({
 | 
			
		||||
    Name: 'WindowSwitcherPopup',
 | 
			
		||||
    Extends: SwitcherPopup.SwitcherPopup,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent();
 | 
			
		||||
        this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
 | 
			
		||||
 | 
			
		||||
@@ -572,19 +571,12 @@ var WindowSwitcherPopup = new Lang.Class({
 | 
			
		||||
        this._items = this._switcherList.icons;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getWindowList() {
 | 
			
		||||
        let workspace = null;
 | 
			
		||||
 | 
			
		||||
        if (this._settings.get_boolean('current-workspace-only')) {
 | 
			
		||||
            let workspaceManager = global.workspace_manager;
 | 
			
		||||
 | 
			
		||||
            workspace = workspaceManager.get_active_workspace();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    _getWindowList: function() {
 | 
			
		||||
        let workspace = this._settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() : null;
 | 
			
		||||
        return getWindows(workspace);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _closeWindow(windowIndex) {
 | 
			
		||||
    _closeWindow: function(windowIndex) {
 | 
			
		||||
        let windowIcon = this._items[windowIndex];
 | 
			
		||||
        if (!windowIcon)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -592,7 +584,7 @@ var WindowSwitcherPopup = new Lang.Class({
 | 
			
		||||
        windowIcon.window.delete(global.get_current_time());
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _keyPressHandler(keysym, action) {
 | 
			
		||||
    _keyPressHandler: function(keysym, action) {
 | 
			
		||||
        if (action == Meta.KeyBindingAction.SWITCH_WINDOWS) {
 | 
			
		||||
            this._select(this._next());
 | 
			
		||||
        } else if (action == Meta.KeyBindingAction.SWITCH_WINDOWS_BACKWARD) {
 | 
			
		||||
@@ -611,7 +603,7 @@ var WindowSwitcherPopup = new Lang.Class({
 | 
			
		||||
        return Clutter.EVENT_STOP;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _finish() {
 | 
			
		||||
    _finish: function() {
 | 
			
		||||
        Main.activateWindow(this._items[this._selectedIndex].window);
 | 
			
		||||
 | 
			
		||||
        this.parent();
 | 
			
		||||
@@ -622,24 +614,17 @@ var WindowCyclerPopup = new Lang.Class({
 | 
			
		||||
    Name: 'WindowCyclerPopup',
 | 
			
		||||
    Extends: CyclerPopup,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
 | 
			
		||||
        this.parent();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getWindows() {
 | 
			
		||||
        let workspace = null;
 | 
			
		||||
 | 
			
		||||
        if (this._settings.get_boolean('current-workspace-only')) {
 | 
			
		||||
            let workspaceManager = global.workspace_manager;
 | 
			
		||||
 | 
			
		||||
            workspace = workspaceManager.get_active_workspace();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    _getWindows: function() {
 | 
			
		||||
        let workspace = this._settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() : null;
 | 
			
		||||
        return getWindows(workspace);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _keyPressHandler(keysym, action) {
 | 
			
		||||
    _keyPressHandler: function(keysym, action) {
 | 
			
		||||
        if (action == Meta.KeyBindingAction.CYCLE_WINDOWS)
 | 
			
		||||
            this._select(this._next());
 | 
			
		||||
        else if (action == Meta.KeyBindingAction.CYCLE_WINDOWS_BACKWARD)
 | 
			
		||||
@@ -654,7 +639,7 @@ var WindowCyclerPopup = new Lang.Class({
 | 
			
		||||
var AppIcon = new Lang.Class({
 | 
			
		||||
    Name: 'AppIcon',
 | 
			
		||||
 | 
			
		||||
    _init(app) {
 | 
			
		||||
    _init: function(app) {
 | 
			
		||||
        this.app = app;
 | 
			
		||||
        this.actor = new St.BoxLayout({ style_class: 'alt-tab-app',
 | 
			
		||||
                                         vertical: true });
 | 
			
		||||
@@ -666,7 +651,7 @@ var AppIcon = new Lang.Class({
 | 
			
		||||
        this.actor.add(this.label, { x_fill: false });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    set_size(size) {
 | 
			
		||||
    set_size: function(size) {
 | 
			
		||||
        this.icon = this.app.create_icon_texture(size);
 | 
			
		||||
        this._iconBin.child = this.icon;
 | 
			
		||||
    }
 | 
			
		||||
@@ -676,7 +661,7 @@ var AppSwitcher = new Lang.Class({
 | 
			
		||||
    Name: 'AppSwitcher',
 | 
			
		||||
    Extends: SwitcherPopup.SwitcherList,
 | 
			
		||||
 | 
			
		||||
    _init(apps, altTabPopup) {
 | 
			
		||||
    _init : function(apps, altTabPopup) {
 | 
			
		||||
        this.parent(true);
 | 
			
		||||
 | 
			
		||||
        this.icons = [];
 | 
			
		||||
@@ -684,14 +669,8 @@ 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 = null;
 | 
			
		||||
        if (settings.get_boolean('current-workspace-only')) {
 | 
			
		||||
            let workspaceManager = global.workspace_manager;
 | 
			
		||||
 | 
			
		||||
            workspace = workspaceManager.get_active_workspace();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let workspace = settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace()
 | 
			
		||||
                                                                       : null;
 | 
			
		||||
        let allWindows = global.display.get_tab_list(Meta.TabList.NORMAL, workspace);
 | 
			
		||||
 | 
			
		||||
        // Construct the AppIcons, add to the popup
 | 
			
		||||
@@ -699,9 +678,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(
 | 
			
		||||
                w => windowTracker.get_window_app (w) == appIcon.app
 | 
			
		||||
            );
 | 
			
		||||
            appIcon.cachedWindows = allWindows.filter(function(w) {
 | 
			
		||||
                return windowTracker.get_window_app (w) == appIcon.app;
 | 
			
		||||
            });
 | 
			
		||||
            if (appIcon.cachedWindows.length > 0)
 | 
			
		||||
                this._addIcon(appIcon);
 | 
			
		||||
        }
 | 
			
		||||
@@ -711,10 +690,10 @@ var AppSwitcher = new Lang.Class({
 | 
			
		||||
        this._altTabPopup = altTabPopup;
 | 
			
		||||
        this._mouseTimeOutId = 0;
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
        if (this._mouseTimeOutId != 0)
 | 
			
		||||
            Mainloop.source_remove(this._mouseTimeOutId);
 | 
			
		||||
 | 
			
		||||
@@ -723,7 +702,7 @@ var AppSwitcher = new Lang.Class({
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setIconSize() {
 | 
			
		||||
    _setIconSize: function() {
 | 
			
		||||
        let j = 0;
 | 
			
		||||
        while(this._items.length > 1 && this._items[j].style_class != 'item-box') {
 | 
			
		||||
                j++;
 | 
			
		||||
@@ -742,7 +721,9 @@ 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(s => s * scaleFactor);
 | 
			
		||||
        let iconSizes = baseIconSizes.map(function(s) {
 | 
			
		||||
            return s * scaleFactor;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (this._items.length == 1) {
 | 
			
		||||
            this._iconSize = baseIconSizes[0];
 | 
			
		||||
@@ -763,12 +744,12 @@ var AppSwitcher = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getPreferredHeight(actor, forWidth, alloc) {
 | 
			
		||||
    _getPreferredHeight: function (actor, forWidth, alloc) {
 | 
			
		||||
        this._setIconSize();
 | 
			
		||||
        this.parent(actor, forWidth, alloc);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _allocate(actor, box, flags) {
 | 
			
		||||
    _allocate: function (actor, box, flags) {
 | 
			
		||||
        // Allocate the main list items
 | 
			
		||||
        this.parent(actor, box, flags);
 | 
			
		||||
 | 
			
		||||
@@ -789,22 +770,22 @@ var AppSwitcher = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
    // We override SwitcherList's _onItemEnter method to delay
 | 
			
		||||
    // activation when the thumbnail list is open
 | 
			
		||||
    _onItemEnter(index) {
 | 
			
		||||
    _onItemEnter: function (index) {
 | 
			
		||||
        if (this._mouseTimeOutId != 0)
 | 
			
		||||
            Mainloop.source_remove(this._mouseTimeOutId);
 | 
			
		||||
        if (this._altTabPopup.thumbnailsVisible) {
 | 
			
		||||
            this._mouseTimeOutId = Mainloop.timeout_add(APP_ICON_HOVER_TIMEOUT,
 | 
			
		||||
                                                        () => {
 | 
			
		||||
                                                            this._enterItem(index);
 | 
			
		||||
                                                            this._mouseTimeOutId = 0;
 | 
			
		||||
                                                            return GLib.SOURCE_REMOVE;
 | 
			
		||||
                                                        });
 | 
			
		||||
                                                        Lang.bind(this, function () {
 | 
			
		||||
                                                                            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(index) {
 | 
			
		||||
    _enterItem: function(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))
 | 
			
		||||
@@ -818,7 +799,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(n, justOutline) {
 | 
			
		||||
    highlight : function(n, justOutline) {
 | 
			
		||||
        if (this.icons[this._curApp]) {
 | 
			
		||||
            if (this.icons[this._curApp].cachedWindows.length == 1)
 | 
			
		||||
                this._arrows[this._curApp].hide();
 | 
			
		||||
@@ -837,7 +818,7 @@ var AppSwitcher = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _addIcon(appIcon) {
 | 
			
		||||
    _addIcon : function(appIcon) {
 | 
			
		||||
        this.icons.push(appIcon);
 | 
			
		||||
        let item = this.addItem(appIcon.actor, appIcon.label);
 | 
			
		||||
 | 
			
		||||
@@ -848,7 +829,7 @@ var AppSwitcher = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        let n = this._arrows.length;
 | 
			
		||||
        let arrow = new St.DrawingArea({ style_class: 'switcher-arrow' });
 | 
			
		||||
        arrow.connect('repaint', () => { SwitcherPopup.drawArrow(arrow, St.Side.BOTTOM); });
 | 
			
		||||
        arrow.connect('repaint', function() { SwitcherPopup.drawArrow(arrow, St.Side.BOTTOM); });
 | 
			
		||||
        this._list.add_actor(arrow);
 | 
			
		||||
        this._arrows.push(arrow);
 | 
			
		||||
 | 
			
		||||
@@ -858,7 +839,7 @@ var AppSwitcher = new Lang.Class({
 | 
			
		||||
            item.add_accessible_state (Atk.StateType.EXPANDABLE);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _removeIcon(app) {
 | 
			
		||||
    _removeIcon: function(app) {
 | 
			
		||||
        let index = this.icons.findIndex(icon => {
 | 
			
		||||
            return icon.app == app;
 | 
			
		||||
        });
 | 
			
		||||
@@ -874,7 +855,7 @@ var ThumbnailList = new Lang.Class({
 | 
			
		||||
    Name: 'ThumbnailList',
 | 
			
		||||
    Extends: SwitcherPopup.SwitcherList,
 | 
			
		||||
 | 
			
		||||
    _init(windows) {
 | 
			
		||||
    _init : function(windows) {
 | 
			
		||||
        this.parent(false);
 | 
			
		||||
 | 
			
		||||
        this._labels = new Array();
 | 
			
		||||
@@ -910,7 +891,7 @@ var ThumbnailList = new Lang.Class({
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addClones(availHeight) {
 | 
			
		||||
    addClones : function (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();
 | 
			
		||||
@@ -933,9 +914,7 @@ var ThumbnailList = new Lang.Class({
 | 
			
		||||
            this._thumbnailBins[i].set_height(binHeight);
 | 
			
		||||
            this._thumbnailBins[i].add_actor(clone);
 | 
			
		||||
 | 
			
		||||
            clone._destroyId = mutterWindow.connect('destroy', source => {
 | 
			
		||||
                this._removeThumbnail(source, clone);
 | 
			
		||||
            });
 | 
			
		||||
            clone._destroyId = mutterWindow.connect('destroy', Lang.bind(this, this._removeThumbnail, clone));
 | 
			
		||||
            this._clones.push(clone);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -943,7 +922,7 @@ var ThumbnailList = new Lang.Class({
 | 
			
		||||
        this._thumbnailBins = new Array();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _removeThumbnail(source, clone) {
 | 
			
		||||
    _removeThumbnail: function(source, clone) {
 | 
			
		||||
        let index = this._clones.indexOf(clone);
 | 
			
		||||
        if (index === -1)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -959,7 +938,7 @@ var ThumbnailList = new Lang.Class({
 | 
			
		||||
            this.actor.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
        this._clones.forEach(clone => {
 | 
			
		||||
            if (clone.source)
 | 
			
		||||
                clone.source.disconnect(clone._destroyId);
 | 
			
		||||
@@ -971,7 +950,7 @@ var ThumbnailList = new Lang.Class({
 | 
			
		||||
var WindowIcon = new Lang.Class({
 | 
			
		||||
    Name: 'WindowIcon',
 | 
			
		||||
 | 
			
		||||
    _init(window, mode) {
 | 
			
		||||
    _init: function(window, mode) {
 | 
			
		||||
        this.window = window;
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.BoxLayout({ style_class: 'alt-tab-app',
 | 
			
		||||
@@ -1014,7 +993,7 @@ var WindowIcon = new Lang.Class({
 | 
			
		||||
        this._icon.set_size(size * scaleFactor, size * scaleFactor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createAppIcon(app, size) {
 | 
			
		||||
    _createAppIcon: function(app, size) {
 | 
			
		||||
        let appIcon = app ? app.create_icon_texture(size)
 | 
			
		||||
                          : new St.Icon({ icon_name: 'icon-missing',
 | 
			
		||||
                                          icon_size: size });
 | 
			
		||||
@@ -1029,7 +1008,7 @@ var WindowList = new Lang.Class({
 | 
			
		||||
    Name: 'WindowList',
 | 
			
		||||
    Extends: SwitcherPopup.SwitcherList,
 | 
			
		||||
 | 
			
		||||
    _init(windows, mode) {
 | 
			
		||||
    _init : function(windows, mode) {
 | 
			
		||||
        this.parent(true);
 | 
			
		||||
 | 
			
		||||
        this._label = new St.Label({ x_align: Clutter.ActorAlign.CENTER,
 | 
			
		||||
@@ -1054,13 +1033,13 @@ var WindowList = new Lang.Class({
 | 
			
		||||
        this.actor.connect('destroy', () => { this._onDestroy(); });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
        this.icons.forEach(icon => {
 | 
			
		||||
            icon.window.disconnect(icon._unmanagedSignalId);
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getPreferredHeight(actor, forWidth, alloc) {
 | 
			
		||||
    _getPreferredHeight: function(actor, forWidth, alloc) {
 | 
			
		||||
        this.parent(actor, forWidth, alloc);
 | 
			
		||||
 | 
			
		||||
        let spacing = this.actor.get_theme_node().get_padding(St.Side.BOTTOM);
 | 
			
		||||
@@ -1069,7 +1048,7 @@ var WindowList = new Lang.Class({
 | 
			
		||||
        alloc.natural_size += labelNat + spacing;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _allocateTop(actor, box, flags) {
 | 
			
		||||
    _allocateTop: function(actor, box, flags) {
 | 
			
		||||
        let childBox = new Clutter.ActorBox();
 | 
			
		||||
        childBox.x1 = box.x1;
 | 
			
		||||
        childBox.x2 = box.x2;
 | 
			
		||||
@@ -1082,13 +1061,13 @@ var WindowList = new Lang.Class({
 | 
			
		||||
        this.parent(actor, box, flags);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    highlight(index, justOutline) {
 | 
			
		||||
    highlight: function(index, justOutline) {
 | 
			
		||||
        this.parent(index, justOutline);
 | 
			
		||||
 | 
			
		||||
        this._label.set_text(index == -1 ? '' : this.icons[index].label.text);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _removeWindow(window) {
 | 
			
		||||
    _removeWindow: function(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(file, width, height, speed) {
 | 
			
		||||
    _init: function(file, width, height, speed) {
 | 
			
		||||
        this.actor = new St.Bin();
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
 | 
			
		||||
        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,
 | 
			
		||||
                                                                            this._animationsLoaded.bind(this));
 | 
			
		||||
                                                                            Lang.bind(this, this._animationsLoaded));
 | 
			
		||||
        this.actor.set_child(this._animations);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    play() {
 | 
			
		||||
    play: function() {
 | 
			
		||||
        if (this._isLoaded && this._timeoutId == 0) {
 | 
			
		||||
            if (this._frame == 0)
 | 
			
		||||
                this._showFrame(0);
 | 
			
		||||
 | 
			
		||||
            this._timeoutId = GLib.timeout_add(GLib.PRIORITY_LOW, this._speed, this._update.bind(this));
 | 
			
		||||
            this._timeoutId = GLib.timeout_add(GLib.PRIORITY_LOW, this._speed, Lang.bind(this, this._update));
 | 
			
		||||
            GLib.Source.set_name_by_id(this._timeoutId, '[gnome-shell] this._update');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._isPlaying = true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    stop() {
 | 
			
		||||
    stop: function() {
 | 
			
		||||
        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(frame) {
 | 
			
		||||
    _showFrame: function(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() {
 | 
			
		||||
    _update: function() {
 | 
			
		||||
        this._showFrame(this._frame + 1);
 | 
			
		||||
        return GLib.SOURCE_CONTINUE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _animationsLoaded() {
 | 
			
		||||
    _animationsLoaded: function() {
 | 
			
		||||
        this._isLoaded = this._animations.get_n_children() > 0;
 | 
			
		||||
 | 
			
		||||
        if (this._isPlaying)
 | 
			
		||||
            this.play();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
        this.stop();
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -82,7 +82,7 @@ var AnimatedIcon = new Lang.Class({
 | 
			
		||||
    Name: 'AnimatedIcon',
 | 
			
		||||
    Extends: Animation,
 | 
			
		||||
 | 
			
		||||
    _init(file, size) {
 | 
			
		||||
    _init: function(file, size) {
 | 
			
		||||
        this.parent(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,6 @@ 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',
 | 
			
		||||
@@ -35,7 +34,6 @@ 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',
 | 
			
		||||
@@ -51,24 +49,24 @@ var AppFavorites = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
    FAVORITE_APPS_KEY: 'favorite-apps',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._favorites = {};
 | 
			
		||||
        global.settings.connect('changed::' + this.FAVORITE_APPS_KEY, this._onFavsChanged.bind(this));
 | 
			
		||||
        global.settings.connect('changed::' + this.FAVORITE_APPS_KEY, Lang.bind(this, this._onFavsChanged));
 | 
			
		||||
        this.reload();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onFavsChanged() {
 | 
			
		||||
    _onFavsChanged: function() {
 | 
			
		||||
        this.reload();
 | 
			
		||||
        this.emit('changed');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    reload() {
 | 
			
		||||
    reload: function() {
 | 
			
		||||
        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(id => {
 | 
			
		||||
        ids = ids.map(function (id) {
 | 
			
		||||
            let newId = RENAMED_DESKTOP_IDS[id];
 | 
			
		||||
            if (newId !== undefined &&
 | 
			
		||||
                appSys.lookup_app(newId) != null) {
 | 
			
		||||
@@ -81,8 +79,11 @@ var AppFavorites = new Lang.Class({
 | 
			
		||||
        if (updated)
 | 
			
		||||
            global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
 | 
			
		||||
 | 
			
		||||
        let apps = ids.map(id => appSys.lookup_app(id))
 | 
			
		||||
                      .filter(app => app != null);
 | 
			
		||||
        let apps = ids.map(function (id) {
 | 
			
		||||
                return appSys.lookup_app(id);
 | 
			
		||||
            }).filter(function (app) {
 | 
			
		||||
                return app != null;
 | 
			
		||||
            });
 | 
			
		||||
        this._favorites = {};
 | 
			
		||||
        for (let i = 0; i < apps.length; i++) {
 | 
			
		||||
            let app = apps[i];
 | 
			
		||||
@@ -90,29 +91,29 @@ var AppFavorites = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getIds() {
 | 
			
		||||
    _getIds: function() {
 | 
			
		||||
        let ret = [];
 | 
			
		||||
        for (let id in this._favorites)
 | 
			
		||||
            ret.push(id);
 | 
			
		||||
        return ret;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getFavoriteMap() {
 | 
			
		||||
    getFavoriteMap: function() {
 | 
			
		||||
        return this._favorites;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getFavorites() {
 | 
			
		||||
    getFavorites: function() {
 | 
			
		||||
        let ret = [];
 | 
			
		||||
        for (let id in this._favorites)
 | 
			
		||||
            ret.push(this._favorites[id]);
 | 
			
		||||
        return ret;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    isFavorite(appId) {
 | 
			
		||||
    isFavorite: function(appId) {
 | 
			
		||||
        return appId in this._favorites;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _addFavorite(appId, pos) {
 | 
			
		||||
    _addFavorite: function(appId, pos) {
 | 
			
		||||
        if (appId in this._favorites)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
@@ -131,7 +132,7 @@ var AppFavorites = new Lang.Class({
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addFavoriteAtPos(appId, pos) {
 | 
			
		||||
    addFavoriteAtPos: function(appId, pos) {
 | 
			
		||||
        if (!this._addFavorite(appId, pos))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -139,31 +140,31 @@ var AppFavorites = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        Main.overview.setMessage(_("%s has been added to your favorites.").format(app.get_name()),
 | 
			
		||||
                                 { forFeedback: true,
 | 
			
		||||
                                   undoCallback: () => {
 | 
			
		||||
                                       this._removeFavorite(appId);
 | 
			
		||||
                                   }
 | 
			
		||||
                                   undoCallback: Lang.bind(this, function () {
 | 
			
		||||
                                                               this._removeFavorite(appId);
 | 
			
		||||
                                                           })
 | 
			
		||||
                                 });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addFavorite(appId) {
 | 
			
		||||
    addFavorite: function(appId) {
 | 
			
		||||
        this.addFavoriteAtPos(appId, -1);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    moveFavoriteToPos(appId, pos) {
 | 
			
		||||
    moveFavoriteToPos: function(appId, pos) {
 | 
			
		||||
        this._removeFavorite(appId);
 | 
			
		||||
        this._addFavorite(appId, pos);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _removeFavorite(appId) {
 | 
			
		||||
    _removeFavorite: function(appId) {
 | 
			
		||||
        if (!appId in this._favorites)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        let ids = this._getIds().filter(id => id != appId);
 | 
			
		||||
        let ids = this._getIds().filter(function (id) { return id != appId; });
 | 
			
		||||
        global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    removeFavorite(appId) {
 | 
			
		||||
    removeFavorite: function(appId) {
 | 
			
		||||
        let ids = this._getIds();
 | 
			
		||||
        let pos = ids.indexOf(appId);
 | 
			
		||||
 | 
			
		||||
@@ -173,9 +174,9 @@ var AppFavorites = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        Main.overview.setMessage(_("%s has been removed from your favorites.").format(app.get_name()),
 | 
			
		||||
                                 { forFeedback: true,
 | 
			
		||||
                                   undoCallback: () => {
 | 
			
		||||
                                       this._addFavorite(appId, pos);
 | 
			
		||||
                                   }
 | 
			
		||||
                                   undoCallback: Lang.bind(this, function () {
 | 
			
		||||
                                                               this._addFavorite(appId, pos);
 | 
			
		||||
                                                           })
 | 
			
		||||
                                 });
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,7 @@ var AudioDeviceSelectionDialog = new Lang.Class({
 | 
			
		||||
    Name: 'AudioDeviceSelectionDialog',
 | 
			
		||||
    Extends: ModalDialog.ModalDialog,
 | 
			
		||||
 | 
			
		||||
    _init(devices) {
 | 
			
		||||
    _init: function(devices) {
 | 
			
		||||
        this.parent({ styleClass: 'audio-device-selection-dialog' });
 | 
			
		||||
 | 
			
		||||
        this._deviceItems = {};
 | 
			
		||||
@@ -50,11 +50,11 @@ var AudioDeviceSelectionDialog = new Lang.Class({
 | 
			
		||||
            throw new Error('Too few devices for a selection');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
    destroy: function() {
 | 
			
		||||
        this.parent();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _buildLayout(devices) {
 | 
			
		||||
    _buildLayout: function(devices) {
 | 
			
		||||
        let title = new St.Label({ style_class: 'audio-selection-title',
 | 
			
		||||
                                   text: _("Select Audio Device"),
 | 
			
		||||
                                   x_align: Clutter.ActorAlign.CENTER });
 | 
			
		||||
@@ -65,14 +65,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: this._openSettings.bind(this),
 | 
			
		||||
        this.addButton({ action: Lang.bind(this, this._openSettings),
 | 
			
		||||
                         label: _("Sound Settings") });
 | 
			
		||||
        this.addButton({ action: this.close.bind(this),
 | 
			
		||||
        this.addButton({ action: Lang.bind(this, this.close),
 | 
			
		||||
                         label: _("Cancel"),
 | 
			
		||||
                         key: Clutter.Escape });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getDeviceLabel(device) {
 | 
			
		||||
    _getDeviceLabel: function(device) {
 | 
			
		||||
        switch(device) {
 | 
			
		||||
            case AudioDevice.HEADPHONES:
 | 
			
		||||
                return _("Headphones");
 | 
			
		||||
@@ -85,7 +85,7 @@ var AudioDeviceSelectionDialog = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getDeviceIcon(device) {
 | 
			
		||||
    _getDeviceIcon: function(device) {
 | 
			
		||||
        switch(device) {
 | 
			
		||||
            case AudioDevice.HEADPHONES:
 | 
			
		||||
                return 'audio-headphones-symbolic';
 | 
			
		||||
@@ -98,14 +98,16 @@ var AudioDeviceSelectionDialog = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _addDevice(device) {
 | 
			
		||||
    _addDevice: function(device) {
 | 
			
		||||
        let box = new St.BoxLayout({ style_class: 'audio-selection-device-box',
 | 
			
		||||
                                     vertical: true });
 | 
			
		||||
        box.connect('notify::height', () => {
 | 
			
		||||
            Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
 | 
			
		||||
                box.width = box.height;
 | 
			
		||||
        box.connect('notify::height',
 | 
			
		||||
            function() {
 | 
			
		||||
                Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
 | 
			
		||||
                    function() {
 | 
			
		||||
                        box.width = box.height;
 | 
			
		||||
                    });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let icon = new St.Icon({ style_class: 'audio-selection-device-icon',
 | 
			
		||||
                                 icon_name: this._getDeviceIcon(device) });
 | 
			
		||||
@@ -121,14 +123,15 @@ var AudioDeviceSelectionDialog = new Lang.Class({
 | 
			
		||||
                                     child: box });
 | 
			
		||||
        this._selectionBox.add(button);
 | 
			
		||||
 | 
			
		||||
        button.connect('clicked', () => {
 | 
			
		||||
            this.emit('device-selected', device);
 | 
			
		||||
            this.close();
 | 
			
		||||
            Main.overview.hide();
 | 
			
		||||
        });
 | 
			
		||||
        button.connect('clicked', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                this.emit('device-selected', device);
 | 
			
		||||
                this.close();
 | 
			
		||||
                Main.overview.hide();
 | 
			
		||||
            }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _openSettings() {
 | 
			
		||||
    _openSettings: function() {
 | 
			
		||||
        let desktopFile = 'gnome-sound-panel.desktop'
 | 
			
		||||
        let app = Shell.AppSystem.get_default().lookup_app(desktopFile);
 | 
			
		||||
 | 
			
		||||
@@ -146,7 +149,7 @@ var AudioDeviceSelectionDialog = new Lang.Class({
 | 
			
		||||
var AudioDeviceSelectionDBus = new Lang.Class({
 | 
			
		||||
    Name: 'AudioDeviceSelectionDBus',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._audioSelectionDialog = null;
 | 
			
		||||
 | 
			
		||||
        this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(AudioDeviceSelectionIface, this);
 | 
			
		||||
@@ -155,16 +158,17 @@ var AudioDeviceSelectionDBus = new Lang.Class({
 | 
			
		||||
        Gio.DBus.session.own_name('org.gnome.Shell.AudioDeviceSelection', Gio.BusNameOwnerFlags.REPLACE, null, null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDialogClosed() {
 | 
			
		||||
    _onDialogClosed: function() {
 | 
			
		||||
        this._audioSelectionDialog = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDeviceSelected(dialog, device) {
 | 
			
		||||
    _onDeviceSelected: function(dialog, device) {
 | 
			
		||||
        let connection = this._dbusImpl.get_connection();
 | 
			
		||||
        let info = this._dbusImpl.get_info();
 | 
			
		||||
        let deviceName = Object.keys(AudioDevice).filter(
 | 
			
		||||
            dev => AudioDevice[dev] == device
 | 
			
		||||
        )[0].toLowerCase();
 | 
			
		||||
            function(dev) {
 | 
			
		||||
                return AudioDevice[dev] == device;
 | 
			
		||||
            })[0].toLowerCase();
 | 
			
		||||
        connection.emit_signal(this._audioSelectionDialog._sender,
 | 
			
		||||
                               this._dbusImpl.get_object_path(),
 | 
			
		||||
                               info ? info.name : null,
 | 
			
		||||
@@ -172,7 +176,7 @@ var AudioDeviceSelectionDBus = new Lang.Class({
 | 
			
		||||
                               GLib.Variant.new('(s)', [deviceName]));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    OpenAsync(params, invocation) {
 | 
			
		||||
    OpenAsync: function(params, invocation) {
 | 
			
		||||
        if (this._audioSelectionDialog) {
 | 
			
		||||
            invocation.return_value(null);
 | 
			
		||||
            return;
 | 
			
		||||
@@ -180,7 +184,9 @@ var AudioDeviceSelectionDBus = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        let [deviceNames] = params;
 | 
			
		||||
        let devices = 0;
 | 
			
		||||
        deviceNames.forEach(n => { devices |= AudioDevice[n.toUpperCase()]; });
 | 
			
		||||
        deviceNames.forEach(function(n) {
 | 
			
		||||
            devices |= AudioDevice[n.toUpperCase()];
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let dialog;
 | 
			
		||||
        try {
 | 
			
		||||
@@ -191,16 +197,16 @@ var AudioDeviceSelectionDBus = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
        dialog._sender = invocation.get_sender();
 | 
			
		||||
 | 
			
		||||
        dialog.connect('closed', this._onDialogClosed.bind(this));
 | 
			
		||||
        dialog.connect('closed', Lang.bind(this, this._onDialogClosed));
 | 
			
		||||
        dialog.connect('device-selected',
 | 
			
		||||
                       this._onDeviceSelected.bind(this));
 | 
			
		||||
                       Lang.bind(this, this._onDeviceSelected));
 | 
			
		||||
        dialog.open();
 | 
			
		||||
 | 
			
		||||
        this._audioSelectionDialog = dialog;
 | 
			
		||||
        invocation.return_value(null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    CloseAsync(params, invocation) {
 | 
			
		||||
    CloseAsync: function(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() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._fileMonitors = {};
 | 
			
		||||
        this._backgroundSources = {};
 | 
			
		||||
        this._animations = {};
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    monitorFile(file) {
 | 
			
		||||
    monitorFile: function(file) {
 | 
			
		||||
        let key = file.hash();
 | 
			
		||||
        if (this._fileMonitors[key])
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let monitor = file.monitor(Gio.FileMonitorFlags.NONE, null);
 | 
			
		||||
        monitor.connect('changed',
 | 
			
		||||
                        (obj, file, otherFile, eventType) => {
 | 
			
		||||
                        Lang.bind(this, function(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(params) {
 | 
			
		||||
    getAnimation: function(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, () => {
 | 
			
		||||
                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');
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
@@ -184,20 +184,20 @@ var BackgroundCache = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        animation = new Animation({ file: params.file });
 | 
			
		||||
 | 
			
		||||
        animation.load(() => {
 | 
			
		||||
            this._animations[params.settingsSchema] = animation;
 | 
			
		||||
        animation.load(Lang.bind(this, function() {
 | 
			
		||||
                           this._animations[params.settingsSchema] = animation;
 | 
			
		||||
 | 
			
		||||
            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');
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
                           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');
 | 
			
		||||
                           }
 | 
			
		||||
                       }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getBackgroundSource(layoutManager, settingsSchema) {
 | 
			
		||||
    getBackgroundSource: function(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(settingsSchema) {
 | 
			
		||||
    releaseBackgroundSource: function(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(params) {
 | 
			
		||||
    _init: function(params) {
 | 
			
		||||
        params = Params.parse(params, { monitorIndex: 0,
 | 
			
		||||
                                        layoutManager: Main.layoutManager,
 | 
			
		||||
                                        settings: null,
 | 
			
		||||
                                        file: null,
 | 
			
		||||
                                        style: null });
 | 
			
		||||
 | 
			
		||||
        this.background = new Meta.Background({ meta_display: global.display });
 | 
			
		||||
        this.background = new Meta.Background({ meta_screen: global.screen });
 | 
			
		||||
        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', () => {
 | 
			
		||||
            this.emit('changed');
 | 
			
		||||
        });
 | 
			
		||||
        this._settingsChangedSignalId = this._settings.connect('changed', Lang.bind(this, function() {
 | 
			
		||||
                                            this.emit('changed');
 | 
			
		||||
                                        }));
 | 
			
		||||
 | 
			
		||||
        this._load();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
    destroy: function() {
 | 
			
		||||
        this._cancellable.cancel();
 | 
			
		||||
        this._removeAnimationTimeout();
 | 
			
		||||
 | 
			
		||||
@@ -300,12 +300,12 @@ var Background = new Lang.Class({
 | 
			
		||||
        this._settingsChangedSignalId = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    updateResolution() {
 | 
			
		||||
    updateResolution: function() {
 | 
			
		||||
        if (this._animation)
 | 
			
		||||
            this._refreshAnimation();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _refreshAnimation() {
 | 
			
		||||
    _refreshAnimation: function() {
 | 
			
		||||
        if (!this._animation)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -313,20 +313,20 @@ var Background = new Lang.Class({
 | 
			
		||||
        this._updateAnimation();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setLoaded() {
 | 
			
		||||
    _setLoaded: function() {
 | 
			
		||||
        if (this.isLoaded)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this.isLoaded = true;
 | 
			
		||||
 | 
			
		||||
        let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
 | 
			
		||||
        let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
 | 
			
		||||
            this.emit('loaded');
 | 
			
		||||
            return GLib.SOURCE_REMOVE;
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
        GLib.Source.set_name_by_id(id, '[gnome-shell] this.emit');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _loadPattern() {
 | 
			
		||||
    _loadPattern: function() {
 | 
			
		||||
        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(file) {
 | 
			
		||||
    _watchFile: function(file) {
 | 
			
		||||
        let key = file.hash();
 | 
			
		||||
        if (this._fileWatches[key])
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._cache.monitorFile(file);
 | 
			
		||||
        let signalId = this._cache.connect('file-changed',
 | 
			
		||||
                                           (cache, changedFile) => {
 | 
			
		||||
                                           Lang.bind(this, function(cache, changedFile) {
 | 
			
		||||
                                               if (changedFile.equal(file)) {
 | 
			
		||||
                                                   let imageCache = Meta.BackgroundImageCache.get_default();
 | 
			
		||||
                                                   imageCache.purge(changedFile);
 | 
			
		||||
                                                   this.emit('changed');
 | 
			
		||||
                                               }
 | 
			
		||||
                                           });
 | 
			
		||||
                                           }));
 | 
			
		||||
        this._fileWatches[key] = signalId;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _removeAnimationTimeout() {
 | 
			
		||||
    _removeAnimationTimeout: function() {
 | 
			
		||||
        if (this._updateAnimationTimeoutId) {
 | 
			
		||||
            GLib.source_remove(this._updateAnimationTimeoutId);
 | 
			
		||||
            this._updateAnimationTimeoutId = 0;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateAnimation() {
 | 
			
		||||
    _updateAnimation: function() {
 | 
			
		||||
        this._updateAnimationTimeoutId = 0;
 | 
			
		||||
 | 
			
		||||
        this._animation.update(this._layoutManager.monitors[this._monitorIndex]);
 | 
			
		||||
        let files = this._animation.keyFrameFiles;
 | 
			
		||||
 | 
			
		||||
        let finish = () => {
 | 
			
		||||
        let finish = Lang.bind(this, function() {
 | 
			
		||||
            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,17 +396,18 @@ var Background = new Lang.Class({
 | 
			
		||||
                if (numPendingImages == 0)
 | 
			
		||||
                    finish();
 | 
			
		||||
            } else {
 | 
			
		||||
                let id = image.connect('loaded', () => {
 | 
			
		||||
                    image.disconnect(id);
 | 
			
		||||
                    numPendingImages--;
 | 
			
		||||
                    if (numPendingImages == 0)
 | 
			
		||||
                        finish();
 | 
			
		||||
                });
 | 
			
		||||
                let id = image.connect('loaded',
 | 
			
		||||
                                       Lang.bind(this, function() {
 | 
			
		||||
                                           image.disconnect(id);
 | 
			
		||||
                                           numPendingImages--;
 | 
			
		||||
                                           if (numPendingImages == 0)
 | 
			
		||||
                                               finish();
 | 
			
		||||
                                       }));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _queueUpdateAnimation() {
 | 
			
		||||
    _queueUpdateAnimation: function() {
 | 
			
		||||
        if (this._updateAnimationTimeoutId != 0)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -427,18 +428,18 @@ var Background = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._updateAnimationTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
 | 
			
		||||
                                                      interval,
 | 
			
		||||
                                                      () => {
 | 
			
		||||
                                                          this._updateAnimationTimeoutId = 0;
 | 
			
		||||
                                                          this._updateAnimation();
 | 
			
		||||
                                                          return GLib.SOURCE_REMOVE;
 | 
			
		||||
                                                      });
 | 
			
		||||
                                                      Lang.bind(this, function() {
 | 
			
		||||
                                                                    this._updateAnimationTimeoutId = 0;
 | 
			
		||||
                                                                    this._updateAnimation();
 | 
			
		||||
                                                                    return GLib.SOURCE_REMOVE;
 | 
			
		||||
                                                                }));
 | 
			
		||||
        GLib.Source.set_name_by_id(this._updateAnimationTimeoutId, '[gnome-shell] this._updateAnimation');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _loadAnimation(file) {
 | 
			
		||||
    _loadAnimation: function(file) {
 | 
			
		||||
        this._cache.getAnimation({ file: file,
 | 
			
		||||
                                   settingsSchema: this._settings.schema_id,
 | 
			
		||||
                                   onLoaded: animation => {
 | 
			
		||||
                                   onLoaded: Lang.bind(this, function(animation) {
 | 
			
		||||
                                       this._animation = animation;
 | 
			
		||||
 | 
			
		||||
                                       if (!this._animation || this._cancellable.is_cancelled()) {
 | 
			
		||||
@@ -448,11 +449,11 @@ var Background = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
                                       this._updateAnimation();
 | 
			
		||||
                                       this._watchFile(file);
 | 
			
		||||
                                   }
 | 
			
		||||
                                   })
 | 
			
		||||
                                 });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _loadImage(file) {
 | 
			
		||||
    _loadImage: function(file) {
 | 
			
		||||
        this.background.set_file(file, this._style);
 | 
			
		||||
        this._watchFile(file);
 | 
			
		||||
 | 
			
		||||
@@ -461,21 +462,22 @@ var Background = new Lang.Class({
 | 
			
		||||
        if (image.is_loaded())
 | 
			
		||||
            this._setLoaded();
 | 
			
		||||
        else {
 | 
			
		||||
            let id = image.connect('loaded', () => {
 | 
			
		||||
                this._setLoaded();
 | 
			
		||||
                image.disconnect(id);
 | 
			
		||||
            });
 | 
			
		||||
            let id = image.connect('loaded',
 | 
			
		||||
                                   Lang.bind(this, function() {
 | 
			
		||||
                                       this._setLoaded();
 | 
			
		||||
                                       image.disconnect(id);
 | 
			
		||||
                                   }));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _loadFile(file) {
 | 
			
		||||
    _loadFile: function(file) {
 | 
			
		||||
        if (file.get_basename().endsWith('.xml'))
 | 
			
		||||
            this._loadAnimation(file);
 | 
			
		||||
        else
 | 
			
		||||
            this._loadImage(file);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _load() {
 | 
			
		||||
    _load: function () {
 | 
			
		||||
        this._cache = getBackgroundCache();
 | 
			
		||||
 | 
			
		||||
        this._loadPattern();
 | 
			
		||||
@@ -495,16 +497,16 @@ let _systemBackground;
 | 
			
		||||
var SystemBackground = new Lang.Class({
 | 
			
		||||
    Name: 'SystemBackground',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png');
 | 
			
		||||
 | 
			
		||||
        if (_systemBackground == null) {
 | 
			
		||||
            _systemBackground = new Meta.Background({ meta_display: global.display });
 | 
			
		||||
            _systemBackground = new Meta.Background({ meta_screen: global.screen });
 | 
			
		||||
            _systemBackground.set_color(DEFAULT_BACKGROUND_COLOR);
 | 
			
		||||
            _systemBackground.set_file(file, GDesktopEnums.BackgroundStyle.WALLPAPER);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.actor = new Meta.BackgroundActor({ meta_display: global.display,
 | 
			
		||||
        this.actor = new Meta.BackgroundActor({ meta_screen: global.screen,
 | 
			
		||||
                                                monitor: 0,
 | 
			
		||||
                                                background: _systemBackground });
 | 
			
		||||
 | 
			
		||||
@@ -512,17 +514,18 @@ var SystemBackground = new Lang.Class({
 | 
			
		||||
        let image = cache.load(file);
 | 
			
		||||
        if (image.is_loaded()) {
 | 
			
		||||
            image = null;
 | 
			
		||||
            let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
 | 
			
		||||
            let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
 | 
			
		||||
                this.emit('loaded');
 | 
			
		||||
                return GLib.SOURCE_REMOVE;
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
            GLib.Source.set_name_by_id(id, '[gnome-shell] SystemBackground.loaded');
 | 
			
		||||
        } else {
 | 
			
		||||
            let id = image.connect('loaded', () => {
 | 
			
		||||
                this.emit('loaded');
 | 
			
		||||
                image.disconnect(id);
 | 
			
		||||
                image = null;
 | 
			
		||||
            });
 | 
			
		||||
            let id = image.connect('loaded',
 | 
			
		||||
                                   Lang.bind(this, function() {
 | 
			
		||||
                                       this.emit('loaded');
 | 
			
		||||
                                       image.disconnect(id);
 | 
			
		||||
                                       image = null;
 | 
			
		||||
                                   }));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
@@ -531,20 +534,18 @@ Signals.addSignalMethods(SystemBackground.prototype);
 | 
			
		||||
var BackgroundSource = new Lang.Class({
 | 
			
		||||
    Name: 'BackgroundSource',
 | 
			
		||||
 | 
			
		||||
    _init(layoutManager, settingsSchema) {
 | 
			
		||||
    _init: function(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 = [];
 | 
			
		||||
 | 
			
		||||
        let monitorManager = Meta.MonitorManager.get();
 | 
			
		||||
        this._monitorsChangedId =
 | 
			
		||||
            monitorManager.connect('monitors-changed',
 | 
			
		||||
                                   this._onMonitorsChanged.bind(this));
 | 
			
		||||
        this._monitorsChangedId = global.screen.connect('monitors-changed',
 | 
			
		||||
                                                        Lang.bind(this, this._onMonitorsChanged));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onMonitorsChanged() {
 | 
			
		||||
    _onMonitorsChanged: function() {
 | 
			
		||||
        for (let monitorIndex in this._backgrounds) {
 | 
			
		||||
            let background = this._backgrounds[monitorIndex];
 | 
			
		||||
 | 
			
		||||
@@ -558,7 +559,7 @@ var BackgroundSource = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getBackground(monitorIndex) {
 | 
			
		||||
    getBackground: function(monitorIndex) {
 | 
			
		||||
        let file = null;
 | 
			
		||||
        let style;
 | 
			
		||||
 | 
			
		||||
@@ -593,11 +594,11 @@ var BackgroundSource = new Lang.Class({
 | 
			
		||||
                style: style
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            background._changedId = background.connect('changed', () => {
 | 
			
		||||
            background._changedId = background.connect('changed', Lang.bind(this, function() {
 | 
			
		||||
                background.disconnect(background._changedId);
 | 
			
		||||
                background.destroy();
 | 
			
		||||
                delete this._backgrounds[monitorIndex];
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
            this._backgrounds[monitorIndex] = background;
 | 
			
		||||
        }
 | 
			
		||||
@@ -605,9 +606,8 @@ var BackgroundSource = new Lang.Class({
 | 
			
		||||
        return this._backgrounds[monitorIndex];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
        let monitorManager = Meta.MonitorManager.get();
 | 
			
		||||
        monitorManager.disconnect(this._monitorsChangedId);
 | 
			
		||||
    destroy: function() {
 | 
			
		||||
        global.screen.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(params) {
 | 
			
		||||
    _init: function(params) {
 | 
			
		||||
        params = Params.parse(params, { file: null });
 | 
			
		||||
 | 
			
		||||
        this.file = params.file;
 | 
			
		||||
@@ -632,17 +632,19 @@ var Animation = new Lang.Class({
 | 
			
		||||
        this.loaded = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    load(callback) {
 | 
			
		||||
    load: function(callback) {
 | 
			
		||||
        this._show = new GnomeDesktop.BGSlideShow({ filename: this.file.get_path() });
 | 
			
		||||
 | 
			
		||||
        this._show.load_async(null, (object, result) => {
 | 
			
		||||
            this.loaded = true;
 | 
			
		||||
            if (callback)
 | 
			
		||||
                callback();
 | 
			
		||||
        });
 | 
			
		||||
        this._show.load_async(null,
 | 
			
		||||
                              Lang.bind(this,
 | 
			
		||||
                                        function(object, result) {
 | 
			
		||||
                                            this.loaded = true;
 | 
			
		||||
                                            if (callback)
 | 
			
		||||
                                                callback();
 | 
			
		||||
                                        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    update(monitor) {
 | 
			
		||||
    update: function(monitor) {
 | 
			
		||||
        this.keyFrameFiles = [];
 | 
			
		||||
 | 
			
		||||
        if (!this._show)
 | 
			
		||||
@@ -668,7 +670,7 @@ Signals.addSignalMethods(Animation.prototype);
 | 
			
		||||
var BackgroundManager = new Lang.Class({
 | 
			
		||||
    Name: 'BackgroundManager',
 | 
			
		||||
 | 
			
		||||
    _init(params) {
 | 
			
		||||
    _init: function(params) {
 | 
			
		||||
        params = Params.parse(params, { container: null,
 | 
			
		||||
                                        layoutManager: Main.layoutManager,
 | 
			
		||||
                                        monitorIndex: null,
 | 
			
		||||
@@ -690,7 +692,7 @@ var BackgroundManager = new Lang.Class({
 | 
			
		||||
        this._newBackgroundActor = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
    destroy: function() {
 | 
			
		||||
        let cache = getBackgroundCache();
 | 
			
		||||
        cache.releaseBackgroundSource(this._settingsSchema);
 | 
			
		||||
        this._backgroundSource = null;
 | 
			
		||||
@@ -706,7 +708,7 @@ var BackgroundManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _swapBackgroundActor() {
 | 
			
		||||
    _swapBackgroundActor: function() {
 | 
			
		||||
        let oldBackgroundActor = this.backgroundActor;
 | 
			
		||||
        this.backgroundActor = this._newBackgroundActor;
 | 
			
		||||
        this._newBackgroundActor = null;
 | 
			
		||||
@@ -716,14 +718,14 @@ var BackgroundManager = new Lang.Class({
 | 
			
		||||
                         { opacity: 0,
 | 
			
		||||
                           time: FADE_ANIMATION_TIME,
 | 
			
		||||
                           transition: 'easeOutQuad',
 | 
			
		||||
                           onComplete() {
 | 
			
		||||
                           onComplete: function() {
 | 
			
		||||
                               oldBackgroundActor.background.run_dispose();
 | 
			
		||||
                               oldBackgroundActor.destroy();
 | 
			
		||||
                           }
 | 
			
		||||
                         });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateBackgroundActor() {
 | 
			
		||||
    _updateBackgroundActor: function() {
 | 
			
		||||
        if (this._newBackgroundActor) {
 | 
			
		||||
            /* Skip displaying existing background queued for load */
 | 
			
		||||
            this._newBackgroundActor.destroy();
 | 
			
		||||
@@ -743,18 +745,19 @@ 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() {
 | 
			
		||||
    _createBackgroundActor: function() {
 | 
			
		||||
        let background = this._backgroundSource.getBackground(this._monitorIndex);
 | 
			
		||||
        let backgroundActor = new Meta.BackgroundActor({ meta_display: global.display,
 | 
			
		||||
        let backgroundActor = new Meta.BackgroundActor({ meta_screen: global.screen,
 | 
			
		||||
                                                         monitor: this._monitorIndex,
 | 
			
		||||
                                                         background: background.background,
 | 
			
		||||
                                                         vignette: this._vignette,
 | 
			
		||||
@@ -772,19 +775,19 @@ var BackgroundManager = new Lang.Class({
 | 
			
		||||
            backgroundActor.lower_bottom();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let changeSignalId = background.connect('changed', () => {
 | 
			
		||||
        let changeSignalId = background.connect('changed', Lang.bind(this, function() {
 | 
			
		||||
            background.disconnect(changeSignalId);
 | 
			
		||||
            changeSignalId = null;
 | 
			
		||||
            this._updateBackgroundActor();
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        backgroundActor.connect('destroy', () => {
 | 
			
		||||
        backgroundActor.connect('destroy', Lang.bind(this, function() {
 | 
			
		||||
            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(layoutManager) {
 | 
			
		||||
    _init: function(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', (action, actor, state) => {
 | 
			
		||||
    clickAction.connect('long-press', function(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', action => {
 | 
			
		||||
    clickAction.connect('clicked', function(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', () => {
 | 
			
		||||
    let grabOpBeginId = global.display.connect('grab-op-begin', function () {
 | 
			
		||||
        clickAction.release();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    actor.connect('destroy', () => {
 | 
			
		||||
    actor.connect('destroy', function() {
 | 
			
		||||
        actor._backgroundMenu.destroy();
 | 
			
		||||
        actor._backgroundMenu = null;
 | 
			
		||||
        actor._backgroundManager = null;
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@ var POPUP_ANIMATION_TIME = 0.15;
 | 
			
		||||
var BoxPointer = new Lang.Class({
 | 
			
		||||
    Name: 'BoxPointer',
 | 
			
		||||
 | 
			
		||||
    _init(arrowSide, binProperties) {
 | 
			
		||||
    _init: function(arrowSide, binProperties) {
 | 
			
		||||
        this._arrowSide = arrowSide;
 | 
			
		||||
        this._userArrowSide = arrowSide;
 | 
			
		||||
        this._arrowOrigin = 0;
 | 
			
		||||
@@ -44,13 +44,13 @@ 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', this._getPreferredWidth.bind(this));
 | 
			
		||||
        this._container.connect('get-preferred-height', this._getPreferredHeight.bind(this));
 | 
			
		||||
        this._container.connect('allocate', this._allocate.bind(this));
 | 
			
		||||
        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.bin = new St.Bin(binProperties);
 | 
			
		||||
        this._container.add_actor(this.bin);
 | 
			
		||||
        this._border = new St.DrawingArea();
 | 
			
		||||
        this._border.connect('repaint', this._drawBorder.bind(this));
 | 
			
		||||
        this._border.connect('repaint', Lang.bind(this, this._drawBorder));
 | 
			
		||||
        this._container.add_actor(this._border);
 | 
			
		||||
        this.bin.raise(this._border);
 | 
			
		||||
        this._xOffset = 0;
 | 
			
		||||
@@ -66,20 +66,20 @@ var BoxPointer = new Lang.Class({
 | 
			
		||||
        return this._arrowSide;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _muteInput() {
 | 
			
		||||
    _muteInput: function() {
 | 
			
		||||
        if (this._capturedEventId == 0)
 | 
			
		||||
            this._capturedEventId = this.actor.connect('captured-event',
 | 
			
		||||
                                                       () => Clutter.EVENT_STOP);
 | 
			
		||||
                                                       function() { return Clutter.EVENT_STOP; });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _unmuteInput() {
 | 
			
		||||
    _unmuteInput: function() {
 | 
			
		||||
        if (this._capturedEventId != 0) {
 | 
			
		||||
            this.actor.disconnect(this._capturedEventId);
 | 
			
		||||
            this._capturedEventId = 0;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    show(animate, onComplete) {
 | 
			
		||||
    show: function(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 +112,15 @@ var BoxPointer = new Lang.Class({
 | 
			
		||||
                                 xOffset: 0,
 | 
			
		||||
                                 yOffset: 0,
 | 
			
		||||
                                 transition: 'linear',
 | 
			
		||||
                                 onComplete: () => {
 | 
			
		||||
                                 onComplete: Lang.bind(this, function() {
 | 
			
		||||
                                     this._unmuteInput();
 | 
			
		||||
                                     if (onComplete)
 | 
			
		||||
                                         onComplete();
 | 
			
		||||
                                 },
 | 
			
		||||
                                 }),
 | 
			
		||||
                                 time: animationTime });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hide(animate, onComplete) {
 | 
			
		||||
    hide: function(animate, onComplete) {
 | 
			
		||||
        if (!this.actor.visible)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -156,18 +156,18 @@ var BoxPointer = new Lang.Class({
 | 
			
		||||
                                 yOffset: yOffset,
 | 
			
		||||
                                 transition: 'linear',
 | 
			
		||||
                                 time: animationTime,
 | 
			
		||||
                                 onComplete: () => {
 | 
			
		||||
                                 onComplete: Lang.bind(this, function () {
 | 
			
		||||
                                     this.actor.hide();
 | 
			
		||||
                                     this.opacity = 0;
 | 
			
		||||
                                     this.xOffset = 0;
 | 
			
		||||
                                     this.yOffset = 0;
 | 
			
		||||
                                     if (onComplete)
 | 
			
		||||
                                         onComplete();
 | 
			
		||||
                                 }
 | 
			
		||||
                                 })
 | 
			
		||||
                               });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _adjustAllocationForArrow(isWidth, alloc) {
 | 
			
		||||
    _adjustAllocationForArrow: function(isWidth, alloc) {
 | 
			
		||||
        let themeNode = this.actor.get_theme_node();
 | 
			
		||||
        let borderWidth = themeNode.get_length('-arrow-border-width');
 | 
			
		||||
        alloc.min_size += borderWidth * 2;
 | 
			
		||||
@@ -180,14 +180,14 @@ var BoxPointer = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getPreferredWidth(actor, forHeight, alloc) {
 | 
			
		||||
    _getPreferredWidth: function(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(actor, forWidth, alloc) {
 | 
			
		||||
    _getPreferredHeight: function(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 +196,7 @@ var BoxPointer = new Lang.Class({
 | 
			
		||||
        this._adjustAllocationForArrow(false, alloc);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _allocate(actor, box, flags) {
 | 
			
		||||
    _allocate: function(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 +236,7 @@ var BoxPointer = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _drawBorder(area) {
 | 
			
		||||
    _drawBorder: function(area) {
 | 
			
		||||
        let themeNode = this.actor.get_theme_node();
 | 
			
		||||
 | 
			
		||||
        if (this._arrowActor) {
 | 
			
		||||
@@ -418,7 +418,7 @@ var BoxPointer = new Lang.Class({
 | 
			
		||||
        cr.$dispose();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setPosition(sourceActor, alignment) {
 | 
			
		||||
    setPosition: function(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 +430,7 @@ var BoxPointer = new Lang.Class({
 | 
			
		||||
        this._updateFlip();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setSourceAlignment(alignment) {
 | 
			
		||||
    setSourceAlignment: function(alignment) {
 | 
			
		||||
        this._sourceAlignment = alignment;
 | 
			
		||||
 | 
			
		||||
        if (!this._sourceActor)
 | 
			
		||||
@@ -439,7 +439,7 @@ var BoxPointer = new Lang.Class({
 | 
			
		||||
        this.setPosition(this._sourceActor, this._arrowAlignment);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _reposition() {
 | 
			
		||||
    _reposition: function() {
 | 
			
		||||
        let sourceActor = this._sourceActor;
 | 
			
		||||
        let alignment = this._arrowAlignment;
 | 
			
		||||
 | 
			
		||||
@@ -556,7 +556,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(origin) {
 | 
			
		||||
    setArrowOrigin: function(origin) {
 | 
			
		||||
        if (this._arrowOrigin != origin) {
 | 
			
		||||
            this._arrowOrigin = origin;
 | 
			
		||||
            this._border.queue_repaint();
 | 
			
		||||
@@ -566,14 +566,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(actor) {
 | 
			
		||||
    setArrowActor: function(actor) {
 | 
			
		||||
        if (this._arrowActor != actor) {
 | 
			
		||||
            this._arrowActor = actor;
 | 
			
		||||
            this._border.queue_repaint();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _shiftActor() {
 | 
			
		||||
    _shiftActor : function() {
 | 
			
		||||
        // 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 +584,7 @@ var BoxPointer = new Lang.Class({
 | 
			
		||||
                                    -(this._yPosition + this._yOffset));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _calculateArrowSide(arrowSide) {
 | 
			
		||||
    _calculateArrowSide: function(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 +618,15 @@ var BoxPointer = new Lang.Class({
 | 
			
		||||
        return arrowSide;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateFlip() {
 | 
			
		||||
    _updateFlip: function() {
 | 
			
		||||
        let arrowSide = this._calculateArrowSide(this._userArrowSide);
 | 
			
		||||
        if (this._arrowSide != arrowSide) {
 | 
			
		||||
            this._arrowSide = arrowSide;
 | 
			
		||||
            this._reposition();
 | 
			
		||||
            Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
 | 
			
		||||
            Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
 | 
			
		||||
                this._container.queue_relayout();
 | 
			
		||||
                return false;
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
            this.emit('arrow-side-changed');
 | 
			
		||||
        }
 | 
			
		||||
@@ -658,18 +658,18 @@ var BoxPointer = new Lang.Class({
 | 
			
		||||
        return this.actor.opacity;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    updateArrowSide(side) {
 | 
			
		||||
    updateArrowSide: function(side) {
 | 
			
		||||
        this._arrowSide = side;
 | 
			
		||||
        this._border.queue_repaint();
 | 
			
		||||
 | 
			
		||||
        this.emit('arrow-side-changed');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getPadding(side) {
 | 
			
		||||
    getPadding: function(side) {
 | 
			
		||||
        return this.bin.get_theme_node().get_padding(side);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getArrowHeight() {
 | 
			
		||||
    getArrowHeight: function() {
 | 
			
		||||
        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_ = (context, str) => context + '\u0004' + str;
 | 
			
		||||
var NC_ = function(context, str) { return 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(id, date, end, summary, allDay) {
 | 
			
		||||
    _init: function(id, date, end, summary, allDay) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
        this.date = date;
 | 
			
		||||
        this.end = end;
 | 
			
		||||
@@ -108,27 +108,27 @@ var CalendarEvent = new Lang.Class({
 | 
			
		||||
var EmptyEventSource = new Lang.Class({
 | 
			
		||||
    Name: 'EmptyEventSource',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.isLoading = false;
 | 
			
		||||
        this.isDummy = true;
 | 
			
		||||
        this.hasCalendars = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
    destroy: function() {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    ignoreEvent(event) {
 | 
			
		||||
    ignoreEvent: function(event) {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    requestRange(begin, end) {
 | 
			
		||||
    requestRange: function(begin, end) {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getEvents(begin, end) {
 | 
			
		||||
    getEvents: function(begin, end) {
 | 
			
		||||
        let result = [];
 | 
			
		||||
        return result;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hasEvents(day) {
 | 
			
		||||
    hasEvents: function(day) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -179,7 +179,7 @@ function _dateIntervalsOverlap(a0, a1, b0, b1)
 | 
			
		||||
var DBusEventSource = new Lang.Class({
 | 
			
		||||
    Name: 'DBusEventSource',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._resetCache();
 | 
			
		||||
        this.isLoading = false;
 | 
			
		||||
        this.isDummy = false;
 | 
			
		||||
@@ -188,13 +188,14 @@ var DBusEventSource = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        let savedState = global.get_persistent_state('as', 'ignored_events');
 | 
			
		||||
        if (savedState)
 | 
			
		||||
            savedState.deep_unpack().forEach(eventId => {
 | 
			
		||||
                this._ignoredEvents.set(eventId, true);
 | 
			
		||||
            });
 | 
			
		||||
            savedState.deep_unpack().forEach(Lang.bind(this,
 | 
			
		||||
                function(eventId) {
 | 
			
		||||
                    this._ignoredEvents.set(eventId, true);
 | 
			
		||||
                }));
 | 
			
		||||
 | 
			
		||||
        this._initialized = false;
 | 
			
		||||
        this._dbusProxy = new CalendarServer();
 | 
			
		||||
        this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, (object, result) => {
 | 
			
		||||
        this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(object, result) {
 | 
			
		||||
            let loaded = false;
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
@@ -215,28 +216,28 @@ var DBusEventSource = new Lang.Class({
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this._dbusProxy.connectSignal('Changed', this._onChanged.bind(this));
 | 
			
		||||
            this._dbusProxy.connectSignal('Changed', Lang.bind(this, this._onChanged));
 | 
			
		||||
 | 
			
		||||
            this._dbusProxy.connect('notify::g-name-owner', () => {
 | 
			
		||||
            this._dbusProxy.connect('notify::g-name-owner', Lang.bind(this, function() {
 | 
			
		||||
                if (this._dbusProxy.g_name_owner)
 | 
			
		||||
                    this._onNameAppeared();
 | 
			
		||||
                else
 | 
			
		||||
                    this._onNameVanished();
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
            this._dbusProxy.connect('g-properties-changed', () => {
 | 
			
		||||
            this._dbusProxy.connect('g-properties-changed', Lang.bind(this, function() {
 | 
			
		||||
                this.emit('notify::has-calendars');
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
            this._initialized = loaded;
 | 
			
		||||
            if (loaded) {
 | 
			
		||||
                this.emit('notify::has-calendars');
 | 
			
		||||
                this._onNameAppeared();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
    destroy: function() {
 | 
			
		||||
        this._dbusProxy.run_dispose();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -247,28 +248,28 @@ var DBusEventSource = new Lang.Class({
 | 
			
		||||
            return false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _resetCache() {
 | 
			
		||||
    _resetCache: function() {
 | 
			
		||||
        this._events = [];
 | 
			
		||||
        this._lastRequestBegin = null;
 | 
			
		||||
        this._lastRequestEnd = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onNameAppeared(owner) {
 | 
			
		||||
    _onNameAppeared: function(owner) {
 | 
			
		||||
        this._initialized = true;
 | 
			
		||||
        this._resetCache();
 | 
			
		||||
        this._loadEvents(true);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onNameVanished(oldOwner) {
 | 
			
		||||
    _onNameVanished: function(oldOwner) {
 | 
			
		||||
        this._resetCache();
 | 
			
		||||
        this.emit('changed');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onChanged() {
 | 
			
		||||
    _onChanged: function() {
 | 
			
		||||
        this._loadEvents(false);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onEventsReceived(results, error) {
 | 
			
		||||
    _onEventsReceived: function(results, error) {
 | 
			
		||||
        let newEvents = [];
 | 
			
		||||
        let appointments = results ? results[0] : null;
 | 
			
		||||
        if (appointments != null) {
 | 
			
		||||
@@ -282,7 +283,9 @@ var DBusEventSource = new Lang.Class({
 | 
			
		||||
                let event = new CalendarEvent(id, date, end, summary, allDay);
 | 
			
		||||
                newEvents.push(event);
 | 
			
		||||
            }
 | 
			
		||||
            newEvents.sort((ev1, ev2) => ev1.date.getTime() - ev2.date.getTime());
 | 
			
		||||
            newEvents.sort(function(event1, event2) {
 | 
			
		||||
                return event1.date.getTime() - event2.date.getTime();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._events = newEvents;
 | 
			
		||||
@@ -290,7 +293,7 @@ var DBusEventSource = new Lang.Class({
 | 
			
		||||
        this.emit('changed');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _loadEvents(forceReload) {
 | 
			
		||||
    _loadEvents: function(forceReload) {
 | 
			
		||||
        // Ignore while loading
 | 
			
		||||
        if (!this._initialized)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -299,12 +302,12 @@ var DBusEventSource = new Lang.Class({
 | 
			
		||||
            this._dbusProxy.GetEventsRemote(this._curRequestBegin.getTime() / 1000,
 | 
			
		||||
                                            this._curRequestEnd.getTime() / 1000,
 | 
			
		||||
                                            forceReload,
 | 
			
		||||
                                            this._onEventsReceived.bind(this),
 | 
			
		||||
                                            Lang.bind(this, this._onEventsReceived),
 | 
			
		||||
                                            Gio.DBusCallFlags.NONE);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    ignoreEvent(event) {
 | 
			
		||||
    ignoreEvent: function(event) {
 | 
			
		||||
        if (this._ignoredEvents.get(event.id))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -314,7 +317,7 @@ var DBusEventSource = new Lang.Class({
 | 
			
		||||
        this.emit('changed');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    requestRange(begin, end) {
 | 
			
		||||
    requestRange: function(begin, end) {
 | 
			
		||||
        if (!(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
 | 
			
		||||
            this.isLoading = true;
 | 
			
		||||
            this._lastRequestBegin = begin;
 | 
			
		||||
@@ -325,7 +328,7 @@ var DBusEventSource = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getEvents(begin, end) {
 | 
			
		||||
    getEvents: function(begin, end) {
 | 
			
		||||
        let result = [];
 | 
			
		||||
        for(let n = 0; n < this._events.length; n++) {
 | 
			
		||||
            let event = this._events[n];
 | 
			
		||||
@@ -337,7 +340,7 @@ var DBusEventSource = new Lang.Class({
 | 
			
		||||
                result.push(event);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        result.sort((event1, event2) => {
 | 
			
		||||
        result.sort(function(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;
 | 
			
		||||
@@ -346,7 +349,7 @@ var DBusEventSource = new Lang.Class({
 | 
			
		||||
        return result;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hasEvents(day) {
 | 
			
		||||
    hasEvents: function(day) {
 | 
			
		||||
        let dayBegin = _getBeginningOfDay(day);
 | 
			
		||||
        let dayEnd = _getEndOfDay(day);
 | 
			
		||||
 | 
			
		||||
@@ -363,11 +366,11 @@ Signals.addSignalMethods(DBusEventSource.prototype);
 | 
			
		||||
var Calendar = new Lang.Class({
 | 
			
		||||
    Name: 'Calendar',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        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, this._onSettingsChange.bind(this));
 | 
			
		||||
        this._settings.connect('changed::' + SHOW_WEEKDATE_KEY, Lang.bind(this, this._onSettingsChange));
 | 
			
		||||
        this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
@@ -398,25 +401,25 @@ var Calendar = new Lang.Class({
 | 
			
		||||
                                     reactive: true });
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('scroll-event',
 | 
			
		||||
                           this._onScroll.bind(this));
 | 
			
		||||
                           Lang.bind(this, this._onScroll));
 | 
			
		||||
 | 
			
		||||
        this._buildHeader ();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // @eventSource: is an object implementing the EventSource API, e.g. the
 | 
			
		||||
    // requestRange(), getEvents(), hasEvents() methods and the ::changed signal.
 | 
			
		||||
    setEventSource(eventSource) {
 | 
			
		||||
    setEventSource: function(eventSource) {
 | 
			
		||||
        this._eventSource = eventSource;
 | 
			
		||||
        this._eventSource.connect('changed', () => {
 | 
			
		||||
        this._eventSource.connect('changed', Lang.bind(this, function() {
 | 
			
		||||
            this._rebuildCalendar();
 | 
			
		||||
            this._update();
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
        this._rebuildCalendar();
 | 
			
		||||
        this._update();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Sets the calendar to show a specific date
 | 
			
		||||
    setDate(date) {
 | 
			
		||||
    setDate: function(date) {
 | 
			
		||||
        if (sameDay(date, this._selectedDate))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -425,14 +428,14 @@ var Calendar = new Lang.Class({
 | 
			
		||||
        this.emit('selected-date-changed', new Date(this._selectedDate));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    updateTimeZone() {
 | 
			
		||||
    updateTimeZone: function() {
 | 
			
		||||
        // The calendar need to be rebuilt after a time zone update because
 | 
			
		||||
        // the date might have changed.
 | 
			
		||||
        this._rebuildCalendar();
 | 
			
		||||
        this._update();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _buildHeader() {
 | 
			
		||||
    _buildHeader: function() {
 | 
			
		||||
        let layout = this.actor.layout_manager;
 | 
			
		||||
        let offsetCols = this._useWeekdate ? 1 : 0;
 | 
			
		||||
        this.actor.destroy_all_children();
 | 
			
		||||
@@ -446,7 +449,7 @@ var Calendar = new Lang.Class({
 | 
			
		||||
                                           accessible_name: _("Previous month"),
 | 
			
		||||
                                           can_focus: true });
 | 
			
		||||
        this._topBox.add(this._backButton);
 | 
			
		||||
        this._backButton.connect('clicked', this._onPrevMonthButtonClicked.bind(this));
 | 
			
		||||
        this._backButton.connect('clicked', Lang.bind(this, this._onPrevMonthButtonClicked));
 | 
			
		||||
 | 
			
		||||
        this._monthLabel = new St.Label({style_class: 'calendar-month-label',
 | 
			
		||||
                                         can_focus: true });
 | 
			
		||||
@@ -456,7 +459,7 @@ var Calendar = new Lang.Class({
 | 
			
		||||
                                              accessible_name: _("Next month"),
 | 
			
		||||
                                              can_focus: true });
 | 
			
		||||
        this._topBox.add(this._forwardButton);
 | 
			
		||||
        this._forwardButton.connect('clicked', this._onNextMonthButtonClicked.bind(this));
 | 
			
		||||
        this._forwardButton.connect('clicked', Lang.bind(this, this._onNextMonthButtonClicked));
 | 
			
		||||
 | 
			
		||||
        // Add weekday labels...
 | 
			
		||||
        //
 | 
			
		||||
@@ -487,7 +490,7 @@ var Calendar = new Lang.Class({
 | 
			
		||||
        this._firstDayIndex = this.actor.get_n_children();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onScroll(actor, event) {
 | 
			
		||||
    _onScroll : function(actor, event) {
 | 
			
		||||
        switch (event.get_scroll_direction()) {
 | 
			
		||||
        case Clutter.ScrollDirection.UP:
 | 
			
		||||
        case Clutter.ScrollDirection.LEFT:
 | 
			
		||||
@@ -501,7 +504,7 @@ var Calendar = new Lang.Class({
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onPrevMonthButtonClicked() {
 | 
			
		||||
    _onPrevMonthButtonClicked: function() {
 | 
			
		||||
        let newDate = new Date(this._selectedDate);
 | 
			
		||||
        let oldMonth = newDate.getMonth();
 | 
			
		||||
        if (oldMonth == 0) {
 | 
			
		||||
@@ -525,7 +528,7 @@ var Calendar = new Lang.Class({
 | 
			
		||||
        this.setDate(newDate);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onNextMonthButtonClicked() {
 | 
			
		||||
    _onNextMonthButtonClicked: function() {
 | 
			
		||||
        let newDate = new Date(this._selectedDate);
 | 
			
		||||
        let oldMonth = newDate.getMonth();
 | 
			
		||||
        if (oldMonth == 11) {
 | 
			
		||||
@@ -549,14 +552,14 @@ var Calendar = new Lang.Class({
 | 
			
		||||
        this.setDate(newDate);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSettingsChange() {
 | 
			
		||||
    _onSettingsChange: function() {
 | 
			
		||||
        this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
 | 
			
		||||
        this._buildHeader();
 | 
			
		||||
        this._rebuildCalendar();
 | 
			
		||||
        this._update();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _rebuildCalendar() {
 | 
			
		||||
    _rebuildCalendar: function() {
 | 
			
		||||
        let now = new Date();
 | 
			
		||||
 | 
			
		||||
        // Remove everything but the topBox and the weekday labels
 | 
			
		||||
@@ -614,11 +617,11 @@ var Calendar = new Lang.Class({
 | 
			
		||||
                button.reactive = false;
 | 
			
		||||
 | 
			
		||||
            button._date = new Date(iter);
 | 
			
		||||
            button.connect('clicked', () => {
 | 
			
		||||
            button.connect('clicked', Lang.bind(this, function() {
 | 
			
		||||
                this._shouldDateGrabFocus = true;
 | 
			
		||||
                this.setDate(button._date);
 | 
			
		||||
                this._shouldDateGrabFocus = false;
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
            let hasEvents = this._eventSource.hasEvents(iter);
 | 
			
		||||
            let styleClass = 'calendar-day-base calendar-day';
 | 
			
		||||
@@ -677,7 +680,7 @@ var Calendar = new Lang.Class({
 | 
			
		||||
        this._eventSource.requestRange(beginDate, iter);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _update() {
 | 
			
		||||
    _update: function() {
 | 
			
		||||
        let now = new Date();
 | 
			
		||||
 | 
			
		||||
        if (sameYear(this._selectedDate, now))
 | 
			
		||||
@@ -688,7 +691,7 @@ var Calendar = new Lang.Class({
 | 
			
		||||
        if (!this._calendarBegin || !sameMonth(this._selectedDate, this._calendarBegin) || !sameDay(now, this._markedAsToday))
 | 
			
		||||
            this._rebuildCalendar();
 | 
			
		||||
 | 
			
		||||
        this._buttons.forEach(button => {
 | 
			
		||||
        this._buttons.forEach(Lang.bind(this, function(button) {
 | 
			
		||||
            if (sameDay(button._date, this._selectedDate)) {
 | 
			
		||||
                button.add_style_pseudo_class('selected');
 | 
			
		||||
                if (this._shouldDateGrabFocus)
 | 
			
		||||
@@ -696,7 +699,7 @@ var Calendar = new Lang.Class({
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                button.remove_style_pseudo_class('selected');
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
Signals.addSignalMethods(Calendar.prototype);
 | 
			
		||||
@@ -705,7 +708,7 @@ var EventMessage = new Lang.Class({
 | 
			
		||||
    Name: 'EventMessage',
 | 
			
		||||
    Extends: MessageList.Message,
 | 
			
		||||
 | 
			
		||||
    _init(event, date) {
 | 
			
		||||
    _init: function(event, date) {
 | 
			
		||||
        this._event = event;
 | 
			
		||||
        this._date = date;
 | 
			
		||||
 | 
			
		||||
@@ -720,7 +723,7 @@ var EventMessage = new Lang.Class({
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _formatEventTime() {
 | 
			
		||||
    _formatEventTime: function() {
 | 
			
		||||
        let periodBegin = _getBeginningOfDay(this._date);
 | 
			
		||||
        let periodEnd = _getEndOfDay(this._date);
 | 
			
		||||
        let allDay = (this._event.allDay || (this._event.date <= periodBegin &&
 | 
			
		||||
@@ -753,7 +756,7 @@ var EventMessage = new Lang.Class({
 | 
			
		||||
        return title;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    canClose() {
 | 
			
		||||
    canClose: function() {
 | 
			
		||||
        return isToday(this._date);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -762,7 +765,7 @@ var NotificationMessage = new Lang.Class({
 | 
			
		||||
    Name: 'NotificationMessage',
 | 
			
		||||
    Extends: MessageList.Message,
 | 
			
		||||
 | 
			
		||||
    _init(notification) {
 | 
			
		||||
    _init: function(notification) {
 | 
			
		||||
        this.notification = notification;
 | 
			
		||||
 | 
			
		||||
        this.parent(notification.title, notification.bannerBodyText);
 | 
			
		||||
@@ -770,19 +773,21 @@ var NotificationMessage = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this.setIcon(this._getIcon());
 | 
			
		||||
 | 
			
		||||
        this.connect('close', () => {
 | 
			
		||||
            this._closed = true;
 | 
			
		||||
            this.notification.destroy(MessageTray.NotificationDestroyedReason.DISMISSED);
 | 
			
		||||
        });
 | 
			
		||||
        this._destroyId = notification.connect('destroy', () => {
 | 
			
		||||
            if (!this._closed)
 | 
			
		||||
                this.close();
 | 
			
		||||
        });
 | 
			
		||||
        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._updatedId = notification.connect('updated',
 | 
			
		||||
                                               this._onUpdated.bind(this));
 | 
			
		||||
                                               Lang.bind(this, this._onUpdated));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getIcon() {
 | 
			
		||||
    _getIcon: function() {
 | 
			
		||||
        if (this.notification.gicon)
 | 
			
		||||
            return new St.Icon({ gicon: this.notification.gicon,
 | 
			
		||||
                                 icon_size: MESSAGE_ICON_SIZE });
 | 
			
		||||
@@ -790,18 +795,18 @@ var NotificationMessage = new Lang.Class({
 | 
			
		||||
            return this.notification.source.createIcon(MESSAGE_ICON_SIZE);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onUpdated(n, clear) {
 | 
			
		||||
    _onUpdated: function(n, clear) {
 | 
			
		||||
        this.setIcon(this._getIcon());
 | 
			
		||||
        this.setTitle(n.title);
 | 
			
		||||
        this.setBody(n.bannerBodyText);
 | 
			
		||||
        this.setUseBodyMarkup(n.bannerBodyMarkup);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onClicked() {
 | 
			
		||||
    _onClicked: function() {
 | 
			
		||||
        this.notification.activate();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
        if (this._updatedId)
 | 
			
		||||
            this.notification.disconnect(this._updatedId);
 | 
			
		||||
        this._updatedId = 0;
 | 
			
		||||
@@ -816,13 +821,11 @@ var EventsSection = new Lang.Class({
 | 
			
		||||
    Name: 'EventsSection',
 | 
			
		||||
    Extends: MessageList.MessageListSection,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
 | 
			
		||||
        this._desktopSettings.connect('changed', this._reloadEvents.bind(this));
 | 
			
		||||
        this._desktopSettings.connect('changed', Lang.bind(this, this._reloadEvents));
 | 
			
		||||
        this._eventSource = new EmptyEventSource();
 | 
			
		||||
 | 
			
		||||
        this._messageById = new Map();
 | 
			
		||||
 | 
			
		||||
        this.parent();
 | 
			
		||||
 | 
			
		||||
        this._title = new St.Button({ style_class: 'events-section-title',
 | 
			
		||||
@@ -831,28 +834,28 @@ var EventsSection = new Lang.Class({
 | 
			
		||||
                                      can_focus: true });
 | 
			
		||||
        this.actor.insert_child_below(this._title, null);
 | 
			
		||||
 | 
			
		||||
        this._title.connect('clicked', this._onTitleClicked.bind(this));
 | 
			
		||||
        this._title.connect('key-focus-in', this._onKeyFocusIn.bind(this));
 | 
			
		||||
        this._title.connect('clicked', Lang.bind(this, this._onTitleClicked));
 | 
			
		||||
        this._title.connect('key-focus-in', Lang.bind(this, this._onKeyFocusIn));
 | 
			
		||||
 | 
			
		||||
        Shell.AppSystem.get_default().connect('installed-changed',
 | 
			
		||||
                                              this._appInstalledChanged.bind(this));
 | 
			
		||||
                                              Lang.bind(this, this._appInstalledChanged));
 | 
			
		||||
        this._appInstalledChanged();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _ignoreEvent(event) {
 | 
			
		||||
    _ignoreEvent: function(event) {
 | 
			
		||||
        this._eventSource.ignoreEvent(event);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setEventSource(eventSource) {
 | 
			
		||||
    setEventSource: function(eventSource) {
 | 
			
		||||
        this._eventSource = eventSource;
 | 
			
		||||
        this._eventSource.connect('changed', this._reloadEvents.bind(this));
 | 
			
		||||
        this._eventSource.connect('changed', Lang.bind(this, this._reloadEvents));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get allowed() {
 | 
			
		||||
        return Main.sessionMode.showCalendarEvents;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateTitle() {
 | 
			
		||||
    _updateTitle: function() {
 | 
			
		||||
        this._title.visible = !isToday(this._date);
 | 
			
		||||
 | 
			
		||||
        if (!this._title.visible)
 | 
			
		||||
@@ -871,57 +874,45 @@ var EventsSection = new Lang.Class({
 | 
			
		||||
        this._title.label = this._date.toLocaleFormat(dayFormat);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _reloadEvents() {
 | 
			
		||||
    _reloadEvents: function() {
 | 
			
		||||
        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 = 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);
 | 
			
		||||
            }
 | 
			
		||||
            let message = new EventMessage(event, this._date);
 | 
			
		||||
            message.connect('close', Lang.bind(this, function() {
 | 
			
		||||
                this._ignoreEvent(event);
 | 
			
		||||
            }));
 | 
			
		||||
            this.addMessage(message, false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._reloading = false;
 | 
			
		||||
        this._sync();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _appInstalledChanged() {
 | 
			
		||||
    _appInstalledChanged: function() {
 | 
			
		||||
        this._calendarApp = undefined;
 | 
			
		||||
        this._title.reactive = (this._getCalendarApp() != null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getCalendarApp() {
 | 
			
		||||
    _getCalendarApp: function() {
 | 
			
		||||
        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(a => a.equal(app));
 | 
			
		||||
            let defaultInRecommended = apps.some(function(a) { return a.equal(app); });
 | 
			
		||||
            this._calendarApp = defaultInRecommended ? app : apps[0];
 | 
			
		||||
        } else {
 | 
			
		||||
            this._calendarApp = null;
 | 
			
		||||
@@ -929,7 +920,7 @@ var EventsSection = new Lang.Class({
 | 
			
		||||
        return this._calendarApp;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onTitleClicked() {
 | 
			
		||||
    _onTitleClicked: function() {
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
        Main.panel.closeCalendar();
 | 
			
		||||
 | 
			
		||||
@@ -939,17 +930,17 @@ var EventsSection = new Lang.Class({
 | 
			
		||||
        app.launch([], global.create_app_launch_context(0, -1));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setDate(date) {
 | 
			
		||||
    setDate: function(date) {
 | 
			
		||||
        this.parent(date);
 | 
			
		||||
        this._updateTitle();
 | 
			
		||||
        this._reloadEvents();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _shouldShow() {
 | 
			
		||||
    _shouldShow: function() {
 | 
			
		||||
        return !this.empty || !isToday(this._date);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sync() {
 | 
			
		||||
    _sync: function() {
 | 
			
		||||
        if (this._reloading)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -961,18 +952,18 @@ var NotificationSection = new Lang.Class({
 | 
			
		||||
    Name: 'NotificationSection',
 | 
			
		||||
    Extends: MessageList.MessageListSection,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent();
 | 
			
		||||
 | 
			
		||||
        this._sources = new Map();
 | 
			
		||||
        this._nUrgent = 0;
 | 
			
		||||
 | 
			
		||||
        Main.messageTray.connect('source-added', this._sourceAdded.bind(this));
 | 
			
		||||
        Main.messageTray.getSources().forEach(source => {
 | 
			
		||||
        Main.messageTray.connect('source-added', Lang.bind(this, this._sourceAdded));
 | 
			
		||||
        Main.messageTray.getSources().forEach(Lang.bind(this, function(source) {
 | 
			
		||||
            this._sourceAdded(Main.messageTray, source);
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('notify::mapped', this._onMapped.bind(this));
 | 
			
		||||
        this.actor.connect('notify::mapped', Lang.bind(this, this._onMapped));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get allowed() {
 | 
			
		||||
@@ -980,7 +971,7 @@ var NotificationSection = new Lang.Class({
 | 
			
		||||
               !Main.sessionMode.isGreeter;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createTimeLabel(datetime) {
 | 
			
		||||
    _createTimeLabel: function(datetime) {
 | 
			
		||||
        let label = new St.Label({ style_class: 'event-time',
 | 
			
		||||
                                   x_align: Clutter.ActorAlign.START,
 | 
			
		||||
                                   y_align: Clutter.ActorAlign.END });
 | 
			
		||||
@@ -991,37 +982,39 @@ var NotificationSection = new Lang.Class({
 | 
			
		||||
        return label;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sourceAdded(tray, source) {
 | 
			
		||||
    _sourceAdded: function(tray, source) {
 | 
			
		||||
        let obj = {
 | 
			
		||||
            destroyId: 0,
 | 
			
		||||
            notificationAddedId: 0,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        obj.destroyId = source.connect('destroy', source => {
 | 
			
		||||
        obj.destroyId = source.connect('destroy', Lang.bind(this, function(source) {
 | 
			
		||||
            this._onSourceDestroy(source, obj);
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
        obj.notificationAddedId = source.connect('notification-added',
 | 
			
		||||
                                                 this._onNotificationAdded.bind(this));
 | 
			
		||||
                                                 Lang.bind(this, this._onNotificationAdded));
 | 
			
		||||
 | 
			
		||||
        this._sources.set(source, obj);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onNotificationAdded(source, notification) {
 | 
			
		||||
    _onNotificationAdded: function(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', () => {
 | 
			
		||||
            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--;
 | 
			
		||||
        });
 | 
			
		||||
        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--;
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        if (isUrgent) {
 | 
			
		||||
            // Keep track of urgent notifications to keep them on top
 | 
			
		||||
@@ -1037,14 +1030,14 @@ var NotificationSection = new Lang.Class({
 | 
			
		||||
        this.addMessageAtIndex(message, index, this.actor.mapped);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSourceDestroy(source, obj) {
 | 
			
		||||
    _onSourceDestroy: function(source, obj) {
 | 
			
		||||
        source.disconnect(obj.destroyId);
 | 
			
		||||
        source.disconnect(obj.notificationAddedId);
 | 
			
		||||
 | 
			
		||||
        this._sources.delete(source);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onMapped() {
 | 
			
		||||
    _onMapped: function() {
 | 
			
		||||
        if (!this.actor.mapped)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -1053,7 +1046,7 @@ var NotificationSection = new Lang.Class({
 | 
			
		||||
                message.notification.acknowledged = true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _shouldShow() {
 | 
			
		||||
    _shouldShow: function() {
 | 
			
		||||
        return !this.empty && isToday(this._date);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -1061,7 +1054,7 @@ var NotificationSection = new Lang.Class({
 | 
			
		||||
var Placeholder = new Lang.Class({
 | 
			
		||||
    Name: 'Placeholder',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.actor = new St.BoxLayout({ style_class: 'message-list-placeholder',
 | 
			
		||||
                                        vertical: true });
 | 
			
		||||
 | 
			
		||||
@@ -1081,14 +1074,14 @@ var Placeholder = new Lang.Class({
 | 
			
		||||
        this._sync();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setDate(date) {
 | 
			
		||||
    setDate: function(date) {
 | 
			
		||||
        if (sameDay(this._date, date))
 | 
			
		||||
            return;
 | 
			
		||||
        this._date = date;
 | 
			
		||||
        this._sync();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sync() {
 | 
			
		||||
    _sync: function() {
 | 
			
		||||
        let today = isToday(this._date);
 | 
			
		||||
        if (today && this._icon.gicon == this._todayIcon)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -1108,7 +1101,7 @@ var Placeholder = new Lang.Class({
 | 
			
		||||
var CalendarMessageList = new Lang.Class({
 | 
			
		||||
    Name: 'CalendarMessageList',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.actor = new St.Widget({ style_class: 'message-list',
 | 
			
		||||
                                     layout_manager: new Clutter.BinLayout(),
 | 
			
		||||
                                     x_expand: true, y_expand: true });
 | 
			
		||||
@@ -1153,10 +1146,10 @@ var CalendarMessageList = new Lang.Class({
 | 
			
		||||
        this._eventsSection = new EventsSection();
 | 
			
		||||
        this._addSection(this._eventsSection);
 | 
			
		||||
 | 
			
		||||
        Main.sessionMode.connect('updated', this._sync.bind(this));
 | 
			
		||||
        Main.sessionMode.connect('updated', Lang.bind(this, this._sync));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _addSection(section) {
 | 
			
		||||
    _addSection: function(section) {
 | 
			
		||||
        let obj = {
 | 
			
		||||
            destroyId: 0,
 | 
			
		||||
            visibleId:  0,
 | 
			
		||||
@@ -1164,24 +1157,25 @@ var CalendarMessageList = new Lang.Class({
 | 
			
		||||
            canClearChangedId: 0,
 | 
			
		||||
            keyFocusId: 0
 | 
			
		||||
        };
 | 
			
		||||
        obj.destroyId = section.actor.connect('destroy', () => {
 | 
			
		||||
            this._removeSection(section);
 | 
			
		||||
        });
 | 
			
		||||
        obj.destroyId = section.actor.connect('destroy', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                this._removeSection(section);
 | 
			
		||||
            }));
 | 
			
		||||
        obj.visibleId = section.actor.connect('notify::visible',
 | 
			
		||||
                                              this._sync.bind(this));
 | 
			
		||||
                                              Lang.bind(this, this._sync));
 | 
			
		||||
        obj.emptyChangedId = section.connect('empty-changed',
 | 
			
		||||
                                             this._sync.bind(this));
 | 
			
		||||
                                             Lang.bind(this, this._sync));
 | 
			
		||||
        obj.canClearChangedId = section.connect('can-clear-changed',
 | 
			
		||||
                                                this._sync.bind(this));
 | 
			
		||||
                                                Lang.bind(this, this._sync));
 | 
			
		||||
        obj.keyFocusId = section.connect('key-focus-in',
 | 
			
		||||
                                         this._onKeyFocusIn.bind(this));
 | 
			
		||||
                                         Lang.bind(this, this._onKeyFocusIn));
 | 
			
		||||
 | 
			
		||||
        this._sections.set(section, obj);
 | 
			
		||||
        this._sectionList.add_actor(section.actor);
 | 
			
		||||
        this._sync();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _removeSection(section) {
 | 
			
		||||
    _removeSection: function(section) {
 | 
			
		||||
        let obj = this._sections.get(section);
 | 
			
		||||
        section.actor.disconnect(obj.destroyId);
 | 
			
		||||
        section.actor.disconnect(obj.visibleId);
 | 
			
		||||
@@ -1194,30 +1188,36 @@ var CalendarMessageList = new Lang.Class({
 | 
			
		||||
        this._sync();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onKeyFocusIn(section, actor) {
 | 
			
		||||
    _onKeyFocusIn: function(section, actor) {
 | 
			
		||||
        Util.ensureActorVisibleInScrollView(this._scrollView, actor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sync() {
 | 
			
		||||
    _sync: function() {
 | 
			
		||||
        let sections = [...this._sections.keys()];
 | 
			
		||||
        let visible = sections.some(s => s.allowed);
 | 
			
		||||
        let visible = sections.some(function(s) {
 | 
			
		||||
            return s.allowed;
 | 
			
		||||
        });
 | 
			
		||||
        this.actor.visible = visible;
 | 
			
		||||
        if (!visible)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let empty = sections.every(s => s.empty || !s.actor.visible);
 | 
			
		||||
        let empty = sections.every(function(s) {
 | 
			
		||||
            return s.empty || !s.actor.visible;
 | 
			
		||||
        });
 | 
			
		||||
        this._placeholder.actor.visible = empty;
 | 
			
		||||
        this._clearButton.visible = !empty;
 | 
			
		||||
 | 
			
		||||
        let canClear = sections.some(s => s.canClear && s.actor.visible);
 | 
			
		||||
        let canClear = sections.some(function(s) {
 | 
			
		||||
            return s.canClear && s.actor.visible;
 | 
			
		||||
        });
 | 
			
		||||
        this._clearButton.reactive = canClear;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setEventSource(eventSource) {
 | 
			
		||||
    setEventSource: function(eventSource) {
 | 
			
		||||
        this._eventsSection.setEventSource(eventSource);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setDate(date) {
 | 
			
		||||
    setDate: function(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(label) {
 | 
			
		||||
    _init: function(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(label) {
 | 
			
		||||
    setLabel: function(label) {
 | 
			
		||||
        this._label.set_text(label);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getLabelActor() {
 | 
			
		||||
    getLabelActor: function() {
 | 
			
		||||
        return this._label;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
@@ -14,7 +13,6 @@ 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',
 | 
			
		||||
@@ -24,11 +22,10 @@ var CloseDialog = new Lang.Class({
 | 
			
		||||
        'window': GObject.ParamSpec.override('window', Meta.CloseDialog)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _init(window) {
 | 
			
		||||
    _init: function (window) {
 | 
			
		||||
        this.parent();
 | 
			
		||||
        this._window = window;
 | 
			
		||||
        this._dialog = null;
 | 
			
		||||
        this._timeoutId = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get window() {
 | 
			
		||||
@@ -39,7 +36,7 @@ var CloseDialog = new Lang.Class({
 | 
			
		||||
        this._window = window;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createDialogContent() {
 | 
			
		||||
    _createDialogContent: function () {
 | 
			
		||||
        let tracker = Shell.WindowTracker.get_default();
 | 
			
		||||
        let windowApp = tracker.get_window_app(this._window);
 | 
			
		||||
 | 
			
		||||
@@ -51,7 +48,7 @@ var CloseDialog = new Lang.Class({
 | 
			
		||||
        return new Dialog.MessageDialogContent({ icon, title, subtitle });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _initDialog() {
 | 
			
		||||
    _initDialog: function () {
 | 
			
		||||
        if (this._dialog)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -62,16 +59,16 @@ var CloseDialog = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._dialog.addContent(this._createDialogContent());
 | 
			
		||||
        this._dialog.addButton({ label:   _('Force Quit'),
 | 
			
		||||
                                 action:  this._onClose.bind(this),
 | 
			
		||||
                                 action:  Lang.bind(this, this._onClose),
 | 
			
		||||
                                 default: true });
 | 
			
		||||
        this._dialog.addButton({ label:  _('Wait'),
 | 
			
		||||
                                 action: this._onWait.bind(this),
 | 
			
		||||
                                 action: Lang.bind(this, this._onWait),
 | 
			
		||||
                                 key:    Clutter.Escape });
 | 
			
		||||
 | 
			
		||||
        global.focus_manager.add_group(this._dialog);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _addWindowEffect() {
 | 
			
		||||
    _addWindowEffect: function () {
 | 
			
		||||
        // 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.
 | 
			
		||||
@@ -82,32 +79,24 @@ var CloseDialog = new Lang.Class({
 | 
			
		||||
        surfaceActor.add_effect_with_name("gnome-shell-frozen-window", effect);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _removeWindowEffect() {
 | 
			
		||||
    _removeWindowEffect: function () {
 | 
			
		||||
        let windowActor = this._window.get_compositor_private();
 | 
			
		||||
        let surfaceActor = windowActor.get_first_child();
 | 
			
		||||
        surfaceActor.remove_effect_by_name("gnome-shell-frozen-window");
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onWait() {
 | 
			
		||||
    _onWait: function () {
 | 
			
		||||
        this.response(Meta.CloseDialogResponse.WAIT);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onClose() {
 | 
			
		||||
    _onClose: function () {
 | 
			
		||||
        this.response(Meta.CloseDialogResponse.FORCE_CLOSE);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_show() {
 | 
			
		||||
    vfunc_show: function () {
 | 
			
		||||
        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();
 | 
			
		||||
 | 
			
		||||
@@ -118,21 +107,16 @@ var CloseDialog = new Lang.Class({
 | 
			
		||||
                         { scale_y: 1,
 | 
			
		||||
                           transition: 'linear',
 | 
			
		||||
                           time: DIALOG_TRANSITION_TIME,
 | 
			
		||||
                           onComplete: () => {
 | 
			
		||||
                           onComplete: Lang.bind(this, function () {
 | 
			
		||||
                               Main.layoutManager.trackChrome(this._dialog, { affectsInputRegion: true });
 | 
			
		||||
                           }
 | 
			
		||||
                           })
 | 
			
		||||
                         });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_hide() {
 | 
			
		||||
    vfunc_hide: function () {
 | 
			
		||||
        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();
 | 
			
		||||
@@ -141,13 +125,13 @@ var CloseDialog = new Lang.Class({
 | 
			
		||||
                         { scale_y: 0,
 | 
			
		||||
                           transition: 'linear',
 | 
			
		||||
                           time: DIALOG_TRANSITION_TIME,
 | 
			
		||||
                           onComplete: () => {
 | 
			
		||||
                           onComplete: Lang.bind(this, function () {
 | 
			
		||||
                               dialog.destroy();
 | 
			
		||||
                           }
 | 
			
		||||
                           })
 | 
			
		||||
                         });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_focus() {
 | 
			
		||||
    vfunc_focus: function () {
 | 
			
		||||
        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() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._allComponents = {};
 | 
			
		||||
        this._enabledComponents = [];
 | 
			
		||||
 | 
			
		||||
        Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
 | 
			
		||||
        Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
 | 
			
		||||
        this._sessionUpdated();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sessionUpdated() {
 | 
			
		||||
    _sessionUpdated: function() {
 | 
			
		||||
        let newEnabledComponents = Main.sessionMode.components;
 | 
			
		||||
 | 
			
		||||
        newEnabledComponents.filter(
 | 
			
		||||
            name => this._enabledComponents.indexOf(name) == -1
 | 
			
		||||
        ).forEach(name => {
 | 
			
		||||
        newEnabledComponents.filter(Lang.bind(this, function(name) {
 | 
			
		||||
            return this._enabledComponents.indexOf(name) == -1;
 | 
			
		||||
        })).forEach(Lang.bind(this, function(name) {
 | 
			
		||||
            this._enableComponent(name);
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._enabledComponents.filter(
 | 
			
		||||
            name => newEnabledComponents.indexOf(name) == -1
 | 
			
		||||
        ).forEach(name => {
 | 
			
		||||
        this._enabledComponents.filter(Lang.bind(this, function(name) {
 | 
			
		||||
            return newEnabledComponents.indexOf(name) == -1;
 | 
			
		||||
        })).forEach(Lang.bind(this, function(name) {
 | 
			
		||||
            this._disableComponent(name);
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._enabledComponents = newEnabledComponents;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _importComponent(name) {
 | 
			
		||||
    _importComponent: function(name) {
 | 
			
		||||
        let module = imports.ui.components[name];
 | 
			
		||||
        return module.Component;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _ensureComponent(name) {
 | 
			
		||||
    _ensureComponent: function(name) {
 | 
			
		||||
        let component = this._allComponents[name];
 | 
			
		||||
        if (component)
 | 
			
		||||
            return component;
 | 
			
		||||
@@ -50,13 +50,13 @@ var ComponentManager = new Lang.Class({
 | 
			
		||||
        return component;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _enableComponent(name) {
 | 
			
		||||
    _enableComponent: function(name) {
 | 
			
		||||
        let component = this._ensureComponent(name);
 | 
			
		||||
	if (component)
 | 
			
		||||
            component.enable();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _disableComponent(name) {
 | 
			
		||||
    _disableComponent: function(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() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
 | 
			
		||||
        this._volumeQueue = [];
 | 
			
		||||
        this._session = new GnomeSession.SessionManager();
 | 
			
		||||
        this._session.connectSignal('InhibitorAdded',
 | 
			
		||||
                                    this._InhibitorsChanged.bind(this));
 | 
			
		||||
                                    Lang.bind(this, this._InhibitorsChanged));
 | 
			
		||||
        this._session.connectSignal('InhibitorRemoved',
 | 
			
		||||
                                    this._InhibitorsChanged.bind(this));
 | 
			
		||||
                                    Lang.bind(this, this._InhibitorsChanged));
 | 
			
		||||
        this._inhibited = false;
 | 
			
		||||
 | 
			
		||||
        this._volumeMonitor = Gio.VolumeMonitor.get();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    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));
 | 
			
		||||
    enable: function() {
 | 
			
		||||
        this._volumeAddedId = this._volumeMonitor.connect('volume-added', Lang.bind(this, this._onVolumeAdded));
 | 
			
		||||
        this._volumeRemovedId = this._volumeMonitor.connect('volume-removed', Lang.bind(this, this._onVolumeRemoved));
 | 
			
		||||
        this._driveConnectedId = this._volumeMonitor.connect('drive-connected', Lang.bind(this, this._onDriveConnected));
 | 
			
		||||
        this._driveDisconnectedId = this._volumeMonitor.connect('drive-disconnected', Lang.bind(this, this._onDriveDisconnected));
 | 
			
		||||
        this._driveEjectButtonId = this._volumeMonitor.connect('drive-eject-button', Lang.bind(this, this._onDriveEjectButton));
 | 
			
		||||
 | 
			
		||||
        this._mountAllId = Mainloop.idle_add(this._startupMountAll.bind(this));
 | 
			
		||||
        this._mountAllId = Mainloop.idle_add(Lang.bind(this, this._startupMountAll));
 | 
			
		||||
        GLib.Source.set_name_by_id(this._mountAllId, '[gnome-shell] this._startupMountAll');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    disable() {
 | 
			
		||||
    disable: function() {
 | 
			
		||||
        this._volumeMonitor.disconnect(this._volumeAddedId);
 | 
			
		||||
        this._volumeMonitor.disconnect(this._volumeRemovedId);
 | 
			
		||||
        this._volumeMonitor.disconnect(this._driveConnectedId);
 | 
			
		||||
@@ -59,28 +59,29 @@ var AutomountManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _InhibitorsChanged(object, senderName, [inhibtor]) {
 | 
			
		||||
    _InhibitorsChanged: function(object, senderName, [inhibtor]) {
 | 
			
		||||
        this._session.IsInhibitedRemote(GNOME_SESSION_AUTOMOUNT_INHIBIT,
 | 
			
		||||
            (result, error) => {
 | 
			
		||||
                if (!error) {
 | 
			
		||||
                    this._inhibited = result[0];
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            Lang.bind(this,
 | 
			
		||||
                function(result, error) {
 | 
			
		||||
                    if (!error) {
 | 
			
		||||
                        this._inhibited = result[0];
 | 
			
		||||
                    }
 | 
			
		||||
                }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _startupMountAll() {
 | 
			
		||||
    _startupMountAll: function() {
 | 
			
		||||
        let volumes = this._volumeMonitor.get_volumes();
 | 
			
		||||
        volumes.forEach(volume => {
 | 
			
		||||
        volumes.forEach(Lang.bind(this, function(volume) {
 | 
			
		||||
            this._checkAndMountVolume(volume, { checkSession: false,
 | 
			
		||||
                                                useMountOp: false,
 | 
			
		||||
                                                allowAutorun: false });
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._mountAllId = 0;
 | 
			
		||||
        return GLib.SOURCE_REMOVE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDriveConnected() {
 | 
			
		||||
    _onDriveConnected: function() {
 | 
			
		||||
        // if we're not in the current ConsoleKit session,
 | 
			
		||||
        // or screensaver is active, don't play sounds
 | 
			
		||||
        if (!this._session.SessionIsActive)
 | 
			
		||||
@@ -91,7 +92,7 @@ var AutomountManager = new Lang.Class({
 | 
			
		||||
                                null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDriveDisconnected() {
 | 
			
		||||
    _onDriveDisconnected: function() {
 | 
			
		||||
        // if we're not in the current ConsoleKit session,
 | 
			
		||||
        // or screensaver is active, don't play sounds
 | 
			
		||||
        if (!this._session.SessionIsActive)
 | 
			
		||||
@@ -102,7 +103,7 @@ var AutomountManager = new Lang.Class({
 | 
			
		||||
                                null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDriveEjectButton(monitor, drive) {
 | 
			
		||||
    _onDriveEjectButton: function(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)
 | 
			
		||||
@@ -113,31 +114,31 @@ var AutomountManager = new Lang.Class({
 | 
			
		||||
        if (drive.can_stop()) {
 | 
			
		||||
            drive.stop
 | 
			
		||||
                (Gio.MountUnmountFlags.FORCE, null, null,
 | 
			
		||||
                 (drive, res) => {
 | 
			
		||||
                 Lang.bind(this, function(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,
 | 
			
		||||
                 (drive, res) => {
 | 
			
		||||
                 Lang.bind(this, function(drive, res) {
 | 
			
		||||
                     try {
 | 
			
		||||
                         drive.eject_with_operation_finish(res);
 | 
			
		||||
                     } catch (e) {
 | 
			
		||||
                         log("Unable to eject the drive after drive-eject-button " + e.toString());
 | 
			
		||||
                     }
 | 
			
		||||
                 });
 | 
			
		||||
                 }));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onVolumeAdded(monitor, volume) {
 | 
			
		||||
    _onVolumeAdded: function(monitor, volume) {
 | 
			
		||||
        this._checkAndMountVolume(volume);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _checkAndMountVolume(volume, params) {
 | 
			
		||||
    _checkAndMountVolume: function(volume, params) {
 | 
			
		||||
        params = Params.parse(params, { checkSession: true,
 | 
			
		||||
                                        useMountOp: true,
 | 
			
		||||
                                        allowAutorun: true });
 | 
			
		||||
@@ -177,7 +178,7 @@ var AutomountManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _mountVolume(volume, operation, allowAutorun) {
 | 
			
		||||
    _mountVolume: function(volume, operation, allowAutorun) {
 | 
			
		||||
        if (allowAutorun)
 | 
			
		||||
            this._allowAutorun(volume);
 | 
			
		||||
 | 
			
		||||
@@ -185,10 +186,10 @@ var AutomountManager = new Lang.Class({
 | 
			
		||||
        volume._operation = operation;
 | 
			
		||||
 | 
			
		||||
        volume.mount(0, mountOp, null,
 | 
			
		||||
                     this._onVolumeMounted.bind(this));
 | 
			
		||||
                     Lang.bind(this, this._onVolumeMounted));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onVolumeMounted(volume, res) {
 | 
			
		||||
    _onVolumeMounted: function(volume, res) {
 | 
			
		||||
        this._allowAutorunExpire(volume);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
@@ -209,12 +210,14 @@ var AutomountManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onVolumeRemoved(monitor, volume) {
 | 
			
		||||
    _onVolumeRemoved: function(monitor, volume) {
 | 
			
		||||
        this._volumeQueue = 
 | 
			
		||||
            this._volumeQueue.filter(element => (element != volume));
 | 
			
		||||
            this._volumeQueue.filter(function(element) {
 | 
			
		||||
                return (element != volume);
 | 
			
		||||
            });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _reaskPassword(volume) {
 | 
			
		||||
    _reaskPassword: function(volume) {
 | 
			
		||||
        let existingDialog = volume._operation ? volume._operation.borrowDialog() : null;
 | 
			
		||||
        let operation = 
 | 
			
		||||
            new ShellMountOperation.ShellMountOperation(volume,
 | 
			
		||||
@@ -222,17 +225,17 @@ var AutomountManager = new Lang.Class({
 | 
			
		||||
        this._mountVolume(volume, operation);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _closeOperation(volume) {
 | 
			
		||||
    _closeOperation: function(volume) {
 | 
			
		||||
        if (volume._operation)
 | 
			
		||||
            volume._operation.close();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _allowAutorun(volume) {
 | 
			
		||||
    _allowAutorun: function(volume) {
 | 
			
		||||
        volume.allowAutorun = true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _allowAutorunExpire(volume) {
 | 
			
		||||
        let id = Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, () => {
 | 
			
		||||
    _allowAutorunExpire: function(volume) {
 | 
			
		||||
        let id = Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, function() {
 | 
			
		||||
            volume.allowAutorun = false;
 | 
			
		||||
            return GLib.SOURCE_REMOVE;
 | 
			
		||||
        });
 | 
			
		||||
 
 | 
			
		||||
@@ -93,25 +93,26 @@ function HotplugSniffer() {
 | 
			
		||||
var ContentTypeDiscoverer = new Lang.Class({
 | 
			
		||||
    Name: 'ContentTypeDiscoverer',
 | 
			
		||||
 | 
			
		||||
    _init(callback) {
 | 
			
		||||
    _init: function(callback) {
 | 
			
		||||
        this._callback = callback;
 | 
			
		||||
        this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    guessContentTypes(mount) {
 | 
			
		||||
    guessContentTypes: function(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,
 | 
			
		||||
                                     this._onContentTypeGuessed.bind(this));
 | 
			
		||||
                                     Lang.bind(this,
 | 
			
		||||
                                               this._onContentTypeGuessed));
 | 
			
		||||
        } else {
 | 
			
		||||
            this._emitCallback(mount, []);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onContentTypeGuessed(mount, res) {
 | 
			
		||||
    _onContentTypeGuessed: function(mount, res) {
 | 
			
		||||
        let contentTypes = [];
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
@@ -128,23 +129,23 @@ var ContentTypeDiscoverer = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
            let hotplugSniffer = new HotplugSniffer();
 | 
			
		||||
            hotplugSniffer.SniffURIRemote(root.get_uri(),
 | 
			
		||||
                 ([contentTypes]) => {
 | 
			
		||||
                 Lang.bind(this, function([contentTypes]) {
 | 
			
		||||
                     this._emitCallback(mount, contentTypes);
 | 
			
		||||
                 });
 | 
			
		||||
                 }));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _emitCallback(mount, contentTypes) {
 | 
			
		||||
    _emitCallback: function(mount, contentTypes) {
 | 
			
		||||
        if (!contentTypes)
 | 
			
		||||
            contentTypes = [];
 | 
			
		||||
 | 
			
		||||
        // we're not interested in win32 software content types here
 | 
			
		||||
        contentTypes = contentTypes.filter(
 | 
			
		||||
            type => (type != 'x-content/win32-software')
 | 
			
		||||
        );
 | 
			
		||||
        contentTypes = contentTypes.filter(function(type) {
 | 
			
		||||
            return (type != 'x-content/win32-software');
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let apps = [];
 | 
			
		||||
        contentTypes.forEach(type => {
 | 
			
		||||
        contentTypes.forEach(function(type) {
 | 
			
		||||
            let app = Gio.app_info_get_default_for_type(type, false);
 | 
			
		||||
 | 
			
		||||
            if (app)
 | 
			
		||||
@@ -161,36 +162,36 @@ var ContentTypeDiscoverer = new Lang.Class({
 | 
			
		||||
var AutorunManager = new Lang.Class({
 | 
			
		||||
    Name: 'AutorunManager',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._session = new GnomeSession.SessionManager();
 | 
			
		||||
        this._volumeMonitor = Gio.VolumeMonitor.get();
 | 
			
		||||
 | 
			
		||||
        this._dispatcher = new AutorunDispatcher(this);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    enable() {
 | 
			
		||||
        this._mountAddedId = this._volumeMonitor.connect('mount-added', this._onMountAdded.bind(this));
 | 
			
		||||
        this._mountRemovedId = this._volumeMonitor.connect('mount-removed', this._onMountRemoved.bind(this));
 | 
			
		||||
    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));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    disable() {
 | 
			
		||||
    disable: function() {
 | 
			
		||||
        this._volumeMonitor.disconnect(this._mountAddedId);
 | 
			
		||||
        this._volumeMonitor.disconnect(this._mountRemovedId);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onMountAdded(monitor, mount) {
 | 
			
		||||
    _onMountAdded: function(monitor, mount) {
 | 
			
		||||
        // don't do anything if our session is not the currently
 | 
			
		||||
        // active one
 | 
			
		||||
        if (!this._session.SessionIsActive)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let discoverer = new ContentTypeDiscoverer((mount, apps, contentTypes) => {
 | 
			
		||||
        let discoverer = new ContentTypeDiscoverer(Lang.bind(this, function(mount, apps, contentTypes) {
 | 
			
		||||
            this._dispatcher.addMount(mount, apps, contentTypes);
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
        discoverer.guessContentTypes(mount);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onMountRemoved(monitor, mount) {
 | 
			
		||||
    _onMountRemoved: function(monitor, mount) {
 | 
			
		||||
        this._dispatcher.removeMount(mount);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -198,13 +199,13 @@ var AutorunManager = new Lang.Class({
 | 
			
		||||
var AutorunDispatcher = new Lang.Class({
 | 
			
		||||
    Name: 'AutorunDispatcher',
 | 
			
		||||
 | 
			
		||||
    _init(manager) {
 | 
			
		||||
    _init: function(manager) {
 | 
			
		||||
        this._manager = manager;
 | 
			
		||||
        this._sources = [];
 | 
			
		||||
        this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getAutorunSettingForType(contentType) {
 | 
			
		||||
    _getAutorunSettingForType: function(contentType) {
 | 
			
		||||
        let runApp = this._settings.get_strv(SETTING_START_APP);
 | 
			
		||||
        if (runApp.indexOf(contentType) != -1)
 | 
			
		||||
            return AutorunSetting.RUN;
 | 
			
		||||
@@ -220,8 +221,11 @@ var AutorunDispatcher = new Lang.Class({
 | 
			
		||||
        return AutorunSetting.ASK;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getSourceForMount(mount) {
 | 
			
		||||
        let filtered = this._sources.filter(source => (source.mount == mount));
 | 
			
		||||
    _getSourceForMount: function(mount) {
 | 
			
		||||
        let filtered =
 | 
			
		||||
            this._sources.filter(function (source) {
 | 
			
		||||
                return (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
 | 
			
		||||
@@ -232,7 +236,7 @@ var AutorunDispatcher = new Lang.Class({
 | 
			
		||||
        return null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _addSource(mount, apps) {
 | 
			
		||||
    _addSource: function(mount, apps) {
 | 
			
		||||
        // if we already have a source showing for this 
 | 
			
		||||
        // mount, return
 | 
			
		||||
        if (this._getSourceForMount(mount))
 | 
			
		||||
@@ -242,7 +246,7 @@ var AutorunDispatcher = new Lang.Class({
 | 
			
		||||
        this._sources.push(new AutorunSource(this._manager, mount, apps));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addMount(mount, apps, contentTypes) {
 | 
			
		||||
    addMount: function(mount, apps, contentTypes) {
 | 
			
		||||
        // if autorun is disabled globally, return
 | 
			
		||||
        if (this._settings.get_boolean(SETTING_DISABLE_AUTORUN))
 | 
			
		||||
            return;
 | 
			
		||||
@@ -280,7 +284,7 @@ var AutorunDispatcher = new Lang.Class({
 | 
			
		||||
            this._addSource(mount, apps);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    removeMount(mount) {
 | 
			
		||||
    removeMount: function(mount) {
 | 
			
		||||
        let source = this._getSourceForMount(mount);
 | 
			
		||||
        
 | 
			
		||||
        // if we aren't tracking this mount, don't do anything
 | 
			
		||||
@@ -296,7 +300,7 @@ var AutorunSource = new Lang.Class({
 | 
			
		||||
    Name: 'AutorunSource',
 | 
			
		||||
    Extends: MessageTray.Source,
 | 
			
		||||
 | 
			
		||||
    _init(manager, mount, apps) {
 | 
			
		||||
    _init: function(manager, mount, apps) {
 | 
			
		||||
        this._manager = manager;
 | 
			
		||||
        this.mount = mount;
 | 
			
		||||
        this.apps = apps;
 | 
			
		||||
@@ -310,11 +314,11 @@ var AutorunSource = new Lang.Class({
 | 
			
		||||
        this.notify(this._notification);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getIcon() {
 | 
			
		||||
    getIcon: function() {
 | 
			
		||||
        return this.mount.get_icon();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createPolicy() {
 | 
			
		||||
    _createPolicy: function() {
 | 
			
		||||
        return new MessageTray.NotificationApplicationPolicy('org.gnome.Nautilus');
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -323,27 +327,27 @@ var AutorunNotification = new Lang.Class({
 | 
			
		||||
    Name: 'AutorunNotification',
 | 
			
		||||
    Extends: MessageTray.Notification,
 | 
			
		||||
 | 
			
		||||
    _init(manager, source) {
 | 
			
		||||
    _init: function(manager, source) {
 | 
			
		||||
        this.parent(source, source.title);
 | 
			
		||||
 | 
			
		||||
        this._manager = manager;
 | 
			
		||||
        this._mount = source.mount;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    createBanner() {
 | 
			
		||||
    createBanner: function() {
 | 
			
		||||
        let banner = new MessageTray.NotificationBanner(this);
 | 
			
		||||
 | 
			
		||||
        this.source.apps.forEach(app => {
 | 
			
		||||
        this.source.apps.forEach(Lang.bind(this, function (app) {
 | 
			
		||||
            let actor = this._buttonForApp(app);
 | 
			
		||||
 | 
			
		||||
            if (actor)
 | 
			
		||||
                banner.addButton(actor);
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        return banner;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _buttonForApp(app) {
 | 
			
		||||
    _buttonForApp: function(app) {
 | 
			
		||||
        let box = new St.BoxLayout();
 | 
			
		||||
        let icon = new St.Icon({ gicon: app.get_icon(),
 | 
			
		||||
                                 style_class: 'hotplug-notification-item-icon' });
 | 
			
		||||
@@ -362,15 +366,15 @@ var AutorunNotification = new Lang.Class({
 | 
			
		||||
                                     button_mask: St.ButtonMask.ONE,
 | 
			
		||||
                                     style_class: 'hotplug-notification-item button' });
 | 
			
		||||
 | 
			
		||||
        button.connect('clicked', () => {
 | 
			
		||||
        button.connect('clicked', Lang.bind(this, function() {
 | 
			
		||||
            startAppForMount(app, this._mount);
 | 
			
		||||
            this.destroy();
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        return button;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activate() {
 | 
			
		||||
    activate: function() {
 | 
			
		||||
        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() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent({ styleClass: 'prompt-dialog' });
 | 
			
		||||
 | 
			
		||||
        this.prompt = new Shell.KeyringPrompt();
 | 
			
		||||
        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));
 | 
			
		||||
        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));
 | 
			
		||||
 | 
			
		||||
        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: this._onCancelButton.bind(this),
 | 
			
		||||
                                              action: Lang.bind(this, this._onCancelButton),
 | 
			
		||||
                                              key: Clutter.Escape });
 | 
			
		||||
        this._continueButton = this.addButton({ label: '',
 | 
			
		||||
                                                action: this._onContinueButton.bind(this),
 | 
			
		||||
                                                action: Lang.bind(this, this._onContinueButton),
 | 
			
		||||
                                                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(working) {
 | 
			
		||||
    _setWorking: function(working) {
 | 
			
		||||
        if (!this._workSpinner)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -84,7 +84,7 @@ var KeyringDialog = new Lang.Class({
 | 
			
		||||
                               time: WORK_SPINNER_ANIMATION_TIME,
 | 
			
		||||
                               transition: 'linear',
 | 
			
		||||
                               onCompleteScope: this,
 | 
			
		||||
                               onComplete() {
 | 
			
		||||
                               onComplete: function() {
 | 
			
		||||
                                   if (this._workSpinner)
 | 
			
		||||
                                       this._workSpinner.stop();
 | 
			
		||||
                               }
 | 
			
		||||
@@ -92,7 +92,7 @@ var KeyringDialog = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _buildControlTable() {
 | 
			
		||||
    _buildControlTable: function() {
 | 
			
		||||
        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', this._onPasswordActivate.bind(this));
 | 
			
		||||
            this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onPasswordActivate));
 | 
			
		||||
 | 
			
		||||
            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', this._onConfirmActivate.bind(this));
 | 
			
		||||
            this._confirmEntry.clutter_text.connect('activate', Lang.bind(this, this._onConfirmActivate));
 | 
			
		||||
            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(sensitive) {
 | 
			
		||||
    _updateSensitivity: function(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() {
 | 
			
		||||
    _ensureOpen: function() {
 | 
			
		||||
        // 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(prompt) {
 | 
			
		||||
    _onShowPassword: function(prompt) {
 | 
			
		||||
        this._buildControlTable();
 | 
			
		||||
        this._ensureOpen();
 | 
			
		||||
        this._updateSensitivity(true);
 | 
			
		||||
        this._passwordEntry.grab_key_focus();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onShowConfirm(prompt) {
 | 
			
		||||
    _onShowConfirm: function(prompt) {
 | 
			
		||||
        this._buildControlTable();
 | 
			
		||||
        this._ensureOpen();
 | 
			
		||||
        this._updateSensitivity(true);
 | 
			
		||||
        this._continueButton.grab_key_focus();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onHidePrompt(prompt) {
 | 
			
		||||
    _onHidePrompt: function(prompt) {
 | 
			
		||||
        this.close();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onPasswordActivate() {
 | 
			
		||||
    _onPasswordActivate: function() {
 | 
			
		||||
        if (this.prompt.confirm_visible)
 | 
			
		||||
            this._confirmEntry.grab_key_focus();
 | 
			
		||||
        else
 | 
			
		||||
            this._onContinueButton();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onConfirmActivate() {
 | 
			
		||||
    _onConfirmActivate: function() {
 | 
			
		||||
        this._onContinueButton();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onContinueButton() {
 | 
			
		||||
    _onContinueButton: function() {
 | 
			
		||||
        this._updateSensitivity(false);
 | 
			
		||||
        this.prompt.complete();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onCancelButton() {
 | 
			
		||||
    _onCancelButton: function() {
 | 
			
		||||
        this.prompt.cancel();
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
@@ -261,13 +261,15 @@ var KeyringDialog = new Lang.Class({
 | 
			
		||||
var KeyringDummyDialog = new Lang.Class({
 | 
			
		||||
    Name: 'KeyringDummyDialog',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.prompt = new Shell.KeyringPrompt();
 | 
			
		||||
        this.prompt.connect('show-password', this._cancelPrompt.bind(this));
 | 
			
		||||
        this.prompt.connect('show-confirm', this._cancelPrompt.bind(this));
 | 
			
		||||
        this.prompt.connect('show-password',
 | 
			
		||||
                            Lang.bind(this, this._cancelPrompt));
 | 
			
		||||
        this.prompt.connect('show-confirm', Lang.bind(this,
 | 
			
		||||
                            this._cancelPrompt));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _cancelPrompt() {
 | 
			
		||||
    _cancelPrompt: function() {
 | 
			
		||||
        this.prompt.cancel();
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -275,21 +277,22 @@ var KeyringDummyDialog = new Lang.Class({
 | 
			
		||||
var KeyringPrompter = new Lang.Class({
 | 
			
		||||
    Name: 'KeyringPrompter',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._prompter = new Gcr.SystemPrompter();
 | 
			
		||||
        this._prompter.connect('new-prompt', () => {
 | 
			
		||||
            let dialog = this._enabled ? new KeyringDialog()
 | 
			
		||||
                                       : new KeyringDummyDialog();
 | 
			
		||||
            this._currentPrompt = dialog.prompt;
 | 
			
		||||
            return this._currentPrompt;
 | 
			
		||||
        });
 | 
			
		||||
        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._dbusId = null;
 | 
			
		||||
        this._registered = false;
 | 
			
		||||
        this._enabled = false;
 | 
			
		||||
        this._currentPrompt = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    enable() {
 | 
			
		||||
    enable: function() {
 | 
			
		||||
        if (!this._registered) {
 | 
			
		||||
            this._prompter.register(Gio.DBus.session);
 | 
			
		||||
            this._dbusId = Gio.DBus.session.own_name('org.gnome.keyring.SystemPrompter',
 | 
			
		||||
@@ -299,7 +302,7 @@ var KeyringPrompter = new Lang.Class({
 | 
			
		||||
        this._enabled = true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    disable() {
 | 
			
		||||
    disable: function() {
 | 
			
		||||
        this._enabled = false;
 | 
			
		||||
 | 
			
		||||
        if (this._prompter.prompting)
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ var NetworkSecretDialog = new Lang.Class({
 | 
			
		||||
    Name: 'NetworkSecretDialog',
 | 
			
		||||
    Extends: ModalDialog.ModalDialog,
 | 
			
		||||
 | 
			
		||||
    _init(agent, requestId, connection, settingName, hints, contentOverride) {
 | 
			
		||||
    _init: function(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', this._onOk.bind(this));
 | 
			
		||||
                secret.entry.clutter_text.connect('text-changed', () => {
 | 
			
		||||
                secret.entry.clutter_text.connect('activate', Lang.bind(this, this._onOk));
 | 
			
		||||
                secret.entry.clutter_text.connect('text-changed', Lang.bind(this, function() {
 | 
			
		||||
                    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: this._onOk.bind(this),
 | 
			
		||||
                           action: Lang.bind(this, this._onOk),
 | 
			
		||||
                           default: true
 | 
			
		||||
                         };
 | 
			
		||||
 | 
			
		||||
        this.setButtons([{ label: _("Cancel"),
 | 
			
		||||
                           action: this.cancel.bind(this),
 | 
			
		||||
                           action: Lang.bind(this, this.cancel),
 | 
			
		||||
                           key:    Clutter.KEY_Escape,
 | 
			
		||||
                         },
 | 
			
		||||
                         this._okButton]);
 | 
			
		||||
@@ -123,7 +123,7 @@ var NetworkSecretDialog = new Lang.Class({
 | 
			
		||||
        this._updateOkButton();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateOkButton() {
 | 
			
		||||
    _updateOkButton: function() {
 | 
			
		||||
        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() {
 | 
			
		||||
    _onOk: function() {
 | 
			
		||||
        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() {
 | 
			
		||||
    cancel: function() {
 | 
			
		||||
        this._agent.respond(this._requestId, Shell.NetworkAgentResponse.USER_CANCELED);
 | 
			
		||||
        this.close(global.get_current_time());
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _validateWpaPsk(secret) {
 | 
			
		||||
    _validateWpaPsk: function(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(secret) {
 | 
			
		||||
    _validateStaticWep: function(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(secrets, wirelessSetting) {
 | 
			
		||||
    _getWirelessSecrets: function(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(secrets) {
 | 
			
		||||
    _get8021xSecrets: function(secrets) {
 | 
			
		||||
        let ieee8021xSetting = this._connection.get_setting_802_1x();
 | 
			
		||||
        let phase2method;
 | 
			
		||||
 | 
			
		||||
@@ -256,7 +256,7 @@ var NetworkSecretDialog = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getPPPoESecrets(secrets) {
 | 
			
		||||
    _getPPPoESecrets: function(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(secrets, connectionType) {
 | 
			
		||||
    _getMobileSecrets: function(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() {
 | 
			
		||||
    _getContent: function() {
 | 
			
		||||
        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(agent, requestId, authHelper, serviceType, connection, hints, flags) {
 | 
			
		||||
    _init: function(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,
 | 
			
		||||
                                                    this._vpnChildFinished.bind(this));
 | 
			
		||||
                                                    Lang.bind(this, this._vpnChildFinished));
 | 
			
		||||
 | 
			
		||||
            this._writeConnection();
 | 
			
		||||
        } catch(e) {
 | 
			
		||||
@@ -394,7 +394,7 @@ var VPNRequestHandler = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    cancel(respond) {
 | 
			
		||||
    cancel: function(respond) {
 | 
			
		||||
        if (respond)
 | 
			
		||||
            this._agent.respond(this._requestId, Shell.NetworkAgentResponse.USER_CANCELED);
 | 
			
		||||
 | 
			
		||||
@@ -410,7 +410,7 @@ var VPNRequestHandler = new Lang.Class({
 | 
			
		||||
        this.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
    destroy: function() {
 | 
			
		||||
        if (this._destroyed)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -424,7 +424,7 @@ var VPNRequestHandler = new Lang.Class({
 | 
			
		||||
        this._destroyed = true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _vpnChildFinished(pid, status, requestObj) {
 | 
			
		||||
    _vpnChildFinished: function(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(line) {
 | 
			
		||||
    _vpnChildProcessLineOldStyle: function(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() {
 | 
			
		||||
        this._dataStdout.read_line_async(GLib.PRIORITY_DEFAULT, null, (stream, result) => {
 | 
			
		||||
    _readStdoutOldStyle: function() {
 | 
			
		||||
        this._dataStdout.read_line_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(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() {
 | 
			
		||||
        this._dataStdout.fill_async(-1, GLib.PRIORITY_DEFAULT, null, (stream, result) => {
 | 
			
		||||
    _readStdoutNewStyle: function() {
 | 
			
		||||
        this._dataStdout.fill_async(-1, GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(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() {
 | 
			
		||||
    _showNewStyleDialog: function() {
 | 
			
		||||
        let keyfile = new GLib.KeyFile();
 | 
			
		||||
        let data;
 | 
			
		||||
        let contentOverride;
 | 
			
		||||
@@ -558,18 +558,18 @@ var VPNRequestHandler = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _writeConnection() {
 | 
			
		||||
    _writeConnection: function() {
 | 
			
		||||
        let vpnSetting = this._connection.get_setting_vpn();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            vpnSetting.foreach_data_item((key, value) => {
 | 
			
		||||
            vpnSetting.foreach_data_item(Lang.bind(this, function(key, value) {
 | 
			
		||||
                this._stdin.write('DATA_KEY=' + key + '\n', null);
 | 
			
		||||
                this._stdin.write('DATA_VAL=' + (value || '') + '\n\n', null);
 | 
			
		||||
            });
 | 
			
		||||
            vpnSetting.foreach_secret((key, value) => {
 | 
			
		||||
            }));
 | 
			
		||||
            vpnSetting.foreach_secret(Lang.bind(this, function(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 +584,7 @@ Signals.addSignalMethods(VPNRequestHandler.prototype);
 | 
			
		||||
var NetworkAgent = new Lang.Class({
 | 
			
		||||
    Name: 'NetworkAgent',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent',
 | 
			
		||||
                                                capabilities: NM.SecretAgentCapabilities.VPN_HINTS,
 | 
			
		||||
                                                auto_register: false
 | 
			
		||||
@@ -602,31 +602,26 @@ var NetworkAgent = new Lang.Class({
 | 
			
		||||
            log('Failed to create monitor for VPN plugin dir: ' + e.message);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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');
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        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');
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    enable() {
 | 
			
		||||
    enable: function() {
 | 
			
		||||
        if (!this._native)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._native.auto_register = true;
 | 
			
		||||
        if (this._initialized && !this._native.registered)
 | 
			
		||||
        if (!this._native.registered)
 | 
			
		||||
            this._native.register_async(null, null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    disable() {
 | 
			
		||||
    disable: function() {
 | 
			
		||||
        let requestId;
 | 
			
		||||
 | 
			
		||||
        for (requestId in this._dialogs)
 | 
			
		||||
@@ -645,11 +640,11 @@ var NetworkAgent = new Lang.Class({
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._native.auto_register = false;
 | 
			
		||||
        if (this._initialized && this._native.registered)
 | 
			
		||||
        if (this._native.registered)
 | 
			
		||||
            this._native.unregister_async(null, null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _showNotification(requestId, connection, settingName, hints, flags) {
 | 
			
		||||
    _showNotification: function(requestId, connection, settingName, hints, flags) {
 | 
			
		||||
        let source = new MessageTray.Source(_("Network Manager"), 'network-transmit-receive');
 | 
			
		||||
        source.policy = new MessageTray.NotificationApplicationPolicy('gnome-network-panel');
 | 
			
		||||
 | 
			
		||||
@@ -660,7 +655,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().get_data());
 | 
			
		||||
            let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid());
 | 
			
		||||
            title = _("Authentication required by wireless network");
 | 
			
		||||
            body = _("Passwords or encryption keys are required to access the wireless network “%s”.").format(ssid);
 | 
			
		||||
            break;
 | 
			
		||||
@@ -693,44 +688,44 @@ var NetworkAgent = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        let notification = new MessageTray.Notification(source, title, body);
 | 
			
		||||
 | 
			
		||||
        notification.connect('activated', () => {
 | 
			
		||||
        notification.connect('activated', Lang.bind(this, function() {
 | 
			
		||||
            notification.answered = true;
 | 
			
		||||
            this._handleRequest(requestId, connection, settingName, hints, flags);
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._notifications[requestId] = notification;
 | 
			
		||||
        notification.connect('destroy', () => {
 | 
			
		||||
        notification.connect('destroy', Lang.bind(this, function() {
 | 
			
		||||
            if (!notification.answered)
 | 
			
		||||
                this._native.respond(requestId, Shell.NetworkAgentResponse.USER_CANCELED);
 | 
			
		||||
            delete this._notifications[requestId];
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        Main.messageTray.add(source);
 | 
			
		||||
        source.notify(notification);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _newRequest(agent, requestId, connection, settingName, hints, flags) {
 | 
			
		||||
    _newRequest:  function(agent, requestId, connection, settingName, hints, flags) {
 | 
			
		||||
        if (!(flags & NM.SecretAgentGetSecretsFlags.USER_REQUESTED))
 | 
			
		||||
            this._showNotification(requestId, connection, settingName, hints, flags);
 | 
			
		||||
        else
 | 
			
		||||
            this._handleRequest(requestId, connection, settingName, hints, flags);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _handleRequest(requestId, connection, settingName, hints, flags) {
 | 
			
		||||
    _handleRequest: function(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', () => {
 | 
			
		||||
        dialog.connect('destroy', Lang.bind(this, function() {
 | 
			
		||||
            delete this._dialogs[requestId];
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
        this._dialogs[requestId] = dialog;
 | 
			
		||||
        dialog.open(global.get_current_time());
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _cancelRequest(agent, requestId) {
 | 
			
		||||
    _cancelRequest: function(agent, requestId) {
 | 
			
		||||
        if (this._dialogs[requestId]) {
 | 
			
		||||
            this._dialogs[requestId].close(global.get_current_time());
 | 
			
		||||
            this._dialogs[requestId].destroy();
 | 
			
		||||
@@ -741,7 +736,7 @@ var NetworkAgent = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _vpnRequest(requestId, connection, hints, flags) {
 | 
			
		||||
    _vpnRequest: function(requestId, connection, hints, flags) {
 | 
			
		||||
        let vpnSetting = connection.get_setting_vpn();
 | 
			
		||||
        let serviceType = vpnSetting.service_type;
 | 
			
		||||
 | 
			
		||||
@@ -757,42 +752,70 @@ var NetworkAgent = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let vpnRequest = new VPNRequestHandler(this._native, requestId, binary, serviceType, connection, hints, flags);
 | 
			
		||||
        vpnRequest.connect('destroy', () => {
 | 
			
		||||
        vpnRequest.connect('destroy', Lang.bind(this, function() {
 | 
			
		||||
            delete this._vpnRequests[requestId];
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
        this._vpnRequests[requestId] = vpnRequest;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _buildVPNServiceCache() {
 | 
			
		||||
    _buildVPNServiceCache: function() {
 | 
			
		||||
        if (this._vpnCacheBuilt)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._vpnCacheBuilt = true;
 | 
			
		||||
        this._vpnBinaries = { };
 | 
			
		||||
 | 
			
		||||
        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;
 | 
			
		||||
        try {
 | 
			
		||||
            let fileEnum = this._pluginDir.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null);
 | 
			
		||||
            let info;
 | 
			
		||||
 | 
			
		||||
            let prop = plugin.lookup_property('GNOME', 'supports-external-ui-mode');
 | 
			
		||||
            if (prop) {
 | 
			
		||||
                prop = prop.trim().toLowerCase();
 | 
			
		||||
                externalUIMode = ['true', 'yes', 'on', '1'].includes(prop);
 | 
			
		||||
            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;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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));
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        } catch(e) {
 | 
			
		||||
            logError(e, 'error while enumerating VPN auth helpers');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
var Component = NetworkAgent;
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,6 @@ const PolkitAgent = imports.gi.PolkitAgent;
 | 
			
		||||
const Animation = imports.ui.animation;
 | 
			
		||||
const Components = imports.ui.components;
 | 
			
		||||
const Dialog = imports.ui.dialog;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const ModalDialog = imports.ui.modalDialog;
 | 
			
		||||
const ShellEntry = imports.ui.shellEntry;
 | 
			
		||||
const UserWidget = imports.ui.userWidget;
 | 
			
		||||
@@ -32,7 +31,7 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
    Name: 'AuthenticationDialog',
 | 
			
		||||
    Extends: ModalDialog.ModalDialog,
 | 
			
		||||
 | 
			
		||||
    _init(actionId, body, cookie, userNames) {
 | 
			
		||||
    _init: function(actionId, body, cookie, userNames) {
 | 
			
		||||
        this.parent({ styleClass: 'prompt-dialog' });
 | 
			
		||||
 | 
			
		||||
        this.actionId = actionId;
 | 
			
		||||
@@ -40,10 +39,6 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
        this.userNames = userNames;
 | 
			
		||||
        this._wasDismissed = false;
 | 
			
		||||
 | 
			
		||||
        this._sessionUpdatedId = Main.sessionMode.connect('updated', () => {
 | 
			
		||||
            this._group.visible = !Main.sessionMode.isLocked;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let icon = new Gio.ThemedIcon({ name: 'dialog-password-symbolic' });
 | 
			
		||||
        let title = _("Authentication Required");
 | 
			
		||||
 | 
			
		||||
@@ -65,9 +60,9 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
        this._user = AccountsService.UserManager.get_default().get_user(userName);
 | 
			
		||||
        let userRealName = this._user.get_real_name()
 | 
			
		||||
        this._userLoadedId = this._user.connect('notify::is_loaded',
 | 
			
		||||
                                                this._onUserChanged.bind(this));
 | 
			
		||||
                                                Lang.bind(this, this._onUserChanged));
 | 
			
		||||
        this._userChangedId = this._user.connect('changed',
 | 
			
		||||
                                                 this._onUserChanged.bind(this));
 | 
			
		||||
                                                 Lang.bind(this, this._onUserChanged));
 | 
			
		||||
 | 
			
		||||
        // Special case 'root'
 | 
			
		||||
        let userIsRoot = false;
 | 
			
		||||
@@ -113,7 +108,7 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
                                             text: "",
 | 
			
		||||
                                             can_focus: true});
 | 
			
		||||
        ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true });
 | 
			
		||||
        this._passwordEntry.clutter_text.connect('activate', this._onEntryActivate.bind(this));
 | 
			
		||||
        this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivate));
 | 
			
		||||
        this._passwordBox.add(this._passwordEntry,
 | 
			
		||||
                              { expand: true });
 | 
			
		||||
 | 
			
		||||
@@ -151,10 +146,10 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
        this._nullMessageLabel.show();
 | 
			
		||||
 | 
			
		||||
        this._cancelButton = this.addButton({ label: _("Cancel"),
 | 
			
		||||
                                              action: this.cancel.bind(this),
 | 
			
		||||
                                              action: Lang.bind(this, this.cancel),
 | 
			
		||||
                                              key: Clutter.Escape });
 | 
			
		||||
        this._okButton = this.addButton({ label:  _("Authenticate"),
 | 
			
		||||
                                          action: this._onAuthenticateButtonPressed.bind(this),
 | 
			
		||||
                                          action: Lang.bind(this, this._onAuthenticateButtonPressed),
 | 
			
		||||
                                          default: true });
 | 
			
		||||
 | 
			
		||||
        this._doneEmitted = false;
 | 
			
		||||
@@ -163,7 +158,7 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
        this._cookie = cookie;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setWorking(working) {
 | 
			
		||||
    _setWorking: function(working) {
 | 
			
		||||
        Tweener.removeTweens(this._workSpinner.actor);
 | 
			
		||||
        if (working) {
 | 
			
		||||
            this._workSpinner.play();
 | 
			
		||||
@@ -179,7 +174,7 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
                               time: WORK_SPINNER_ANIMATION_TIME,
 | 
			
		||||
                               transition: 'linear',
 | 
			
		||||
                               onCompleteScope: this,
 | 
			
		||||
                               onComplete() {
 | 
			
		||||
                               onComplete: function() {
 | 
			
		||||
                                   if (this._workSpinner)
 | 
			
		||||
                                       this._workSpinner.stop();
 | 
			
		||||
                               }
 | 
			
		||||
@@ -187,26 +182,18 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    performAuthentication() {
 | 
			
		||||
    performAuthentication: function() {
 | 
			
		||||
        this.destroySession();
 | 
			
		||||
        this._session = new PolkitAgent.Session({ identity: this._identityToAuth,
 | 
			
		||||
                                                  cookie: this._cookie });
 | 
			
		||||
        this._session.connect('completed', this._onSessionCompleted.bind(this));
 | 
			
		||||
        this._session.connect('request', this._onSessionRequest.bind(this));
 | 
			
		||||
        this._session.connect('show-error', this._onSessionShowError.bind(this));
 | 
			
		||||
        this._session.connect('show-info', this._onSessionShowInfo.bind(this));
 | 
			
		||||
        this._session.connect('completed', Lang.bind(this, this._onSessionCompleted));
 | 
			
		||||
        this._session.connect('request', Lang.bind(this, this._onSessionRequest));
 | 
			
		||||
        this._session.connect('show-error', Lang.bind(this, this._onSessionShowError));
 | 
			
		||||
        this._session.connect('show-info', Lang.bind(this, this._onSessionShowInfo));
 | 
			
		||||
        this._session.initiate();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    close(timestamp) {
 | 
			
		||||
        this.parent(timestamp);
 | 
			
		||||
 | 
			
		||||
        if (this._sessionUpdatedId)
 | 
			
		||||
            Main.sessionMode.disconnect(this._sessionUpdatedId);
 | 
			
		||||
        this._sessionUpdatedId = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _ensureOpen() {
 | 
			
		||||
    _ensureOpen: function() {
 | 
			
		||||
        // NOTE: ModalDialog.open() is safe to call if the dialog is
 | 
			
		||||
        // already open - it just returns true without side-effects
 | 
			
		||||
        if (!this.open(global.get_current_time())) {
 | 
			
		||||
@@ -228,14 +215,14 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _emitDone(dismissed) {
 | 
			
		||||
    _emitDone: function(dismissed) {
 | 
			
		||||
        if (!this._doneEmitted) {
 | 
			
		||||
            this._doneEmitted = true;
 | 
			
		||||
            this.emit('done', dismissed);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateSensitivity(sensitive) {
 | 
			
		||||
    _updateSensitivity: function(sensitive) {
 | 
			
		||||
        this._passwordEntry.reactive = sensitive;
 | 
			
		||||
        this._passwordEntry.clutter_text.editable = sensitive;
 | 
			
		||||
 | 
			
		||||
@@ -244,7 +231,7 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
        this._setWorking(!sensitive);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onEntryActivate() {
 | 
			
		||||
    _onEntryActivate: function() {
 | 
			
		||||
        let response = this._passwordEntry.get_text();
 | 
			
		||||
        this._updateSensitivity(false);
 | 
			
		||||
        this._session.response(response);
 | 
			
		||||
@@ -255,11 +242,11 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
        this._nullMessageLabel.show();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onAuthenticateButtonPressed() {
 | 
			
		||||
    _onAuthenticateButtonPressed: function() {
 | 
			
		||||
        this._onEntryActivate();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSessionCompleted(session, gainedAuthorization) {
 | 
			
		||||
    _onSessionCompleted: function(session, gainedAuthorization) {
 | 
			
		||||
        if (this._completed || this._doneEmitted)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -291,7 +278,7 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSessionRequest(session, request, echo_on) {
 | 
			
		||||
    _onSessionRequest: function(session, request, echo_on) {
 | 
			
		||||
        // Cheap localization trick
 | 
			
		||||
        if (request == 'Password:' || request == 'Password: ')
 | 
			
		||||
            this._passwordLabel.set_text(_("Password:"));
 | 
			
		||||
@@ -310,7 +297,7 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
        this._ensureOpen();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSessionShowError(session, text) {
 | 
			
		||||
    _onSessionShowError: function(session, text) {
 | 
			
		||||
        this._passwordEntry.set_text('');
 | 
			
		||||
        this._errorMessageLabel.set_text(text);
 | 
			
		||||
        this._errorMessageLabel.show();
 | 
			
		||||
@@ -319,7 +306,7 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
        this._ensureOpen();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSessionShowInfo(session, text) {
 | 
			
		||||
    _onSessionShowInfo: function(session, text) {
 | 
			
		||||
        this._passwordEntry.set_text('');
 | 
			
		||||
        this._infoMessageLabel.set_text(text);
 | 
			
		||||
        this._infoMessageLabel.show();
 | 
			
		||||
@@ -328,7 +315,7 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
        this._ensureOpen();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroySession() {
 | 
			
		||||
    destroySession: function() {
 | 
			
		||||
        if (this._session) {
 | 
			
		||||
            if (!this._completed)
 | 
			
		||||
                this._session.cancel();
 | 
			
		||||
@@ -337,14 +324,14 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onUserChanged() {
 | 
			
		||||
    _onUserChanged: function() {
 | 
			
		||||
        if (this._user.is_loaded && this._userAvatar) {
 | 
			
		||||
            this._userAvatar.update();
 | 
			
		||||
            this._userAvatar.actor.show();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    cancel() {
 | 
			
		||||
    cancel: function() {
 | 
			
		||||
        this._wasDismissed = true;
 | 
			
		||||
        this.close(global.get_current_time());
 | 
			
		||||
        this._emitDone(true);
 | 
			
		||||
@@ -355,16 +342,15 @@ Signals.addSignalMethods(AuthenticationDialog.prototype);
 | 
			
		||||
var AuthenticationAgent = new Lang.Class({
 | 
			
		||||
    Name: 'AuthenticationAgent',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._currentDialog = null;
 | 
			
		||||
        this._handle = null;
 | 
			
		||||
        this._native = new Shell.PolkitAuthenticationAgent();
 | 
			
		||||
        this._native.connect('initiate', this._onInitiate.bind(this));
 | 
			
		||||
        this._native.connect('cancel', this._onCancel.bind(this));
 | 
			
		||||
        this._sessionUpdatedId = 0;
 | 
			
		||||
        this._native.connect('initiate', Lang.bind(this, this._onInitiate));
 | 
			
		||||
        this._native.connect('cancel', Lang.bind(this, this._onCancel));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    enable() {
 | 
			
		||||
    enable: function() {
 | 
			
		||||
        try {
 | 
			
		||||
            this._native.register();
 | 
			
		||||
        } catch(e) {
 | 
			
		||||
@@ -372,7 +358,7 @@ var AuthenticationAgent = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    disable() {
 | 
			
		||||
    disable: function() {
 | 
			
		||||
        try {
 | 
			
		||||
            this._native.unregister();
 | 
			
		||||
        } catch(e) {
 | 
			
		||||
@@ -380,18 +366,7 @@ var AuthenticationAgent = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onInitiate(nativeAgent, actionId, message, iconName, cookie, userNames) {
 | 
			
		||||
        // Don't pop up a dialog while locked
 | 
			
		||||
        if (Main.sessionMode.isLocked) {
 | 
			
		||||
            this._sessionUpdatedId = Main.sessionMode.connect('updated', () => {
 | 
			
		||||
                Main.sessionMode.disconnect(this._sessionUpdatedId);
 | 
			
		||||
                this._sessionUpdatedId = 0;
 | 
			
		||||
 | 
			
		||||
                this._onInitiate(nativeAgent, actionId, message, iconName, cookie, userNames);
 | 
			
		||||
            });
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    _onInitiate: function(nativeAgent, actionId, message, iconName, cookie, userNames) {
 | 
			
		||||
        this._currentDialog = new AuthenticationDialog(actionId, message, cookie, userNames);
 | 
			
		||||
 | 
			
		||||
        // We actually don't want to open the dialog until we know for
 | 
			
		||||
@@ -404,27 +379,23 @@ var AuthenticationAgent = new Lang.Class({
 | 
			
		||||
        // See https://bugzilla.gnome.org/show_bug.cgi?id=643062 for more
 | 
			
		||||
        // discussion.
 | 
			
		||||
 | 
			
		||||
        this._currentDialog.connect('done', this._onDialogDone.bind(this));
 | 
			
		||||
        this._currentDialog.connect('done', Lang.bind(this, this._onDialogDone));
 | 
			
		||||
        this._currentDialog.performAuthentication();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onCancel(nativeAgent) {
 | 
			
		||||
    _onCancel: function(nativeAgent) {
 | 
			
		||||
        this._completeRequest(false);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDialogDone(dialog, dismissed) {
 | 
			
		||||
    _onDialogDone: function(dialog, dismissed) {
 | 
			
		||||
        this._completeRequest(dismissed);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _completeRequest(dismissed) {
 | 
			
		||||
    _completeRequest: function(dismissed) {
 | 
			
		||||
        this._currentDialog.close();
 | 
			
		||||
        this._currentDialog.destroySession();
 | 
			
		||||
        this._currentDialog = null;
 | 
			
		||||
 | 
			
		||||
        if (this._sessionUpdatedId)
 | 
			
		||||
            Main.sessionMode.disconnect(this._sessionUpdatedId);
 | 
			
		||||
        this._sessionUpdatedId = 0;
 | 
			
		||||
 | 
			
		||||
        this._native.complete(dismissed);
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@ var NotificationDirection = {
 | 
			
		||||
    RECEIVED: 'chat-received'
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var N_ = s => s;
 | 
			
		||||
var N_ = function(s) { return s; };
 | 
			
		||||
 | 
			
		||||
function makeMessageFromTpMessage(tpMessage, direction) {
 | 
			
		||||
    let [text, flags] = tpMessage.to_text();
 | 
			
		||||
@@ -82,7 +82,7 @@ function makeMessageFromTplEvent(event) {
 | 
			
		||||
var TelepathyComponent = new Lang.Class({
 | 
			
		||||
    Name: 'TelepathyComponent',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._client = null;
 | 
			
		||||
 | 
			
		||||
        if (!HAVE_TP)
 | 
			
		||||
@@ -91,7 +91,7 @@ var TelepathyComponent = new Lang.Class({
 | 
			
		||||
        this._client = new TelepathyClient();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    enable() {
 | 
			
		||||
    enable: function() {
 | 
			
		||||
        if (!this._client)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -105,7 +105,7 @@ var TelepathyComponent = new Lang.Class({
 | 
			
		||||
            this._client.account_manager.prepare_async(null, null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    disable() {
 | 
			
		||||
    disable: function() {
 | 
			
		||||
        if (!this._client)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -117,7 +117,7 @@ var TelepathyClient = HAVE_TP ? new Lang.Class({
 | 
			
		||||
    Name: 'TelepathyClient',
 | 
			
		||||
    Extends: Tp.BaseClient,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        // channel path -> ChatSource
 | 
			
		||||
        this._chatSources = {};
 | 
			
		||||
        this._chatState = Tp.ChannelChatState.ACTIVE;
 | 
			
		||||
@@ -157,10 +157,10 @@ var TelepathyClient = HAVE_TP ? new Lang.Class({
 | 
			
		||||
        // Allow other clients (such as Empathy) to pre-empt our channels if
 | 
			
		||||
        // needed
 | 
			
		||||
        this.set_delegated_channels_callback(
 | 
			
		||||
            this._delegatedChannelsCb.bind(this));
 | 
			
		||||
            Lang.bind(this, this._delegatedChannelsCb));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_observe_channels(account, conn, channels,
 | 
			
		||||
    vfunc_observe_channels: function(account, conn, channels,
 | 
			
		||||
                                     dispatchOp, requests, context) {
 | 
			
		||||
        let len = channels.length;
 | 
			
		||||
        for (let i = 0; i < len; i++) {
 | 
			
		||||
@@ -181,25 +181,26 @@ var TelepathyClient = HAVE_TP ? new Lang.Class({
 | 
			
		||||
        context.accept();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createChatSource(account, conn, channel, contact) {
 | 
			
		||||
    _createChatSource: function(account, conn, channel, contact) {
 | 
			
		||||
        if (this._chatSources[channel.get_object_path()])
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let source = new ChatSource(account, conn, channel, contact, this);
 | 
			
		||||
 | 
			
		||||
        this._chatSources[channel.get_object_path()] = source;
 | 
			
		||||
        source.connect('destroy', () => {
 | 
			
		||||
            delete this._chatSources[channel.get_object_path()];
 | 
			
		||||
        });
 | 
			
		||||
        source.connect('destroy', Lang.bind(this,
 | 
			
		||||
                       function() {
 | 
			
		||||
                           delete this._chatSources[channel.get_object_path()];
 | 
			
		||||
                       }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_handle_channels(account, conn, channels, requests,
 | 
			
		||||
    vfunc_handle_channels: function(account, conn, channels, requests,
 | 
			
		||||
                                    user_action_time, context) {
 | 
			
		||||
        this._handlingChannels(account, conn, channels, true);
 | 
			
		||||
        context.accept();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _handlingChannels(account, conn, channels, notify) {
 | 
			
		||||
    _handlingChannels: function(account, conn, channels, notify) {
 | 
			
		||||
        let len = channels.length;
 | 
			
		||||
        for (let i = 0; i < len; i++) {
 | 
			
		||||
            let channel = channels[i];
 | 
			
		||||
@@ -233,7 +234,7 @@ var TelepathyClient = HAVE_TP ? new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_add_dispatch_operation(account, conn, channels,
 | 
			
		||||
    vfunc_add_dispatch_operation: function(account, conn, channels,
 | 
			
		||||
                                           dispatchOp, context) {
 | 
			
		||||
        let channel = channels[0];
 | 
			
		||||
        let chanType = channel.get_channel_type();
 | 
			
		||||
@@ -251,7 +252,7 @@ var TelepathyClient = HAVE_TP ? new Lang.Class({
 | 
			
		||||
                                        message: 'Unsupported channel type' }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _approveTextChannel(account, conn, channel, dispatchOp, context) {
 | 
			
		||||
    _approveTextChannel: function(account, conn, channel, dispatchOp, context) {
 | 
			
		||||
        let [targetHandle, targetHandleType] = channel.get_handle();
 | 
			
		||||
 | 
			
		||||
        if (targetHandleType != Tp.HandleType.CONTACT) {
 | 
			
		||||
@@ -261,19 +262,19 @@ var TelepathyClient = HAVE_TP ? new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Approve private text channels right away as we are going to handle it
 | 
			
		||||
        dispatchOp.claim_with_async(this, (dispatchOp, result) => {
 | 
			
		||||
        dispatchOp.claim_with_async(this, Lang.bind(this, function(dispatchOp, result) {
 | 
			
		||||
            try {
 | 
			
		||||
                dispatchOp.claim_with_finish(result);
 | 
			
		||||
                this._handlingChannels(account, conn, [channel], false);
 | 
			
		||||
            } catch (err) {
 | 
			
		||||
                log('Failed to Claim channel: ' + err);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        context.accept();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _delegatedChannelsCb(client, channels) {
 | 
			
		||||
    _delegatedChannelsCb: function(client, channels) {
 | 
			
		||||
        // Nothing to do as we don't make a distinction between observed and
 | 
			
		||||
        // handled channels.
 | 
			
		||||
    },
 | 
			
		||||
@@ -283,7 +284,7 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
    Name: 'ChatSource',
 | 
			
		||||
    Extends: MessageTray.Source,
 | 
			
		||||
 | 
			
		||||
    _init(account, conn, channel, contact, client) {
 | 
			
		||||
    _init: function(account, conn, channel, contact, client) {
 | 
			
		||||
        this._account = account;
 | 
			
		||||
        this._contact = contact;
 | 
			
		||||
        this._client = client;
 | 
			
		||||
@@ -295,19 +296,19 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._conn = conn;
 | 
			
		||||
        this._channel = channel;
 | 
			
		||||
        this._closedId = this._channel.connect('invalidated', this._channelClosed.bind(this));
 | 
			
		||||
        this._closedId = this._channel.connect('invalidated', Lang.bind(this, this._channelClosed));
 | 
			
		||||
 | 
			
		||||
        this._notifyTimeoutId = 0;
 | 
			
		||||
 | 
			
		||||
        this._presence = contact.get_presence_type();
 | 
			
		||||
 | 
			
		||||
        this._sentId = this._channel.connect('message-sent', this._messageSent.bind(this));
 | 
			
		||||
        this._receivedId = this._channel.connect('message-received', this._messageReceived.bind(this));
 | 
			
		||||
        this._pendingId = this._channel.connect('pending-message-removed', this._pendingRemoved.bind(this));
 | 
			
		||||
        this._sentId = this._channel.connect('message-sent', Lang.bind(this, this._messageSent));
 | 
			
		||||
        this._receivedId = this._channel.connect('message-received', Lang.bind(this, this._messageReceived));
 | 
			
		||||
        this._pendingId = this._channel.connect('pending-message-removed', Lang.bind(this, this._pendingRemoved));
 | 
			
		||||
 | 
			
		||||
        this._notifyAliasId = this._contact.connect('notify::alias', this._updateAlias.bind(this));
 | 
			
		||||
        this._notifyAvatarId = this._contact.connect('notify::avatar-file', this._updateAvatarIcon.bind(this));
 | 
			
		||||
        this._presenceChangedId = this._contact.connect('presence-changed', this._presenceChanged.bind(this));
 | 
			
		||||
        this._notifyAliasId = this._contact.connect('notify::alias', Lang.bind(this, this._updateAlias));
 | 
			
		||||
        this._notifyAvatarId = this._contact.connect('notify::avatar-file', Lang.bind(this, this._updateAvatarIcon));
 | 
			
		||||
        this._presenceChangedId = this._contact.connect('presence-changed', Lang.bind(this, this._presenceChanged));
 | 
			
		||||
 | 
			
		||||
        // Add ourselves as a source.
 | 
			
		||||
        Main.messageTray.add(this);
 | 
			
		||||
@@ -315,42 +316,45 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
        this._getLogMessages();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _ensureNotification() {
 | 
			
		||||
    _ensureNotification: function() {
 | 
			
		||||
        if (this._notification)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._notification = new ChatNotification(this);
 | 
			
		||||
        this._notification.connect('activated', this.open.bind(this));
 | 
			
		||||
        this._notification.connect('updated', () => {
 | 
			
		||||
            if (this._banner && this._banner.expanded)
 | 
			
		||||
                this._ackMessages();
 | 
			
		||||
        });
 | 
			
		||||
        this._notification.connect('destroy', () => {
 | 
			
		||||
            this._notification = null;
 | 
			
		||||
        });
 | 
			
		||||
        this._notification.connect('activated', Lang.bind(this, this.open));
 | 
			
		||||
        this._notification.connect('updated', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                if (this._banner && this._banner.expanded)
 | 
			
		||||
                    this._ackMessages();
 | 
			
		||||
            }));
 | 
			
		||||
        this._notification.connect('destroy', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                this._notification = null;
 | 
			
		||||
            }));
 | 
			
		||||
        this.pushNotification(this._notification);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createPolicy() {
 | 
			
		||||
    _createPolicy: function() {
 | 
			
		||||
        if (this._account.protocol_name == 'irc')
 | 
			
		||||
            return new MessageTray.NotificationApplicationPolicy('org.gnome.Polari');
 | 
			
		||||
        return new MessageTray.NotificationApplicationPolicy('empathy');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    createBanner() {
 | 
			
		||||
    createBanner: function() {
 | 
			
		||||
        this._banner = new ChatNotificationBanner(this._notification);
 | 
			
		||||
 | 
			
		||||
        // We ack messages when the user expands the new notification
 | 
			
		||||
        let id = this._banner.connect('expanded', this._ackMessages.bind(this));
 | 
			
		||||
        this._banner.actor.connect('destroy', () => {
 | 
			
		||||
            this._banner.disconnect(id);
 | 
			
		||||
            this._banner = null;
 | 
			
		||||
        });
 | 
			
		||||
        let id = this._banner.connect('expanded', Lang.bind(this, this._ackMessages));
 | 
			
		||||
        this._banner.actor.connect('destroy', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                this._banner.disconnect(id);
 | 
			
		||||
                this._banner = null;
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        return this._banner;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateAlias() {
 | 
			
		||||
    _updateAlias: function() {
 | 
			
		||||
        let oldAlias = this.title;
 | 
			
		||||
        let newAlias = this._contact.get_alias();
 | 
			
		||||
 | 
			
		||||
@@ -362,7 +366,7 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
            this._notification.appendAliasChange(oldAlias, newAlias);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getIcon() {
 | 
			
		||||
    getIcon: function() {
 | 
			
		||||
        let file = this._contact.get_avatar_file();
 | 
			
		||||
        if (file) {
 | 
			
		||||
            return new Gio.FileIcon({ file: file });
 | 
			
		||||
@@ -371,7 +375,7 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getSecondaryIcon() {
 | 
			
		||||
    getSecondaryIcon: function() {
 | 
			
		||||
        let iconName;
 | 
			
		||||
        let presenceType = this._contact.get_presence_type();
 | 
			
		||||
 | 
			
		||||
@@ -400,7 +404,7 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
       return new Gio.ThemedIcon({ name: iconName });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateAvatarIcon() {
 | 
			
		||||
    _updateAvatarIcon: function() {
 | 
			
		||||
        this.iconUpdated();
 | 
			
		||||
        if (this._notifiction)
 | 
			
		||||
            this._notification.update(this._notification.title,
 | 
			
		||||
@@ -408,7 +412,7 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
                                      { gicon: this.getIcon() });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    open() {
 | 
			
		||||
    open: function() {
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
        Main.panel.closeCalendar();
 | 
			
		||||
 | 
			
		||||
@@ -433,16 +437,16 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getLogMessages() {
 | 
			
		||||
    _getLogMessages: function() {
 | 
			
		||||
        let logManager = Tpl.LogManager.dup_singleton();
 | 
			
		||||
        let entity = Tpl.Entity.new_from_tp_contact(this._contact, Tpl.EntityType.CONTACT);
 | 
			
		||||
 | 
			
		||||
        logManager.get_filtered_events_async(this._account, entity,
 | 
			
		||||
                                             Tpl.EventTypeMask.TEXT, SCROLLBACK_HISTORY_LINES,
 | 
			
		||||
                                             null, this._displayPendingMessages.bind(this));
 | 
			
		||||
                                             null, Lang.bind(this, this._displayPendingMessages));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _displayPendingMessages(logManager, result) {
 | 
			
		||||
    _displayPendingMessages: function(logManager, result) {
 | 
			
		||||
        let [success, events] = logManager.get_filtered_events_finish(result);
 | 
			
		||||
 | 
			
		||||
        let logMessages = events.map(makeMessageFromTplEvent);
 | 
			
		||||
@@ -495,12 +499,12 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
            this.notify();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy(reason) {
 | 
			
		||||
    destroy: function(reason) {
 | 
			
		||||
        if (this._client.is_handling_channel(this._channel)) {
 | 
			
		||||
            this._ackMessages();
 | 
			
		||||
            // The chat box has been destroyed so it can't
 | 
			
		||||
            // handle the channel any more.
 | 
			
		||||
            this._channel.close_async((channel, result) => {
 | 
			
		||||
            this._channel.close_async(function(channel, result) {
 | 
			
		||||
                channel.close_finish(result);
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -530,7 +534,7 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
        this.parent(reason);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _channelClosed() {
 | 
			
		||||
    _channelClosed: function() {
 | 
			
		||||
        this.destroy(MessageTray.NotificationDestroyedReason.SOURCE_CLOSED);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -547,7 +551,7 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
        return this.count > 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _messageReceived(channel, message) {
 | 
			
		||||
    _messageReceived: function(channel, message) {
 | 
			
		||||
        if (message.get_message_type() == Tp.ChannelTextMessageType.DELIVERY_REPORT)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -563,11 +567,11 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
        if (this._notifyTimeoutId != 0)
 | 
			
		||||
            Mainloop.source_remove(this._notifyTimeoutId);
 | 
			
		||||
        this._notifyTimeoutId = Mainloop.timeout_add(500,
 | 
			
		||||
            this._notifyTimeout.bind(this));
 | 
			
		||||
            Lang.bind(this, this._notifyTimeout));
 | 
			
		||||
        GLib.Source.set_name_by_id(this._notifyTimeoutId, '[gnome-shell] this._notifyTimeout');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _notifyTimeout() {
 | 
			
		||||
    _notifyTimeout: function() {
 | 
			
		||||
        if (this._pendingMessages.length != 0)
 | 
			
		||||
            this.notify();
 | 
			
		||||
 | 
			
		||||
@@ -578,17 +582,17 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
    // This is called for both messages we send from
 | 
			
		||||
    // our client and other clients as well.
 | 
			
		||||
    _messageSent(channel, message, flags, token) {
 | 
			
		||||
    _messageSent: function(channel, message, flags, token) {
 | 
			
		||||
        this._ensureNotification();
 | 
			
		||||
        message = makeMessageFromTpMessage(message, NotificationDirection.SENT);
 | 
			
		||||
        this._notification.appendMessage(message);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    notify() {
 | 
			
		||||
    notify: function() {
 | 
			
		||||
        this.parent(this._notification);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    respond(text) {
 | 
			
		||||
    respond: function(text) {
 | 
			
		||||
        let type;
 | 
			
		||||
        if (text.slice(0, 4) == '/me ') {
 | 
			
		||||
            type = Tp.ChannelTextMessageType.ACTION;
 | 
			
		||||
@@ -598,12 +602,12 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let msg = Tp.ClientMessage.new_text(type, text);
 | 
			
		||||
        this._channel.send_message_async(msg, 0, (src, result) => {
 | 
			
		||||
        this._channel.send_message_async(msg, 0, Lang.bind(this, function (src, result) {
 | 
			
		||||
            this._channel.send_message_finish(result); 
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setChatState(state) {
 | 
			
		||||
    setChatState: function(state) {
 | 
			
		||||
        // We don't want to send COMPOSING every time a letter is typed into
 | 
			
		||||
        // the entry. We send the state only when it changes. Telepathy/Empathy
 | 
			
		||||
        // might change it behind our back if the user is using both
 | 
			
		||||
@@ -616,14 +620,14 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _presenceChanged(contact, presence, status, message) {
 | 
			
		||||
    _presenceChanged: function (contact, presence, status, message) {
 | 
			
		||||
        if (this._notification)
 | 
			
		||||
            this._notification.update(this._notification.title,
 | 
			
		||||
                                      this._notification.bannerBodyText,
 | 
			
		||||
                                      { secondaryGIcon: this.getSecondaryIcon() });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _pendingRemoved(channel, message) {
 | 
			
		||||
    _pendingRemoved: function(channel, message) {
 | 
			
		||||
        let idx = this._pendingMessages.indexOf(message);
 | 
			
		||||
 | 
			
		||||
        if (idx >= 0) {
 | 
			
		||||
@@ -636,7 +640,7 @@ var ChatSource = new Lang.Class({
 | 
			
		||||
            this._banner.hide();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _ackMessages() {
 | 
			
		||||
    _ackMessages: function() {
 | 
			
		||||
        // Don't clear our messages here, tp-glib will send a
 | 
			
		||||
        // 'pending-message-removed' for each one.
 | 
			
		||||
        this._channel.ack_all_pending_messages_async(null);
 | 
			
		||||
@@ -647,7 +651,7 @@ var ChatNotification = new Lang.Class({
 | 
			
		||||
    Name: 'ChatNotification',
 | 
			
		||||
    Extends: MessageTray.Notification,
 | 
			
		||||
 | 
			
		||||
    _init(source) {
 | 
			
		||||
    _init: function(source) {
 | 
			
		||||
        this.parent(source, source.title, null,
 | 
			
		||||
                    { secondaryGIcon: source.getSecondaryIcon() });
 | 
			
		||||
        this.setUrgency(MessageTray.Urgency.HIGH);
 | 
			
		||||
@@ -657,7 +661,7 @@ var ChatNotification = new Lang.Class({
 | 
			
		||||
        this._timestampTimeoutId = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy(reason) {
 | 
			
		||||
    destroy: function(reason) {
 | 
			
		||||
        if (this._timestampTimeoutId)
 | 
			
		||||
            Mainloop.source_remove(this._timestampTimeoutId);
 | 
			
		||||
        this._timestampTimeoutId = 0;
 | 
			
		||||
@@ -677,7 +681,7 @@ var ChatNotification = new Lang.Class({
 | 
			
		||||
     *   will be added, regardless of the difference since the
 | 
			
		||||
     *   last timestamp
 | 
			
		||||
     */
 | 
			
		||||
    appendMessage(message, noTimestamp) {
 | 
			
		||||
    appendMessage: function(message, noTimestamp) {
 | 
			
		||||
        let messageBody = GLib.markup_escape_text(message.text, -1);
 | 
			
		||||
        let styles = [message.direction];
 | 
			
		||||
 | 
			
		||||
@@ -702,7 +706,7 @@ var ChatNotification = new Lang.Class({
 | 
			
		||||
                       noTimestamp: noTimestamp });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _filterMessages() {
 | 
			
		||||
    _filterMessages: function() {
 | 
			
		||||
        if (this.messages.length < 1)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -718,7 +722,7 @@ var ChatNotification = new Lang.Class({
 | 
			
		||||
        let maxLength = (lastMessageTime < currentTime - SCROLLBACK_RECENT_TIME) ?
 | 
			
		||||
            SCROLLBACK_IDLE_LENGTH : SCROLLBACK_RECENT_LENGTH;
 | 
			
		||||
 | 
			
		||||
        let filteredHistory = this.messages.filter(item => item.realMessage);
 | 
			
		||||
        let filteredHistory = this.messages.filter(function(item) { return item.realMessage });
 | 
			
		||||
        if (filteredHistory.length > maxLength) {
 | 
			
		||||
            let lastMessageToKeep = filteredHistory[maxLength];
 | 
			
		||||
            let expired = this.messages.splice(this.messages.indexOf(lastMessageToKeep));
 | 
			
		||||
@@ -737,7 +741,7 @@ var ChatNotification = new Lang.Class({
 | 
			
		||||
     *  timestamp: The timestamp of the message.
 | 
			
		||||
     *  noTimestamp: suppress timestamp signal?
 | 
			
		||||
     */
 | 
			
		||||
    _append(props) {
 | 
			
		||||
    _append: function(props) {
 | 
			
		||||
        let currentTime = (Date.now() / 1000);
 | 
			
		||||
        props = Params.parse(props, { body: null,
 | 
			
		||||
                                      group: null,
 | 
			
		||||
@@ -767,7 +771,7 @@ var ChatNotification = new Lang.Class({
 | 
			
		||||
                // from the timestamp of the message.
 | 
			
		||||
                this._timestampTimeoutId = Mainloop.timeout_add_seconds(
 | 
			
		||||
                    SCROLLBACK_IMMEDIATE_TIME - (currentTime - timestamp),
 | 
			
		||||
                    this.appendTimestamp.bind(this));
 | 
			
		||||
                    Lang.bind(this, this.appendTimestamp));
 | 
			
		||||
                GLib.Source.set_name_by_id(this._timestampTimeoutId, '[gnome-shell] this.appendTimestamp');
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -775,7 +779,7 @@ var ChatNotification = new Lang.Class({
 | 
			
		||||
        this._filterMessages();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    appendTimestamp() {
 | 
			
		||||
    appendTimestamp: function() {
 | 
			
		||||
        this._timestampTimeoutId = 0;
 | 
			
		||||
 | 
			
		||||
        this.messages[0].showTimestamp = true;
 | 
			
		||||
@@ -786,7 +790,7 @@ var ChatNotification = new Lang.Class({
 | 
			
		||||
        return GLib.SOURCE_REMOVE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    appendAliasChange(oldAlias, newAlias) {
 | 
			
		||||
    appendAliasChange: function(oldAlias, newAlias) {
 | 
			
		||||
        oldAlias = GLib.markup_escape_text(oldAlias, -1);
 | 
			
		||||
        newAlias = GLib.markup_escape_text(newAlias, -1);
 | 
			
		||||
 | 
			
		||||
@@ -806,7 +810,7 @@ var ChatLineBox = new Lang.Class({
 | 
			
		||||
    Name: 'ChatLineBox',
 | 
			
		||||
    Extends: St.BoxLayout,
 | 
			
		||||
 | 
			
		||||
    vfunc_get_preferred_height(forWidth) {
 | 
			
		||||
    vfunc_get_preferred_height: function(forWidth) {
 | 
			
		||||
        let [, natHeight] = this.parent(forWidth);
 | 
			
		||||
        return [natHeight, natHeight];
 | 
			
		||||
    }
 | 
			
		||||
@@ -816,23 +820,23 @@ var ChatNotificationBanner = new Lang.Class({
 | 
			
		||||
    Name: 'ChatNotificationBanner',
 | 
			
		||||
    Extends: MessageTray.NotificationBanner,
 | 
			
		||||
 | 
			
		||||
    _init(notification) {
 | 
			
		||||
    _init: function(notification) {
 | 
			
		||||
        this.parent(notification);
 | 
			
		||||
 | 
			
		||||
        this._responseEntry = new St.Entry({ style_class: 'chat-response',
 | 
			
		||||
                                             x_expand: true,
 | 
			
		||||
                                             can_focus: true });
 | 
			
		||||
        this._responseEntry.clutter_text.connect('activate', this._onEntryActivated.bind(this));
 | 
			
		||||
        this._responseEntry.clutter_text.connect('text-changed', this._onEntryChanged.bind(this));
 | 
			
		||||
        this._responseEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivated));
 | 
			
		||||
        this._responseEntry.clutter_text.connect('text-changed', Lang.bind(this, this._onEntryChanged));
 | 
			
		||||
        this.setActionArea(this._responseEntry);
 | 
			
		||||
 | 
			
		||||
        this._responseEntry.clutter_text.connect('key-focus-in', () => {
 | 
			
		||||
        this._responseEntry.clutter_text.connect('key-focus-in', Lang.bind(this, function() {
 | 
			
		||||
            this.focused = true;
 | 
			
		||||
        });
 | 
			
		||||
        this._responseEntry.clutter_text.connect('key-focus-out', () => {
 | 
			
		||||
        }));
 | 
			
		||||
        this._responseEntry.clutter_text.connect('key-focus-out', Lang.bind(this, function() {
 | 
			
		||||
            this.focused = false;
 | 
			
		||||
            this.emit('unfocused');
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._scrollArea = new St.ScrollView({ style_class: 'chat-scrollview vfade',
 | 
			
		||||
                                               vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
 | 
			
		||||
@@ -851,11 +855,11 @@ var ChatNotificationBanner = new Lang.Class({
 | 
			
		||||
        // force a scroll to the bottom if things change while we were at the
 | 
			
		||||
        // bottom
 | 
			
		||||
        this._oldMaxScrollValue = this._scrollArea.vscroll.adjustment.value;
 | 
			
		||||
        this._scrollArea.vscroll.adjustment.connect('changed', adjustment => {
 | 
			
		||||
        this._scrollArea.vscroll.adjustment.connect('changed', Lang.bind(this, function(adjustment) {
 | 
			
		||||
            if (adjustment.value == this._oldMaxScrollValue)
 | 
			
		||||
                this.scrollTo(St.Side.BOTTOM);
 | 
			
		||||
            this._oldMaxScrollValue = Math.max(adjustment.lower, adjustment.upper - adjustment.page_size);
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._inputHistory = new History.HistoryManager({ entry: this._responseEntry.clutter_text });
 | 
			
		||||
 | 
			
		||||
@@ -864,32 +868,32 @@ var ChatNotificationBanner = new Lang.Class({
 | 
			
		||||
        this._messageActors = new Map();
 | 
			
		||||
 | 
			
		||||
        this._messageAddedId = this.notification.connect('message-added',
 | 
			
		||||
            (n, message) => {
 | 
			
		||||
            Lang.bind(this, function(n, message) {
 | 
			
		||||
                this._addMessage(message);
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
        this._messageRemovedId = this.notification.connect('message-removed',
 | 
			
		||||
            (n, message) => {
 | 
			
		||||
            Lang.bind(this, function(n, message) {
 | 
			
		||||
                let actor = this._messageActors.get(message);
 | 
			
		||||
                if (this._messageActors.delete(message))
 | 
			
		||||
                    actor.destroy();
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
        this._timestampChangedId = this.notification.connect('timestamp-changed',
 | 
			
		||||
            (n, message) => {
 | 
			
		||||
            Lang.bind(this, function(n, message) {
 | 
			
		||||
                this._updateTimestamp(message);
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        for (let i = this.notification.messages.length - 1; i >= 0; i--)
 | 
			
		||||
            this._addMessage(this.notification.messages[i]);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
        this.parent();
 | 
			
		||||
        this.notification.disconnect(this._messageAddedId);
 | 
			
		||||
        this.notification.disconnect(this._messageRemovedId);
 | 
			
		||||
        this.notification.disconnect(this._timestampChangedId);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    scrollTo(side) {
 | 
			
		||||
    scrollTo: function(side) {
 | 
			
		||||
        let adjustment = this._scrollArea.vscroll.adjustment;
 | 
			
		||||
        if (side == St.Side.TOP)
 | 
			
		||||
            adjustment.value = adjustment.lower;
 | 
			
		||||
@@ -897,11 +901,11 @@ var ChatNotificationBanner = new Lang.Class({
 | 
			
		||||
            adjustment.value = adjustment.upper;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hide() {
 | 
			
		||||
    hide: function() {
 | 
			
		||||
        this.emit('done-displaying');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _addMessage(message) {
 | 
			
		||||
    _addMessage: function(message) {
 | 
			
		||||
        let highlighter = new MessageList.URLHighlighter(message.body, true, true);
 | 
			
		||||
        let body = highlighter.actor;
 | 
			
		||||
 | 
			
		||||
@@ -923,7 +927,7 @@ var ChatNotificationBanner = new Lang.Class({
 | 
			
		||||
        this._updateTimestamp(message);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateTimestamp(message) {
 | 
			
		||||
    _updateTimestamp: function(message) {
 | 
			
		||||
        let actor = this._messageActors.get(message);
 | 
			
		||||
        if (!actor)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -944,7 +948,7 @@ var ChatNotificationBanner = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onEntryActivated() {
 | 
			
		||||
    _onEntryActivated: function() {
 | 
			
		||||
        let text = this._responseEntry.get_text();
 | 
			
		||||
        if (text == '')
 | 
			
		||||
            return;
 | 
			
		||||
@@ -957,7 +961,7 @@ var ChatNotificationBanner = new Lang.Class({
 | 
			
		||||
        this.notification.source.respond(text);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _composingStopTimeout() {
 | 
			
		||||
    _composingStopTimeout: function() {
 | 
			
		||||
        this._composingTimeoutId = 0;
 | 
			
		||||
 | 
			
		||||
        this.notification.source.setChatState(Tp.ChannelChatState.PAUSED);
 | 
			
		||||
@@ -965,7 +969,7 @@ var ChatNotificationBanner = new Lang.Class({
 | 
			
		||||
        return GLib.SOURCE_REMOVE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onEntryChanged() {
 | 
			
		||||
    _onEntryChanged: function() {
 | 
			
		||||
        let text = this._responseEntry.get_text();
 | 
			
		||||
 | 
			
		||||
        // If we're typing, we want to send COMPOSING.
 | 
			
		||||
@@ -984,7 +988,7 @@ var ChatNotificationBanner = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
            this._composingTimeoutId = Mainloop.timeout_add_seconds(
 | 
			
		||||
                COMPOSING_STOP_TIMEOUT,
 | 
			
		||||
                this._composingStopTimeout.bind(this));
 | 
			
		||||
                Lang.bind(this, this._composingStopTimeout));
 | 
			
		||||
            GLib.Source.set_name_by_id(this._composingTimeoutId, '[gnome-shell] this._composingStopTimeout');
 | 
			
		||||
        } else {
 | 
			
		||||
            this.notification.source.setChatState(Tp.ChannelChatState.ACTIVE);
 | 
			
		||||
 
 | 
			
		||||
@@ -24,14 +24,14 @@ var SortGroup = {
 | 
			
		||||
var CtrlAltTabManager = new Lang.Class({
 | 
			
		||||
    Name: 'CtrlAltTabManager',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._items = [];
 | 
			
		||||
        this.addGroup(global.window_group, _("Windows"),
 | 
			
		||||
                      'focus-windows-symbolic', { sortGroup: SortGroup.TOP,
 | 
			
		||||
                                                  focusCallback: this._focusWindows.bind(this) });
 | 
			
		||||
                                                  focusCallback: Lang.bind(this, this._focusWindows) });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addGroup(root, name, icon, params) {
 | 
			
		||||
    addGroup: function(root, name, icon, params) {
 | 
			
		||||
        let item = Params.parse(params, { sortGroup: SortGroup.MIDDLE,
 | 
			
		||||
                                          proxy: root,
 | 
			
		||||
                                          focusCallback: null });
 | 
			
		||||
@@ -41,12 +41,12 @@ var CtrlAltTabManager = new Lang.Class({
 | 
			
		||||
        item.iconName = icon;
 | 
			
		||||
 | 
			
		||||
        this._items.push(item);
 | 
			
		||||
        root.connect('destroy', () => { this.removeGroup(root); });
 | 
			
		||||
        root.connect('destroy', Lang.bind(this, function() { this.removeGroup(root); }));
 | 
			
		||||
        if (root instanceof St.Widget)
 | 
			
		||||
            global.focus_manager.add_group(root);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    removeGroup(root) {
 | 
			
		||||
    removeGroup: function(root) {
 | 
			
		||||
        if (root instanceof St.Widget)
 | 
			
		||||
            global.focus_manager.remove_group(root);
 | 
			
		||||
        for (let i = 0; i < this._items.length; i++) {
 | 
			
		||||
@@ -57,7 +57,7 @@ var CtrlAltTabManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    focusGroup(item, timestamp) {
 | 
			
		||||
    focusGroup: function(item, timestamp) {
 | 
			
		||||
        if (item.focusCallback)
 | 
			
		||||
            item.focusCallback(timestamp);
 | 
			
		||||
        else
 | 
			
		||||
@@ -68,7 +68,7 @@ var CtrlAltTabManager = new Lang.Class({
 | 
			
		||||
    // and everything else in between, sorted by X coordinate, so that
 | 
			
		||||
    // they will have the same left-to-right ordering in the
 | 
			
		||||
    // Ctrl-Alt-Tab dialog as they do onscreen.
 | 
			
		||||
    _sortItems(a, b) {
 | 
			
		||||
    _sortItems: function(a, b) {
 | 
			
		||||
        if (a.sortGroup != b.sortGroup)
 | 
			
		||||
            return a.sortGroup - b.sortGroup;
 | 
			
		||||
 | 
			
		||||
@@ -79,17 +79,15 @@ var CtrlAltTabManager = new Lang.Class({
 | 
			
		||||
        return ax - bx;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    popup(backward, binding, mask) {
 | 
			
		||||
    popup: function(backward, binding, mask) {
 | 
			
		||||
        // Start with the set of focus groups that are currently mapped
 | 
			
		||||
        let items = this._items.filter(item => item.proxy.mapped);
 | 
			
		||||
        let items = this._items.filter(function (item) { return item.proxy.mapped; });
 | 
			
		||||
 | 
			
		||||
        // And add the windows metacity would show in its Ctrl-Alt-Tab list
 | 
			
		||||
        if (Main.sessionMode.hasWindows && !Main.overview.visible) {
 | 
			
		||||
            let display = global.display;
 | 
			
		||||
            let workspaceManager = global.workspace_manager;
 | 
			
		||||
            let activeWorkspace = workspaceManager.get_active_workspace();
 | 
			
		||||
            let windows = display.get_tab_list(Meta.TabList.DOCKS,
 | 
			
		||||
                                               activeWorkspace);
 | 
			
		||||
            let screen = global.screen;
 | 
			
		||||
            let display = screen.get_display();
 | 
			
		||||
            let windows = display.get_tab_list(Meta.TabList.DOCKS, screen.get_active_workspace ());
 | 
			
		||||
            let windowTracker = Shell.WindowTracker.get_default();
 | 
			
		||||
            let textureCache = St.TextureCache.get_default();
 | 
			
		||||
            for (let i = 0; i < windows.length; i++) {
 | 
			
		||||
@@ -107,9 +105,10 @@ var CtrlAltTabManager = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
                items.push({ name: windows[i].title,
 | 
			
		||||
                             proxy: windows[i].get_compositor_private(),
 | 
			
		||||
                             focusCallback: function(timestamp) {
 | 
			
		||||
                                 Main.activateWindow(this, timestamp);
 | 
			
		||||
                             }.bind(windows[i]),
 | 
			
		||||
                             focusCallback: Lang.bind(windows[i],
 | 
			
		||||
                                 function(timestamp) {
 | 
			
		||||
                                     Main.activateWindow(this, timestamp);
 | 
			
		||||
                                 }),
 | 
			
		||||
                             iconActor: icon,
 | 
			
		||||
                             iconName: iconName,
 | 
			
		||||
                             sortGroup: SortGroup.MIDDLE });
 | 
			
		||||
@@ -119,21 +118,21 @@ var CtrlAltTabManager = new Lang.Class({
 | 
			
		||||
        if (!items.length)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        items.sort(this._sortItems.bind(this));
 | 
			
		||||
        items.sort(Lang.bind(this, this._sortItems));
 | 
			
		||||
 | 
			
		||||
        if (!this._popup) {
 | 
			
		||||
            this._popup = new CtrlAltTabPopup(items);
 | 
			
		||||
            this._popup.show(backward, binding, mask);
 | 
			
		||||
 | 
			
		||||
            this._popup.actor.connect('destroy',
 | 
			
		||||
                                      () => {
 | 
			
		||||
                                      Lang.bind(this, function() {
 | 
			
		||||
                                          this._popup = null;
 | 
			
		||||
                                      });
 | 
			
		||||
                                      }));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _focusWindows(timestamp) {
 | 
			
		||||
        global.display.focus_default_window(timestamp);
 | 
			
		||||
    _focusWindows: function(timestamp) {
 | 
			
		||||
        global.screen.focus_default_window(timestamp);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@@ -141,13 +140,13 @@ var CtrlAltTabPopup = new Lang.Class({
 | 
			
		||||
    Name: 'CtrlAltTabPopup',
 | 
			
		||||
    Extends: SwitcherPopup.SwitcherPopup,
 | 
			
		||||
 | 
			
		||||
    _init(items) {
 | 
			
		||||
    _init: function(items) {
 | 
			
		||||
        this.parent(items);
 | 
			
		||||
 | 
			
		||||
        this._switcherList = new CtrlAltTabSwitcher(this._items);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _keyPressHandler(keysym, action) {
 | 
			
		||||
    _keyPressHandler: function(keysym, action) {
 | 
			
		||||
        if (action == Meta.KeyBindingAction.SWITCH_PANELS)
 | 
			
		||||
            this._select(this._next());
 | 
			
		||||
        else if (action == Meta.KeyBindingAction.SWITCH_PANELS_BACKWARD)
 | 
			
		||||
@@ -162,7 +161,7 @@ var CtrlAltTabPopup = new Lang.Class({
 | 
			
		||||
        return Clutter.EVENT_STOP;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _finish(time) {
 | 
			
		||||
    _finish : function(time) {
 | 
			
		||||
        this.parent(time);
 | 
			
		||||
        Main.ctrlAltTabManager.focusGroup(this._items[this._selectedIndex], time);
 | 
			
		||||
    },
 | 
			
		||||
@@ -172,14 +171,14 @@ var CtrlAltTabSwitcher = new Lang.Class({
 | 
			
		||||
    Name: 'CtrlAltTabSwitcher',
 | 
			
		||||
    Extends: SwitcherPopup.SwitcherList,
 | 
			
		||||
 | 
			
		||||
    _init(items) {
 | 
			
		||||
    _init : function(items) {
 | 
			
		||||
        this.parent(true);
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < items.length; i++)
 | 
			
		||||
            this._addIcon(items[i]);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _addIcon(item) {
 | 
			
		||||
    _addIcon : function(item) {
 | 
			
		||||
        let box = new St.BoxLayout({ style_class: 'alt-tab-app',
 | 
			
		||||
                                     vertical: true });
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										198
									
								
								js/ui/dash.js
									
									
									
									
									
								
							
							
						
						@@ -37,7 +37,7 @@ var DashItemContainer = new Lang.Class({
 | 
			
		||||
    Name: 'DashItemContainer',
 | 
			
		||||
    Extends: St.Widget,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent({ style_class: 'dash-item-container' });
 | 
			
		||||
 | 
			
		||||
        this._labelText = "";
 | 
			
		||||
@@ -56,7 +56,7 @@ var DashItemContainer = new Lang.Class({
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_allocate(box, flags) {
 | 
			
		||||
    vfunc_allocate: function(box, flags) {
 | 
			
		||||
        this.set_allocation(box, flags);
 | 
			
		||||
 | 
			
		||||
        if (this.child == null)
 | 
			
		||||
@@ -80,7 +80,7 @@ var DashItemContainer = new Lang.Class({
 | 
			
		||||
        this.child.allocate(childBox, flags);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_get_preferred_height(forWidth) {
 | 
			
		||||
    vfunc_get_preferred_height: function(forWidth) {
 | 
			
		||||
        let themeNode = this.get_theme_node();
 | 
			
		||||
 | 
			
		||||
        if (this.child == null)
 | 
			
		||||
@@ -92,7 +92,7 @@ var DashItemContainer = new Lang.Class({
 | 
			
		||||
                                                 natHeight * this.child.scale_y);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_get_preferred_width(forHeight) {
 | 
			
		||||
    vfunc_get_preferred_width: function(forHeight) {
 | 
			
		||||
        let themeNode = this.get_theme_node();
 | 
			
		||||
 | 
			
		||||
        if (this.child == null)
 | 
			
		||||
@@ -104,7 +104,7 @@ var DashItemContainer = new Lang.Class({
 | 
			
		||||
                                                natWidth * this.child.scale_y);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    showLabel() {
 | 
			
		||||
    showLabel: function() {
 | 
			
		||||
        if (!this._labelText)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -138,23 +138,23 @@ var DashItemContainer = new Lang.Class({
 | 
			
		||||
                         });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setLabelText(text) {
 | 
			
		||||
    setLabelText: function(text) {
 | 
			
		||||
        this._labelText = text;
 | 
			
		||||
        this.child.accessible_name = text;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hideLabel() {
 | 
			
		||||
    hideLabel: function () {
 | 
			
		||||
        Tweener.addTween(this.label,
 | 
			
		||||
                         { opacity: 0,
 | 
			
		||||
                           time: DASH_ITEM_LABEL_HIDE_TIME,
 | 
			
		||||
                           transition: 'easeOutQuad',
 | 
			
		||||
                           onComplete: () => {
 | 
			
		||||
                           onComplete: Lang.bind(this, function() {
 | 
			
		||||
                               this.label.hide();
 | 
			
		||||
                           }
 | 
			
		||||
                           })
 | 
			
		||||
                         });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setChild(actor) {
 | 
			
		||||
    setChild: function(actor) {
 | 
			
		||||
        if (this.child == actor)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -168,7 +168,7 @@ var DashItemContainer = new Lang.Class({
 | 
			
		||||
        this.child.set_opacity(this._childOpacity);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    show(animate) {
 | 
			
		||||
    show: function(animate) {
 | 
			
		||||
        if (this.child == null)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -181,7 +181,7 @@ var DashItemContainer = new Lang.Class({
 | 
			
		||||
                         });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    animateOutAndDestroy() {
 | 
			
		||||
    animateOutAndDestroy: function() {
 | 
			
		||||
        this.label.hide();
 | 
			
		||||
 | 
			
		||||
        if (this.child == null) {
 | 
			
		||||
@@ -195,9 +195,9 @@ var DashItemContainer = new Lang.Class({
 | 
			
		||||
                           childOpacity: 0,
 | 
			
		||||
                           time: DASH_ANIMATION_TIME,
 | 
			
		||||
                           transition: 'easeOutQuad',
 | 
			
		||||
                           onComplete: () => {
 | 
			
		||||
                           onComplete: Lang.bind(this, function() {
 | 
			
		||||
                               this.destroy();
 | 
			
		||||
                           }
 | 
			
		||||
                           })
 | 
			
		||||
                         });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -235,7 +235,7 @@ var ShowAppsIcon = new Lang.Class({
 | 
			
		||||
    Name: 'ShowAppsIcon',
 | 
			
		||||
    Extends: DashItemContainer,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent();
 | 
			
		||||
 | 
			
		||||
        this.toggleButton = new St.Button({ style_class: 'show-apps',
 | 
			
		||||
@@ -246,7 +246,7 @@ var ShowAppsIcon = new Lang.Class({
 | 
			
		||||
        this.icon = new IconGrid.BaseIcon(_("Show Applications"),
 | 
			
		||||
                                           { setSizeManually: true,
 | 
			
		||||
                                             showLabel: false,
 | 
			
		||||
                                             createIcon: this._createIcon.bind(this) });
 | 
			
		||||
                                             createIcon: Lang.bind(this, this._createIcon) });
 | 
			
		||||
        this.toggleButton.add_actor(this.icon.actor);
 | 
			
		||||
        this.toggleButton._delegate = this;
 | 
			
		||||
 | 
			
		||||
@@ -254,7 +254,7 @@ var ShowAppsIcon = new Lang.Class({
 | 
			
		||||
        this.setDragApp(null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createIcon(size) {
 | 
			
		||||
    _createIcon: function(size) {
 | 
			
		||||
        this._iconActor = new St.Icon({ icon_name: 'view-app-grid-symbolic',
 | 
			
		||||
                                        icon_size: size,
 | 
			
		||||
                                        style_class: 'show-apps-icon',
 | 
			
		||||
@@ -262,7 +262,7 @@ var ShowAppsIcon = new Lang.Class({
 | 
			
		||||
        return this._iconActor;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _canRemoveApp(app) {
 | 
			
		||||
    _canRemoveApp: function(app) {
 | 
			
		||||
        if (app == null)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
@@ -274,7 +274,7 @@ var ShowAppsIcon = new Lang.Class({
 | 
			
		||||
        return isFavorite;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setDragApp(app) {
 | 
			
		||||
    setDragApp: function(app) {
 | 
			
		||||
        let canRemove = this._canRemoveApp(app);
 | 
			
		||||
 | 
			
		||||
        this.toggleButton.set_hover(canRemove);
 | 
			
		||||
@@ -287,24 +287,25 @@ var ShowAppsIcon = new Lang.Class({
 | 
			
		||||
            this.setLabelText(_("Show Applications"));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    handleDragOver(source, actor, x, y, time) {
 | 
			
		||||
    handleDragOver: function(source, actor, x, y, time) {
 | 
			
		||||
        if (!this._canRemoveApp(getAppFromSource(source)))
 | 
			
		||||
            return DND.DragMotionResult.NO_DROP;
 | 
			
		||||
 | 
			
		||||
        return DND.DragMotionResult.MOVE_DROP;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    acceptDrop(source, actor, x, y, time) {
 | 
			
		||||
    acceptDrop: function(source, actor, x, y, time) {
 | 
			
		||||
        let app = getAppFromSource(source);
 | 
			
		||||
        if (!this._canRemoveApp(app))
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        let id = app.get_id();
 | 
			
		||||
 | 
			
		||||
        Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
 | 
			
		||||
            AppFavorites.getAppFavorites().removeFavorite(id);
 | 
			
		||||
            return false;
 | 
			
		||||
        });
 | 
			
		||||
        Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
 | 
			
		||||
            function () {
 | 
			
		||||
                AppFavorites.getAppFavorites().removeFavorite(id);
 | 
			
		||||
                return false;
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
@@ -314,7 +315,7 @@ var DragPlaceholderItem = new Lang.Class({
 | 
			
		||||
    Name: 'DragPlaceholderItem',
 | 
			
		||||
    Extends: DashItemContainer,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent();
 | 
			
		||||
        this.setChild(new St.Bin({ style_class: 'placeholder' }));
 | 
			
		||||
    }
 | 
			
		||||
@@ -324,7 +325,7 @@ var EmptyDropTargetItem = new Lang.Class({
 | 
			
		||||
    Name: 'EmptyDropTargetItem',
 | 
			
		||||
    Extends: DashItemContainer,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent();
 | 
			
		||||
        this.setChild(new St.Bin({ style_class: 'empty-dash-drop-target' }));
 | 
			
		||||
    }
 | 
			
		||||
@@ -334,14 +335,14 @@ var DashActor = new Lang.Class({
 | 
			
		||||
    Name: 'DashActor',
 | 
			
		||||
    Extends: St.Widget,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        let layout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.VERTICAL });
 | 
			
		||||
        this.parent({ name: 'dash',
 | 
			
		||||
                      layout_manager: layout,
 | 
			
		||||
                      clip_to_allocation: true });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_allocate(box, flags) {
 | 
			
		||||
    vfunc_allocate: function(box, flags) {
 | 
			
		||||
        let contentBox = this.get_theme_node().get_content_box(box);
 | 
			
		||||
        let availWidth = contentBox.x2 - contentBox.x1;
 | 
			
		||||
 | 
			
		||||
@@ -362,7 +363,7 @@ var DashActor = new Lang.Class({
 | 
			
		||||
        showAppsButton.allocate(childBox, flags);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_get_preferred_height(forWidth) {
 | 
			
		||||
    vfunc_get_preferred_height: function(forWidth) {
 | 
			
		||||
        // We want to request the natural height of all our children
 | 
			
		||||
        // as our natural height, so we chain up to StWidget (which
 | 
			
		||||
        // then calls BoxLayout), but we only request the showApps
 | 
			
		||||
@@ -385,7 +386,7 @@ const baseIconSizes = [ 16, 22, 24, 32, 48, 64 ];
 | 
			
		||||
var Dash = new Lang.Class({
 | 
			
		||||
    Name: 'Dash',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init : function() {
 | 
			
		||||
        this._maxHeight = -1;
 | 
			
		||||
        this.iconSize = 64;
 | 
			
		||||
        this._shownInitially = false;
 | 
			
		||||
@@ -414,39 +415,40 @@ var Dash = new Lang.Class({
 | 
			
		||||
        this._container.add_actor(this._showAppsIcon);
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Bin({ child: this._container });
 | 
			
		||||
        this.actor.connect('notify::height', () => {
 | 
			
		||||
            if (this._maxHeight != this.actor.height)
 | 
			
		||||
                this._queueRedisplay();
 | 
			
		||||
            this._maxHeight = this.actor.height;
 | 
			
		||||
        });
 | 
			
		||||
        this.actor.connect('notify::height', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                if (this._maxHeight != this.actor.height)
 | 
			
		||||
                    this._queueRedisplay();
 | 
			
		||||
                this._maxHeight = this.actor.height;
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        this._workId = Main.initializeDeferredWork(this._box, this._redisplay.bind(this));
 | 
			
		||||
        this._workId = Main.initializeDeferredWork(this._box, Lang.bind(this, this._redisplay));
 | 
			
		||||
 | 
			
		||||
        this._appSystem = Shell.AppSystem.get_default();
 | 
			
		||||
 | 
			
		||||
        this._appSystem.connect('installed-changed', () => {
 | 
			
		||||
        this._appSystem.connect('installed-changed', Lang.bind(this, function() {
 | 
			
		||||
            AppFavorites.getAppFavorites().reload();
 | 
			
		||||
            this._queueRedisplay();
 | 
			
		||||
        });
 | 
			
		||||
        AppFavorites.getAppFavorites().connect('changed', this._queueRedisplay.bind(this));
 | 
			
		||||
        this._appSystem.connect('app-state-changed', this._queueRedisplay.bind(this));
 | 
			
		||||
        }));
 | 
			
		||||
        AppFavorites.getAppFavorites().connect('changed', Lang.bind(this, this._queueRedisplay));
 | 
			
		||||
        this._appSystem.connect('app-state-changed', Lang.bind(this, this._queueRedisplay));
 | 
			
		||||
 | 
			
		||||
        Main.overview.connect('item-drag-begin',
 | 
			
		||||
                              this._onDragBegin.bind(this));
 | 
			
		||||
                              Lang.bind(this, this._onDragBegin));
 | 
			
		||||
        Main.overview.connect('item-drag-end',
 | 
			
		||||
                              this._onDragEnd.bind(this));
 | 
			
		||||
                              Lang.bind(this, this._onDragEnd));
 | 
			
		||||
        Main.overview.connect('item-drag-cancelled',
 | 
			
		||||
                              this._onDragCancelled.bind(this));
 | 
			
		||||
                              Lang.bind(this, this._onDragCancelled));
 | 
			
		||||
 | 
			
		||||
        // Translators: this is the name of the dock/favorites area on
 | 
			
		||||
        // the left of the overview
 | 
			
		||||
        Main.ctrlAltTabManager.addGroup(this.actor, _("Dash"), 'user-bookmarks-symbolic');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragBegin() {
 | 
			
		||||
    _onDragBegin: function() {
 | 
			
		||||
        this._dragCancelled = false;
 | 
			
		||||
        this._dragMonitor = {
 | 
			
		||||
            dragMotion: this._onDragMotion.bind(this)
 | 
			
		||||
            dragMotion: Lang.bind(this, this._onDragMotion)
 | 
			
		||||
        };
 | 
			
		||||
        DND.addDragMonitor(this._dragMonitor);
 | 
			
		||||
 | 
			
		||||
@@ -457,26 +459,26 @@ var Dash = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragCancelled() {
 | 
			
		||||
    _onDragCancelled: function() {
 | 
			
		||||
        this._dragCancelled = true;
 | 
			
		||||
        this._endDrag();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragEnd() {
 | 
			
		||||
    _onDragEnd: function() {
 | 
			
		||||
        if (this._dragCancelled)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._endDrag();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _endDrag() {
 | 
			
		||||
    _endDrag: function() {
 | 
			
		||||
        this._clearDragPlaceholder();
 | 
			
		||||
        this._clearEmptyDropTarget();
 | 
			
		||||
        this._showAppsIcon.setDragApp(null);
 | 
			
		||||
        DND.removeDragMonitor(this._dragMonitor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragMotion(dragEvent) {
 | 
			
		||||
    _onDragMotion: function(dragEvent) {
 | 
			
		||||
        let app = getAppFromSource(dragEvent.source);
 | 
			
		||||
        if (app == null)
 | 
			
		||||
            return DND.DragMotionResult.CONTINUE;
 | 
			
		||||
@@ -495,56 +497,56 @@ var Dash = new Lang.Class({
 | 
			
		||||
        return DND.DragMotionResult.CONTINUE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _appIdListToHash(apps) {
 | 
			
		||||
    _appIdListToHash: function(apps) {
 | 
			
		||||
        let ids = {};
 | 
			
		||||
        for (let i = 0; i < apps.length; i++)
 | 
			
		||||
            ids[apps[i].get_id()] = apps[i];
 | 
			
		||||
        return ids;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _queueRedisplay() {
 | 
			
		||||
    _queueRedisplay: function () {
 | 
			
		||||
        Main.queueDeferredWork(this._workId);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _hookUpLabel(item, appIcon) {
 | 
			
		||||
        item.child.connect('notify::hover', () => {
 | 
			
		||||
    _hookUpLabel: function(item, appIcon) {
 | 
			
		||||
        item.child.connect('notify::hover', Lang.bind(this, function() {
 | 
			
		||||
            this._syncLabel(item, appIcon);
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        let id = Main.overview.connect('hiding', () => {
 | 
			
		||||
        let id = Main.overview.connect('hiding', Lang.bind(this, function() {
 | 
			
		||||
            this._labelShowing = false;
 | 
			
		||||
            item.hideLabel();
 | 
			
		||||
        });
 | 
			
		||||
        item.child.connect('destroy', () => {
 | 
			
		||||
        }));
 | 
			
		||||
        item.child.connect('destroy', function() {
 | 
			
		||||
            Main.overview.disconnect(id);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (appIcon) {
 | 
			
		||||
            appIcon.connect('sync-tooltip', () => {
 | 
			
		||||
            appIcon.connect('sync-tooltip', Lang.bind(this, function() {
 | 
			
		||||
                this._syncLabel(item, appIcon);
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createAppItem(app) {
 | 
			
		||||
    _createAppItem: function(app) {
 | 
			
		||||
        let appIcon = new AppDisplay.AppIcon(app,
 | 
			
		||||
                                             { setSizeManually: true,
 | 
			
		||||
                                               showLabel: false });
 | 
			
		||||
        if (appIcon._draggable) {
 | 
			
		||||
            appIcon._draggable.connect('drag-begin',
 | 
			
		||||
                                       () => {
 | 
			
		||||
                                       Lang.bind(this, function() {
 | 
			
		||||
                                           appIcon.actor.opacity = 50;
 | 
			
		||||
                                       });
 | 
			
		||||
                                       }));
 | 
			
		||||
            appIcon._draggable.connect('drag-end',
 | 
			
		||||
                                       () => {
 | 
			
		||||
                                       Lang.bind(this, function() {
 | 
			
		||||
                                           appIcon.actor.opacity = 255;
 | 
			
		||||
                                       });
 | 
			
		||||
                                       }));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        appIcon.connect('menu-state-changed',
 | 
			
		||||
                        (appIcon, opened) => {
 | 
			
		||||
                        Lang.bind(this, function(appIcon, opened) {
 | 
			
		||||
                            this._itemMenuStateChanged(item, opened);
 | 
			
		||||
                        });
 | 
			
		||||
                        }));
 | 
			
		||||
 | 
			
		||||
        let item = new DashItemContainer();
 | 
			
		||||
        item.setChild(appIcon.actor);
 | 
			
		||||
@@ -560,7 +562,7 @@ var Dash = new Lang.Class({
 | 
			
		||||
        return item;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _itemMenuStateChanged(item, opened) {
 | 
			
		||||
    _itemMenuStateChanged: function(item, opened) {
 | 
			
		||||
        // When the menu closes, it calls sync_hover, which means
 | 
			
		||||
        // that the notify::hover handler does everything we need to.
 | 
			
		||||
        if (opened) {
 | 
			
		||||
@@ -573,19 +575,19 @@ var Dash = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _syncLabel(item, appIcon) {
 | 
			
		||||
    _syncLabel: function (item, appIcon) {
 | 
			
		||||
        let shouldShow = appIcon ? appIcon.shouldShowTooltip() : item.child.get_hover();
 | 
			
		||||
 | 
			
		||||
        if (shouldShow) {
 | 
			
		||||
            if (this._showLabelTimeoutId == 0) {
 | 
			
		||||
                let timeout = this._labelShowing ? 0 : DASH_ITEM_HOVER_TIMEOUT;
 | 
			
		||||
                this._showLabelTimeoutId = Mainloop.timeout_add(timeout,
 | 
			
		||||
                    () => {
 | 
			
		||||
                    Lang.bind(this, function() {
 | 
			
		||||
                        this._labelShowing = true;
 | 
			
		||||
                        item.showLabel();
 | 
			
		||||
                        this._showLabelTimeoutId = 0;
 | 
			
		||||
                        return GLib.SOURCE_REMOVE;
 | 
			
		||||
                    });
 | 
			
		||||
                    }));
 | 
			
		||||
                GLib.Source.set_name_by_id(this._showLabelTimeoutId, '[gnome-shell] item.showLabel');
 | 
			
		||||
                if (this._resetHoverTimeoutId > 0) {
 | 
			
		||||
                    Mainloop.source_remove(this._resetHoverTimeoutId);
 | 
			
		||||
@@ -599,22 +601,22 @@ var Dash = new Lang.Class({
 | 
			
		||||
            item.hideLabel();
 | 
			
		||||
            if (this._labelShowing) {
 | 
			
		||||
                this._resetHoverTimeoutId = Mainloop.timeout_add(DASH_ITEM_HOVER_TIMEOUT,
 | 
			
		||||
                    () => {
 | 
			
		||||
                    Lang.bind(this, function() {
 | 
			
		||||
                        this._labelShowing = false;
 | 
			
		||||
                        this._resetHoverTimeoutId = 0;
 | 
			
		||||
                        return GLib.SOURCE_REMOVE;
 | 
			
		||||
                    });
 | 
			
		||||
                    }));
 | 
			
		||||
                GLib.Source.set_name_by_id(this._resetHoverTimeoutId, '[gnome-shell] this._labelShowing');
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _adjustIconSize() {
 | 
			
		||||
    _adjustIconSize: function() {
 | 
			
		||||
        // For the icon size, we only consider children which are "proper"
 | 
			
		||||
        // icons (i.e. ignoring drag placeholders) and which are not
 | 
			
		||||
        // animating out (which means they will be destroyed at the end of
 | 
			
		||||
        // the animation)
 | 
			
		||||
        let iconChildren = this._box.get_children().filter(actor => {
 | 
			
		||||
        let iconChildren = this._box.get_children().filter(function(actor) {
 | 
			
		||||
            return actor.child &&
 | 
			
		||||
                   actor.child._delegate &&
 | 
			
		||||
                   actor.child._delegate.icon &&
 | 
			
		||||
@@ -653,7 +655,9 @@ var Dash = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        let availSize = availHeight / iconChildren.length;
 | 
			
		||||
 | 
			
		||||
        let iconSizes = baseIconSizes.map(s => s * scaleFactor);
 | 
			
		||||
        let iconSizes = baseIconSizes.map(function(s) {
 | 
			
		||||
            return s * scaleFactor;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let newIconSize = baseIconSizes[0];
 | 
			
		||||
        for (let i = 0; i < iconSizes.length; i++) {
 | 
			
		||||
@@ -699,18 +703,20 @@ var Dash = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _redisplay() {
 | 
			
		||||
    _redisplay: function () {
 | 
			
		||||
        let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
 | 
			
		||||
 | 
			
		||||
        let running = this._appSystem.get_running();
 | 
			
		||||
 | 
			
		||||
        let children = this._box.get_children().filter(actor => {
 | 
			
		||||
        let children = this._box.get_children().filter(function(actor) {
 | 
			
		||||
                return actor.child &&
 | 
			
		||||
                       actor.child._delegate &&
 | 
			
		||||
                       actor.child._delegate.app;
 | 
			
		||||
            });
 | 
			
		||||
        // Apps currently in the dash
 | 
			
		||||
        let oldApps = children.map(actor => actor.child._delegate.app);
 | 
			
		||||
        let oldApps = children.map(function(actor) {
 | 
			
		||||
                return actor.child._delegate.app;
 | 
			
		||||
            });
 | 
			
		||||
        // Apps supposed to be in the dash
 | 
			
		||||
        let newApps = [];
 | 
			
		||||
 | 
			
		||||
@@ -776,7 +782,7 @@ var Dash = new Lang.Class({
 | 
			
		||||
            let nextApp = newApps.length > newIndex + 1 ? newApps[newIndex + 1]
 | 
			
		||||
                                                        : null;
 | 
			
		||||
            let insertHere = nextApp && nextApp == oldApp;
 | 
			
		||||
            let alreadyRemoved = removedActors.reduce((result, actor) => {
 | 
			
		||||
            let alreadyRemoved = removedActors.reduce(function(result, actor) {
 | 
			
		||||
                let removedApp = actor.child._delegate.app;
 | 
			
		||||
                return result || removedApp == newApp;
 | 
			
		||||
            }, false);
 | 
			
		||||
@@ -828,26 +834,27 @@ var Dash = new Lang.Class({
 | 
			
		||||
        this._box.queue_relayout();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _clearDragPlaceholder() {
 | 
			
		||||
    _clearDragPlaceholder: function() {
 | 
			
		||||
        if (this._dragPlaceholder) {
 | 
			
		||||
            this._animatingPlaceholdersCount++;
 | 
			
		||||
            this._dragPlaceholder.animateOutAndDestroy();
 | 
			
		||||
            this._dragPlaceholder.connect('destroy', () => {
 | 
			
		||||
                this._animatingPlaceholdersCount--;
 | 
			
		||||
            });
 | 
			
		||||
            this._dragPlaceholder.connect('destroy',
 | 
			
		||||
                Lang.bind(this, function() {
 | 
			
		||||
                    this._animatingPlaceholdersCount--;
 | 
			
		||||
                }));
 | 
			
		||||
            this._dragPlaceholder = null;
 | 
			
		||||
        }
 | 
			
		||||
        this._dragPlaceholderPos = -1;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _clearEmptyDropTarget() {
 | 
			
		||||
    _clearEmptyDropTarget: function() {
 | 
			
		||||
        if (this._emptyDropTarget) {
 | 
			
		||||
            this._emptyDropTarget.animateOutAndDestroy();
 | 
			
		||||
            this._emptyDropTarget = null;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    handleDragOver(source, actor, x, y, time) {
 | 
			
		||||
    handleDragOver : function(source, actor, x, y, time) {
 | 
			
		||||
        let app = getAppFromSource(source);
 | 
			
		||||
 | 
			
		||||
        // Don't allow favoriting of transient apps
 | 
			
		||||
@@ -925,7 +932,7 @@ var Dash = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Draggable target interface
 | 
			
		||||
    acceptDrop(source, actor, x, y, time) {
 | 
			
		||||
    acceptDrop : function(source, actor, x, y, time) {
 | 
			
		||||
        let app = getAppFromSource(source);
 | 
			
		||||
 | 
			
		||||
        // Don't allow favoriting of transient apps
 | 
			
		||||
@@ -961,14 +968,15 @@ var Dash = new Lang.Class({
 | 
			
		||||
        if (!this._dragPlaceholder)
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
 | 
			
		||||
            let appFavorites = AppFavorites.getAppFavorites();
 | 
			
		||||
            if (srcIsFavorite)
 | 
			
		||||
                appFavorites.moveFavoriteToPos(id, favPos);
 | 
			
		||||
            else
 | 
			
		||||
                appFavorites.addFavoriteAtPos(id, favPos);
 | 
			
		||||
            return false;
 | 
			
		||||
        });
 | 
			
		||||
        Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
 | 
			
		||||
            function () {
 | 
			
		||||
                let appFavorites = AppFavorites.getAppFavorites();
 | 
			
		||||
                if (srcIsFavorite)
 | 
			
		||||
                    appFavorites.moveFavoriteToPos(id, favPos);
 | 
			
		||||
                else
 | 
			
		||||
                    appFavorites.addFavoriteAtPos(id, favPos);
 | 
			
		||||
                return false;
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@ function _isToday(date) {
 | 
			
		||||
var TodayButton = new Lang.Class({
 | 
			
		||||
    Name: 'TodayButton',
 | 
			
		||||
 | 
			
		||||
    _init(calendar) {
 | 
			
		||||
    _init: function(calendar) {
 | 
			
		||||
        // Having the ability to go to the current date if the user is already
 | 
			
		||||
        // on the current date can be confusing. So don't make the button reactive
 | 
			
		||||
        // until the selected date changes.
 | 
			
		||||
@@ -43,9 +43,10 @@ var TodayButton = new Lang.Class({
 | 
			
		||||
                                     can_focus: true,
 | 
			
		||||
                                     reactive: false
 | 
			
		||||
                                   });
 | 
			
		||||
        this.actor.connect('clicked', () => {
 | 
			
		||||
            this._calendar.setDate(new Date(), false);
 | 
			
		||||
        });
 | 
			
		||||
        this.actor.connect('clicked', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                this._calendar.setDate(new Date(), false);
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        let hbox = new St.BoxLayout({ vertical: true });
 | 
			
		||||
        this.actor.add_actor(hbox);
 | 
			
		||||
@@ -58,14 +59,15 @@ var TodayButton = new Lang.Class({
 | 
			
		||||
        hbox.add_actor(this._dateLabel);
 | 
			
		||||
 | 
			
		||||
        this._calendar = calendar;
 | 
			
		||||
        this._calendar.connect('selected-date-changed', (calendar, date) => {
 | 
			
		||||
            // Make the button reactive only if the selected date is not the
 | 
			
		||||
            // current date.
 | 
			
		||||
            this.actor.reactive = !_isToday(date)
 | 
			
		||||
        });
 | 
			
		||||
        this._calendar.connect('selected-date-changed', Lang.bind(this,
 | 
			
		||||
            function(calendar, date) {
 | 
			
		||||
                // Make the button reactive only if the selected date is not the
 | 
			
		||||
                // current date.
 | 
			
		||||
                this.actor.reactive = !_isToday(date)
 | 
			
		||||
            }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setDate(date) {
 | 
			
		||||
    setDate: function(date) {
 | 
			
		||||
        this._dayLabel.set_text(date.toLocaleFormat('%A'));
 | 
			
		||||
 | 
			
		||||
        /* Translators: This is the date format to use when the calendar popup is
 | 
			
		||||
@@ -86,7 +88,7 @@ var TodayButton = new Lang.Class({
 | 
			
		||||
var WorldClocksSection = new Lang.Class({
 | 
			
		||||
    Name: 'WorldClocksSection',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._clock = new GnomeDesktop.WallClock();
 | 
			
		||||
        this._clockNotifyId = 0;
 | 
			
		||||
 | 
			
		||||
@@ -95,12 +97,13 @@ var WorldClocksSection = new Lang.Class({
 | 
			
		||||
        this.actor = new St.Button({ style_class: 'world-clocks-button',
 | 
			
		||||
                                     x_fill: true,
 | 
			
		||||
                                     can_focus: true });
 | 
			
		||||
        this.actor.connect('clicked', () => {
 | 
			
		||||
            this._clockAppMon.activateApp();
 | 
			
		||||
        this.actor.connect('clicked', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                this._clockAppMon.activateApp();
 | 
			
		||||
 | 
			
		||||
            Main.overview.hide();
 | 
			
		||||
            Main.panel.closeCalendar();
 | 
			
		||||
        });
 | 
			
		||||
                Main.overview.hide();
 | 
			
		||||
                Main.panel.closeCalendar();
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
 | 
			
		||||
        this._grid = new St.Widget({ style_class: 'world-clocks-grid',
 | 
			
		||||
@@ -112,17 +115,17 @@ var WorldClocksSection = new Lang.Class({
 | 
			
		||||
        this._clockAppMon = new Util.AppSettingsMonitor('org.gnome.clocks.desktop',
 | 
			
		||||
                                                        'org.gnome.clocks');
 | 
			
		||||
        this._clockAppMon.connect('available-changed',
 | 
			
		||||
                                  this._sync.bind(this));
 | 
			
		||||
                                  Lang.bind(this, this._sync));
 | 
			
		||||
        this._clockAppMon.watchSetting('world-clocks',
 | 
			
		||||
                                       this._clocksChanged.bind(this));
 | 
			
		||||
                                       Lang.bind(this, this._clocksChanged));
 | 
			
		||||
        this._sync();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sync() {
 | 
			
		||||
    _sync: function() {
 | 
			
		||||
        this.actor.visible = this._clockAppMon.available;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _clocksChanged(settings) {
 | 
			
		||||
    _clocksChanged: function(settings) {
 | 
			
		||||
        this._grid.destroy_all_children();
 | 
			
		||||
        this._locations = [];
 | 
			
		||||
 | 
			
		||||
@@ -136,7 +139,7 @@ var WorldClocksSection = new Lang.Class({
 | 
			
		||||
                this._locations.push({ location: l });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._locations.sort((a, b) => {
 | 
			
		||||
        this._locations.sort(function(a, b) {
 | 
			
		||||
            return a.location.get_timezone().get_offset() -
 | 
			
		||||
                   b.location.get_timezone().get_offset();
 | 
			
		||||
        });
 | 
			
		||||
@@ -153,10 +156,8 @@ var WorldClocksSection = new Lang.Class({
 | 
			
		||||
        for (let i = 0; i < this._locations.length; i++) {
 | 
			
		||||
            let l = this._locations[i].location;
 | 
			
		||||
 | 
			
		||||
            let name = l.get_level() == GWeather.LocationLevel.NAMED_TIMEZONE ? l.get_name()
 | 
			
		||||
                                                                              : l.get_city_name();
 | 
			
		||||
            let label = new St.Label({ style_class: 'world-clocks-city',
 | 
			
		||||
                                       text: name,
 | 
			
		||||
                                       text: l.get_city_name(),
 | 
			
		||||
                                       x_align: Clutter.ActorAlign.START,
 | 
			
		||||
                                       x_expand: true });
 | 
			
		||||
 | 
			
		||||
@@ -178,7 +179,7 @@ var WorldClocksSection = new Lang.Class({
 | 
			
		||||
        if (this._grid.get_n_children() > 1) {
 | 
			
		||||
            if (!this._clockNotifyId)
 | 
			
		||||
                this._clockNotifyId =
 | 
			
		||||
                    this._clock.connect('notify::clock', this._updateLabels.bind(this));
 | 
			
		||||
                    this._clock.connect('notify::clock', Lang.bind(this, this._updateLabels));
 | 
			
		||||
            this._updateLabels();
 | 
			
		||||
        } else {
 | 
			
		||||
            if (this._clockNotifyId)
 | 
			
		||||
@@ -187,7 +188,7 @@ var WorldClocksSection = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateLabels() {
 | 
			
		||||
    _updateLabels: function() {
 | 
			
		||||
        for (let i = 0; i < this._locations.length; i++) {
 | 
			
		||||
            let l = this._locations[i];
 | 
			
		||||
            let tz = GLib.TimeZone.new(l.location.get_timezone().get_tzid());
 | 
			
		||||
@@ -200,7 +201,7 @@ var WorldClocksSection = new Lang.Class({
 | 
			
		||||
var WeatherSection = new Lang.Class({
 | 
			
		||||
    Name: 'WeatherSection',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._weatherClient = new Weather.WeatherClient();
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Button({ style_class: 'weather-button',
 | 
			
		||||
@@ -232,11 +233,11 @@ var WeatherSection = new Lang.Class({
 | 
			
		||||
        this._conditionsLabel.clutter_text.line_wrap = true;
 | 
			
		||||
        box.add_child(this._conditionsLabel);
 | 
			
		||||
 | 
			
		||||
        this._weatherClient.connect('changed', this._sync.bind(this));
 | 
			
		||||
        this._weatherClient.connect('changed', Lang.bind(this, this._sync));
 | 
			
		||||
        this._sync();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getSummary(info, capitalize=false) {
 | 
			
		||||
    _getSummary: function(info, capitalize=false) {
 | 
			
		||||
        let options = capitalize ? GWeather.FormatOptions.SENTENCE_CAPITALIZATION
 | 
			
		||||
                                 : GWeather.FormatOptions.NO_CAPITALIZATION;
 | 
			
		||||
 | 
			
		||||
@@ -250,7 +251,7 @@ var WeatherSection = new Lang.Class({
 | 
			
		||||
        return GWeather.Sky.to_string_full(sky, options);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sameSummary(info1, info2) {
 | 
			
		||||
    _sameSummary: function(info1, info2) {
 | 
			
		||||
        let [ok1, phenom1, qualifier1] = info1.get_value_conditions();
 | 
			
		||||
        let [ok2, phenom2, qualifier2] = info2.get_value_conditions();
 | 
			
		||||
        if (ok1 || ok2)
 | 
			
		||||
@@ -261,7 +262,7 @@ var WeatherSection = new Lang.Class({
 | 
			
		||||
        return sky1 == sky2;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getSummaryText() {
 | 
			
		||||
    _getSummaryText: function() {
 | 
			
		||||
        let info = this._weatherClient.info;
 | 
			
		||||
        let forecasts = info.get_forecast_list();
 | 
			
		||||
        if (forecasts.length == 0) // No forecasts, just current conditions
 | 
			
		||||
@@ -309,7 +310,7 @@ var WeatherSection = new Lang.Class({
 | 
			
		||||
        return String.prototype.format.apply(fmt, summaries);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getLabelText() {
 | 
			
		||||
    _getLabelText: function() {
 | 
			
		||||
        if (!this._weatherClient.hasLocation)
 | 
			
		||||
            return _("Select a location…");
 | 
			
		||||
 | 
			
		||||
@@ -328,7 +329,7 @@ var WeatherSection = new Lang.Class({
 | 
			
		||||
        return _("Weather information is currently unavailable");
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sync() {
 | 
			
		||||
    _sync: function() {
 | 
			
		||||
        this.actor.visible = this._weatherClient.available;
 | 
			
		||||
 | 
			
		||||
        if (!this.actor.visible)
 | 
			
		||||
@@ -341,7 +342,7 @@ var WeatherSection = new Lang.Class({
 | 
			
		||||
var MessagesIndicator = new Lang.Class({
 | 
			
		||||
    Name: 'MessagesIndicator',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.actor = new St.Icon({ icon_name: 'message-indicator-symbolic',
 | 
			
		||||
                                   icon_size: 16,
 | 
			
		||||
                                   visible: false, y_expand: true,
 | 
			
		||||
@@ -349,28 +350,31 @@ var MessagesIndicator = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._sources = [];
 | 
			
		||||
 | 
			
		||||
        Main.messageTray.connect('source-added', this._onSourceAdded.bind(this));
 | 
			
		||||
        Main.messageTray.connect('source-removed', this._onSourceRemoved.bind(this));
 | 
			
		||||
        Main.messageTray.connect('queue-changed', this._updateCount.bind(this));
 | 
			
		||||
        Main.messageTray.connect('source-added', Lang.bind(this, this._onSourceAdded));
 | 
			
		||||
        Main.messageTray.connect('source-removed', Lang.bind(this, this._onSourceRemoved));
 | 
			
		||||
        Main.messageTray.connect('queue-changed', Lang.bind(this, this._updateCount));
 | 
			
		||||
 | 
			
		||||
        let sources = Main.messageTray.getSources();
 | 
			
		||||
        sources.forEach(source => { this._onSourceAdded(null, source); });
 | 
			
		||||
        sources.forEach(Lang.bind(this, function(source) { this._onSourceAdded(null, source); }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSourceAdded(tray, source) {
 | 
			
		||||
        source.connect('count-updated', this._updateCount.bind(this));
 | 
			
		||||
    _onSourceAdded: function(tray, source) {
 | 
			
		||||
        source.connect('count-updated', Lang.bind(this, this._updateCount));
 | 
			
		||||
        this._sources.push(source);
 | 
			
		||||
        this._updateCount();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSourceRemoved(tray, source) {
 | 
			
		||||
    _onSourceRemoved: function(tray, source) {
 | 
			
		||||
        this._sources.splice(this._sources.indexOf(source), 1);
 | 
			
		||||
        this._updateCount();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateCount() {
 | 
			
		||||
    _updateCount: function() {
 | 
			
		||||
        let count = 0;
 | 
			
		||||
        this._sources.forEach(source => { count += source.unseenCount; });
 | 
			
		||||
        this._sources.forEach(Lang.bind(this,
 | 
			
		||||
            function(source) {
 | 
			
		||||
                count += source.unseenCount;
 | 
			
		||||
            }));
 | 
			
		||||
        count -= Main.messageTray.queueCount;
 | 
			
		||||
 | 
			
		||||
        this.actor.visible = (count > 0);
 | 
			
		||||
@@ -381,19 +385,19 @@ var IndicatorPad = new Lang.Class({
 | 
			
		||||
    Name: 'IndicatorPad',
 | 
			
		||||
    Extends: St.Widget,
 | 
			
		||||
 | 
			
		||||
    _init(actor) {
 | 
			
		||||
    _init: function(actor) {
 | 
			
		||||
        this._source = actor;
 | 
			
		||||
        this._source.connect('notify::visible', () => { this.queue_relayout(); });
 | 
			
		||||
        this.parent();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_get_preferred_width(container, forHeight) {
 | 
			
		||||
    vfunc_get_preferred_width: function(container, forHeight) {
 | 
			
		||||
        if (this._source.visible)
 | 
			
		||||
            return this._source.get_preferred_width(forHeight);
 | 
			
		||||
        return [0, 0];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_get_preferred_height(container, forWidth) {
 | 
			
		||||
    vfunc_get_preferred_height: function(container, forWidth) {
 | 
			
		||||
        if (this._source.visible)
 | 
			
		||||
            return this._source.get_preferred_height(forWidth);
 | 
			
		||||
        return [0, 0];
 | 
			
		||||
@@ -404,7 +408,7 @@ var FreezableBinLayout = new Lang.Class({
 | 
			
		||||
    Name: 'FreezableBinLayout',
 | 
			
		||||
    Extends: Clutter.BinLayout,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent();
 | 
			
		||||
 | 
			
		||||
        this._frozen = false;
 | 
			
		||||
@@ -421,19 +425,19 @@ var FreezableBinLayout = new Lang.Class({
 | 
			
		||||
            this.layout_changed();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_get_preferred_width(container, forHeight) {
 | 
			
		||||
    vfunc_get_preferred_width: function(container, forHeight) {
 | 
			
		||||
        if (!this._frozen || this._savedWidth.some(isNaN))
 | 
			
		||||
            return this.parent(container, forHeight);
 | 
			
		||||
        return this._savedWidth;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_get_preferred_height(container, forWidth) {
 | 
			
		||||
    vfunc_get_preferred_height: function(container, forWidth) {
 | 
			
		||||
        if (!this._frozen || this._savedHeight.some(isNaN))
 | 
			
		||||
            return this.parent(container, forWidth);
 | 
			
		||||
        return this._savedHeight;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_allocate(container, allocation, flags) {
 | 
			
		||||
    vfunc_allocate: function(container, allocation, flags) {
 | 
			
		||||
        this.parent(container, allocation, flags);
 | 
			
		||||
 | 
			
		||||
        let [width, height] = allocation.get_size();
 | 
			
		||||
@@ -446,12 +450,12 @@ var CalendarColumnLayout = new Lang.Class({
 | 
			
		||||
    Name: 'CalendarColumnLayout',
 | 
			
		||||
    Extends: Clutter.BoxLayout,
 | 
			
		||||
 | 
			
		||||
    _init(actor) {
 | 
			
		||||
    _init: function(actor) {
 | 
			
		||||
        this.parent({ orientation: Clutter.Orientation.VERTICAL });
 | 
			
		||||
        this._calActor = actor;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_get_preferred_width(container, forHeight) {
 | 
			
		||||
    vfunc_get_preferred_width: function(container, forHeight) {
 | 
			
		||||
        if (!this._calActor || this._calActor.get_parent() != container)
 | 
			
		||||
            return this.parent(container, forHeight);
 | 
			
		||||
        return this._calActor.get_preferred_width(forHeight);
 | 
			
		||||
@@ -462,7 +466,7 @@ var DateMenuButton = new Lang.Class({
 | 
			
		||||
    Name: 'DateMenuButton',
 | 
			
		||||
    Extends: PanelMenu.Button,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        let item;
 | 
			
		||||
        let hbox;
 | 
			
		||||
        let vbox;
 | 
			
		||||
@@ -496,12 +500,12 @@ var DateMenuButton = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._calendar = new Calendar.Calendar();
 | 
			
		||||
        this._calendar.connect('selected-date-changed',
 | 
			
		||||
                               (calendar, date) => {
 | 
			
		||||
                               Lang.bind(this, function(calendar, date) {
 | 
			
		||||
                                   layout.frozen = !_isToday(date);
 | 
			
		||||
                                   this._messageList.setDate(date);
 | 
			
		||||
                               });
 | 
			
		||||
                               }));
 | 
			
		||||
 | 
			
		||||
        this.menu.connect('open-state-changed', (menu, isOpen) => {
 | 
			
		||||
        this.menu.connect('open-state-changed', Lang.bind(this, function(menu, isOpen) {
 | 
			
		||||
            // Whenever the menu is opened, select today
 | 
			
		||||
            if (isOpen) {
 | 
			
		||||
                let now = new Date();
 | 
			
		||||
@@ -509,7 +513,7 @@ var DateMenuButton = new Lang.Class({
 | 
			
		||||
                this._date.setDate(now);
 | 
			
		||||
                this._messageList.setDate(now);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        // Fill up the first column
 | 
			
		||||
        this._messageList = new Calendar.CalendarMessageList();
 | 
			
		||||
@@ -547,17 +551,17 @@ var DateMenuButton = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._clock = new GnomeDesktop.WallClock();
 | 
			
		||||
        this._clock.bind_property('clock', this._clockDisplay, 'text', GObject.BindingFlags.SYNC_CREATE);
 | 
			
		||||
        this._clock.connect('notify::timezone', this._updateTimeZone.bind(this));
 | 
			
		||||
        this._clock.connect('notify::timezone', Lang.bind(this, this._updateTimeZone));
 | 
			
		||||
 | 
			
		||||
        Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
 | 
			
		||||
        Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
 | 
			
		||||
        this._sessionUpdated();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getEventSource() {
 | 
			
		||||
    _getEventSource: function() {
 | 
			
		||||
        return new Calendar.DBusEventSource();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setEventSource(eventSource) {
 | 
			
		||||
    _setEventSource: function(eventSource) {
 | 
			
		||||
        if (this._eventSource)
 | 
			
		||||
            this._eventSource.destroy();
 | 
			
		||||
 | 
			
		||||
@@ -567,7 +571,7 @@ var DateMenuButton = new Lang.Class({
 | 
			
		||||
        this._eventSource = eventSource;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateTimeZone() {
 | 
			
		||||
    _updateTimeZone: function() {
 | 
			
		||||
        // SpiderMonkey caches the time zone so we must explicitly clear it
 | 
			
		||||
        // before we can update the calendar, see
 | 
			
		||||
        // https://bugzilla.gnome.org/show_bug.cgi?id=678507
 | 
			
		||||
@@ -576,7 +580,7 @@ var DateMenuButton = new Lang.Class({
 | 
			
		||||
        this._calendar.updateTimeZone();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sessionUpdated() {
 | 
			
		||||
    _sessionUpdated: function() {
 | 
			
		||||
        let eventSource;
 | 
			
		||||
        let showEvents = Main.sessionMode.showCalendarEvents;
 | 
			
		||||
        if (showEvents) {
 | 
			
		||||
 
 | 
			
		||||
@@ -11,9 +11,9 @@ var Dialog = new Lang.Class({
 | 
			
		||||
    Name: 'Dialog',
 | 
			
		||||
    Extends: St.Widget,
 | 
			
		||||
 | 
			
		||||
    _init(parentActor, styleClass) {
 | 
			
		||||
    _init: function (parentActor, styleClass) {
 | 
			
		||||
        this.parent({ layout_manager: new Clutter.BinLayout() });
 | 
			
		||||
        this.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.connect('destroy', Lang.bind(this, this._onDestroy));
 | 
			
		||||
 | 
			
		||||
        this._initialKeyFocus = null;
 | 
			
		||||
        this._initialKeyFocusDestroyId = 0;
 | 
			
		||||
@@ -26,11 +26,11 @@ var Dialog = new Lang.Class({
 | 
			
		||||
            this._dialog.add_style_class_name(styleClass);
 | 
			
		||||
 | 
			
		||||
        this._parentActor = parentActor;
 | 
			
		||||
        this._eventId = this._parentActor.connect('event', this._modalEventHandler.bind(this));
 | 
			
		||||
        this._eventId = this._parentActor.connect('event', Lang.bind(this, this._modalEventHandler));
 | 
			
		||||
        this._parentActor.add_child(this);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createDialog() {
 | 
			
		||||
    _createDialog: function () {
 | 
			
		||||
        this._dialog = new St.BoxLayout({ style_class: 'modal-dialog',
 | 
			
		||||
                                          x_align:     Clutter.ActorAlign.CENTER,
 | 
			
		||||
                                          y_align:     Clutter.ActorAlign.CENTER,
 | 
			
		||||
@@ -56,13 +56,13 @@ var Dialog = new Lang.Class({
 | 
			
		||||
                           y_align: St.Align.START });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
    _onDestroy: function () {
 | 
			
		||||
        if (this._eventId != 0)
 | 
			
		||||
            this._parentActor.disconnect(this._eventId);
 | 
			
		||||
        this._eventId = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _modalEventHandler(actor, event) {
 | 
			
		||||
    _modalEventHandler: function (actor, event) {
 | 
			
		||||
        if (event.type() == Clutter.EventType.KEY_PRESS) {
 | 
			
		||||
            this._pressedKey = event.get_key_symbol();
 | 
			
		||||
        } else if (event.type() == Clutter.EventType.KEY_RELEASE) {
 | 
			
		||||
@@ -88,7 +88,7 @@ var Dialog = new Lang.Class({
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setInitialKeyFocus(actor) {
 | 
			
		||||
    _setInitialKeyFocus: function(actor) {
 | 
			
		||||
        if (this._initialKeyFocus)
 | 
			
		||||
            this._initialKeyFocus.disconnect(this._initialKeyFocusDestroyId);
 | 
			
		||||
 | 
			
		||||
@@ -104,11 +104,11 @@ var Dialog = new Lang.Class({
 | 
			
		||||
        return this._initialKeyFocus || this;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addContent(actor) {
 | 
			
		||||
    addContent: function (actor) {
 | 
			
		||||
        this.contentLayout.add (actor, { expand: true });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addButton(buttonInfo) {
 | 
			
		||||
    addButton: function (buttonInfo) {
 | 
			
		||||
        let { label, action, key } = buttonInfo;
 | 
			
		||||
        let isDefault = buttonInfo['default'];
 | 
			
		||||
        let keys;
 | 
			
		||||
@@ -145,7 +145,7 @@ var Dialog = new Lang.Class({
 | 
			
		||||
        return button;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    clearButtons() {
 | 
			
		||||
    clearButtons: function () {
 | 
			
		||||
        this.buttonLayout.destroy_all_children();
 | 
			
		||||
        this._buttonKeys = {};
 | 
			
		||||
    },
 | 
			
		||||
@@ -173,7 +173,7 @@ var MessageDialogContent = new Lang.Class({
 | 
			
		||||
                                         null)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _init(params) {
 | 
			
		||||
    _init: function(params) {
 | 
			
		||||
        this._icon = new St.Icon({ y_align: Clutter.ActorAlign.START });
 | 
			
		||||
        this._title = new St.Label({ style_class: 'headline' });
 | 
			
		||||
        this._subtitle = new St.Label();
 | 
			
		||||
@@ -243,7 +243,7 @@ var MessageDialogContent = new Lang.Class({
 | 
			
		||||
        this.notify(prop);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    insertBeforeBody(actor) {
 | 
			
		||||
    insertBeforeBody: function(actor) {
 | 
			
		||||
        this.messageBox.insert_child_below(actor, this._body);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										85
									
								
								js/ui/dnd.js
									
									
									
									
									
								
							
							
						
						@@ -49,9 +49,10 @@ function _getEventHandlerActor() {
 | 
			
		||||
        Main.uiGroup.add_actor(eventHandlerActor);
 | 
			
		||||
        // We connect to 'event' rather than 'captured-event' because the capturing phase doesn't happen
 | 
			
		||||
        // when you've grabbed the pointer.
 | 
			
		||||
        eventHandlerActor.connect('event', (actor, event) => {
 | 
			
		||||
            return currentDraggable._onEvent(actor, event);
 | 
			
		||||
        });
 | 
			
		||||
        eventHandlerActor.connect('event',
 | 
			
		||||
                                  function(actor, event) {
 | 
			
		||||
                                      return currentDraggable._onEvent(actor, event);
 | 
			
		||||
                                  });
 | 
			
		||||
    }
 | 
			
		||||
    return eventHandlerActor;
 | 
			
		||||
}
 | 
			
		||||
@@ -71,7 +72,7 @@ function removeDragMonitor(monitor) {
 | 
			
		||||
var _Draggable = new Lang.Class({
 | 
			
		||||
    Name: 'Draggable',
 | 
			
		||||
 | 
			
		||||
    _init(actor, params) {
 | 
			
		||||
    _init : function(actor, params) {
 | 
			
		||||
        params = Params.parse(params, { manualMode: false,
 | 
			
		||||
                                        restoreOnSuccess: false,
 | 
			
		||||
                                        dragActorMaxSize: undefined,
 | 
			
		||||
@@ -80,18 +81,18 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        this.actor = actor;
 | 
			
		||||
        if (!params.manualMode) {
 | 
			
		||||
            this.actor.connect('button-press-event',
 | 
			
		||||
                               this._onButtonPress.bind(this));
 | 
			
		||||
                               Lang.bind(this, this._onButtonPress));
 | 
			
		||||
            this.actor.connect('touch-event',
 | 
			
		||||
                               this._onTouchEvent.bind(this));
 | 
			
		||||
                               Lang.bind(this, this._onTouchEvent));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('destroy', () => {
 | 
			
		||||
        this.actor.connect('destroy', Lang.bind(this, function() {
 | 
			
		||||
            this._actorDestroyed = true;
 | 
			
		||||
 | 
			
		||||
            if (this._dragInProgress && this._dragCancellable)
 | 
			
		||||
                this._cancelDrag(global.get_current_time());
 | 
			
		||||
            this.disconnectAll();
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
        this._onEventId = null;
 | 
			
		||||
        this._touchSequence = null;
 | 
			
		||||
 | 
			
		||||
@@ -107,7 +108,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        this._eventsGrabbed = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onButtonPress(actor, event) {
 | 
			
		||||
    _onButtonPress : function (actor, event) {
 | 
			
		||||
        if (event.get_button() != 1)
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
 | 
			
		||||
@@ -124,7 +125,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onTouchEvent(actor, event) {
 | 
			
		||||
    _onTouchEvent: function (actor, event) {
 | 
			
		||||
        if (event.type() != Clutter.EventType.TOUCH_BEGIN ||
 | 
			
		||||
            !global.display.is_pointer_emulating_sequence(event.get_event_sequence()))
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
@@ -144,7 +145,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _grabDevice(actor) {
 | 
			
		||||
    _grabDevice: function(actor) {
 | 
			
		||||
        let manager = Clutter.DeviceManager.get_default();
 | 
			
		||||
        let pointer = manager.get_core_device(Clutter.InputDeviceType.POINTER_DEVICE);
 | 
			
		||||
 | 
			
		||||
@@ -156,7 +157,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        this._grabbedDevice = pointer;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _ungrabDevice() {
 | 
			
		||||
    _ungrabDevice: function() {
 | 
			
		||||
        if (this._touchSequence)
 | 
			
		||||
            this._grabbedDevice.sequence_ungrab (this._touchSequence);
 | 
			
		||||
        else
 | 
			
		||||
@@ -166,13 +167,13 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        this._grabbedDevice = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _grabActor() {
 | 
			
		||||
    _grabActor: function() {
 | 
			
		||||
        this._grabDevice(this.actor);
 | 
			
		||||
        this._onEventId = this.actor.connect('event',
 | 
			
		||||
                                             this._onEvent.bind(this));
 | 
			
		||||
                                             Lang.bind(this, this._onEvent));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _ungrabActor() {
 | 
			
		||||
    _ungrabActor: function() {
 | 
			
		||||
        if (!this._onEventId)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -181,7 +182,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        this._onEventId = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _grabEvents() {
 | 
			
		||||
    _grabEvents: function() {
 | 
			
		||||
        if (!this._eventsGrabbed) {
 | 
			
		||||
            this._eventsGrabbed = Main.pushModal(_getEventHandlerActor());
 | 
			
		||||
            if (this._eventsGrabbed)
 | 
			
		||||
@@ -189,7 +190,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _ungrabEvents() {
 | 
			
		||||
    _ungrabEvents: function() {
 | 
			
		||||
        if (this._eventsGrabbed) {
 | 
			
		||||
            this._ungrabDevice();
 | 
			
		||||
            Main.popModal(_getEventHandlerActor());
 | 
			
		||||
@@ -197,7 +198,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onEvent(actor, event) {
 | 
			
		||||
    _onEvent: function(actor, event) {
 | 
			
		||||
        // We intercept BUTTON_RELEASE event to know that the button was released in case we
 | 
			
		||||
        // didn't start the drag, to drop the draggable in case the drag was in progress, and
 | 
			
		||||
        // to complete the drag and ensure that whatever happens to be under the pointer does
 | 
			
		||||
@@ -248,7 +249,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
     * actors for other purposes (for example if you're using
 | 
			
		||||
     * PopupMenu.ignoreRelease())
 | 
			
		||||
     */
 | 
			
		||||
    fakeRelease() {
 | 
			
		||||
    fakeRelease: function() {
 | 
			
		||||
        this._buttonDown = false;
 | 
			
		||||
        this._ungrabActor();
 | 
			
		||||
    },
 | 
			
		||||
@@ -263,7 +264,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
     * This function is useful to call if you've specified manualMode
 | 
			
		||||
     * for the draggable.
 | 
			
		||||
     */
 | 
			
		||||
    startDrag(stageX, stageY, time, sequence) {
 | 
			
		||||
    startDrag: function (stageX, stageY, time, sequence) {
 | 
			
		||||
        currentDraggable = this;
 | 
			
		||||
        this._dragInProgress = true;
 | 
			
		||||
 | 
			
		||||
@@ -280,7 +281,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._touchSequence = sequence;
 | 
			
		||||
        this._grabEvents();
 | 
			
		||||
        global.display.set_cursor(Meta.Cursor.DND_IN_DRAG);
 | 
			
		||||
        global.screen.set_cursor(Meta.Cursor.DND_IN_DRAG);
 | 
			
		||||
 | 
			
		||||
        this._dragX = this._dragStartX = stageX;
 | 
			
		||||
        this._dragY = this._dragStartY = stageY;
 | 
			
		||||
@@ -370,7 +371,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
                                   scale_y: scale * origScale,
 | 
			
		||||
                                   time: SCALE_ANIMATION_TIME,
 | 
			
		||||
                                   transition: 'easeOutQuad',
 | 
			
		||||
                                   onUpdate() {
 | 
			
		||||
                                   onUpdate: function() {
 | 
			
		||||
                                       let currentScale = this._dragActor.scale_x / origScale;
 | 
			
		||||
                                       this._dragOffsetX = currentScale * origDragOffsetX;
 | 
			
		||||
                                       this._dragOffsetY = currentScale * origDragOffsetY;
 | 
			
		||||
@@ -382,7 +383,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _maybeStartDrag(event) {
 | 
			
		||||
    _maybeStartDrag:  function(event) {
 | 
			
		||||
        let [stageX, stageY] = event.get_coords();
 | 
			
		||||
 | 
			
		||||
        // See if the user has moved the mouse enough to trigger a drag
 | 
			
		||||
@@ -396,7 +397,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateDragHover() {
 | 
			
		||||
    _updateDragHover : function () {
 | 
			
		||||
        this._updateHoverId = 0;
 | 
			
		||||
        let target = this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
 | 
			
		||||
                                                                  this._dragX, this._dragY);
 | 
			
		||||
@@ -412,7 +413,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
            if (motionFunc) {
 | 
			
		||||
                let result = motionFunc(dragEvent);
 | 
			
		||||
                if (result != DragMotionResult.CONTINUE) {
 | 
			
		||||
                    global.display.set_cursor(DRAG_CURSOR_MAP[result]);
 | 
			
		||||
                    global.screen.set_cursor(DRAG_CURSOR_MAP[result]);
 | 
			
		||||
                    return GLib.SOURCE_REMOVE;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -430,26 +431,26 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
                                                             targY,
 | 
			
		||||
                                                             0);
 | 
			
		||||
                if (result != DragMotionResult.CONTINUE) {
 | 
			
		||||
                    global.display.set_cursor(DRAG_CURSOR_MAP[result]);
 | 
			
		||||
                    global.screen.set_cursor(DRAG_CURSOR_MAP[result]);
 | 
			
		||||
                    return GLib.SOURCE_REMOVE;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            target = target.get_parent();
 | 
			
		||||
        }
 | 
			
		||||
        global.display.set_cursor(Meta.Cursor.DND_IN_DRAG);
 | 
			
		||||
        global.screen.set_cursor(Meta.Cursor.DND_IN_DRAG);
 | 
			
		||||
        return GLib.SOURCE_REMOVE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _queueUpdateDragHover() {
 | 
			
		||||
    _queueUpdateDragHover: function() {
 | 
			
		||||
        if (this._updateHoverId)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._updateHoverId = GLib.idle_add(GLib.PRIORITY_DEFAULT,
 | 
			
		||||
                                            this._updateDragHover.bind(this));
 | 
			
		||||
                                            Lang.bind(this, this._updateDragHover));
 | 
			
		||||
        GLib.Source.set_name_by_id(this._updateHoverId, '[gnome-shell] this._updateDragHover');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateDragPosition(event) {
 | 
			
		||||
    _updateDragPosition : function (event) {
 | 
			
		||||
        let [stageX, stageY] = event.get_coords();
 | 
			
		||||
        this._dragX = stageX;
 | 
			
		||||
        this._dragY = stageY;
 | 
			
		||||
@@ -460,7 +461,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _dragActorDropped(event) {
 | 
			
		||||
    _dragActorDropped: function(event) {
 | 
			
		||||
        let [dropX, dropY] = event.get_coords();
 | 
			
		||||
        let target = this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
 | 
			
		||||
                                                                  dropX, dropY);
 | 
			
		||||
@@ -509,7 +510,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    this._dragInProgress = false;
 | 
			
		||||
                    global.display.set_cursor(Meta.Cursor.DEFAULT);
 | 
			
		||||
                    global.screen.set_cursor(Meta.Cursor.DEFAULT);
 | 
			
		||||
                    this.emit('drag-end', event.get_time(), true);
 | 
			
		||||
                    this._dragComplete();
 | 
			
		||||
                    return true;
 | 
			
		||||
@@ -523,7 +524,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getRestoreLocation() {
 | 
			
		||||
    _getRestoreLocation: function() {
 | 
			
		||||
        let x, y, scale;
 | 
			
		||||
 | 
			
		||||
        if (this._dragActorSource && this._dragActorSource.visible) {
 | 
			
		||||
@@ -555,13 +556,13 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        return [x, y, scale];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _cancelDrag(eventTime) {
 | 
			
		||||
    _cancelDrag: function(eventTime) {
 | 
			
		||||
        this.emit('drag-cancelled', eventTime);
 | 
			
		||||
        this._dragInProgress = false;
 | 
			
		||||
        let [snapBackX, snapBackY, snapBackScale] = this._getRestoreLocation();
 | 
			
		||||
 | 
			
		||||
        if (this._actorDestroyed) {
 | 
			
		||||
            global.display.set_cursor(Meta.Cursor.DEFAULT);
 | 
			
		||||
            global.screen.set_cursor(Meta.Cursor.DEFAULT);
 | 
			
		||||
            if (!this._buttonDown)
 | 
			
		||||
                this._dragComplete();
 | 
			
		||||
            this.emit('drag-end', eventTime, false);
 | 
			
		||||
@@ -580,7 +581,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
                             });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _restoreDragActor(eventTime) {
 | 
			
		||||
    _restoreDragActor: function(eventTime) {
 | 
			
		||||
        this._dragInProgress = false;
 | 
			
		||||
        let [restoreX, restoreY, restoreScale] = this._getRestoreLocation();
 | 
			
		||||
 | 
			
		||||
@@ -593,14 +594,14 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
                             { time: REVERT_ANIMATION_TIME });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _animateDragEnd(eventTime, params) {
 | 
			
		||||
    _animateDragEnd: function (eventTime, params) {
 | 
			
		||||
        this._animationInProgress = true;
 | 
			
		||||
 | 
			
		||||
        // finish animation if the actor gets destroyed
 | 
			
		||||
        // during it
 | 
			
		||||
        this._dragActorDestroyId =
 | 
			
		||||
            this._dragActor.connect('destroy',
 | 
			
		||||
                                    this._finishAnimation.bind(this));
 | 
			
		||||
                                    Lang.bind(this, this._finishAnimation));
 | 
			
		||||
 | 
			
		||||
        params['opacity']          = this._dragOrigOpacity;
 | 
			
		||||
        params['transition']       = 'easeOutQuad';
 | 
			
		||||
@@ -612,7 +613,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        Tweener.addTween(this._dragActor, params)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _finishAnimation() {
 | 
			
		||||
    _finishAnimation : function () {
 | 
			
		||||
        if (!this._animationInProgress)
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
@@ -620,10 +621,10 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        if (!this._buttonDown)
 | 
			
		||||
            this._dragComplete();
 | 
			
		||||
 | 
			
		||||
        global.display.set_cursor(Meta.Cursor.DEFAULT);
 | 
			
		||||
        global.screen.set_cursor(Meta.Cursor.DEFAULT);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onAnimationComplete(dragActor, eventTime) {
 | 
			
		||||
    _onAnimationComplete : function (dragActor, eventTime) {
 | 
			
		||||
        dragActor.disconnect(this._dragActorDestroyId);
 | 
			
		||||
        this._dragActorDestroyId = 0;
 | 
			
		||||
 | 
			
		||||
@@ -640,7 +641,7 @@ var _Draggable = new Lang.Class({
 | 
			
		||||
        this._finishAnimation();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _dragComplete() {
 | 
			
		||||
    _dragComplete: function() {
 | 
			
		||||
        if (!this._actorDestroyed)
 | 
			
		||||
            Shell.util_set_hidden_from_pick(this._dragActor, false);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,23 +16,25 @@ var EdgeDragAction = new Lang.Class({
 | 
			
		||||
    Extends: Clutter.GestureAction,
 | 
			
		||||
    Signals: { 'activated': {} },
 | 
			
		||||
 | 
			
		||||
    _init(side, allowedModes) {
 | 
			
		||||
    _init : function(side, allowedModes) {
 | 
			
		||||
        this.parent();
 | 
			
		||||
        this._side = side;
 | 
			
		||||
        this._allowedModes = allowedModes;
 | 
			
		||||
        this.set_n_touch_points(1);
 | 
			
		||||
 | 
			
		||||
        global.display.connect('grab-op-begin', () => { this.cancel(); });
 | 
			
		||||
        global.display.connect('grab-op-begin', Lang.bind(this, function() {
 | 
			
		||||
            this.cancel();
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getMonitorRect(x, y) {
 | 
			
		||||
    _getMonitorRect : function (x, y) {
 | 
			
		||||
        let rect = new Meta.Rectangle({ x: x - 1, y: y - 1, width: 1, height: 1 });
 | 
			
		||||
        let monitorIndex = global.display.get_monitor_index_for_rect(rect);
 | 
			
		||||
        let monitorIndex = global.screen.get_monitor_index_for_rect(rect);
 | 
			
		||||
 | 
			
		||||
        return global.display.get_monitor_geometry(monitorIndex);
 | 
			
		||||
        return global.screen.get_monitor_geometry(monitorIndex);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_gesture_prepare(action, actor) {
 | 
			
		||||
    vfunc_gesture_prepare : function(action, actor) {
 | 
			
		||||
        if (this.get_n_current_points() == 0)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
@@ -48,7 +50,7 @@ var EdgeDragAction = new Lang.Class({
 | 
			
		||||
                (this._side == St.Side.BOTTOM && y > monitorRect.y + monitorRect.height - EDGE_THRESHOLD));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_gesture_progress(action, actor) {
 | 
			
		||||
    vfunc_gesture_progress : function (action, actor) {
 | 
			
		||||
        let [startX, startY] = this.get_press_coords(0);
 | 
			
		||||
        let [x, y] = this.get_motion_coords(0);
 | 
			
		||||
        let offsetX = Math.abs (x - startX);
 | 
			
		||||
@@ -68,7 +70,7 @@ var EdgeDragAction = new Lang.Class({
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_gesture_end(action, actor) {
 | 
			
		||||
    vfunc_gesture_end : function (action, actor) {
 | 
			
		||||
        let [startX, startY] = this.get_press_coords(0);
 | 
			
		||||
        let [x, y] = this.get_motion_coords(0);
 | 
			
		||||
        let monitorRect = this._getMonitorRect(startX, startY);
 | 
			
		||||
 
 | 
			
		||||
@@ -63,12 +63,12 @@ const EndSessionDialogIface = '<node> \
 | 
			
		||||
const logoutDialogContent = {
 | 
			
		||||
    subjectWithUser: C_("title", "Log Out %s"),
 | 
			
		||||
    subject: C_("title", "Log Out"),
 | 
			
		||||
    descriptionWithUser(user, seconds) {
 | 
			
		||||
    descriptionWithUser: function(user, seconds) {
 | 
			
		||||
        return ngettext("%s will be logged out automatically in %d second.",
 | 
			
		||||
                        "%s will be logged out automatically in %d seconds.",
 | 
			
		||||
                        seconds).format(user, seconds);
 | 
			
		||||
    },
 | 
			
		||||
    description(seconds) {
 | 
			
		||||
    description: function(seconds) {
 | 
			
		||||
        return ngettext("You will be logged out automatically in %d second.",
 | 
			
		||||
                        "You will be logged out automatically in %d seconds.",
 | 
			
		||||
                        seconds).format(seconds);
 | 
			
		||||
@@ -83,7 +83,7 @@ const logoutDialogContent = {
 | 
			
		||||
const shutdownDialogContent = {
 | 
			
		||||
    subject: C_("title", "Power Off"),
 | 
			
		||||
    subjectWithUpdates: C_("title", "Install Updates & Power Off"),
 | 
			
		||||
    description(seconds) {
 | 
			
		||||
    description: function(seconds) {
 | 
			
		||||
        return ngettext("The system will power off automatically in %d second.",
 | 
			
		||||
                        "The system will power off automatically in %d seconds.",
 | 
			
		||||
                        seconds).format(seconds);
 | 
			
		||||
@@ -101,7 +101,7 @@ const shutdownDialogContent = {
 | 
			
		||||
 | 
			
		||||
const restartDialogContent = {
 | 
			
		||||
    subject: C_("title", "Restart"),
 | 
			
		||||
    description(seconds) {
 | 
			
		||||
    description: function(seconds) {
 | 
			
		||||
        return ngettext("The system will restart automatically in %d second.",
 | 
			
		||||
                        "The system will restart automatically in %d seconds.",
 | 
			
		||||
                        seconds).format(seconds);
 | 
			
		||||
@@ -117,7 +117,7 @@ const restartDialogContent = {
 | 
			
		||||
const restartUpdateDialogContent = {
 | 
			
		||||
 | 
			
		||||
    subject: C_("title", "Restart & Install Updates"),
 | 
			
		||||
    description(seconds) {
 | 
			
		||||
    description: function(seconds) {
 | 
			
		||||
        return ngettext("The system will automatically restart and install updates in %d second.",
 | 
			
		||||
                        "The system will automatically restart and install updates in %d seconds.",
 | 
			
		||||
                        seconds).format(seconds);
 | 
			
		||||
@@ -135,7 +135,7 @@ const restartUpdateDialogContent = {
 | 
			
		||||
const restartUpgradeDialogContent = {
 | 
			
		||||
 | 
			
		||||
    subject: C_("title", "Restart & Install Upgrade"),
 | 
			
		||||
    upgradeDescription(distroName, distroVersion) {
 | 
			
		||||
    upgradeDescription: function(distroName, distroVersion) {
 | 
			
		||||
        /* Translators: This is the text displayed for system upgrades in the
 | 
			
		||||
           shut down dialog. First %s gets replaced with the distro name and
 | 
			
		||||
           second %s with the distro version to upgrade to */
 | 
			
		||||
@@ -279,7 +279,7 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
    Name: 'EndSessionDialog',
 | 
			
		||||
    Extends: ModalDialog.ModalDialog,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent({ styleClass: 'end-session-dialog',
 | 
			
		||||
                      destroyOnClose: false });
 | 
			
		||||
 | 
			
		||||
@@ -290,22 +290,22 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
        this._pkOfflineProxy = new PkOfflineProxy(Gio.DBus.system,
 | 
			
		||||
                                                  'org.freedesktop.PackageKit',
 | 
			
		||||
                                                  '/org/freedesktop/PackageKit',
 | 
			
		||||
                                                  (proxy, error) => {
 | 
			
		||||
                                                  Lang.bind(this, function(proxy, error) {
 | 
			
		||||
                                                      if (error)
 | 
			
		||||
                                                          log(error.message);
 | 
			
		||||
                                                  });
 | 
			
		||||
                                                  }));
 | 
			
		||||
        this._powerProxy = new UPowerProxy(Gio.DBus.system,
 | 
			
		||||
                                           'org.freedesktop.UPower',
 | 
			
		||||
                                           '/org/freedesktop/UPower',
 | 
			
		||||
                                           (proxy, error) => {
 | 
			
		||||
                                           Lang.bind(this, function(proxy, error) {
 | 
			
		||||
                                               if (error) {
 | 
			
		||||
                                                   log(error.message);
 | 
			
		||||
                                                   return;
 | 
			
		||||
                                               }
 | 
			
		||||
                                               this._powerProxy.connect('g-properties-changed',
 | 
			
		||||
                                                                        this._sync.bind(this));
 | 
			
		||||
                                                                        Lang.bind(this, this._sync));
 | 
			
		||||
                                               this._sync();
 | 
			
		||||
                                           });
 | 
			
		||||
                                           }));
 | 
			
		||||
 | 
			
		||||
        this._secondsLeft = 0;
 | 
			
		||||
        this._totalSecondsToStayOpen = 0;
 | 
			
		||||
@@ -313,12 +313,12 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
        this._sessions = [];
 | 
			
		||||
 | 
			
		||||
        this.connect('destroy',
 | 
			
		||||
                     this._onDestroy.bind(this));
 | 
			
		||||
                     Lang.bind(this, this._onDestroy));
 | 
			
		||||
        this.connect('opened',
 | 
			
		||||
                     this._onOpened.bind(this));
 | 
			
		||||
                     Lang.bind(this, this._onOpened));
 | 
			
		||||
 | 
			
		||||
        this._userLoadedId = this._user.connect('notify::is_loaded', this._sync.bind(this));
 | 
			
		||||
        this._userChangedId = this._user.connect('changed', this._sync.bind(this));
 | 
			
		||||
        this._userLoadedId = this._user.connect('notify::is_loaded', Lang.bind(this, this._sync));
 | 
			
		||||
        this._userChangedId = this._user.connect('changed', Lang.bind(this, this._sync));
 | 
			
		||||
 | 
			
		||||
        let mainContentLayout = new St.BoxLayout({ vertical: false });
 | 
			
		||||
        this.contentLayout.add(mainContentLayout,
 | 
			
		||||
@@ -354,7 +354,7 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
                            y_align: St.Align.START });
 | 
			
		||||
 | 
			
		||||
        this._checkBox = new CheckBox.CheckBox();
 | 
			
		||||
        this._checkBox.actor.connect('clicked', this._sync.bind(this));
 | 
			
		||||
        this._checkBox.actor.connect('clicked', Lang.bind(this, this._sync));
 | 
			
		||||
        messageLayout.add(this._checkBox.actor);
 | 
			
		||||
 | 
			
		||||
        this._batteryWarning = new St.Label({ style_class: 'end-session-dialog-warning',
 | 
			
		||||
@@ -398,12 +398,12 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
        this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
        this._user.disconnect(this._userLoadedId);
 | 
			
		||||
        this._user.disconnect(this._userChangedId);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sync() {
 | 
			
		||||
    _sync: function() {
 | 
			
		||||
        let open = (this.state == ModalDialog.State.OPENING || this.state == ModalDialog.State.OPENED);
 | 
			
		||||
        if (!open)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -476,47 +476,48 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
        this._sessionHeader.visible = hasSessions;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateButtons() {
 | 
			
		||||
    _updateButtons: function() {
 | 
			
		||||
        let dialogContent = DialogContent[this._type];
 | 
			
		||||
        let buttons = [{ action: this.cancel.bind(this),
 | 
			
		||||
        let buttons = [{ action: Lang.bind(this, this.cancel),
 | 
			
		||||
                         label:  _("Cancel"),
 | 
			
		||||
                         key:    Clutter.Escape }];
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < dialogContent.confirmButtons.length; i++) {
 | 
			
		||||
            let signal = dialogContent.confirmButtons[i].signal;
 | 
			
		||||
            let label = dialogContent.confirmButtons[i].label;
 | 
			
		||||
            buttons.push({ action: () => {
 | 
			
		||||
                               this.close(true);
 | 
			
		||||
                               let signalId = this.connect('closed', () => {
 | 
			
		||||
                                   this.disconnect(signalId);
 | 
			
		||||
                                   this._confirm(signal);
 | 
			
		||||
                               });
 | 
			
		||||
                           },
 | 
			
		||||
            buttons.push({ action: Lang.bind(this, function() {
 | 
			
		||||
                                       this.close(true);
 | 
			
		||||
                                       let signalId = this.connect('closed',
 | 
			
		||||
                                                                   Lang.bind(this, function() {
 | 
			
		||||
                                                                       this.disconnect(signalId);
 | 
			
		||||
                                                                       this._confirm(signal);
 | 
			
		||||
                                                                   }));
 | 
			
		||||
                                   }),
 | 
			
		||||
                           label: label });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.setButtons(buttons);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    close(skipSignal) {
 | 
			
		||||
    close: function(skipSignal) {
 | 
			
		||||
        this.parent();
 | 
			
		||||
 | 
			
		||||
        if (!skipSignal)
 | 
			
		||||
            this._dbusImpl.emit_signal('Closed', null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    cancel() {
 | 
			
		||||
    cancel: function() {
 | 
			
		||||
        this._stopTimer();
 | 
			
		||||
        this._dbusImpl.emit_signal('Canceled', null);
 | 
			
		||||
        this.close();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _confirm(signal) {
 | 
			
		||||
        let callback = () => {
 | 
			
		||||
    _confirm: function(signal) {
 | 
			
		||||
        let callback = Lang.bind(this, function() {
 | 
			
		||||
            this._fadeOutDialog();
 | 
			
		||||
            this._stopTimer();
 | 
			
		||||
            this._dbusImpl.emit_signal(signal, null);
 | 
			
		||||
        };
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Offline update not available; just emit the signal
 | 
			
		||||
        if (!this._checkBox.actor.visible) {
 | 
			
		||||
@@ -546,12 +547,13 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onOpened() {
 | 
			
		||||
    _onOpened: function() {
 | 
			
		||||
        this._sync();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _triggerOfflineUpdateReboot(callback) {
 | 
			
		||||
        this._pkOfflineProxy.TriggerRemote('reboot', (result, error) => {
 | 
			
		||||
    _triggerOfflineUpdateReboot: function(callback) {
 | 
			
		||||
        this._pkOfflineProxy.TriggerRemote('reboot',
 | 
			
		||||
                                           function (result, error) {
 | 
			
		||||
            if (error)
 | 
			
		||||
                log(error.message);
 | 
			
		||||
 | 
			
		||||
@@ -559,8 +561,9 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _triggerOfflineUpdateShutdown(callback) {
 | 
			
		||||
        this._pkOfflineProxy.TriggerRemote('power-off', (result, error) => {
 | 
			
		||||
    _triggerOfflineUpdateShutdown: function(callback) {
 | 
			
		||||
        this._pkOfflineProxy.TriggerRemote('power-off',
 | 
			
		||||
                                           function (result, error) {
 | 
			
		||||
            if (error)
 | 
			
		||||
                log(error.message);
 | 
			
		||||
 | 
			
		||||
@@ -568,8 +571,8 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _triggerOfflineUpdateCancel(callback) {
 | 
			
		||||
        this._pkOfflineProxy.CancelRemote((result, error) => {
 | 
			
		||||
    _triggerOfflineUpdateCancel: function(callback) {
 | 
			
		||||
        this._pkOfflineProxy.CancelRemote(function (result, error) {
 | 
			
		||||
            if (error)
 | 
			
		||||
                log(error.message);
 | 
			
		||||
 | 
			
		||||
@@ -577,31 +580,32 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _startTimer() {
 | 
			
		||||
    _startTimer: function() {
 | 
			
		||||
        let startTime = GLib.get_monotonic_time();
 | 
			
		||||
        this._secondsLeft = this._totalSecondsToStayOpen;
 | 
			
		||||
 | 
			
		||||
        this._timerId = Mainloop.timeout_add_seconds(1, () => {
 | 
			
		||||
            let currentTime = GLib.get_monotonic_time();
 | 
			
		||||
            let secondsElapsed = ((currentTime - startTime) / 1000000);
 | 
			
		||||
        this._timerId = Mainloop.timeout_add_seconds(1, Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                let currentTime = GLib.get_monotonic_time();
 | 
			
		||||
                let secondsElapsed = ((currentTime - startTime) / 1000000);
 | 
			
		||||
 | 
			
		||||
            this._secondsLeft = this._totalSecondsToStayOpen - secondsElapsed;
 | 
			
		||||
            if (this._secondsLeft > 0) {
 | 
			
		||||
                this._sync();
 | 
			
		||||
                return GLib.SOURCE_CONTINUE;
 | 
			
		||||
            }
 | 
			
		||||
                this._secondsLeft = this._totalSecondsToStayOpen - secondsElapsed;
 | 
			
		||||
                if (this._secondsLeft > 0) {
 | 
			
		||||
                    this._sync();
 | 
			
		||||
                    return GLib.SOURCE_CONTINUE;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            let dialogContent = DialogContent[this._type];
 | 
			
		||||
            let button = dialogContent.confirmButtons[dialogContent.confirmButtons.length - 1];
 | 
			
		||||
            this._confirm(button.signal);
 | 
			
		||||
            this._timerId = 0;
 | 
			
		||||
                let dialogContent = DialogContent[this._type];
 | 
			
		||||
                let button = dialogContent.confirmButtons[dialogContent.confirmButtons.length - 1];
 | 
			
		||||
                this._confirm(button.signal);
 | 
			
		||||
                this._timerId = 0;
 | 
			
		||||
 | 
			
		||||
            return GLib.SOURCE_REMOVE;
 | 
			
		||||
        });
 | 
			
		||||
                return GLib.SOURCE_REMOVE;
 | 
			
		||||
            }));
 | 
			
		||||
        GLib.Source.set_name_by_id(this._timerId, '[gnome-shell] this._confirm');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _stopTimer() {
 | 
			
		||||
    _stopTimer: function() {
 | 
			
		||||
        if (this._timerId > 0) {
 | 
			
		||||
            Mainloop.source_remove(this._timerId);
 | 
			
		||||
            this._timerId = 0;
 | 
			
		||||
@@ -610,7 +614,7 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
        this._secondsLeft = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _constructListItemForApp(inhibitor, app) {
 | 
			
		||||
    _constructListItemForApp: function(inhibitor, app) {
 | 
			
		||||
        let actor = new St.BoxLayout({ style_class: 'end-session-dialog-app-list-item',
 | 
			
		||||
                                       can_focus: true });
 | 
			
		||||
        actor.add(app.create_icon_texture(_ITEM_ICON_SIZE));
 | 
			
		||||
@@ -635,7 +639,7 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
        return actor;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onInhibitorLoaded(inhibitor) {
 | 
			
		||||
    _onInhibitorLoaded: function(inhibitor) {
 | 
			
		||||
        if (this._applications.indexOf(inhibitor) < 0) {
 | 
			
		||||
            // Stale inhibitor
 | 
			
		||||
            return;
 | 
			
		||||
@@ -654,7 +658,7 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
        this._sync();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _constructListItemForSession(session) {
 | 
			
		||||
    _constructListItemForSession: function(session) {
 | 
			
		||||
        let avatar = new UserWidget.Avatar(session.user, { iconSize: _ITEM_ICON_SIZE });
 | 
			
		||||
        avatar.update();
 | 
			
		||||
 | 
			
		||||
@@ -684,8 +688,8 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
        return actor;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _loadSessions() {
 | 
			
		||||
        this._loginManager.listSessions(result => {
 | 
			
		||||
    _loadSessions: function() {
 | 
			
		||||
        this._loginManager.listSessions(Lang.bind(this, function(result) {
 | 
			
		||||
            let n = 0;
 | 
			
		||||
            for (let i = 0; i < result.length; i++) {
 | 
			
		||||
                let[id, uid, userName, seat, sessionPath] = result[i];
 | 
			
		||||
@@ -697,14 +701,7 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
                if (proxy.State == 'closing')
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                let sessionId = GLib.getenv('XDG_SESSION_ID');
 | 
			
		||||
                if (!sessionId)
 | 
			
		||||
                    this._loginManager.getCurrentSessionProxy(currentSessionProxy => {
 | 
			
		||||
                        sessionId = currentSessionProxy.Id;
 | 
			
		||||
                        log(`endSessionDialog: No XDG_SESSION_ID, fetched from logind: ${sessionId}`);
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                if (proxy.Id == sessionId)
 | 
			
		||||
                if (proxy.Id == GLib.getenv('XDG_SESSION_ID'))
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                let session = { user: this._userManager.get_user(userName),
 | 
			
		||||
@@ -723,10 +720,10 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this._sync();
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    OpenAsync(parameters, invocation) {
 | 
			
		||||
    OpenAsync: function(parameters, invocation) {
 | 
			
		||||
        let [type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths] = parameters;
 | 
			
		||||
        this._totalSecondsToStayOpen = totalSecondsToStayOpen;
 | 
			
		||||
        this._type = type;
 | 
			
		||||
@@ -753,9 +750,9 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
        let dialogContent = DialogContent[this._type];
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < inhibitorObjectPaths.length; i++) {
 | 
			
		||||
            let inhibitor = new GnomeSession.Inhibitor(inhibitorObjectPaths[i], (proxy, error) => {
 | 
			
		||||
            let inhibitor = new GnomeSession.Inhibitor(inhibitorObjectPaths[i], Lang.bind(this, function(proxy, error) {
 | 
			
		||||
                this._onInhibitorLoaded(proxy);
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
            this._applications.push(inhibitor);
 | 
			
		||||
        }
 | 
			
		||||
@@ -790,13 +787,14 @@ var EndSessionDialog = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._sync();
 | 
			
		||||
 | 
			
		||||
        let signalId = this.connect('opened', () => {
 | 
			
		||||
            invocation.return_value(null);
 | 
			
		||||
            this.disconnect(signalId);
 | 
			
		||||
        });
 | 
			
		||||
        let signalId = this.connect('opened',
 | 
			
		||||
                                    Lang.bind(this, function() {
 | 
			
		||||
                                        invocation.return_value(null);
 | 
			
		||||
                                        this.disconnect(signalId);
 | 
			
		||||
                                    }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    Close(parameters, invocation) {
 | 
			
		||||
    Close: function(parameters, invocation) {
 | 
			
		||||
        this.close();
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -47,14 +47,14 @@ function _patchContainerClass(containerClass) {
 | 
			
		||||
function _patchLayoutClass(layoutClass, styleProps) {
 | 
			
		||||
    if (styleProps)
 | 
			
		||||
        layoutClass.prototype.hookup_style = function(container) {
 | 
			
		||||
            container.connect('style-changed', () => {
 | 
			
		||||
            container.connect('style-changed', Lang.bind(this, function() {
 | 
			
		||||
                let node = container.get_theme_node();
 | 
			
		||||
                for (let prop in styleProps) {
 | 
			
		||||
                    let [found, length] = node.lookup_length(styleProps[prop], false);
 | 
			
		||||
                    if (found)
 | 
			
		||||
                        this[prop] = length;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
        };
 | 
			
		||||
    layoutClass.prototype.child_set = function(actor, props) {
 | 
			
		||||
        let meta = this.get_child_meta(actor.get_parent(), actor);
 | 
			
		||||
@@ -88,7 +88,7 @@ function init() {
 | 
			
		||||
    window._ = Gettext.gettext;
 | 
			
		||||
    window.C_ = Gettext.pgettext;
 | 
			
		||||
    window.ngettext = Gettext.ngettext;
 | 
			
		||||
    window.N_ = s => s;
 | 
			
		||||
    window.N_ = function(s) { return s; };
 | 
			
		||||
 | 
			
		||||
    // Miscellaneous monkeypatching
 | 
			
		||||
    _patchContainerClass(St.BoxLayout);
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ function installExtension(uuid, invocation) {
 | 
			
		||||
 | 
			
		||||
    let message = Soup.form_request_new_from_hash('GET', REPOSITORY_URL_INFO, params);
 | 
			
		||||
 | 
			
		||||
    _httpSession.queue_message(message, (session, message) => {
 | 
			
		||||
    _httpSession.queue_message(message, function(session, message) {
 | 
			
		||||
        if (message.status_code != Soup.KnownStatusCode.OK) {
 | 
			
		||||
            ExtensionSystem.logExtensionError(uuid, 'downloading info: ' + message.status_code);
 | 
			
		||||
            invocation.return_dbus_error('org.gnome.Shell.DownloadInfoError', message.status_code.toString());
 | 
			
		||||
@@ -96,7 +96,7 @@ function gotExtensionZipFile(session, message, uuid, dir, callback, errback) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, (pid, status) => {
 | 
			
		||||
    GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function(pid, status) {
 | 
			
		||||
        GLib.spawn_close_pid(pid);
 | 
			
		||||
 | 
			
		||||
        if (status != 0)
 | 
			
		||||
@@ -119,8 +119,8 @@ function updateExtension(uuid) {
 | 
			
		||||
    let url = REPOSITORY_URL_DOWNLOAD.format(uuid);
 | 
			
		||||
    let message = Soup.form_request_new_from_hash('GET', url, params);
 | 
			
		||||
 | 
			
		||||
    _httpSession.queue_message(message, (session, message) => {
 | 
			
		||||
        gotExtensionZipFile(session, message, uuid, newExtensionTmpDir, () => {
 | 
			
		||||
    _httpSession.queue_message(message, Lang.bind(this, function(session, message) {
 | 
			
		||||
        gotExtensionZipFile(session, message, uuid, newExtensionTmpDir, function() {
 | 
			
		||||
            let oldExtension = ExtensionUtils.extensions[uuid];
 | 
			
		||||
            let extensionDir = oldExtension.dir;
 | 
			
		||||
 | 
			
		||||
@@ -151,10 +151,10 @@ function updateExtension(uuid) {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            FileUtils.recursivelyDeleteDir(oldExtensionTmpDir, true);
 | 
			
		||||
        }, (code, message) => {
 | 
			
		||||
        }, function(code, message) {
 | 
			
		||||
            log('Error while updating extension %s: %s (%s)'.format(uuid, code, message ? message : ''));
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    }));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function checkForUpdates() {
 | 
			
		||||
@@ -168,7 +168,7 @@ function checkForUpdates() {
 | 
			
		||||
 | 
			
		||||
    let url = REPOSITORY_URL_UPDATE;
 | 
			
		||||
    let message = Soup.form_request_new_from_hash('GET', url, params);
 | 
			
		||||
    _httpSession.queue_message(message, (session, message) => {
 | 
			
		||||
    _httpSession.queue_message(message, function(session, message) {
 | 
			
		||||
        if (message.status_code != Soup.KnownStatusCode.OK)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -187,7 +187,7 @@ var InstallExtensionDialog = new Lang.Class({
 | 
			
		||||
    Name: 'InstallExtensionDialog',
 | 
			
		||||
    Extends: ModalDialog.ModalDialog,
 | 
			
		||||
 | 
			
		||||
    _init(uuid, info, invocation) {
 | 
			
		||||
    _init: function(uuid, info, invocation) {
 | 
			
		||||
        this.parent({ styleClass: 'extension-dialog' });
 | 
			
		||||
 | 
			
		||||
        this._uuid = uuid;
 | 
			
		||||
@@ -195,11 +195,11 @@ var InstallExtensionDialog = new Lang.Class({
 | 
			
		||||
        this._invocation = invocation;
 | 
			
		||||
 | 
			
		||||
        this.setButtons([{ label: _("Cancel"),
 | 
			
		||||
                           action: this._onCancelButtonPressed.bind(this),
 | 
			
		||||
                           action: Lang.bind(this, this._onCancelButtonPressed),
 | 
			
		||||
                           key:    Clutter.Escape
 | 
			
		||||
                         },
 | 
			
		||||
                         { label:  _("Install"),
 | 
			
		||||
                           action: this._onInstallButtonPressed.bind(this),
 | 
			
		||||
                           action: Lang.bind(this, this._onInstallButtonPressed),
 | 
			
		||||
                           default: true
 | 
			
		||||
                         }]);
 | 
			
		||||
 | 
			
		||||
@@ -218,12 +218,12 @@ var InstallExtensionDialog = new Lang.Class({
 | 
			
		||||
        box.add(label);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onCancelButtonPressed(button, event) {
 | 
			
		||||
    _onCancelButtonPressed: function(button, event) {
 | 
			
		||||
        this.close();
 | 
			
		||||
        this._invocation.return_value(GLib.Variant.new('(s)', ['cancelled']));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onInstallButtonPressed(button, event) {
 | 
			
		||||
    _onInstallButtonPressed: function(button, event) {
 | 
			
		||||
        let params = { shell_version: Config.PACKAGE_VERSION };
 | 
			
		||||
 | 
			
		||||
        let url = REPOSITORY_URL_DOWNLOAD.format(this._uuid);
 | 
			
		||||
@@ -258,9 +258,9 @@ var InstallExtensionDialog = new Lang.Class({
 | 
			
		||||
            invocation.return_value(GLib.Variant.new('(s)', ['successful']));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _httpSession.queue_message(message, (session, message) => {
 | 
			
		||||
        _httpSession.queue_message(message, Lang.bind(this, function(session, message) {
 | 
			
		||||
            gotExtensionZipFile(session, message, uuid, dir, callback, errback);
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this.close();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -34,8 +34,8 @@ var extensionOrder = [];
 | 
			
		||||
var _signals = {};
 | 
			
		||||
Signals.addSignalMethods(_signals);
 | 
			
		||||
 | 
			
		||||
var connect = _signals.connect.bind(_signals);
 | 
			
		||||
var disconnect = _signals.disconnect.bind(_signals);
 | 
			
		||||
var connect = Lang.bind(_signals, _signals.connect);
 | 
			
		||||
var disconnect = Lang.bind(_signals, _signals.disconnect);
 | 
			
		||||
 | 
			
		||||
const ENABLED_EXTENSIONS_KEY = 'enabled-extensions';
 | 
			
		||||
const DISABLE_USER_EXTENSIONS_KEY = 'disable-user-extensions';
 | 
			
		||||
@@ -273,17 +273,17 @@ function onEnabledExtensionsChanged() {
 | 
			
		||||
 | 
			
		||||
    // Find and enable all the newly enabled extensions: UUIDs found in the
 | 
			
		||||
    // new setting, but not in the old one.
 | 
			
		||||
    newEnabledExtensions.filter(
 | 
			
		||||
        uuid => !enabledExtensions.includes(uuid)
 | 
			
		||||
    ).forEach(uuid => {
 | 
			
		||||
    newEnabledExtensions.filter(function(uuid) {
 | 
			
		||||
        return enabledExtensions.indexOf(uuid) == -1;
 | 
			
		||||
    }).forEach(function(uuid) {
 | 
			
		||||
        enableExtension(uuid);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Find and disable all the newly disabled extensions: UUIDs found in the
 | 
			
		||||
    // old setting, but not in the new one.
 | 
			
		||||
    enabledExtensions.filter(
 | 
			
		||||
        item => !newEnabledExtensions.includes(item)
 | 
			
		||||
    ).forEach(uuid => {
 | 
			
		||||
    enabledExtensions.filter(function(item) {
 | 
			
		||||
        return newEnabledExtensions.indexOf(item) == -1;
 | 
			
		||||
    }).forEach(function(uuid) {
 | 
			
		||||
        disableExtension(uuid);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
@@ -300,7 +300,7 @@ function _onVersionValidationChanged() {
 | 
			
		||||
    enabledExtensions = getEnabledExtensions();
 | 
			
		||||
 | 
			
		||||
    if (Main.sessionMode.allowExtensions) {
 | 
			
		||||
        enabledExtensions.forEach(uuid => {
 | 
			
		||||
        enabledExtensions.forEach(function(uuid) {
 | 
			
		||||
            enableExtension(uuid);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
@@ -314,7 +314,7 @@ function _loadExtensions() {
 | 
			
		||||
    enabledExtensions = getEnabledExtensions();
 | 
			
		||||
 | 
			
		||||
    let finder = new ExtensionUtils.ExtensionFinder();
 | 
			
		||||
    finder.connect('extension-found', (finder, extension) => {
 | 
			
		||||
    finder.connect('extension-found', function(finder, extension) {
 | 
			
		||||
        loadExtension(extension);
 | 
			
		||||
    });
 | 
			
		||||
    finder.scanExtensions();
 | 
			
		||||
@@ -328,7 +328,7 @@ function enableAllExtensions() {
 | 
			
		||||
        _loadExtensions();
 | 
			
		||||
        initted = true;
 | 
			
		||||
    } else {
 | 
			
		||||
        enabledExtensions.forEach(uuid => {
 | 
			
		||||
        enabledExtensions.forEach(function(uuid) {
 | 
			
		||||
            enableExtension(uuid);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
@@ -340,7 +340,7 @@ function disableAllExtensions() {
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (initted) {
 | 
			
		||||
        extensionOrder.slice().reverse().forEach(uuid => {
 | 
			
		||||
        extensionOrder.slice().reverse().forEach(function(uuid) {
 | 
			
		||||
            disableExtension(uuid);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -31,22 +31,22 @@ const STATECHANGED      = 'object:state-changed';
 | 
			
		||||
var FocusCaretTracker = new Lang.Class({
 | 
			
		||||
    Name: 'FocusCaretTracker',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
        this._atspiListener = Atspi.EventListener.new(this._onChanged.bind(this));
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._atspiListener = Atspi.EventListener.new(Lang.bind(this, this._onChanged));
 | 
			
		||||
 | 
			
		||||
        this._atspiInited = false;
 | 
			
		||||
        this._focusListenerRegistered = false;
 | 
			
		||||
        this._caretListenerRegistered = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onChanged(event) {
 | 
			
		||||
    _onChanged: function(event) {
 | 
			
		||||
        if (event.type.indexOf(STATECHANGED) == 0)
 | 
			
		||||
            this.emit('focus-changed', event);
 | 
			
		||||
        else if (event.type == CARETMOVED)
 | 
			
		||||
            this.emit('caret-moved', event);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _initAtspi() {
 | 
			
		||||
    _initAtspi: function() {
 | 
			
		||||
        if (!this._atspiInited && Atspi.init() == 0) {
 | 
			
		||||
            Atspi.set_timeout(250, 250);
 | 
			
		||||
            this._atspiInited = true;
 | 
			
		||||
@@ -55,7 +55,7 @@ var FocusCaretTracker = new Lang.Class({
 | 
			
		||||
	return this._atspiInited;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    registerFocusListener() {
 | 
			
		||||
    registerFocusListener: function() {
 | 
			
		||||
        if (!this._initAtspi() || this._focusListenerRegistered)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -64,7 +64,7 @@ var FocusCaretTracker = new Lang.Class({
 | 
			
		||||
        this._focusListenerRegistered = true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    registerCaretListener() {
 | 
			
		||||
    registerCaretListener: function() {
 | 
			
		||||
        if (!this._initAtspi() || this._caretListenerRegistered)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -72,7 +72,7 @@ var FocusCaretTracker = new Lang.Class({
 | 
			
		||||
        this._caretListenerRegistered = true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    deregisterFocusListener() {
 | 
			
		||||
    deregisterFocusListener: function() {
 | 
			
		||||
        if (!this._focusListenerRegistered)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -81,7 +81,7 @@ var FocusCaretTracker = new Lang.Class({
 | 
			
		||||
        this._focusListenerRegistered = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    deregisterCaretListener() {
 | 
			
		||||
    deregisterCaretListener: function() {
 | 
			
		||||
        if (!this._caretListenerRegistered)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,7 @@ function _popGrabHelper(grabHelper) {
 | 
			
		||||
var GrabHelper = new Lang.Class({
 | 
			
		||||
    Name: 'GrabHelper',
 | 
			
		||||
 | 
			
		||||
    _init(owner, params) {
 | 
			
		||||
    _init: function(owner, params) {
 | 
			
		||||
        this._owner = owner;
 | 
			
		||||
        this._modalParams = params;
 | 
			
		||||
 | 
			
		||||
@@ -66,10 +66,8 @@ var GrabHelper = new Lang.Class({
 | 
			
		||||
    //
 | 
			
		||||
    // Adds @actor to the set of actors that are allowed to process events
 | 
			
		||||
    // during a grab.
 | 
			
		||||
    addActor(actor) {
 | 
			
		||||
        actor.__grabHelperDestroyId = actor.connect('destroy', () => {
 | 
			
		||||
            this.removeActor(actor);
 | 
			
		||||
        });
 | 
			
		||||
    addActor: function(actor) {
 | 
			
		||||
        actor.__grabHelperDestroyId = actor.connect('destroy', Lang.bind(this, function() { this.removeActor(actor); }));
 | 
			
		||||
        this._actors.push(actor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -78,7 +76,7 @@ var GrabHelper = new Lang.Class({
 | 
			
		||||
    //
 | 
			
		||||
    // Removes @actor from the set of actors that are allowed to
 | 
			
		||||
    // process events during a grab.
 | 
			
		||||
    removeActor(actor) {
 | 
			
		||||
    removeActor: function(actor) {
 | 
			
		||||
        let index = this._actors.indexOf(actor);
 | 
			
		||||
        if (index != -1)
 | 
			
		||||
            this._actors.splice(index, 1);
 | 
			
		||||
@@ -88,7 +86,7 @@ var GrabHelper = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _isWithinGrabbedActor(actor) {
 | 
			
		||||
    _isWithinGrabbedActor: function(actor) {
 | 
			
		||||
        let currentActor = this.currentGrab.actor;
 | 
			
		||||
        while (actor) {
 | 
			
		||||
            if (this._actors.indexOf(actor) != -1)
 | 
			
		||||
@@ -112,7 +110,7 @@ var GrabHelper = new Lang.Class({
 | 
			
		||||
        return this._grabStack;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _findStackIndex(actor) {
 | 
			
		||||
    _findStackIndex: function(actor) {
 | 
			
		||||
        if (!actor)
 | 
			
		||||
            return -1;
 | 
			
		||||
 | 
			
		||||
@@ -123,7 +121,7 @@ var GrabHelper = new Lang.Class({
 | 
			
		||||
        return -1;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _actorInGrabStack(actor) {
 | 
			
		||||
    _actorInGrabStack: function(actor) {
 | 
			
		||||
        while (actor) {
 | 
			
		||||
            let idx = this._findStackIndex(actor);
 | 
			
		||||
            if (idx >= 0)
 | 
			
		||||
@@ -133,7 +131,7 @@ var GrabHelper = new Lang.Class({
 | 
			
		||||
        return -1;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    isActorGrabbed(actor) {
 | 
			
		||||
    isActorGrabbed: function(actor) {
 | 
			
		||||
        return this._findStackIndex(actor) >= 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -168,7 +166,7 @@ var GrabHelper = new Lang.Class({
 | 
			
		||||
    // to that actor instead of navigating in @params.actor. This is for
 | 
			
		||||
    // use cases like menus, where we want to grab the menu actor, but keep
 | 
			
		||||
    // focus on the clicked on menu item.
 | 
			
		||||
    grab(params) {
 | 
			
		||||
    grab: function(params) {
 | 
			
		||||
        params = Params.parse(params, { actor: null,
 | 
			
		||||
                                        focus: null,
 | 
			
		||||
                                        onUngrab: null });
 | 
			
		||||
@@ -197,7 +195,7 @@ var GrabHelper = new Lang.Class({
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _takeModalGrab() {
 | 
			
		||||
    _takeModalGrab: function() {
 | 
			
		||||
        let firstGrab = (this._modalCount == 0);
 | 
			
		||||
        if (firstGrab) {
 | 
			
		||||
            if (!Main.pushModal(this._owner, this._modalParams))
 | 
			
		||||
@@ -210,7 +208,7 @@ var GrabHelper = new Lang.Class({
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _releaseModalGrab() {
 | 
			
		||||
    _releaseModalGrab: function() {
 | 
			
		||||
        this._modalCount--;
 | 
			
		||||
        if (this._modalCount > 0)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -229,7 +227,7 @@ var GrabHelper = new Lang.Class({
 | 
			
		||||
    // capture event handler returns false. This is designed for things
 | 
			
		||||
    // like the ComboBoxMenu that go away on press, but need to eat
 | 
			
		||||
    // the next release event.
 | 
			
		||||
    ignoreRelease() {
 | 
			
		||||
    ignoreRelease: function() {
 | 
			
		||||
        this._ignoreUntilRelease = true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -244,7 +242,7 @@ var GrabHelper = new Lang.Class({
 | 
			
		||||
    // popped until the grabbed actor is at the top of the grab stack.
 | 
			
		||||
    // The onUngrab callback for every grab is called for every popped
 | 
			
		||||
    // grab with the parameter %false.
 | 
			
		||||
    ungrab(params) {
 | 
			
		||||
    ungrab: function(params) {
 | 
			
		||||
        params = Params.parse(params, { actor: this.currentGrab.actor,
 | 
			
		||||
                                        isUser: false });
 | 
			
		||||
 | 
			
		||||
@@ -276,7 +274,7 @@ var GrabHelper = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    onCapturedEvent(event) {
 | 
			
		||||
    onCapturedEvent: function(event) {
 | 
			
		||||
        let type = event.type();
 | 
			
		||||
 | 
			
		||||
        if (type == Clutter.EventType.KEY_PRESS &&
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ var DEFAULT_INDEX_LABELS = [ '1', '2', '3', '4', '5', '6', '7', '8',
 | 
			
		||||
var CandidateArea = new Lang.Class({
 | 
			
		||||
    Name: 'CandidateArea',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.actor = new St.BoxLayout({ vertical: true,
 | 
			
		||||
                                        reactive: true,
 | 
			
		||||
                                        visible: false });
 | 
			
		||||
@@ -34,13 +34,13 @@ var CandidateArea = new Lang.Class({
 | 
			
		||||
            this.actor.add(box);
 | 
			
		||||
 | 
			
		||||
            let j = i;
 | 
			
		||||
            box.connect('button-release-event', (actor, event) => {
 | 
			
		||||
            box.connect('button-release-event', Lang.bind(this, function(actor, event) {
 | 
			
		||||
                this.emit('candidate-clicked', j, event.get_button(), event.get_state());
 | 
			
		||||
                return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('scroll-event', (actor, event) => {
 | 
			
		||||
        this.actor.connect('scroll-event', Lang.bind(this, function(actor, event) {
 | 
			
		||||
            let direction = event.get_scroll_direction();
 | 
			
		||||
            switch(direction) {
 | 
			
		||||
            case Clutter.ScrollDirection.UP:
 | 
			
		||||
@@ -51,7 +51,7 @@ var CandidateArea = new Lang.Class({
 | 
			
		||||
                break;
 | 
			
		||||
            };
 | 
			
		||||
            return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._buttonBox = new St.BoxLayout({ style_class: 'candidate-page-button-box' });
 | 
			
		||||
 | 
			
		||||
@@ -65,18 +65,18 @@ var CandidateArea = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this.actor.add(this._buttonBox);
 | 
			
		||||
 | 
			
		||||
        this._previousButton.connect('clicked', () => {
 | 
			
		||||
        this._previousButton.connect('clicked', Lang.bind(this, function() {
 | 
			
		||||
            this.emit('previous-page');
 | 
			
		||||
        });
 | 
			
		||||
        this._nextButton.connect('clicked', () => {
 | 
			
		||||
        }));
 | 
			
		||||
        this._nextButton.connect('clicked', Lang.bind(this, function() {
 | 
			
		||||
            this.emit('next-page');
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._orientation = -1;
 | 
			
		||||
        this._cursorPosition = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setOrientation(orientation) {
 | 
			
		||||
    setOrientation: function(orientation) {
 | 
			
		||||
        if (this._orientation == orientation)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -97,7 +97,7 @@ var CandidateArea = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setCandidates(indexes, candidates, cursorPosition, cursorVisible) {
 | 
			
		||||
    setCandidates: function(indexes, candidates, cursorPosition, cursorVisible) {
 | 
			
		||||
        for (let i = 0; i < MAX_CANDIDATES_PER_PAGE; ++i) {
 | 
			
		||||
            let visible = i < candidates.length;
 | 
			
		||||
            let box = this._candidateBoxes[i];
 | 
			
		||||
@@ -116,7 +116,7 @@ var CandidateArea = new Lang.Class({
 | 
			
		||||
            this._candidateBoxes[cursorPosition].add_style_pseudo_class('selected');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    updateButtons(wrapsAround, page, nPages) {
 | 
			
		||||
    updateButtons: function(wrapsAround, page, nPages) {
 | 
			
		||||
        if (nPages < 2) {
 | 
			
		||||
            this._buttonBox.hide();
 | 
			
		||||
            return;
 | 
			
		||||
@@ -131,7 +131,7 @@ Signals.addSignalMethods(CandidateArea.prototype);
 | 
			
		||||
var CandidatePopup = new Lang.Class({
 | 
			
		||||
    Name: 'CandidatePopup',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._boxPointer = new BoxPointer.BoxPointer(St.Side.TOP);
 | 
			
		||||
        this._boxPointer.actor.visible = false;
 | 
			
		||||
        this._boxPointer.actor.style_class = 'candidate-popup-boxpointer';
 | 
			
		||||
@@ -152,138 +152,150 @@ var CandidatePopup = new Lang.Class({
 | 
			
		||||
        this._candidateArea = new CandidateArea();
 | 
			
		||||
        box.add(this._candidateArea.actor);
 | 
			
		||||
 | 
			
		||||
        this._candidateArea.connect('previous-page', () => {
 | 
			
		||||
        this._candidateArea.connect('previous-page', Lang.bind(this, function() {
 | 
			
		||||
            this._panelService.page_up();
 | 
			
		||||
        });
 | 
			
		||||
        this._candidateArea.connect('next-page', () => {
 | 
			
		||||
        }));
 | 
			
		||||
        this._candidateArea.connect('next-page', Lang.bind(this, function() {
 | 
			
		||||
            this._panelService.page_down();
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._candidateArea.connect('cursor-up', () => {
 | 
			
		||||
        this._candidateArea.connect('cursor-up', Lang.bind(this, function() {
 | 
			
		||||
            this._panelService.cursor_up();
 | 
			
		||||
        });
 | 
			
		||||
        this._candidateArea.connect('cursor-down', () => {
 | 
			
		||||
        }));
 | 
			
		||||
        this._candidateArea.connect('cursor-down', Lang.bind(this, function() {
 | 
			
		||||
            this._panelService.cursor_down();
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._candidateArea.connect('candidate-clicked', (area, index, button, state) => {
 | 
			
		||||
        this._candidateArea.connect('candidate-clicked', Lang.bind(this, function(ca, index, button, state) {
 | 
			
		||||
            this._panelService.candidate_clicked(index, button, state);
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._panelService = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setPanelService(panelService) {
 | 
			
		||||
    setPanelService: function(panelService) {
 | 
			
		||||
        this._panelService = panelService;
 | 
			
		||||
        if (!panelService)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        panelService.connect('set-cursor-location', (ps, x, y, w, h) => {
 | 
			
		||||
            this._setDummyCursorGeometry(x, y, w, h);
 | 
			
		||||
        });
 | 
			
		||||
        panelService.connect('set-cursor-location',
 | 
			
		||||
                             Lang.bind(this, function(ps, x, y, w, h) {
 | 
			
		||||
                                 this._setDummyCursorGeometry(x, y, w, h);
 | 
			
		||||
                             }));
 | 
			
		||||
        try {
 | 
			
		||||
            panelService.connect('set-cursor-location-relative', (ps, x, y, w, h) => {
 | 
			
		||||
                if (!global.display.focus_window)
 | 
			
		||||
                    return;
 | 
			
		||||
                let window = global.display.focus_window.get_compositor_private();
 | 
			
		||||
                this._setDummyCursorGeometry(window.x + x, window.y + y, w, h);
 | 
			
		||||
            });
 | 
			
		||||
            panelService.connect('set-cursor-location-relative',
 | 
			
		||||
                                 Lang.bind(this, function(ps, x, y, w, h) {
 | 
			
		||||
                                     if (!global.display.focus_window)
 | 
			
		||||
                                         return;
 | 
			
		||||
                                     let window = global.display.focus_window.get_compositor_private();
 | 
			
		||||
                                     this._setDummyCursorGeometry(window.x + x, window.y + y, w, h);
 | 
			
		||||
                                 }));
 | 
			
		||||
        } catch(e) {
 | 
			
		||||
            // Only recent IBus versions have support for this signal
 | 
			
		||||
            // which is used for wayland clients. In order to work
 | 
			
		||||
            // with older IBus versions we can silently ignore the
 | 
			
		||||
            // signal's absence.
 | 
			
		||||
        }
 | 
			
		||||
        panelService.connect('update-preedit-text', (ps, text, cursorPosition, visible) => {
 | 
			
		||||
            this._preeditText.visible = visible;
 | 
			
		||||
            this._updateVisibility();
 | 
			
		||||
        panelService.connect('update-preedit-text',
 | 
			
		||||
                             Lang.bind(this, function(ps, text, cursorPosition, visible) {
 | 
			
		||||
                                 this._preeditText.visible = visible;
 | 
			
		||||
                                 this._updateVisibility();
 | 
			
		||||
 | 
			
		||||
            this._preeditText.text = text.get_text();
 | 
			
		||||
                                 this._preeditText.text = text.get_text();
 | 
			
		||||
 | 
			
		||||
            let attrs = text.get_attributes();
 | 
			
		||||
            if (attrs)
 | 
			
		||||
                this._setTextAttributes(this._preeditText.clutter_text,
 | 
			
		||||
                                        attrs);
 | 
			
		||||
        });
 | 
			
		||||
        panelService.connect('show-preedit-text', ps => {
 | 
			
		||||
            this._preeditText.show();
 | 
			
		||||
            this._updateVisibility();
 | 
			
		||||
        });
 | 
			
		||||
        panelService.connect('hide-preedit-text', ps => {
 | 
			
		||||
            this._preeditText.hide();
 | 
			
		||||
            this._updateVisibility();
 | 
			
		||||
        });
 | 
			
		||||
        panelService.connect('update-auxiliary-text', (ps, text, visible) => {
 | 
			
		||||
            this._auxText.visible = visible;
 | 
			
		||||
            this._updateVisibility();
 | 
			
		||||
                                 let attrs = text.get_attributes();
 | 
			
		||||
                                 if (attrs)
 | 
			
		||||
                                     this._setTextAttributes(this._preeditText.clutter_text,
 | 
			
		||||
                                                             attrs);
 | 
			
		||||
                             }));
 | 
			
		||||
        panelService.connect('show-preedit-text',
 | 
			
		||||
                             Lang.bind(this, function(ps) {
 | 
			
		||||
                                 this._preeditText.show();
 | 
			
		||||
                                 this._updateVisibility();
 | 
			
		||||
                             }));
 | 
			
		||||
        panelService.connect('hide-preedit-text',
 | 
			
		||||
                             Lang.bind(this, function(ps) {
 | 
			
		||||
                                 this._preeditText.hide();
 | 
			
		||||
                                 this._updateVisibility();
 | 
			
		||||
                             }));
 | 
			
		||||
        panelService.connect('update-auxiliary-text',
 | 
			
		||||
                             Lang.bind(this, function(ps, text, visible) {
 | 
			
		||||
                                 this._auxText.visible = visible;
 | 
			
		||||
                                 this._updateVisibility();
 | 
			
		||||
 | 
			
		||||
            this._auxText.text = text.get_text();
 | 
			
		||||
        });
 | 
			
		||||
        panelService.connect('show-auxiliary-text', ps => {
 | 
			
		||||
            this._auxText.show();
 | 
			
		||||
            this._updateVisibility();
 | 
			
		||||
        });
 | 
			
		||||
        panelService.connect('hide-auxiliary-text', ps => {
 | 
			
		||||
            this._auxText.hide();
 | 
			
		||||
            this._updateVisibility();
 | 
			
		||||
        });
 | 
			
		||||
        panelService.connect('update-lookup-table', (ps, lookupTable, visible) => {
 | 
			
		||||
            this._candidateArea.actor.visible = visible;
 | 
			
		||||
            this._updateVisibility();
 | 
			
		||||
                                 this._auxText.text = text.get_text();
 | 
			
		||||
                             }));
 | 
			
		||||
        panelService.connect('show-auxiliary-text',
 | 
			
		||||
                             Lang.bind(this, function(ps) {
 | 
			
		||||
                                 this._auxText.show();
 | 
			
		||||
                                 this._updateVisibility();
 | 
			
		||||
                             }));
 | 
			
		||||
        panelService.connect('hide-auxiliary-text',
 | 
			
		||||
                             Lang.bind(this, function(ps) {
 | 
			
		||||
                                 this._auxText.hide();
 | 
			
		||||
                                 this._updateVisibility();
 | 
			
		||||
                             }));
 | 
			
		||||
        panelService.connect('update-lookup-table',
 | 
			
		||||
                             Lang.bind(this, function(ps, lookupTable, visible) {
 | 
			
		||||
                                 this._candidateArea.actor.visible = visible;
 | 
			
		||||
                                 this._updateVisibility();
 | 
			
		||||
 | 
			
		||||
            let nCandidates = lookupTable.get_number_of_candidates();
 | 
			
		||||
            let cursorPos = lookupTable.get_cursor_pos();
 | 
			
		||||
            let pageSize = lookupTable.get_page_size();
 | 
			
		||||
            let nPages = Math.ceil(nCandidates / pageSize);
 | 
			
		||||
            let page = ((cursorPos == 0) ? 0 : Math.floor(cursorPos / pageSize));
 | 
			
		||||
            let startIndex = page * pageSize;
 | 
			
		||||
            let endIndex = Math.min((page + 1) * pageSize, nCandidates);
 | 
			
		||||
                                 let nCandidates = lookupTable.get_number_of_candidates();
 | 
			
		||||
                                 let cursorPos = lookupTable.get_cursor_pos();
 | 
			
		||||
                                 let pageSize = lookupTable.get_page_size();
 | 
			
		||||
                                 let nPages = Math.ceil(nCandidates / pageSize);
 | 
			
		||||
                                 let page = ((cursorPos == 0) ? 0 : Math.floor(cursorPos / pageSize));
 | 
			
		||||
                                 let startIndex = page * pageSize;
 | 
			
		||||
                                 let endIndex = Math.min((page + 1) * pageSize, nCandidates);
 | 
			
		||||
 | 
			
		||||
            let indexes = [];
 | 
			
		||||
            let indexLabel;
 | 
			
		||||
            for (let i = 0; indexLabel = lookupTable.get_label(i); ++i)
 | 
			
		||||
                 indexes.push(indexLabel.get_text());
 | 
			
		||||
                                 let indexes = [];
 | 
			
		||||
                                 let indexLabel;
 | 
			
		||||
                                 for (let i = 0; indexLabel = lookupTable.get_label(i); ++i)
 | 
			
		||||
                                      indexes.push(indexLabel.get_text());
 | 
			
		||||
 | 
			
		||||
            Main.keyboard.resetSuggestions();
 | 
			
		||||
                                 Main.keyboard.resetSuggestions();
 | 
			
		||||
 | 
			
		||||
            let candidates = [];
 | 
			
		||||
            for (let i = startIndex; i < endIndex; ++i) {
 | 
			
		||||
                candidates.push(lookupTable.get_candidate(i).get_text());
 | 
			
		||||
                                 let candidates = [];
 | 
			
		||||
                                 for (let i = startIndex; i < endIndex; ++i) {
 | 
			
		||||
                                     candidates.push(lookupTable.get_candidate(i).get_text());
 | 
			
		||||
 | 
			
		||||
                Main.keyboard.addSuggestion(lookupTable.get_candidate(i).get_text(), () => {
 | 
			
		||||
                    let index = i;
 | 
			
		||||
                    this._panelService.candidate_clicked(index, 1, 0);
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
                                     Main.keyboard.addSuggestion(lookupTable.get_candidate(i).get_text(), Lang.bind(this, function() {
 | 
			
		||||
                                         let index = i;
 | 
			
		||||
                                         this._panelService.candidate_clicked(index, 1, 0);
 | 
			
		||||
                                     }));
 | 
			
		||||
                                 }
 | 
			
		||||
 | 
			
		||||
            this._candidateArea.setCandidates(indexes,
 | 
			
		||||
                                              candidates,
 | 
			
		||||
                                              cursorPos % pageSize,
 | 
			
		||||
                                              lookupTable.is_cursor_visible());
 | 
			
		||||
            this._candidateArea.setOrientation(lookupTable.get_orientation());
 | 
			
		||||
            this._candidateArea.updateButtons(lookupTable.is_round(), page, nPages);
 | 
			
		||||
        });
 | 
			
		||||
        panelService.connect('show-lookup-table', ps => {
 | 
			
		||||
            this._candidateArea.actor.show();
 | 
			
		||||
            this._updateVisibility();
 | 
			
		||||
        });
 | 
			
		||||
        panelService.connect('hide-lookup-table', ps => {
 | 
			
		||||
            this._candidateArea.actor.hide();
 | 
			
		||||
            this._updateVisibility();
 | 
			
		||||
        });
 | 
			
		||||
        panelService.connect('focus-out', ps => {
 | 
			
		||||
            this._boxPointer.hide(BoxPointer.PopupAnimation.NONE);
 | 
			
		||||
            Main.keyboard.resetSuggestions();
 | 
			
		||||
        });
 | 
			
		||||
                                 this._candidateArea.setCandidates(indexes,
 | 
			
		||||
                                                                   candidates,
 | 
			
		||||
                                                                   cursorPos % pageSize,
 | 
			
		||||
                                                                   lookupTable.is_cursor_visible());
 | 
			
		||||
                                 this._candidateArea.setOrientation(lookupTable.get_orientation());
 | 
			
		||||
                                 this._candidateArea.updateButtons(lookupTable.is_round(), page, nPages);
 | 
			
		||||
                             }));
 | 
			
		||||
        panelService.connect('show-lookup-table',
 | 
			
		||||
                             Lang.bind(this, function(ps) {
 | 
			
		||||
                                 this._candidateArea.actor.show();
 | 
			
		||||
                                 this._updateVisibility();
 | 
			
		||||
                             }));
 | 
			
		||||
        panelService.connect('hide-lookup-table',
 | 
			
		||||
                             Lang.bind(this, function(ps) {
 | 
			
		||||
                                 this._candidateArea.actor.hide();
 | 
			
		||||
                                 this._updateVisibility();
 | 
			
		||||
                             }));
 | 
			
		||||
        panelService.connect('focus-out',
 | 
			
		||||
                             Lang.bind(this, function(ps) {
 | 
			
		||||
                                 this._boxPointer.hide(BoxPointer.PopupAnimation.NONE);
 | 
			
		||||
                                 Main.keyboard.resetSuggestions();
 | 
			
		||||
                             }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setDummyCursorGeometry(x, y, w, h) {
 | 
			
		||||
    _setDummyCursorGeometry: function(x, y, w, h) {
 | 
			
		||||
        Main.layoutManager.setDummyCursorGeometry(x, y, w, h);
 | 
			
		||||
        if (this._boxPointer.actor.visible)
 | 
			
		||||
            this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateVisibility() {
 | 
			
		||||
    _updateVisibility: function() {
 | 
			
		||||
        let isVisible = (!Main.keyboard.visible &&
 | 
			
		||||
                         (this._preeditText.visible ||
 | 
			
		||||
                          this._auxText.visible ||
 | 
			
		||||
@@ -298,7 +310,7 @@ var CandidatePopup = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setTextAttributes(clutterText, ibusAttrList) {
 | 
			
		||||
    _setTextAttributes: function(clutterText, ibusAttrList) {
 | 
			
		||||
        let attr;
 | 
			
		||||
        for (let i = 0; attr = ibusAttrList.get(i); ++i)
 | 
			
		||||
            if (attr.get_attr_type() == IBus.AttrType.BACKGROUND)
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,7 @@ var APPICON_ANIMATION_OUT_TIME = 0.25;
 | 
			
		||||
var BaseIcon = new Lang.Class({
 | 
			
		||||
    Name: 'BaseIcon',
 | 
			
		||||
 | 
			
		||||
    _init(label, params) {
 | 
			
		||||
    _init : function(label, params) {
 | 
			
		||||
        params = Params.parse(params, { createIcon: null,
 | 
			
		||||
                                        setSizeManually: false,
 | 
			
		||||
                                        showLabel: true });
 | 
			
		||||
@@ -50,17 +50,19 @@ var BaseIcon = new Lang.Class({
 | 
			
		||||
                                  x_fill: true,
 | 
			
		||||
                                  y_fill: true });
 | 
			
		||||
        this.actor._delegate = this;
 | 
			
		||||
        this.actor.connect('style-changed', this._onStyleChanged.bind(this));
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.actor.connect('style-changed',
 | 
			
		||||
                           Lang.bind(this, this._onStyleChanged));
 | 
			
		||||
        this.actor.connect('destroy',
 | 
			
		||||
                           Lang.bind(this, this._onDestroy));
 | 
			
		||||
 | 
			
		||||
        this._spacing = 0;
 | 
			
		||||
 | 
			
		||||
        let box = new Shell.GenericContainer();
 | 
			
		||||
        box.connect('allocate', this._allocate.bind(this));
 | 
			
		||||
        box.connect('allocate', Lang.bind(this, this._allocate));
 | 
			
		||||
        box.connect('get-preferred-width',
 | 
			
		||||
                    this._getPreferredWidth.bind(this));
 | 
			
		||||
                    Lang.bind(this, this._getPreferredWidth));
 | 
			
		||||
        box.connect('get-preferred-height',
 | 
			
		||||
                    this._getPreferredHeight.bind(this));
 | 
			
		||||
                    Lang.bind(this, this._getPreferredHeight));
 | 
			
		||||
        this.actor.set_child(box);
 | 
			
		||||
 | 
			
		||||
        this.iconSize = ICON_SIZE;
 | 
			
		||||
@@ -83,10 +85,10 @@ var BaseIcon = new Lang.Class({
 | 
			
		||||
        this.icon = null;
 | 
			
		||||
 | 
			
		||||
        let cache = St.TextureCache.get_default();
 | 
			
		||||
        this._iconThemeChangedId = cache.connect('icon-theme-changed', this._onIconThemeChanged.bind(this));
 | 
			
		||||
        this._iconThemeChangedId = cache.connect('icon-theme-changed', Lang.bind(this, this._onIconThemeChanged));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _allocate(actor, box, flags) {
 | 
			
		||||
    _allocate: function(actor, box, flags) {
 | 
			
		||||
        let availWidth = box.x2 - box.x1;
 | 
			
		||||
        let availHeight = box.y2 - box.y1;
 | 
			
		||||
 | 
			
		||||
@@ -120,11 +122,11 @@ var BaseIcon = new Lang.Class({
 | 
			
		||||
        this._iconBin.allocate(childBox, flags);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getPreferredWidth(actor, forHeight, alloc) {
 | 
			
		||||
    _getPreferredWidth: function(actor, forHeight, alloc) {
 | 
			
		||||
        this._getPreferredHeight(actor, -1, alloc);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getPreferredHeight(actor, forWidth, alloc) {
 | 
			
		||||
    _getPreferredHeight: function(actor, forWidth, alloc) {
 | 
			
		||||
        let [iconMinHeight, iconNatHeight] = this._iconBin.get_preferred_height(forWidth);
 | 
			
		||||
        alloc.min_size = iconMinHeight;
 | 
			
		||||
        alloc.natural_size = iconNatHeight;
 | 
			
		||||
@@ -138,11 +140,11 @@ var BaseIcon = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
    // This can be overridden by a subclass, or by the createIcon
 | 
			
		||||
    // parameter to _init()
 | 
			
		||||
    createIcon(size) {
 | 
			
		||||
    createIcon: function(size) {
 | 
			
		||||
        throw new Error('no implementation of createIcon in ' + this);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setIconSize(size) {
 | 
			
		||||
    setIconSize: function(size) {
 | 
			
		||||
        if (!this._setSizeManually)
 | 
			
		||||
            throw new Error('setSizeManually has to be set to use setIconsize');
 | 
			
		||||
 | 
			
		||||
@@ -152,7 +154,7 @@ var BaseIcon = new Lang.Class({
 | 
			
		||||
        this._createIconTexture(size);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createIconTexture(size) {
 | 
			
		||||
    _createIconTexture: function(size) {
 | 
			
		||||
        if (this.icon)
 | 
			
		||||
            this.icon.destroy();
 | 
			
		||||
        this.iconSize = size;
 | 
			
		||||
@@ -161,7 +163,7 @@ var BaseIcon = new Lang.Class({
 | 
			
		||||
        this._iconBin.child = this.icon;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onStyleChanged() {
 | 
			
		||||
    _onStyleChanged: function() {
 | 
			
		||||
        let node = this.actor.get_theme_node();
 | 
			
		||||
        this._spacing = node.get_length('spacing');
 | 
			
		||||
 | 
			
		||||
@@ -179,7 +181,7 @@ var BaseIcon = new Lang.Class({
 | 
			
		||||
        this._createIconTexture(size);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
        if (this._iconThemeChangedId > 0) {
 | 
			
		||||
            let cache = St.TextureCache.get_default();
 | 
			
		||||
            cache.disconnect(this._iconThemeChangedId);
 | 
			
		||||
@@ -187,11 +189,11 @@ var BaseIcon = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onIconThemeChanged() {
 | 
			
		||||
    _onIconThemeChanged: function() {
 | 
			
		||||
        this._createIconTexture(this.iconSize);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    animateZoomOut() {
 | 
			
		||||
    animateZoomOut: function() {
 | 
			
		||||
        // Animate only the child instead of the entire actor, so the
 | 
			
		||||
        // styles like hover and running are not applied while
 | 
			
		||||
        // animating.
 | 
			
		||||
@@ -232,7 +234,7 @@ function zoomOutActor(actor) {
 | 
			
		||||
                       translation_y: containedY - scaledY,
 | 
			
		||||
                       opacity: 0,
 | 
			
		||||
                       transition: 'easeOutQuad',
 | 
			
		||||
                       onComplete() {
 | 
			
		||||
                       onComplete: function() {
 | 
			
		||||
                           actorClone.destroy();
 | 
			
		||||
                       }
 | 
			
		||||
                    });
 | 
			
		||||
@@ -241,7 +243,7 @@ function zoomOutActor(actor) {
 | 
			
		||||
var IconGrid = new Lang.Class({
 | 
			
		||||
    Name: 'IconGrid',
 | 
			
		||||
 | 
			
		||||
    _init(params) {
 | 
			
		||||
    _init: function(params) {
 | 
			
		||||
        params = Params.parse(params, { rowLimit: null,
 | 
			
		||||
                                        columnLimit: null,
 | 
			
		||||
                                        minRows: 1,
 | 
			
		||||
@@ -272,7 +274,7 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
        this._fixedHItemSize = this._fixedVItemSize = undefined;
 | 
			
		||||
        this._grid = new Shell.GenericContainer();
 | 
			
		||||
        this.actor.add(this._grid, { expand: true, y_align: St.Align.START });
 | 
			
		||||
        this.actor.connect('style-changed', this._onStyleChanged.bind(this));
 | 
			
		||||
        this.actor.connect('style-changed', Lang.bind(this, this._onStyleChanged));
 | 
			
		||||
 | 
			
		||||
        // Cancel animations when hiding the overview, to avoid icons
 | 
			
		||||
        // swarming into the void ...
 | 
			
		||||
@@ -281,26 +283,26 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
                this._cancelAnimation();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._grid.connect('get-preferred-width', this._getPreferredWidth.bind(this));
 | 
			
		||||
        this._grid.connect('get-preferred-height', this._getPreferredHeight.bind(this));
 | 
			
		||||
        this._grid.connect('allocate', this._allocate.bind(this));
 | 
			
		||||
        this._grid.connect('actor-added', this._childAdded.bind(this));
 | 
			
		||||
        this._grid.connect('actor-removed', this._childRemoved.bind(this));
 | 
			
		||||
        this._grid.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
 | 
			
		||||
        this._grid.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
 | 
			
		||||
        this._grid.connect('allocate', Lang.bind(this, this._allocate));
 | 
			
		||||
        this._grid.connect('actor-added', Lang.bind(this, this._childAdded));
 | 
			
		||||
        this._grid.connect('actor-removed', Lang.bind(this, this._childRemoved));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _keyFocusIn(actor) {
 | 
			
		||||
    _keyFocusIn: function(actor) {
 | 
			
		||||
        this.emit('key-focus-in', actor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _childAdded(grid, child) {
 | 
			
		||||
        child._iconGridKeyFocusInId = child.connect('key-focus-in', this._keyFocusIn.bind(this));
 | 
			
		||||
    _childAdded: function(grid, child) {
 | 
			
		||||
        child._iconGridKeyFocusInId = child.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _childRemoved(grid, child) {
 | 
			
		||||
    _childRemoved: function(grid, child) {
 | 
			
		||||
        child.disconnect(child._iconGridKeyFocusInId);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getPreferredWidth(grid, forHeight, alloc) {
 | 
			
		||||
    _getPreferredWidth: function (grid, forHeight, alloc) {
 | 
			
		||||
        if (this._fillParent)
 | 
			
		||||
            // Ignore all size requests of children and request a size of 0;
 | 
			
		||||
            // later we'll allocate as many children as fit the parent
 | 
			
		||||
@@ -318,11 +320,15 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
        alloc.natural_size = nColumns * this._getHItemSize() + totalSpacing + this.leftPadding + this.rightPadding;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getVisibleChildren() {
 | 
			
		||||
        return this._grid.get_children().filter(actor => actor.visible);
 | 
			
		||||
    _getVisibleChildren: function() {
 | 
			
		||||
        let children = this._grid.get_children();
 | 
			
		||||
        children = children.filter(function(actor) {
 | 
			
		||||
            return actor.visible;
 | 
			
		||||
        });
 | 
			
		||||
        return children;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getPreferredHeight(grid, forWidth, alloc) {
 | 
			
		||||
    _getPreferredHeight: function (grid, forWidth, alloc) {
 | 
			
		||||
        if (this._fillParent)
 | 
			
		||||
            // Ignore all size requests of children and request a size of 0;
 | 
			
		||||
            // later we'll allocate as many children as fit the parent
 | 
			
		||||
@@ -348,7 +354,7 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
        alloc.natural_size = height;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _allocate(grid, box, flags) {
 | 
			
		||||
    _allocate: function (grid, box, flags) {
 | 
			
		||||
        if (this._fillParent) {
 | 
			
		||||
            // Reset the passed in box to fill the parent
 | 
			
		||||
            let parentBox = this.actor.get_parent().allocation;
 | 
			
		||||
@@ -408,21 +414,21 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
     * Intended to be override by subclasses if they need a different
 | 
			
		||||
     * set of items to be animated.
 | 
			
		||||
     */
 | 
			
		||||
    _getChildrenToAnimate() {
 | 
			
		||||
    _getChildrenToAnimate: function() {
 | 
			
		||||
        return this._getVisibleChildren();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _cancelAnimation() {
 | 
			
		||||
    _cancelAnimation: function() {
 | 
			
		||||
        this._clonesAnimating.forEach(clone => { clone.destroy(); });
 | 
			
		||||
        this._clonesAnimating = [];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _animationDone() {
 | 
			
		||||
    _animationDone: function() {
 | 
			
		||||
        this._clonesAnimating = [];
 | 
			
		||||
        this.emit('animation-done');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    animatePulse(animationDirection) {
 | 
			
		||||
    animatePulse: function(animationDirection) {
 | 
			
		||||
        if (animationDirection != AnimationDirection.IN)
 | 
			
		||||
            throw new Error("Pulse animation only implements 'in' animation direction");
 | 
			
		||||
 | 
			
		||||
@@ -456,24 +462,24 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
                              delay: delay,
 | 
			
		||||
                              scale_x: ANIMATION_BOUNCE_ICON_SCALE,
 | 
			
		||||
                              scale_y: ANIMATION_BOUNCE_ICON_SCALE,
 | 
			
		||||
                              onComplete: () => {
 | 
			
		||||
                              onComplete: Lang.bind(this, function() {
 | 
			
		||||
                                  Tweener.addTween(actor,
 | 
			
		||||
                                                   { time: ANIMATION_TIME_IN - bounceUpTime,
 | 
			
		||||
                                                     transition: 'easeInOutQuad',
 | 
			
		||||
                                                     scale_x: 1,
 | 
			
		||||
                                                     scale_y: 1,
 | 
			
		||||
                                                     onComplete: () => {
 | 
			
		||||
                                                     onComplete: Lang.bind(this, function() {
 | 
			
		||||
                                                        if (isLastItem)
 | 
			
		||||
                                                            this._animationDone();
 | 
			
		||||
                                                        actor.reactive = true;
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                    })
 | 
			
		||||
                                                   });
 | 
			
		||||
                              }
 | 
			
		||||
                              })
 | 
			
		||||
                            });
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    animateSpring(animationDirection, sourceActor) {
 | 
			
		||||
    animateSpring: function(animationDirection, sourceActor) {
 | 
			
		||||
        this._cancelAnimation();
 | 
			
		||||
 | 
			
		||||
        let actors = this._getChildrenToAnimate();
 | 
			
		||||
@@ -489,15 +495,15 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
        // Design decision, 1/2 of the source actor size.
 | 
			
		||||
        let [sourceScaledWidth, sourceScaledHeight] = [sourceWidth / 2, sourceHeight / 2];
 | 
			
		||||
 | 
			
		||||
        actors.forEach(actor => {
 | 
			
		||||
        actors.forEach(function(actor) {
 | 
			
		||||
            let [actorX, actorY] = actor._transformedPosition = actor.get_transformed_position();
 | 
			
		||||
            let [x, y] = [actorX - sourceX, actorY - sourceY];
 | 
			
		||||
            actor._distance = Math.sqrt(x * x + y * y);
 | 
			
		||||
        });
 | 
			
		||||
        let maxDist = actors.reduce((prev, cur) => {
 | 
			
		||||
        let maxDist = actors.reduce(function(prev, cur) {
 | 
			
		||||
            return Math.max(prev, cur._distance);
 | 
			
		||||
        }, 0);
 | 
			
		||||
        let minDist = actors.reduce((prev, cur) => {
 | 
			
		||||
        let minDist = actors.reduce(function(prev, cur) {
 | 
			
		||||
            return Math.min(prev, cur._distance);
 | 
			
		||||
        }, Infinity);
 | 
			
		||||
        let normalization = maxDist - minDist;
 | 
			
		||||
@@ -535,14 +541,14 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
                                   y: finalY,
 | 
			
		||||
                                   scale_x: 1,
 | 
			
		||||
                                   scale_y: 1,
 | 
			
		||||
                                   onComplete: () => {
 | 
			
		||||
                                   onComplete: Lang.bind(this, function() {
 | 
			
		||||
                                       if (isLastItem)
 | 
			
		||||
                                           this._animationDone();
 | 
			
		||||
 | 
			
		||||
                                       actor.opacity = 255;
 | 
			
		||||
                                       actor.reactive = true;
 | 
			
		||||
                                       actorClone.destroy();
 | 
			
		||||
                                   }};
 | 
			
		||||
                                   })};
 | 
			
		||||
                fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
 | 
			
		||||
                               transition: 'easeInOutQuad',
 | 
			
		||||
                               delay: delay,
 | 
			
		||||
@@ -561,14 +567,14 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
                                   y: adjustedSourcePositionY,
 | 
			
		||||
                                   scale_x: scaleX,
 | 
			
		||||
                                   scale_y: scaleY,
 | 
			
		||||
                                   onComplete: () => {
 | 
			
		||||
                                   onComplete: Lang.bind(this, function() {
 | 
			
		||||
                                       if (isLastItem) {
 | 
			
		||||
                                           this._animationDone();
 | 
			
		||||
                                           this._restoreItemsOpacity();
 | 
			
		||||
                                       }
 | 
			
		||||
                                       actor.reactive = true;
 | 
			
		||||
                                       actorClone.destroy();
 | 
			
		||||
                                   }};
 | 
			
		||||
                                   })};
 | 
			
		||||
                fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
 | 
			
		||||
                               transition: 'easeInOutQuad',
 | 
			
		||||
                               delay: ANIMATION_TIME_OUT + delay - ANIMATION_FADE_IN_TIME_FOR_ITEM,
 | 
			
		||||
@@ -581,13 +587,13 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _restoreItemsOpacity() {
 | 
			
		||||
    _restoreItemsOpacity: function() {
 | 
			
		||||
        for (let index = 0; index < this._items.length; index++) {
 | 
			
		||||
            this._items[index].actor.opacity = 255;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getAllocatedChildSizeAndSpacing(child) {
 | 
			
		||||
    _getAllocatedChildSizeAndSpacing: function(child) {
 | 
			
		||||
        let [,, natWidth, natHeight] = child.get_preferred_size();
 | 
			
		||||
        let width = Math.min(this._getHItemSize(), natWidth);
 | 
			
		||||
        let xSpacing = Math.max(0, width - natWidth) / 2;
 | 
			
		||||
@@ -596,7 +602,7 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
        return [width, height, xSpacing, ySpacing];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _calculateChildBox(child, x, y, box) {
 | 
			
		||||
    _calculateChildBox: function(child, x, y, box) {
 | 
			
		||||
        /* Center the item in its allocation horizontally */
 | 
			
		||||
        let [width, height, childXSpacing, childYSpacing] =
 | 
			
		||||
            this._getAllocatedChildSizeAndSpacing(child);
 | 
			
		||||
@@ -614,15 +620,15 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
        return childBox;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    columnsForWidth(rowWidth) {
 | 
			
		||||
    columnsForWidth: function(rowWidth) {
 | 
			
		||||
        return this._computeLayout(rowWidth)[0];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getRowLimit() {
 | 
			
		||||
    getRowLimit: function() {
 | 
			
		||||
        return this._rowLimit;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _computeLayout(forWidth) {
 | 
			
		||||
    _computeLayout: function (forWidth) {
 | 
			
		||||
        let nColumns = 0;
 | 
			
		||||
        let usedWidth = this.leftPadding + this.rightPadding;
 | 
			
		||||
        let spacing = this._getSpacing();
 | 
			
		||||
@@ -639,7 +645,7 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
        return [nColumns, usedWidth];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onStyleChanged() {
 | 
			
		||||
    _onStyleChanged: function() {
 | 
			
		||||
        let themeNode = this.actor.get_theme_node();
 | 
			
		||||
        this._spacing = themeNode.get_length('spacing');
 | 
			
		||||
        this._hItemSize = themeNode.get_length('-shell-grid-horizontal-item-size') || ICON_SIZE;
 | 
			
		||||
@@ -647,7 +653,7 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
        this._grid.queue_relayout();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    nRows(forWidth) {
 | 
			
		||||
    nRows: function(forWidth) {
 | 
			
		||||
        let children = this._getVisibleChildren();
 | 
			
		||||
        let nColumns = (forWidth < 0) ? children.length : this._computeLayout(forWidth)[0];
 | 
			
		||||
        let nRows = (nColumns > 0) ? Math.ceil(children.length / nColumns) : 0;
 | 
			
		||||
@@ -656,35 +662,35 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
        return nRows;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    rowsForHeight(forHeight) {
 | 
			
		||||
    rowsForHeight: function(forHeight) {
 | 
			
		||||
        return Math.floor((forHeight - (this.topPadding + this.bottomPadding) + this._getSpacing()) / (this._getVItemSize() + this._getSpacing()));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    usedHeightForNRows(nRows) {
 | 
			
		||||
    usedHeightForNRows: function(nRows) {
 | 
			
		||||
        return (this._getVItemSize() + this._getSpacing()) * nRows - this._getSpacing() + this.topPadding + this.bottomPadding;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    usedWidth(forWidth) {
 | 
			
		||||
    usedWidth: function(forWidth) {
 | 
			
		||||
        return this.usedWidthForNColumns(this.columnsForWidth(forWidth));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    usedWidthForNColumns(columns) {
 | 
			
		||||
    usedWidthForNColumns: function(columns) {
 | 
			
		||||
        let usedWidth = columns  * (this._getHItemSize() + this._getSpacing());
 | 
			
		||||
        usedWidth -= this._getSpacing();
 | 
			
		||||
        return usedWidth + this.leftPadding + this.rightPadding;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    removeAll() {
 | 
			
		||||
    removeAll: function() {
 | 
			
		||||
        this._items = [];
 | 
			
		||||
        this._grid.remove_all_children();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroyAll() {
 | 
			
		||||
    destroyAll: function() {
 | 
			
		||||
        this._items = [];
 | 
			
		||||
        this._grid.destroy_all_children();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addItem(item, index) {
 | 
			
		||||
    addItem: function(item, index) {
 | 
			
		||||
        if (!item.icon instanceof BaseIcon)
 | 
			
		||||
            throw new Error('Only items with a BaseIcon icon property can be added to IconGrid');
 | 
			
		||||
 | 
			
		||||
@@ -695,35 +701,35 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
            this._grid.add_actor(item.actor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    removeItem(item) {
 | 
			
		||||
    removeItem: function(item) {
 | 
			
		||||
        this._grid.remove_child(item.actor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getItemAtIndex(index) {
 | 
			
		||||
    getItemAtIndex: function(index) {
 | 
			
		||||
        return this._grid.get_child_at_index(index);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    visibleItemsCount() {
 | 
			
		||||
    visibleItemsCount: function() {
 | 
			
		||||
        return this._grid.get_n_children() - this._grid.get_n_skip_paint();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setSpacing(spacing) {
 | 
			
		||||
    setSpacing: function(spacing) {
 | 
			
		||||
        this._fixedSpacing = spacing;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getSpacing() {
 | 
			
		||||
    _getSpacing: function() {
 | 
			
		||||
        return this._fixedSpacing ? this._fixedSpacing : this._spacing;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getHItemSize() {
 | 
			
		||||
    _getHItemSize: function() {
 | 
			
		||||
        return this._fixedHItemSize ? this._fixedHItemSize : this._hItemSize;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getVItemSize() {
 | 
			
		||||
    _getVItemSize: function() {
 | 
			
		||||
        return this._fixedVItemSize ? this._fixedVItemSize : this._vItemSize;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateSpacingForSize(availWidth, availHeight) {
 | 
			
		||||
    _updateSpacingForSize: function(availWidth, availHeight) {
 | 
			
		||||
        let maxEmptyVArea = availHeight - this._minRows * this._getVItemSize();
 | 
			
		||||
        let maxEmptyHArea = availWidth - this._minColumns * this._getHItemSize();
 | 
			
		||||
        let maxHSpacing, maxVSpacing;
 | 
			
		||||
@@ -760,7 +766,7 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
     * This function must to be called before iconGrid allocation,
 | 
			
		||||
     * to know how much spacing can the grid has
 | 
			
		||||
     */
 | 
			
		||||
    adaptToSize(availWidth, availHeight) {
 | 
			
		||||
    adaptToSize: function(availWidth, availHeight) {
 | 
			
		||||
        this._fixedHItemSize = this._hItemSize;
 | 
			
		||||
        this._fixedVItemSize = this._vItemSize;
 | 
			
		||||
        this._updateSpacingForSize(availWidth, availHeight);
 | 
			
		||||
@@ -778,11 +784,11 @@ var IconGrid = new Lang.Class({
 | 
			
		||||
            this._updateSpacingForSize(availWidth, availHeight);
 | 
			
		||||
        }
 | 
			
		||||
        Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
 | 
			
		||||
                       this._updateIconSizes.bind(this));
 | 
			
		||||
                       Lang.bind(this, this._updateIconSizes));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Note that this is ICON_SIZE as used by BaseIcon, not elsewhere in IconGrid; it's a bit messed up
 | 
			
		||||
    _updateIconSizes() {
 | 
			
		||||
    _updateIconSizes: function() {
 | 
			
		||||
        let scale = Math.min(this._fixedHItemSize, this._fixedVItemSize) / Math.max(this._hItemSize, this._vItemSize);
 | 
			
		||||
        let newIconSize = Math.floor(ICON_SIZE * scale);
 | 
			
		||||
        for (let i in this._items) {
 | 
			
		||||
@@ -796,7 +802,7 @@ var PaginatedIconGrid = new Lang.Class({
 | 
			
		||||
    Name: 'PaginatedIconGrid',
 | 
			
		||||
    Extends: IconGrid,
 | 
			
		||||
 | 
			
		||||
    _init(params) {
 | 
			
		||||
    _init: function(params) {
 | 
			
		||||
        this.parent(params);
 | 
			
		||||
        this._nPages = 0;
 | 
			
		||||
        this.currentPage = 0;
 | 
			
		||||
@@ -805,12 +811,12 @@ var PaginatedIconGrid = new Lang.Class({
 | 
			
		||||
        this._childrenPerPage = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getPreferredHeight(grid, forWidth, alloc) {
 | 
			
		||||
    _getPreferredHeight: function (grid, forWidth, alloc) {
 | 
			
		||||
        alloc.min_size = (this._availableHeightPerPageForItems() + this.bottomPadding + this.topPadding) * this._nPages + this._spaceBetweenPages * this._nPages;
 | 
			
		||||
        alloc.natural_size = (this._availableHeightPerPageForItems() + this.bottomPadding + this.topPadding) * this._nPages + this._spaceBetweenPages * this._nPages;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _allocate(grid, box, flags) {
 | 
			
		||||
    _allocate: function (grid, box, flags) {
 | 
			
		||||
         if (this._childrenPerPage == 0)
 | 
			
		||||
            log('computePages() must be called before allocate(); pagination will not work.');
 | 
			
		||||
 | 
			
		||||
@@ -864,7 +870,7 @@ var PaginatedIconGrid = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Overriden from IconGrid
 | 
			
		||||
    _getChildrenToAnimate() {
 | 
			
		||||
    _getChildrenToAnimate: function() {
 | 
			
		||||
        let children = this._getVisibleChildren();
 | 
			
		||||
        let firstIndex = this._childrenPerPage * this.currentPage;
 | 
			
		||||
        let lastIndex = firstIndex + this._childrenPerPage;
 | 
			
		||||
@@ -872,7 +878,7 @@ var PaginatedIconGrid = new Lang.Class({
 | 
			
		||||
        return children.slice(firstIndex, lastIndex);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _computePages(availWidthPerPage, availHeightPerPage) {
 | 
			
		||||
    _computePages: function (availWidthPerPage, availHeightPerPage) {
 | 
			
		||||
        let [nColumns, usedWidth] = this._computeLayout(availWidthPerPage);
 | 
			
		||||
        let nRows;
 | 
			
		||||
        let children = this._getVisibleChildren();
 | 
			
		||||
@@ -891,24 +897,24 @@ var PaginatedIconGrid = new Lang.Class({
 | 
			
		||||
        this._childrenPerPage = nColumns * this._rowsPerPage;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    adaptToSize(availWidth, availHeight) {
 | 
			
		||||
    adaptToSize: function(availWidth, availHeight) {
 | 
			
		||||
        this.parent(availWidth, availHeight);
 | 
			
		||||
        this._computePages(availWidth, availHeight);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _availableHeightPerPageForItems() {
 | 
			
		||||
    _availableHeightPerPageForItems: function() {
 | 
			
		||||
        return this.usedHeightForNRows(this._rowsPerPage) - (this.topPadding + this.bottomPadding);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    nPages() {
 | 
			
		||||
    nPages: function() {
 | 
			
		||||
        return this._nPages;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getPageHeight() {
 | 
			
		||||
    getPageHeight: function() {
 | 
			
		||||
        return this._availableHeightPerPageForItems();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getPageY(pageNumber) {
 | 
			
		||||
    getPageY: function(pageNumber) {
 | 
			
		||||
        if (!this._nPages)
 | 
			
		||||
            return 0;
 | 
			
		||||
 | 
			
		||||
@@ -917,7 +923,7 @@ var PaginatedIconGrid = new Lang.Class({
 | 
			
		||||
        return childBox.y1 - this.topPadding;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getItemPage(item) {
 | 
			
		||||
    getItemPage: function(item) {
 | 
			
		||||
        let children = this._getVisibleChildren();
 | 
			
		||||
        let index = children.indexOf(item);
 | 
			
		||||
        if (index == -1) {
 | 
			
		||||
@@ -935,7 +941,7 @@ var PaginatedIconGrid = new Lang.Class({
 | 
			
		||||
    *
 | 
			
		||||
    * Pan view to create extra space for @nRows above or below @sourceItem.
 | 
			
		||||
    */
 | 
			
		||||
    openExtraSpace(sourceItem, side, nRows) {
 | 
			
		||||
    openExtraSpace: function(sourceItem, side, nRows) {
 | 
			
		||||
        let children = this._getVisibleChildren();
 | 
			
		||||
        let index = children.indexOf(sourceItem.actor);
 | 
			
		||||
        if (index == -1) {
 | 
			
		||||
@@ -979,7 +985,7 @@ var PaginatedIconGrid = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _translateChildren(children, direction, nRows) {
 | 
			
		||||
    _translateChildren: function(children, direction, nRows) {
 | 
			
		||||
        let translationY = nRows * (this._getVItemSize() + this._getSpacing());
 | 
			
		||||
        if (translationY == 0)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -994,12 +1000,15 @@ var PaginatedIconGrid = new Lang.Class({
 | 
			
		||||
                           transition: 'easeInOutQuad'
 | 
			
		||||
                         };
 | 
			
		||||
            if (i == (children.length - 1))
 | 
			
		||||
                params.onComplete = () => { this.emit('space-opened'); };
 | 
			
		||||
                params.onComplete = Lang.bind(this,
 | 
			
		||||
                    function() {
 | 
			
		||||
                        this.emit('space-opened');
 | 
			
		||||
                    });
 | 
			
		||||
            Tweener.addTween(children[i], params);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    closeExtraSpace() {
 | 
			
		||||
    closeExtraSpace: function() {
 | 
			
		||||
        if (!this._translatedChildren || !this._translatedChildren.length) {
 | 
			
		||||
            this.emit('space-closed');
 | 
			
		||||
            return;
 | 
			
		||||
@@ -1012,7 +1021,10 @@ var PaginatedIconGrid = new Lang.Class({
 | 
			
		||||
                             { translation_y: 0,
 | 
			
		||||
                               time: EXTRA_SPACE_ANIMATION_TIME,
 | 
			
		||||
                               transition: 'easeInOutQuad',
 | 
			
		||||
                               onComplete: () => { this.emit('space-closed'); }
 | 
			
		||||
                               onComplete: Lang.bind(this,
 | 
			
		||||
                                   function() {
 | 
			
		||||
                                       this.emit('space-closed');
 | 
			
		||||
                                   })
 | 
			
		||||
                             });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@ var InhibitShortcutsDialog = new Lang.Class({
 | 
			
		||||
        'window': GObject.ParamSpec.override('window', Meta.InhibitShortcutsDialog)
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _init(window) {
 | 
			
		||||
    _init: function(window) {
 | 
			
		||||
        this.parent();
 | 
			
		||||
        this._window = window;
 | 
			
		||||
 | 
			
		||||
@@ -45,14 +45,14 @@ var InhibitShortcutsDialog = new Lang.Class({
 | 
			
		||||
        return windowTracker.get_window_app(this._window);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getRestoreAccel() {
 | 
			
		||||
    _getRestoreAccel: function() {
 | 
			
		||||
        let settings = new Gio.Settings({ schema_id: WAYLAND_KEYBINDINGS_SCHEMA });
 | 
			
		||||
        let accel = settings.get_strv('restore-shortcuts')[0] || '';
 | 
			
		||||
        return Gtk.accelerator_get_label.apply(null,
 | 
			
		||||
                                               Gtk.accelerator_parse(accel));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _buildLayout() {
 | 
			
		||||
    _buildLayout: function() {
 | 
			
		||||
        let name = this._app ? this._app.get_name() : this._window.title;
 | 
			
		||||
 | 
			
		||||
        /* Translators: %s is an application name like "Settings" */
 | 
			
		||||
@@ -84,19 +84,19 @@ var InhibitShortcutsDialog = new Lang.Class({
 | 
			
		||||
                                 default: true });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _emitResponse(response) {
 | 
			
		||||
    _emitResponse: function(response) {
 | 
			
		||||
        this.emit('response', response);
 | 
			
		||||
        this._dialog.close();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_show() {
 | 
			
		||||
    vfunc_show: function() {
 | 
			
		||||
        if (this._app && APP_WHITELIST.indexOf(this._app.get_id()) != -1)
 | 
			
		||||
            this._emitResponse(DialogResponse.ALLOW);
 | 
			
		||||
        else
 | 
			
		||||
            this._dialog.open();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_hide() {
 | 
			
		||||
    vfunc_hide: function() {
 | 
			
		||||
        this._dialog.close();
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -13,15 +13,15 @@ var KbdA11yDialog = new Lang.Class({
 | 
			
		||||
    Name: 'KbdA11yDialog',
 | 
			
		||||
    Extends: GObject.Object,
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._a11ySettings = new Gio.Settings({ schema_id: KEYBOARD_A11Y_SCHEMA });
 | 
			
		||||
 | 
			
		||||
        let deviceManager = Clutter.DeviceManager.get_default();
 | 
			
		||||
        deviceManager.connect('kbd-a11y-flags-changed',
 | 
			
		||||
                              this._showKbdA11yDialog.bind(this));
 | 
			
		||||
                              Lang.bind(this, this._showKbdA11yDialog));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _showKbdA11yDialog(deviceManager, newFlags, whatChanged) {
 | 
			
		||||
    _showKbdA11yDialog: function(deviceManager, newFlags, whatChanged) {
 | 
			
		||||
        let dialog = new ModalDialog.ModalDialog();
 | 
			
		||||
        let title, body;
 | 
			
		||||
        let key, enabled;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										312
									
								
								js/ui/layout.js
									
									
									
									
									
								
							
							
						
						@@ -52,7 +52,7 @@ var MonitorConstraint = new Lang.Class({
 | 
			
		||||
                                                        GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE,
 | 
			
		||||
                                                        false)},
 | 
			
		||||
 | 
			
		||||
    _init(props) {
 | 
			
		||||
    _init: function(props) {
 | 
			
		||||
        this._primary = false;
 | 
			
		||||
        this._index = -1;
 | 
			
		||||
        this._workArea = false;
 | 
			
		||||
@@ -98,21 +98,19 @@ var MonitorConstraint = new Lang.Class({
 | 
			
		||||
        this.notify('work-area');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_set_actor(actor) {
 | 
			
		||||
    vfunc_set_actor: function(actor) {
 | 
			
		||||
        if (actor) {
 | 
			
		||||
            if (!this._monitorsChangedId) {
 | 
			
		||||
                this._monitorsChangedId =
 | 
			
		||||
                    Main.layoutManager.connect('monitors-changed', () => {
 | 
			
		||||
                        this.actor.queue_relayout();
 | 
			
		||||
                    });
 | 
			
		||||
                this._monitorsChangedId = Main.layoutManager.connect('monitors-changed', Lang.bind(this, function() {
 | 
			
		||||
                    this.actor.queue_relayout();
 | 
			
		||||
                }));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!this._workareasChangedId) {
 | 
			
		||||
                this._workareasChangedId =
 | 
			
		||||
                    global.display.connect('workareas-changed', () => {
 | 
			
		||||
                        if (this._workArea)
 | 
			
		||||
                            this.actor.queue_relayout();
 | 
			
		||||
                    });
 | 
			
		||||
                this._workareasChangedId = global.screen.connect('workareas-changed', Lang.bind(this, function() {
 | 
			
		||||
                    if (this._workArea)
 | 
			
		||||
                        this.actor.queue_relayout();
 | 
			
		||||
                }));
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            if (this._monitorsChangedId)
 | 
			
		||||
@@ -120,14 +118,14 @@ var MonitorConstraint = new Lang.Class({
 | 
			
		||||
            this._monitorsChangedId = 0;
 | 
			
		||||
 | 
			
		||||
            if (this._workareasChangedId)
 | 
			
		||||
                global.display.disconnect(this._workareasChangedId);
 | 
			
		||||
                global.screen.disconnect(this._workareasChangedId);
 | 
			
		||||
            this._workareasChangedId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.parent(actor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_update_allocation(actor, actorBox) {
 | 
			
		||||
    vfunc_update_allocation: function(actor, actorBox) {
 | 
			
		||||
        if (!this._primary && this._index < 0)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -142,8 +140,7 @@ var MonitorConstraint = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        let rect;
 | 
			
		||||
        if (this._workArea) {
 | 
			
		||||
            let workspaceManager = global.workspace_manager;
 | 
			
		||||
            let ws = workspaceManager.get_workspace_by_index(0);
 | 
			
		||||
            let ws = global.screen.get_workspace_by_index(0);
 | 
			
		||||
            rect = ws.get_work_area_for_monitor(index);
 | 
			
		||||
        } else {
 | 
			
		||||
            rect = Main.layoutManager.monitors[index];
 | 
			
		||||
@@ -156,7 +153,7 @@ var MonitorConstraint = new Lang.Class({
 | 
			
		||||
var Monitor = new Lang.Class({
 | 
			
		||||
    Name: 'Monitor',
 | 
			
		||||
 | 
			
		||||
    _init(index, geometry) {
 | 
			
		||||
    _init: function(index, geometry) {
 | 
			
		||||
        this.index = index;
 | 
			
		||||
        this.x = geometry.x;
 | 
			
		||||
        this.y = geometry.y;
 | 
			
		||||
@@ -165,7 +162,7 @@ var Monitor = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get inFullscreen() {
 | 
			
		||||
        return global.display.get_monitor_in_fullscreen(this.index);
 | 
			
		||||
        return global.screen.get_monitor_in_fullscreen(this.index);
 | 
			
		||||
    }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
@@ -178,7 +175,7 @@ const defaultParams = {
 | 
			
		||||
var LayoutManager = new Lang.Class({
 | 
			
		||||
    Name: 'LayoutManager',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function () {
 | 
			
		||||
        this._rtl = (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL);
 | 
			
		||||
        this.monitors = [];
 | 
			
		||||
        this.primaryMonitor = null;
 | 
			
		||||
@@ -204,19 +201,22 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        // Set up stage hierarchy to group all UI actors under one container.
 | 
			
		||||
        this.uiGroup = new Shell.GenericContainer({ name: 'uiGroup' });
 | 
			
		||||
        this.uiGroup.connect('allocate', (actor, box, flags) => {
 | 
			
		||||
            let children = actor.get_children();
 | 
			
		||||
            for (let i = 0; i < children.length; i++)
 | 
			
		||||
                children[i].allocate_preferred_size(flags);
 | 
			
		||||
        });
 | 
			
		||||
        this.uiGroup.connect('get-preferred-width', (actor, forHeight, alloc) => {
 | 
			
		||||
            let width = global.stage.width;
 | 
			
		||||
            [alloc.min_size, alloc.natural_size] = [width, width];
 | 
			
		||||
        });
 | 
			
		||||
        this.uiGroup.connect('get-preferred-height', (actor, forWidth, alloc) => {
 | 
			
		||||
            let height = global.stage.height;
 | 
			
		||||
            [alloc.min_size, alloc.natural_size] = [height, height];
 | 
			
		||||
        });
 | 
			
		||||
        this.uiGroup.connect('allocate',
 | 
			
		||||
                        function (actor, box, flags) {
 | 
			
		||||
                            let children = actor.get_children();
 | 
			
		||||
                            for (let i = 0; i < children.length; i++)
 | 
			
		||||
                                children[i].allocate_preferred_size(flags);
 | 
			
		||||
                        });
 | 
			
		||||
        this.uiGroup.connect('get-preferred-width',
 | 
			
		||||
                        function(actor, forHeight, alloc) {
 | 
			
		||||
                            let width = global.stage.width;
 | 
			
		||||
                            [alloc.min_size, alloc.natural_size] = [width, width];
 | 
			
		||||
                        });
 | 
			
		||||
        this.uiGroup.connect('get-preferred-height',
 | 
			
		||||
                        function(actor, forWidth, alloc) {
 | 
			
		||||
                            let height = global.stage.height;
 | 
			
		||||
                            [alloc.min_size, alloc.natural_size] = [height, height];
 | 
			
		||||
                        });
 | 
			
		||||
 | 
			
		||||
        global.stage.remove_actor(global.window_group);
 | 
			
		||||
        this.uiGroup.add_actor(global.window_group);
 | 
			
		||||
@@ -240,7 +240,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        this.addChrome(this.panelBox, { affectsStruts: true,
 | 
			
		||||
                                        trackFullscreen: true });
 | 
			
		||||
        this.panelBox.connect('allocation-changed',
 | 
			
		||||
                              this._panelBoxChanged.bind(this));
 | 
			
		||||
                              Lang.bind(this, this._panelBoxChanged));
 | 
			
		||||
 | 
			
		||||
        this.modalDialogGroup = new St.Widget({ name: 'modalDialogGroup',
 | 
			
		||||
                                                layout_manager: new Clutter.BinLayout() });
 | 
			
		||||
@@ -260,7 +260,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        global.stage.remove_actor(global.top_window_group);
 | 
			
		||||
        this.uiGroup.add_actor(global.top_window_group);
 | 
			
		||||
 | 
			
		||||
        let feedbackGroup = Meta.get_feedback_group_for_display(global.display);
 | 
			
		||||
        let feedbackGroup = Meta.get_feedback_group_for_screen(global.screen);
 | 
			
		||||
        global.stage.remove_actor(feedbackGroup);
 | 
			
		||||
        this.uiGroup.add_actor(feedbackGroup);
 | 
			
		||||
 | 
			
		||||
@@ -270,19 +270,14 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        this._bgManagers = [];
 | 
			
		||||
 | 
			
		||||
        // Need to update struts on new workspaces when they are added
 | 
			
		||||
        let workspaceManager = global.workspace_manager;
 | 
			
		||||
        workspaceManager.connect('notify::n-workspaces',
 | 
			
		||||
                                 this._queueUpdateRegions.bind(this));
 | 
			
		||||
 | 
			
		||||
        let display = global.display;
 | 
			
		||||
        display.connect('restacked',
 | 
			
		||||
                        this._windowsRestacked.bind(this));
 | 
			
		||||
        display.connect('in-fullscreen-changed',
 | 
			
		||||
                        this._updateFullscreen.bind(this));
 | 
			
		||||
 | 
			
		||||
        let monitorManager = Meta.MonitorManager.get();
 | 
			
		||||
        monitorManager.connect('monitors-changed',
 | 
			
		||||
                               this._monitorsChanged.bind(this));
 | 
			
		||||
        global.screen.connect('notify::n-workspaces',
 | 
			
		||||
                              Lang.bind(this, this._queueUpdateRegions));
 | 
			
		||||
        global.screen.connect('restacked',
 | 
			
		||||
                              Lang.bind(this, this._windowsRestacked));
 | 
			
		||||
        global.screen.connect('monitors-changed',
 | 
			
		||||
                              Lang.bind(this, this._monitorsChanged));
 | 
			
		||||
        global.screen.connect('in-fullscreen-changed',
 | 
			
		||||
                              Lang.bind(this, this._updateFullscreen));
 | 
			
		||||
        this._monitorsChanged();
 | 
			
		||||
 | 
			
		||||
        // NVIDIA drivers don't preserve FBO contents across
 | 
			
		||||
@@ -290,47 +285,47 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        // https://bugzilla.gnome.org/show_bug.cgi?id=739178
 | 
			
		||||
        if (Shell.util_need_background_refresh()) {
 | 
			
		||||
            LoginManager.getLoginManager().connect('prepare-for-sleep',
 | 
			
		||||
                (lm, suspending) => {
 | 
			
		||||
                    if (suspending)
 | 
			
		||||
                        return;
 | 
			
		||||
                    Meta.Background.refresh_all();
 | 
			
		||||
                });
 | 
			
		||||
                                                   function(lm, suspending) {
 | 
			
		||||
                                                       if (suspending)
 | 
			
		||||
                                                           return;
 | 
			
		||||
                                                       Meta.Background.refresh_all();
 | 
			
		||||
                                                   });
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // This is called by Main after everything else is constructed
 | 
			
		||||
    init() {
 | 
			
		||||
        Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
 | 
			
		||||
    init: function() {
 | 
			
		||||
        Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
 | 
			
		||||
 | 
			
		||||
        this._loadBackground();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    showOverview() {
 | 
			
		||||
    showOverview: function() {
 | 
			
		||||
        this.overviewGroup.show();
 | 
			
		||||
 | 
			
		||||
        this._inOverview = true;
 | 
			
		||||
        this._updateVisibility();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hideOverview() {
 | 
			
		||||
    hideOverview: function() {
 | 
			
		||||
        this.overviewGroup.hide();
 | 
			
		||||
 | 
			
		||||
        this._inOverview = false;
 | 
			
		||||
        this._updateVisibility();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _sessionUpdated() {
 | 
			
		||||
    _sessionUpdated: function() {
 | 
			
		||||
        this._updateVisibility();
 | 
			
		||||
        this._queueUpdateRegions();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateMonitors() {
 | 
			
		||||
        let display = global.display;
 | 
			
		||||
    _updateMonitors: function() {
 | 
			
		||||
        let screen = global.screen;
 | 
			
		||||
 | 
			
		||||
        this.monitors = [];
 | 
			
		||||
        let nMonitors = display.get_n_monitors();
 | 
			
		||||
        let nMonitors = screen.get_n_monitors();
 | 
			
		||||
        for (let i = 0; i < nMonitors; i++)
 | 
			
		||||
            this.monitors.push(new Monitor(i, display.get_monitor_geometry(i)));
 | 
			
		||||
            this.monitors.push(new Monitor(i, screen.get_monitor_geometry(i)));
 | 
			
		||||
 | 
			
		||||
        if (nMonitors == 0) {
 | 
			
		||||
            this.primaryIndex = this.bottomIndex = -1;
 | 
			
		||||
@@ -339,7 +334,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        } else {
 | 
			
		||||
            // If there are monitors below the primary, then we need
 | 
			
		||||
            // to split primary from bottom.
 | 
			
		||||
            this.primaryIndex = this.bottomIndex = display.get_primary_monitor();
 | 
			
		||||
            this.primaryIndex = this.bottomIndex = screen.get_primary_monitor();
 | 
			
		||||
            for (let i = 0; i < this.monitors.length; i++) {
 | 
			
		||||
                let monitor = this.monitors[i];
 | 
			
		||||
                if (this._isAboveOrBelowPrimary(monitor)) {
 | 
			
		||||
@@ -362,9 +357,9 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateHotCorners() {
 | 
			
		||||
    _updateHotCorners: function() {
 | 
			
		||||
        // destroy old hot corners
 | 
			
		||||
        this.hotCorners.forEach(corner => {
 | 
			
		||||
        this.hotCorners.forEach(function(corner) {
 | 
			
		||||
            if (corner)
 | 
			
		||||
                corner.destroy();
 | 
			
		||||
        });
 | 
			
		||||
@@ -421,22 +416,22 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        this.emit('hot-corners-changed');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _addBackgroundMenu(bgManager) {
 | 
			
		||||
    _addBackgroundMenu: function(bgManager) {
 | 
			
		||||
        BackgroundMenu.addBackgroundMenu(bgManager.backgroundActor, this);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createBackgroundManager(monitorIndex) {
 | 
			
		||||
    _createBackgroundManager: function(monitorIndex) {
 | 
			
		||||
        let bgManager = new Background.BackgroundManager({ container: this._backgroundGroup,
 | 
			
		||||
                                                           layoutManager: this,
 | 
			
		||||
                                                           monitorIndex: monitorIndex });
 | 
			
		||||
 | 
			
		||||
        bgManager.connect('changed', this._addBackgroundMenu.bind(this));
 | 
			
		||||
        bgManager.connect('changed', Lang.bind(this, this._addBackgroundMenu));
 | 
			
		||||
        this._addBackgroundMenu(bgManager);
 | 
			
		||||
 | 
			
		||||
        return bgManager;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _showSecondaryBackgrounds() {
 | 
			
		||||
    _showSecondaryBackgrounds: function() {
 | 
			
		||||
        for (let i = 0; i < this.monitors.length; i++) {
 | 
			
		||||
            if (i != this.primaryIndex) {
 | 
			
		||||
                let backgroundActor = this._bgManagers[i].backgroundActor;
 | 
			
		||||
@@ -450,7 +445,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateBackgrounds() {
 | 
			
		||||
    _updateBackgrounds: function() {
 | 
			
		||||
        let i;
 | 
			
		||||
        for (i = 0; i < this._bgManagers.length; i++)
 | 
			
		||||
            this._bgManagers[i].destroy();
 | 
			
		||||
@@ -469,13 +464,13 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateKeyboardBox() {
 | 
			
		||||
    _updateKeyboardBox: function() {
 | 
			
		||||
        this.keyboardBox.set_position(this.keyboardMonitor.x,
 | 
			
		||||
                                      this.keyboardMonitor.y + this.keyboardMonitor.height);
 | 
			
		||||
        this.keyboardBox.set_size(this.keyboardMonitor.width, -1);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateBoxes() {
 | 
			
		||||
    _updateBoxes: function() {
 | 
			
		||||
        this.screenShieldGroup.set_position(0, 0);
 | 
			
		||||
        this.screenShieldGroup.set_size(global.screen_width, global.screen_height);
 | 
			
		||||
 | 
			
		||||
@@ -488,17 +483,17 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        this.keyboardIndex = this.primaryIndex;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _panelBoxChanged() {
 | 
			
		||||
    _panelBoxChanged: function() {
 | 
			
		||||
        this._updatePanelBarrier();
 | 
			
		||||
 | 
			
		||||
        let size = this.panelBox.height;
 | 
			
		||||
        this.hotCorners.forEach(corner => {
 | 
			
		||||
        this.hotCorners.forEach(function(corner) {
 | 
			
		||||
            if (corner)
 | 
			
		||||
                corner.setBarrierSize(size);
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updatePanelBarrier() {
 | 
			
		||||
    _updatePanelBarrier: function() {
 | 
			
		||||
        if (this._rightPanelBarrier) {
 | 
			
		||||
            this._rightPanelBarrier.destroy();
 | 
			
		||||
            this._rightPanelBarrier = null;
 | 
			
		||||
@@ -517,7 +512,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _monitorsChanged() {
 | 
			
		||||
    _monitorsChanged: function() {
 | 
			
		||||
        this._updateMonitors();
 | 
			
		||||
        this._updateBoxes();
 | 
			
		||||
        this._updateHotCorners();
 | 
			
		||||
@@ -529,7 +524,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        this.emit('monitors-changed');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _isAboveOrBelowPrimary(monitor) {
 | 
			
		||||
    _isAboveOrBelowPrimary: function(monitor) {
 | 
			
		||||
        let primary = this.monitors[this.primaryIndex];
 | 
			
		||||
        let monitorLeft = monitor.x, monitorRight = monitor.x + monitor.width;
 | 
			
		||||
        let primaryLeft = primary.x, primaryRight = primary.x + primary.width;
 | 
			
		||||
@@ -544,7 +539,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get currentMonitor() {
 | 
			
		||||
        let index = global.display.get_current_monitor();
 | 
			
		||||
        let index = global.screen.get_current_monitor();
 | 
			
		||||
        return this.monitors[index];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -563,8 +558,6 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get focusMonitor() {
 | 
			
		||||
        if (this.focusIndex < 0)
 | 
			
		||||
            return null;
 | 
			
		||||
        return this.monitors[this.focusIndex];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -577,7 +570,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        return this._keyboardIndex;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _loadBackground() {
 | 
			
		||||
    _loadBackground: function() {
 | 
			
		||||
        if (!this.primaryMonitor) {
 | 
			
		||||
            this._pendingLoadBackground = true;
 | 
			
		||||
            return;
 | 
			
		||||
@@ -591,13 +584,13 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
                                                      coordinate: Clutter.BindCoordinate.ALL });
 | 
			
		||||
        this._systemBackground.actor.add_constraint(constraint);
 | 
			
		||||
 | 
			
		||||
        let signalId = this._systemBackground.connect('loaded', () => {
 | 
			
		||||
        let signalId = this._systemBackground.connect('loaded', Lang.bind(this, function() {
 | 
			
		||||
            this._systemBackground.disconnect(signalId);
 | 
			
		||||
            this._systemBackground.actor.show();
 | 
			
		||||
            global.stage.show();
 | 
			
		||||
 | 
			
		||||
            this._prepareStartupAnimation();
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Startup Animations
 | 
			
		||||
@@ -615,7 +608,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
    // When starting a normal user session, we want to grow it out of the middle
 | 
			
		||||
    // of the screen.
 | 
			
		||||
 | 
			
		||||
    _prepareStartupAnimation() {
 | 
			
		||||
    _prepareStartupAnimation: function() {
 | 
			
		||||
        // During the initial transition, add a simple actor to block all events,
 | 
			
		||||
        // so they don't get delivered to X11 windows that have been transformed.
 | 
			
		||||
        this._coverPane = new Clutter.Actor({ opacity: 0,
 | 
			
		||||
@@ -659,14 +652,14 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        // until the event loop is uncontended and idle.
 | 
			
		||||
        // This helps to prevent us from running the animation
 | 
			
		||||
        // when the system is bogged down
 | 
			
		||||
        let id = GLib.idle_add(GLib.PRIORITY_LOW, () => {
 | 
			
		||||
        let id = GLib.idle_add(GLib.PRIORITY_LOW, Lang.bind(this, function() {
 | 
			
		||||
            this._startupAnimation();
 | 
			
		||||
            return GLib.SOURCE_REMOVE;
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
        GLib.Source.set_name_by_id(id, '[gnome-shell] this._startupAnimation');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _startupAnimation() {
 | 
			
		||||
    _startupAnimation: function() {
 | 
			
		||||
        if (Meta.is_restart())
 | 
			
		||||
            this._startupAnimationComplete();
 | 
			
		||||
        else if (Main.sessionMode.isGreeter)
 | 
			
		||||
@@ -675,7 +668,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
            this._startupAnimationSession();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _startupAnimationGreeter() {
 | 
			
		||||
    _startupAnimationGreeter: function() {
 | 
			
		||||
        Tweener.addTween(this.panelBox,
 | 
			
		||||
                         { translation_y: 0,
 | 
			
		||||
                           time: STARTUP_ANIMATION_TIME,
 | 
			
		||||
@@ -684,7 +677,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
                           onCompleteScope: this });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _startupAnimationSession() {
 | 
			
		||||
    _startupAnimationSession: function() {
 | 
			
		||||
        Tweener.addTween(this.uiGroup,
 | 
			
		||||
                         { scale_x: 1,
 | 
			
		||||
                           scale_y: 1,
 | 
			
		||||
@@ -695,7 +688,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
                           onCompleteScope: this });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _startupAnimationComplete() {
 | 
			
		||||
    _startupAnimationComplete: function() {
 | 
			
		||||
        this._coverPane.destroy();
 | 
			
		||||
        this._coverPane = null;
 | 
			
		||||
 | 
			
		||||
@@ -716,7 +709,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        this.emit('startup-complete');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    showKeyboard() {
 | 
			
		||||
    showKeyboard: function () {
 | 
			
		||||
        this.keyboardBox.show();
 | 
			
		||||
        Tweener.addTween(this.keyboardBox,
 | 
			
		||||
                         { anchor_y: this.keyboardBox.height,
 | 
			
		||||
@@ -729,17 +722,17 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        this.emit('keyboard-visible-changed', true);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _showKeyboardComplete() {
 | 
			
		||||
    _showKeyboardComplete: function() {
 | 
			
		||||
        // Poke Chrome to update the input shape; it doesn't notice
 | 
			
		||||
        // anchor point changes
 | 
			
		||||
        this._updateRegions();
 | 
			
		||||
 | 
			
		||||
        this._keyboardHeightNotifyId = this.keyboardBox.connect('notify::height', () => {
 | 
			
		||||
        this._keyboardHeightNotifyId = this.keyboardBox.connect('notify::height', Lang.bind(this, function () {
 | 
			
		||||
            this.keyboardBox.anchor_y = this.keyboardBox.height;
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hideKeyboard(immediate) {
 | 
			
		||||
    hideKeyboard: function (immediate) {
 | 
			
		||||
        if (this._keyboardHeightNotifyId) {
 | 
			
		||||
            this.keyboardBox.disconnect(this._keyboardHeightNotifyId);
 | 
			
		||||
            this._keyboardHeightNotifyId = 0;
 | 
			
		||||
@@ -756,7 +749,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        this.emit('keyboard-visible-changed', false);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _hideKeyboardComplete() {
 | 
			
		||||
    _hideKeyboardComplete: function() {
 | 
			
		||||
        this.keyboardBox.hide();
 | 
			
		||||
        this._updateRegions();
 | 
			
		||||
    },
 | 
			
		||||
@@ -771,7 +764,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
    // the actual mouse pointer as it moves, you need to call this
 | 
			
		||||
    // function before you show the menu to ensure it is at the right
 | 
			
		||||
    // position and has the right size.
 | 
			
		||||
    setDummyCursorGeometry(x, y, w, h) {
 | 
			
		||||
    setDummyCursorGeometry: function(x, y, w, h) {
 | 
			
		||||
        this.dummyCursor.set_position(Math.round(x), Math.round(y));
 | 
			
		||||
        this.dummyCursor.set_size(Math.round(w), Math.round(h));
 | 
			
		||||
    },
 | 
			
		||||
@@ -795,7 +788,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
    // will be bound to the presence of fullscreen windows on the same
 | 
			
		||||
    // monitor (it will be hidden whenever a fullscreen window is visible,
 | 
			
		||||
    // and shown otherwise)
 | 
			
		||||
    addChrome(actor, params) {
 | 
			
		||||
    addChrome: function(actor, params) {
 | 
			
		||||
        this.uiGroup.add_actor(actor);
 | 
			
		||||
        if (this.uiGroup.contains(global.top_window_group))
 | 
			
		||||
            this.uiGroup.set_child_below_sibling(actor, global.top_window_group);
 | 
			
		||||
@@ -812,7 +805,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
    // @params can have any of the same values as in addChrome(),
 | 
			
		||||
    // though some possibilities don't make sense. By default, @actor has
 | 
			
		||||
    // the same params as its chrome ancestor.
 | 
			
		||||
    trackChrome(actor, params) {
 | 
			
		||||
    trackChrome: function(actor, params) {
 | 
			
		||||
        let ancestor = actor.get_parent();
 | 
			
		||||
        let index = this._findActor(ancestor);
 | 
			
		||||
        while (ancestor && index == -1) {
 | 
			
		||||
@@ -838,7 +831,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
    // @actor: an actor previously tracked via trackChrome()
 | 
			
		||||
    //
 | 
			
		||||
    // Undoes the effect of trackChrome()
 | 
			
		||||
    untrackChrome(actor) {
 | 
			
		||||
    untrackChrome: function(actor) {
 | 
			
		||||
        this._untrackActor(actor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -846,12 +839,12 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
    // @actor: a chrome actor
 | 
			
		||||
    //
 | 
			
		||||
    // Removes @actor from the chrome
 | 
			
		||||
    removeChrome(actor) {
 | 
			
		||||
    removeChrome: function(actor) {
 | 
			
		||||
        this.uiGroup.remove_actor(actor);
 | 
			
		||||
        this._untrackActor(actor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _findActor(actor) {
 | 
			
		||||
    _findActor: function(actor) {
 | 
			
		||||
        for (let i = 0; i < this._trackedActors.length; i++) {
 | 
			
		||||
            let actorData = this._trackedActors[i];
 | 
			
		||||
            if (actorData.actor == actor)
 | 
			
		||||
@@ -860,18 +853,18 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        return -1;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _trackActor(actor, params) {
 | 
			
		||||
    _trackActor: function(actor, params) {
 | 
			
		||||
        if (this._findActor(actor) != -1)
 | 
			
		||||
            throw new Error('trying to re-track existing chrome actor');
 | 
			
		||||
 | 
			
		||||
        let actorData = Params.parse(params, defaultParams);
 | 
			
		||||
        actorData.actor = actor;
 | 
			
		||||
        actorData.visibleId = actor.connect('notify::visible',
 | 
			
		||||
                                            this._queueUpdateRegions.bind(this));
 | 
			
		||||
                                            Lang.bind(this, this._queueUpdateRegions));
 | 
			
		||||
        actorData.allocationId = actor.connect('notify::allocation',
 | 
			
		||||
                                               this._queueUpdateRegions.bind(this));
 | 
			
		||||
                                               Lang.bind(this, this._queueUpdateRegions));
 | 
			
		||||
        actorData.destroyId = actor.connect('destroy',
 | 
			
		||||
                                            this._untrackActor.bind(this));
 | 
			
		||||
                                            Lang.bind(this, this._untrackActor));
 | 
			
		||||
        // Note that destroying actor will unset its parent, so we don't
 | 
			
		||||
        // need to connect to 'destroy' too.
 | 
			
		||||
 | 
			
		||||
@@ -880,7 +873,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        this._queueUpdateRegions();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _untrackActor(actor) {
 | 
			
		||||
    _untrackActor: function(actor) {
 | 
			
		||||
        let i = this._findActor(actor);
 | 
			
		||||
 | 
			
		||||
        if (i == -1)
 | 
			
		||||
@@ -895,7 +888,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        this._queueUpdateRegions();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateActorVisibility(actorData) {
 | 
			
		||||
    _updateActorVisibility: function(actorData) {
 | 
			
		||||
        if (!actorData.trackFullscreen)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -905,61 +898,60 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
                                    monitor.inFullscreen);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateVisibility() {
 | 
			
		||||
    _updateVisibility: function() {
 | 
			
		||||
        let windowsVisible = Main.sessionMode.hasWindows && !this._inOverview;
 | 
			
		||||
 | 
			
		||||
        global.window_group.visible = windowsVisible;
 | 
			
		||||
        global.top_window_group.visible = windowsVisible;
 | 
			
		||||
 | 
			
		||||
        this._trackedActors.forEach(this._updateActorVisibility.bind(this));
 | 
			
		||||
        this._trackedActors.forEach(Lang.bind(this, this._updateActorVisibility));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getWorkAreaForMonitor(monitorIndex) {
 | 
			
		||||
    getWorkAreaForMonitor: function(monitorIndex) {
 | 
			
		||||
        // Assume that all workspaces will have the same
 | 
			
		||||
        // struts and pick the first one.
 | 
			
		||||
        let workspaceManager = global.workspace_manager;
 | 
			
		||||
        let ws = workspaceManager.get_workspace_by_index(0);
 | 
			
		||||
        let ws = global.screen.get_workspace_by_index(0);
 | 
			
		||||
        return ws.get_work_area_for_monitor(monitorIndex);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // This call guarantees that we return some monitor to simplify usage of it
 | 
			
		||||
    // In practice all tracked actors should be visible on some monitor anyway
 | 
			
		||||
    findIndexForActor(actor) {
 | 
			
		||||
    findIndexForActor: function(actor) {
 | 
			
		||||
        let [x, y] = actor.get_transformed_position();
 | 
			
		||||
        let [w, h] = actor.get_transformed_size();
 | 
			
		||||
        let rect = new Meta.Rectangle({ x: x, y: y, width: w, height: h });
 | 
			
		||||
        return global.display.get_monitor_index_for_rect(rect);
 | 
			
		||||
        return global.screen.get_monitor_index_for_rect(rect);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    findMonitorForActor(actor) {
 | 
			
		||||
    findMonitorForActor: function(actor) {
 | 
			
		||||
        let index = this.findIndexForActor(actor);
 | 
			
		||||
        if (index >= 0 && index < this.monitors.length)
 | 
			
		||||
            return this.monitors[index];
 | 
			
		||||
        return null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _queueUpdateRegions() {
 | 
			
		||||
    _queueUpdateRegions: function() {
 | 
			
		||||
        if (this._startingUp)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (!this._updateRegionIdle)
 | 
			
		||||
            this._updateRegionIdle = Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
 | 
			
		||||
                                                    this._updateRegions.bind(this));
 | 
			
		||||
                                                    Lang.bind(this, this._updateRegions));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getWindowActorsForWorkspace(workspace) {
 | 
			
		||||
        return global.get_window_actors().filter(actor => {
 | 
			
		||||
    _getWindowActorsForWorkspace: function(workspace) {
 | 
			
		||||
        return global.get_window_actors().filter(function (actor) {
 | 
			
		||||
            let win = actor.meta_window;
 | 
			
		||||
            return win.located_on_workspace(workspace);
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateFullscreen() {
 | 
			
		||||
    _updateFullscreen: function() {
 | 
			
		||||
        this._updateVisibility();
 | 
			
		||||
        this._queueUpdateRegions();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowsRestacked() {
 | 
			
		||||
    _windowsRestacked: function() {
 | 
			
		||||
        let changed = false;
 | 
			
		||||
 | 
			
		||||
        if (this._isPopupWindowVisible != global.top_window_group.get_children().some(isPopupMetaWindow))
 | 
			
		||||
@@ -971,7 +963,7 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateRegions() {
 | 
			
		||||
    _updateRegions: function() {
 | 
			
		||||
        if (this._updateRegionIdle) {
 | 
			
		||||
            Meta.later_remove(this._updateRegionIdle);
 | 
			
		||||
            delete this._updateRegionIdle;
 | 
			
		||||
@@ -1061,16 +1053,16 @@ var LayoutManager = new Lang.Class({
 | 
			
		||||
        global.set_stage_input_region(rects);
 | 
			
		||||
        this._isPopupWindowVisible = isPopupMenuVisible;
 | 
			
		||||
 | 
			
		||||
        let workspaceManager = global.workspace_manager;
 | 
			
		||||
        for (let w = 0; w < workspaceManager.n_workspaces; w++) {
 | 
			
		||||
            let workspace = workspaceManager.get_workspace_by_index(w);
 | 
			
		||||
        let screen = global.screen;
 | 
			
		||||
        for (let w = 0; w < screen.n_workspaces; w++) {
 | 
			
		||||
            let workspace = screen.get_workspace_by_index(w);
 | 
			
		||||
            workspace.set_builtin_struts(struts);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return GLib.SOURCE_REMOVE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    modalEnded() {
 | 
			
		||||
    modalEnded: function() {
 | 
			
		||||
        // We don't update the stage input region while in a modal,
 | 
			
		||||
        // so queue an update now.
 | 
			
		||||
        this._queueUpdateRegions();
 | 
			
		||||
@@ -1086,7 +1078,7 @@ Signals.addSignalMethods(LayoutManager.prototype);
 | 
			
		||||
var HotCorner = new Lang.Class({
 | 
			
		||||
    Name: 'HotCorner',
 | 
			
		||||
 | 
			
		||||
    _init(layoutManager, monitor, x, y) {
 | 
			
		||||
    _init : function(layoutManager, monitor, x, y) {
 | 
			
		||||
        // We use this flag to mark the case where the user has entered the
 | 
			
		||||
        // hot corner and has not left both the hot corner and a surrounding
 | 
			
		||||
        // guard area (the "environs"). This avoids triggering the hot corner
 | 
			
		||||
@@ -1104,7 +1096,7 @@ var HotCorner = new Lang.Class({
 | 
			
		||||
                                                    HOT_CORNER_PRESSURE_TIMEOUT,
 | 
			
		||||
                                                    Shell.ActionMode.NORMAL |
 | 
			
		||||
                                                    Shell.ActionMode.OVERVIEW);
 | 
			
		||||
        this._pressureBarrier.connect('trigger', this._toggleOverview.bind(this));
 | 
			
		||||
        this._pressureBarrier.connect('trigger', Lang.bind(this, this._toggleOverview));
 | 
			
		||||
 | 
			
		||||
        // Cache the three ripples instead of dynamically creating and destroying them.
 | 
			
		||||
        this._ripple1 = new St.BoxLayout({ style_class: 'ripple-box', opacity: 0, visible: false });
 | 
			
		||||
@@ -1116,7 +1108,7 @@ var HotCorner = new Lang.Class({
 | 
			
		||||
        layoutManager.uiGroup.add_actor(this._ripple3);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setBarrierSize(size) {
 | 
			
		||||
    setBarrierSize: function(size) {
 | 
			
		||||
        if (this._verticalBarrier) {
 | 
			
		||||
            this._pressureBarrier.removeBarrier(this._verticalBarrier);
 | 
			
		||||
            this._verticalBarrier.destroy();
 | 
			
		||||
@@ -1151,7 +1143,7 @@ var HotCorner = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setupFallbackCornerIfNeeded(layoutManager) {
 | 
			
		||||
    _setupFallbackCornerIfNeeded: function(layoutManager) {
 | 
			
		||||
        if (!global.display.supports_extended_barriers()) {
 | 
			
		||||
            this.actor = new Clutter.Actor({ name: 'hot-corner-environs',
 | 
			
		||||
                                             x: this._x, y: this._y,
 | 
			
		||||
@@ -1177,16 +1169,16 @@ var HotCorner = new Lang.Class({
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.actor.connect('leave-event',
 | 
			
		||||
                               this._onEnvironsLeft.bind(this));
 | 
			
		||||
                               Lang.bind(this, this._onEnvironsLeft));
 | 
			
		||||
 | 
			
		||||
            this._corner.connect('enter-event',
 | 
			
		||||
                                 this._onCornerEntered.bind(this));
 | 
			
		||||
                                 Lang.bind(this, this._onCornerEntered));
 | 
			
		||||
            this._corner.connect('leave-event',
 | 
			
		||||
                                 this._onCornerLeft.bind(this));
 | 
			
		||||
                                 Lang.bind(this, this._onCornerLeft));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
    destroy: function() {
 | 
			
		||||
        this.setBarrierSize(0);
 | 
			
		||||
        this._pressureBarrier.destroy();
 | 
			
		||||
        this._pressureBarrier = null;
 | 
			
		||||
@@ -1195,7 +1187,7 @@ var HotCorner = new Lang.Class({
 | 
			
		||||
            this.actor.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _animRipple(ripple, delay, time, startScale, startOpacity, finalScale) {
 | 
			
		||||
    _animRipple : function(ripple, delay, time, startScale, startOpacity, finalScale) {
 | 
			
		||||
        // We draw a ripple by using a source image and animating it scaling
 | 
			
		||||
        // outwards and fading away. We want the ripples to move linearly
 | 
			
		||||
        // or it looks unrealistic, but if the opacity of the ripple goes
 | 
			
		||||
@@ -1221,11 +1213,11 @@ var HotCorner = new Lang.Class({
 | 
			
		||||
                                   delay: delay,
 | 
			
		||||
                                   time: time,
 | 
			
		||||
                                   transition: 'linear',
 | 
			
		||||
                                   onUpdate() { ripple.opacity = 255 * Math.sqrt(ripple._opacity); },
 | 
			
		||||
                                   onComplete() { ripple.visible = false; } });
 | 
			
		||||
                                   onUpdate: function() { ripple.opacity = 255 * Math.sqrt(ripple._opacity); },
 | 
			
		||||
                                   onComplete: function() { ripple.visible = false; } });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _rippleAnimation() {
 | 
			
		||||
    _rippleAnimation: function() {
 | 
			
		||||
        // Show three concentric ripples expanding outwards; the exact
 | 
			
		||||
        // parameters were found by trial and error, so don't look
 | 
			
		||||
        // for them to make perfect sense mathematically
 | 
			
		||||
@@ -1236,7 +1228,7 @@ var HotCorner = new Lang.Class({
 | 
			
		||||
        this._animRipple(this._ripple3, 0.35,  1.0,   0.0,   0.3,     1);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _toggleOverview() {
 | 
			
		||||
    _toggleOverview: function() {
 | 
			
		||||
        if (this._monitor.inFullscreen)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -1246,7 +1238,7 @@ var HotCorner = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    handleDragOver(source, actor, x, y, time) {
 | 
			
		||||
    handleDragOver: function(source, actor, x, y, time) {
 | 
			
		||||
        if (source != Main.xdndHandler)
 | 
			
		||||
            return DND.DragMotionResult.CONTINUE;
 | 
			
		||||
 | 
			
		||||
@@ -1255,7 +1247,7 @@ var HotCorner = new Lang.Class({
 | 
			
		||||
        return DND.DragMotionResult.CONTINUE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onCornerEntered() {
 | 
			
		||||
    _onCornerEntered : function() {
 | 
			
		||||
        if (!this._entered) {
 | 
			
		||||
            this._entered = true;
 | 
			
		||||
            this._toggleOverview();
 | 
			
		||||
@@ -1263,14 +1255,14 @@ var HotCorner = new Lang.Class({
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onCornerLeft(actor, event) {
 | 
			
		||||
    _onCornerLeft : function(actor, event) {
 | 
			
		||||
        if (event.get_related() != this.actor)
 | 
			
		||||
            this._entered = false;
 | 
			
		||||
        // Consume event, otherwise this will confuse onEnvironsLeft
 | 
			
		||||
        return Clutter.EVENT_STOP;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onEnvironsLeft(actor, event) {
 | 
			
		||||
    _onEnvironsLeft : function(actor, event) {
 | 
			
		||||
        if (event.get_related() != this._corner)
 | 
			
		||||
            this._entered = false;
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
@@ -1280,7 +1272,7 @@ var HotCorner = new Lang.Class({
 | 
			
		||||
var PressureBarrier = new Lang.Class({
 | 
			
		||||
    Name: 'PressureBarrier',
 | 
			
		||||
 | 
			
		||||
    _init(threshold, timeout, actionMode) {
 | 
			
		||||
    _init: function(threshold, timeout, actionMode) {
 | 
			
		||||
        this._threshold = threshold;
 | 
			
		||||
        this._timeout = timeout;
 | 
			
		||||
        this._actionMode = actionMode;
 | 
			
		||||
@@ -1291,57 +1283,57 @@ var PressureBarrier = new Lang.Class({
 | 
			
		||||
        this._reset();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addBarrier(barrier) {
 | 
			
		||||
        barrier._pressureHitId = barrier.connect('hit', this._onBarrierHit.bind(this));
 | 
			
		||||
        barrier._pressureLeftId = barrier.connect('left', this._onBarrierLeft.bind(this));
 | 
			
		||||
    addBarrier: function(barrier) {
 | 
			
		||||
        barrier._pressureHitId = barrier.connect('hit', Lang.bind(this, this._onBarrierHit));
 | 
			
		||||
        barrier._pressureLeftId = barrier.connect('left', Lang.bind(this, this._onBarrierLeft));
 | 
			
		||||
 | 
			
		||||
        this._barriers.push(barrier);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _disconnectBarrier(barrier) {
 | 
			
		||||
    _disconnectBarrier: function(barrier) {
 | 
			
		||||
        barrier.disconnect(barrier._pressureHitId);
 | 
			
		||||
        barrier.disconnect(barrier._pressureLeftId);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    removeBarrier(barrier) {
 | 
			
		||||
    removeBarrier: function(barrier) {
 | 
			
		||||
        this._disconnectBarrier(barrier);
 | 
			
		||||
        this._barriers.splice(this._barriers.indexOf(barrier), 1);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
        this._barriers.forEach(this._disconnectBarrier.bind(this));
 | 
			
		||||
    destroy: function() {
 | 
			
		||||
        this._barriers.forEach(Lang.bind(this, this._disconnectBarrier));
 | 
			
		||||
        this._barriers = [];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setEventFilter(filter) {
 | 
			
		||||
    setEventFilter: function(filter) {
 | 
			
		||||
        this._eventFilter = filter;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _reset() {
 | 
			
		||||
    _reset: function() {
 | 
			
		||||
        this._barrierEvents = [];
 | 
			
		||||
        this._currentPressure = 0;
 | 
			
		||||
        this._lastTime = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _isHorizontal(barrier) {
 | 
			
		||||
    _isHorizontal: function(barrier) {
 | 
			
		||||
        return barrier.y1 == barrier.y2;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getDistanceAcrossBarrier(barrier, event) {
 | 
			
		||||
    _getDistanceAcrossBarrier: function(barrier, event) {
 | 
			
		||||
        if (this._isHorizontal(barrier))
 | 
			
		||||
            return Math.abs(event.dy);
 | 
			
		||||
        else
 | 
			
		||||
            return Math.abs(event.dx);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getDistanceAlongBarrier(barrier, event) {
 | 
			
		||||
    _getDistanceAlongBarrier: function(barrier, event) {
 | 
			
		||||
        if (this._isHorizontal(barrier))
 | 
			
		||||
            return Math.abs(event.dx);
 | 
			
		||||
        else
 | 
			
		||||
            return Math.abs(event.dy);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _trimBarrierEvents() {
 | 
			
		||||
    _trimBarrierEvents: function() {
 | 
			
		||||
        // Events are guaranteed to be sorted in time order from
 | 
			
		||||
        // oldest to newest, so just look for the first old event,
 | 
			
		||||
        // and then chop events after that off.
 | 
			
		||||
@@ -1365,21 +1357,21 @@ var PressureBarrier = new Lang.Class({
 | 
			
		||||
        this._barrierEvents = this._barrierEvents.slice(firstNewEvent);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onBarrierLeft(barrier, event) {
 | 
			
		||||
    _onBarrierLeft: function(barrier, event) {
 | 
			
		||||
        barrier._isHit = false;
 | 
			
		||||
        if (this._barriers.every(b => !b._isHit)) {
 | 
			
		||||
        if (this._barriers.every(function(b) { return !b._isHit; })) {
 | 
			
		||||
            this._reset();
 | 
			
		||||
            this._isTriggered = false;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _trigger() {
 | 
			
		||||
    _trigger: function() {
 | 
			
		||||
        this._isTriggered = true;
 | 
			
		||||
        this.emit('trigger');
 | 
			
		||||
        this._reset();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onBarrierHit(barrier, event) {
 | 
			
		||||
    _onBarrierHit: function(barrier, event) {
 | 
			
		||||
        barrier._isHit = true;
 | 
			
		||||
 | 
			
		||||
        // If we've triggered the barrier, wait until the pointer has the
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ var RadialShaderQuad = new Lang.Class({
 | 
			
		||||
    Name: 'RadialShaderQuad',
 | 
			
		||||
    Extends: Shell.GLSLQuad,
 | 
			
		||||
 | 
			
		||||
    _init(params) {
 | 
			
		||||
    _init: function(params) {
 | 
			
		||||
        this.parent(params);
 | 
			
		||||
 | 
			
		||||
        this._brightnessLocation = this.get_uniform_location('brightness');
 | 
			
		||||
@@ -41,7 +41,7 @@ var RadialShaderQuad = new Lang.Class({
 | 
			
		||||
        this.vignetteSharpness = 0.0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    vfunc_build_pipeline() {
 | 
			
		||||
    vfunc_build_pipeline: function() {
 | 
			
		||||
        this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT,
 | 
			
		||||
                              VIGNETTE_DECLARATIONS, VIGNETTE_CODE, true);
 | 
			
		||||
    },
 | 
			
		||||
@@ -94,7 +94,7 @@ var RadialShaderQuad = new Lang.Class({
 | 
			
		||||
var Lightbox = new Lang.Class({
 | 
			
		||||
    Name: 'Lightbox',
 | 
			
		||||
 | 
			
		||||
    _init(container, params) {
 | 
			
		||||
    _init : function(container, params) {
 | 
			
		||||
        params = Params.parse(params, { inhibitEvents: false,
 | 
			
		||||
                                        width: null,
 | 
			
		||||
                                        height: null,
 | 
			
		||||
@@ -122,7 +122,7 @@ var Lightbox = new Lang.Class({
 | 
			
		||||
        this.actor.hide();
 | 
			
		||||
        this.shown = false;
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('destroy', this._onDestroy.bind(this));
 | 
			
		||||
        this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
 | 
			
		||||
 | 
			
		||||
        if (params.width && params.height) {
 | 
			
		||||
            this.actor.width = params.width;
 | 
			
		||||
@@ -133,13 +133,13 @@ var Lightbox = new Lang.Class({
 | 
			
		||||
            this.actor.add_constraint(constraint);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._actorAddedSignalId = container.connect('actor-added', this._actorAdded.bind(this));
 | 
			
		||||
        this._actorRemovedSignalId = container.connect('actor-removed', this._actorRemoved.bind(this));
 | 
			
		||||
        this._actorAddedSignalId = container.connect('actor-added', Lang.bind(this, this._actorAdded));
 | 
			
		||||
        this._actorRemovedSignalId = container.connect('actor-removed', Lang.bind(this, this._actorRemoved));
 | 
			
		||||
 | 
			
		||||
        this._highlighted = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _actorAdded(container, newChild) {
 | 
			
		||||
    _actorAdded : function(container, newChild) {
 | 
			
		||||
        let children = this._container.get_children();
 | 
			
		||||
        let myIndex = children.indexOf(this.actor);
 | 
			
		||||
        let newChildIndex = children.indexOf(newChild);
 | 
			
		||||
@@ -161,7 +161,7 @@ var Lightbox = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    show(fadeInTime) {
 | 
			
		||||
    show: function(fadeInTime) {
 | 
			
		||||
        fadeInTime = fadeInTime || 0;
 | 
			
		||||
 | 
			
		||||
        Tweener.removeTweens(this.actor);
 | 
			
		||||
@@ -171,27 +171,27 @@ var Lightbox = new Lang.Class({
 | 
			
		||||
                               vignetteSharpness: VIGNETTE_SHARPNESS,
 | 
			
		||||
                               time: fadeInTime,
 | 
			
		||||
                               transition: 'easeOutQuad',
 | 
			
		||||
                               onComplete: () => {
 | 
			
		||||
                               onComplete: Lang.bind(this, function() {
 | 
			
		||||
                                   this.shown = true;
 | 
			
		||||
                                   this.emit('shown');
 | 
			
		||||
                               }
 | 
			
		||||
                               })
 | 
			
		||||
                             });
 | 
			
		||||
        } else {
 | 
			
		||||
            Tweener.addTween(this.actor,
 | 
			
		||||
                             { opacity: 255 * this._fadeFactor,
 | 
			
		||||
                               time: fadeInTime,
 | 
			
		||||
                               transition: 'easeOutQuad',
 | 
			
		||||
                               onComplete: () => {
 | 
			
		||||
                               onComplete: Lang.bind(this, function() {
 | 
			
		||||
                                   this.shown = true;
 | 
			
		||||
                                   this.emit('shown');
 | 
			
		||||
                               }
 | 
			
		||||
                               })
 | 
			
		||||
                             });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hide(fadeOutTime) {
 | 
			
		||||
    hide: function(fadeOutTime) {
 | 
			
		||||
        fadeOutTime = fadeOutTime || 0;
 | 
			
		||||
 | 
			
		||||
        this.shown = false;
 | 
			
		||||
@@ -203,23 +203,23 @@ var Lightbox = new Lang.Class({
 | 
			
		||||
                               opacity: 0,
 | 
			
		||||
                               time: fadeOutTime,
 | 
			
		||||
                               transition: 'easeOutQuad',
 | 
			
		||||
                               onComplete: () => {
 | 
			
		||||
                               onComplete: Lang.bind(this, function() {
 | 
			
		||||
                                   this.actor.hide();
 | 
			
		||||
                               }
 | 
			
		||||
                               })
 | 
			
		||||
                             });
 | 
			
		||||
        } else {
 | 
			
		||||
            Tweener.addTween(this.actor,
 | 
			
		||||
                             { opacity: 0,
 | 
			
		||||
                               time: fadeOutTime,
 | 
			
		||||
                               transition: 'easeOutQuad',
 | 
			
		||||
                               onComplete: () => {
 | 
			
		||||
                               onComplete: Lang.bind(this, function() {
 | 
			
		||||
                                   this.actor.hide();
 | 
			
		||||
                               }
 | 
			
		||||
                               })
 | 
			
		||||
                             });
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _actorRemoved(container, child) {
 | 
			
		||||
    _actorRemoved : function(container, child) {
 | 
			
		||||
        let index = this._children.indexOf(child);
 | 
			
		||||
        if (index != -1) // paranoia
 | 
			
		||||
            this._children.splice(index, 1);
 | 
			
		||||
@@ -236,7 +236,7 @@ var Lightbox = new Lang.Class({
 | 
			
		||||
     * currently-highlighted actor. With no arguments or a false/null
 | 
			
		||||
     * argument, all actors will be unhighlighted.
 | 
			
		||||
     */
 | 
			
		||||
    highlight(window) {
 | 
			
		||||
    highlight : function(window) {
 | 
			
		||||
        if (this._highlighted == window)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -264,7 +264,7 @@ var Lightbox = new Lang.Class({
 | 
			
		||||
     *
 | 
			
		||||
     * Destroys the lightbox.
 | 
			
		||||
     */
 | 
			
		||||
    destroy() {
 | 
			
		||||
    destroy : function() {
 | 
			
		||||
        this.actor.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -274,7 +274,7 @@ var Lightbox = new Lang.Class({
 | 
			
		||||
     * This is called when the lightbox' actor is destroyed, either
 | 
			
		||||
     * by destroying its container or by explicitly calling this.destroy().
 | 
			
		||||
     */
 | 
			
		||||
    _onDestroy() {
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
        this._container.disconnect(this._actorAddedSignalId);
 | 
			
		||||
        this._container.disconnect(this._actorRemovedSignalId);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -40,9 +40,9 @@ var commandHeader = 'const Clutter = imports.gi.Clutter; ' +
 | 
			
		||||
                     * in the shell core code too. */
 | 
			
		||||
                    'const stage = global.stage; ' +
 | 
			
		||||
                    /* Special lookingGlass functions */
 | 
			
		||||
                    'const inspect = Main.lookingGlass.inspect.bind(Main.lookingGlass); ' +
 | 
			
		||||
                    'const inspect = Lang.bind(Main.lookingGlass, Main.lookingGlass.inspect); ' +
 | 
			
		||||
                    'const it = Main.lookingGlass.getIt(); ' +
 | 
			
		||||
                    'const r = Main.lookingGlass.getResult.bind(Main.lookingGlass); ';
 | 
			
		||||
                    'const r = Lang.bind(Main.lookingGlass, Main.lookingGlass.getResult); ';
 | 
			
		||||
 | 
			
		||||
const HISTORY_KEY = 'looking-glass-history';
 | 
			
		||||
// Time between tabs for them to count as a double-tab event
 | 
			
		||||
@@ -53,9 +53,7 @@ var AUTO_COMPLETE_GLOBAL_KEYWORDS = _getAutoCompleteGlobalKeywords();
 | 
			
		||||
function _getAutoCompleteGlobalKeywords() {
 | 
			
		||||
    const keywords = ['true', 'false', 'null', 'new'];
 | 
			
		||||
    // Don't add the private properties of window (i.e., ones starting with '_')
 | 
			
		||||
    const windowProperties = Object.getOwnPropertyNames(window).filter(
 | 
			
		||||
        a => a.charAt(0) != '_'
 | 
			
		||||
    );
 | 
			
		||||
    const windowProperties = Object.getOwnPropertyNames(window).filter(function(a){ return a.charAt(0) != '_' });
 | 
			
		||||
    const headerProperties = JsParse.getDeclaredConstants(commandHeader);
 | 
			
		||||
 | 
			
		||||
    return keywords.concat(windowProperties).concat(headerProperties);
 | 
			
		||||
@@ -64,13 +62,13 @@ function _getAutoCompleteGlobalKeywords() {
 | 
			
		||||
var AutoComplete = new Lang.Class({
 | 
			
		||||
    Name: 'AutoComplete',
 | 
			
		||||
 | 
			
		||||
    _init(entry) {
 | 
			
		||||
    _init: function(entry) {
 | 
			
		||||
        this._entry = entry;
 | 
			
		||||
        this._entry.connect('key-press-event', this._entryKeyPressEvent.bind(this));
 | 
			
		||||
        this._entry.connect('key-press-event', Lang.bind(this, this._entryKeyPressEvent));
 | 
			
		||||
        this._lastTabTime = global.get_current_time();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _processCompletionRequest(event) {
 | 
			
		||||
    _processCompletionRequest: function(event) {
 | 
			
		||||
        if (event.completions.length == 0) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -92,7 +90,7 @@ var AutoComplete = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _entryKeyPressEvent(actor, event) {
 | 
			
		||||
    _entryKeyPressEvent: function(actor, event) {
 | 
			
		||||
        let cursorPos = this._entry.clutter_text.get_cursor_position();
 | 
			
		||||
        let text = this._entry.get_text();
 | 
			
		||||
        if (cursorPos != -1) {
 | 
			
		||||
@@ -117,7 +115,7 @@ var AutoComplete = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
    // Insert characters of text not already included in head at cursor position.  i.e., if text="abc" and head="a",
 | 
			
		||||
    // the string "bc" will be appended to this._entry
 | 
			
		||||
    additionalCompletionText(text, head) {
 | 
			
		||||
    additionalCompletionText: function(text, head) {
 | 
			
		||||
        let additionalCompletionText = text.slice(head.length);
 | 
			
		||||
        let cursorPos = this._entry.clutter_text.get_cursor_position();
 | 
			
		||||
 | 
			
		||||
@@ -130,7 +128,7 @@ Signals.addSignalMethods(AutoComplete.prototype);
 | 
			
		||||
var Notebook = new Lang.Class({
 | 
			
		||||
    Name: 'Notebook',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.actor = new St.BoxLayout({ vertical: true });
 | 
			
		||||
 | 
			
		||||
        this.tabControls = new St.BoxLayout({ style_class: 'labels' });
 | 
			
		||||
@@ -139,15 +137,15 @@ var Notebook = new Lang.Class({
 | 
			
		||||
        this._tabs = [];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    appendPage(name, child) {
 | 
			
		||||
    appendPage: function(name, child) {
 | 
			
		||||
        let labelBox = new St.BoxLayout({ style_class: 'notebook-tab',
 | 
			
		||||
                                          reactive: true,
 | 
			
		||||
                                          track_hover: true });
 | 
			
		||||
        let label = new St.Button({ label: name });
 | 
			
		||||
        label.connect('clicked', () => {
 | 
			
		||||
        label.connect('clicked', Lang.bind(this, function () {
 | 
			
		||||
            this.selectChild(child);
 | 
			
		||||
            return true;
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
        labelBox.add(label, { expand: true });
 | 
			
		||||
        this.tabControls.add(labelBox);
 | 
			
		||||
 | 
			
		||||
@@ -165,14 +163,14 @@ var Notebook = new Lang.Class({
 | 
			
		||||
        this.actor.add(scrollview, { expand: true });
 | 
			
		||||
 | 
			
		||||
        let vAdjust = scrollview.vscroll.adjustment;
 | 
			
		||||
        vAdjust.connect('changed', () => { this._onAdjustScopeChanged(tabData); });
 | 
			
		||||
        vAdjust.connect('notify::value', () => { this._onAdjustValueChanged(tabData); });
 | 
			
		||||
        vAdjust.connect('changed', Lang.bind(this, function () { this._onAdjustScopeChanged(tabData); }));
 | 
			
		||||
        vAdjust.connect('notify::value', Lang.bind(this, function() { this._onAdjustValueChanged(tabData); }));
 | 
			
		||||
 | 
			
		||||
        if (this._selectedIndex == -1)
 | 
			
		||||
            this.selectIndex(0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _unselect() {
 | 
			
		||||
    _unselect: function() {
 | 
			
		||||
        if (this._selectedIndex < 0)
 | 
			
		||||
            return;
 | 
			
		||||
        let tabData = this._tabs[this._selectedIndex];
 | 
			
		||||
@@ -181,7 +179,7 @@ var Notebook = new Lang.Class({
 | 
			
		||||
        this._selectedIndex = -1;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    selectIndex(index) {
 | 
			
		||||
    selectIndex: function(index) {
 | 
			
		||||
        if (index == this._selectedIndex)
 | 
			
		||||
            return;
 | 
			
		||||
        if (index < 0) {
 | 
			
		||||
@@ -203,7 +201,7 @@ var Notebook = new Lang.Class({
 | 
			
		||||
        this.emit('selection', tabData.child);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    selectChild(child) {
 | 
			
		||||
    selectChild: function(child) {
 | 
			
		||||
        if (child == null)
 | 
			
		||||
            this.selectIndex(-1);
 | 
			
		||||
        else {
 | 
			
		||||
@@ -217,26 +215,26 @@ var Notebook = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    scrollToBottom(index) {
 | 
			
		||||
    scrollToBottom: function(index) {
 | 
			
		||||
        let tabData = this._tabs[index];
 | 
			
		||||
        tabData._scrollToBottom = true;
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onAdjustValueChanged(tabData) {
 | 
			
		||||
    _onAdjustValueChanged: function (tabData) {
 | 
			
		||||
        let vAdjust = tabData.scrollView.vscroll.adjustment;
 | 
			
		||||
        if (vAdjust.value < (vAdjust.upper - vAdjust.lower - 0.5))
 | 
			
		||||
            tabData._scrolltoBottom = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onAdjustScopeChanged(tabData) {
 | 
			
		||||
    _onAdjustScopeChanged: function (tabData) {
 | 
			
		||||
        if (!tabData._scrollToBottom)
 | 
			
		||||
            return;
 | 
			
		||||
        let vAdjust = tabData.scrollView.vscroll.adjustment;
 | 
			
		||||
        vAdjust.value = vAdjust.upper - vAdjust.page_size;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    nextTab() {
 | 
			
		||||
    nextTab: function() {
 | 
			
		||||
        let nextIndex = this._selectedIndex;
 | 
			
		||||
        if (nextIndex < this._tabs.length - 1) {
 | 
			
		||||
            ++nextIndex;
 | 
			
		||||
@@ -245,7 +243,7 @@ var Notebook = new Lang.Class({
 | 
			
		||||
        this.selectIndex(nextIndex);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    prevTab() {
 | 
			
		||||
    prevTab: function() {
 | 
			
		||||
        let prevIndex = this._selectedIndex;
 | 
			
		||||
        if (prevIndex > 0) {
 | 
			
		||||
            --prevIndex;
 | 
			
		||||
@@ -268,7 +266,7 @@ function objectToString(o) {
 | 
			
		||||
var ObjLink = new Lang.Class({
 | 
			
		||||
    Name: 'ObjLink',
 | 
			
		||||
 | 
			
		||||
    _init(lookingGlass, o, title) {
 | 
			
		||||
    _init: function(lookingGlass, o, title) {
 | 
			
		||||
        let text;
 | 
			
		||||
        if (title)
 | 
			
		||||
            text = title;
 | 
			
		||||
@@ -282,12 +280,12 @@ var ObjLink = new Lang.Class({
 | 
			
		||||
                                     style_class: 'shell-link',
 | 
			
		||||
                                     label: text });
 | 
			
		||||
        this.actor.get_child().single_line_mode = true;
 | 
			
		||||
        this.actor.connect('clicked', this._onClicked.bind(this));
 | 
			
		||||
        this.actor.connect('clicked', Lang.bind(this, this._onClicked));
 | 
			
		||||
 | 
			
		||||
        this._lookingGlass = lookingGlass;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onClicked(link) {
 | 
			
		||||
    _onClicked: function (link) {
 | 
			
		||||
        this._lookingGlass.inspectObject(this._obj, this.actor);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -295,7 +293,7 @@ var ObjLink = new Lang.Class({
 | 
			
		||||
var Result = new Lang.Class({
 | 
			
		||||
    Name: 'Result',
 | 
			
		||||
 | 
			
		||||
    _init(lookingGlass, command, o, index) {
 | 
			
		||||
    _init: function(lookingGlass, command, o, index) {
 | 
			
		||||
        this.index = index;
 | 
			
		||||
        this.o = o;
 | 
			
		||||
 | 
			
		||||
@@ -318,17 +316,17 @@ var Result = new Lang.Class({
 | 
			
		||||
var WindowList = new Lang.Class({
 | 
			
		||||
    Name: 'WindowList',
 | 
			
		||||
 | 
			
		||||
    _init(lookingGlass) {
 | 
			
		||||
    _init: function(lookingGlass) {
 | 
			
		||||
        this.actor = new St.BoxLayout({ name: 'Windows', vertical: true, style: 'spacing: 8px' });
 | 
			
		||||
        let tracker = Shell.WindowTracker.get_default();
 | 
			
		||||
        this._updateId = Main.initializeDeferredWork(this.actor, this._updateWindowList.bind(this));
 | 
			
		||||
        global.display.connect('window-created', this._updateWindowList.bind(this));
 | 
			
		||||
        tracker.connect('tracked-windows-changed', this._updateWindowList.bind(this));
 | 
			
		||||
        this._updateId = Main.initializeDeferredWork(this.actor, Lang.bind(this, this._updateWindowList));
 | 
			
		||||
        global.display.connect('window-created', Lang.bind(this, this._updateWindowList));
 | 
			
		||||
        tracker.connect('tracked-windows-changed', Lang.bind(this, this._updateWindowList));
 | 
			
		||||
 | 
			
		||||
        this._lookingGlass = lookingGlass;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateWindowList() {
 | 
			
		||||
    _updateWindowList: function() {
 | 
			
		||||
        this.actor.destroy_all_children();
 | 
			
		||||
        let windows = global.get_window_actors();
 | 
			
		||||
        let tracker = Shell.WindowTracker.get_default();
 | 
			
		||||
@@ -336,7 +334,7 @@ var WindowList = new Lang.Class({
 | 
			
		||||
            let metaWindow = windows[i].metaWindow;
 | 
			
		||||
            // Avoid multiple connections
 | 
			
		||||
            if (!metaWindow._lookingGlassManaged) {
 | 
			
		||||
                metaWindow.connect('unmanaged', this._updateWindowList.bind(this));
 | 
			
		||||
                metaWindow.connect('unmanaged', Lang.bind(this, this._updateWindowList));
 | 
			
		||||
                metaWindow._lookingGlassManaged = true;
 | 
			
		||||
            }
 | 
			
		||||
            let box = new St.BoxLayout({ vertical: true });
 | 
			
		||||
@@ -366,7 +364,7 @@ Signals.addSignalMethods(WindowList.prototype);
 | 
			
		||||
var ObjInspector = new Lang.Class({
 | 
			
		||||
    Name: 'ObjInspector',
 | 
			
		||||
 | 
			
		||||
    _init(lookingGlass) {
 | 
			
		||||
    _init: function(lookingGlass) {
 | 
			
		||||
        this._obj = null;
 | 
			
		||||
        this._previousObj = null;
 | 
			
		||||
 | 
			
		||||
@@ -383,7 +381,7 @@ var ObjInspector = new Lang.Class({
 | 
			
		||||
        this._lookingGlass = lookingGlass;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    selectObject(obj, skipPrevious) {
 | 
			
		||||
    selectObject: function(obj, skipPrevious) {
 | 
			
		||||
        if (!skipPrevious)
 | 
			
		||||
            this._previousObj = this._obj;
 | 
			
		||||
        else
 | 
			
		||||
@@ -399,17 +397,17 @@ var ObjInspector = new Lang.Class({
 | 
			
		||||
        label.single_line_mode = true;
 | 
			
		||||
        hbox.add(label, { expand: true, y_fill: false });
 | 
			
		||||
        let button = new St.Button({ label: 'Insert', style_class: 'lg-obj-inspector-button' });
 | 
			
		||||
        button.connect('clicked', this._onInsert.bind(this));
 | 
			
		||||
        button.connect('clicked', Lang.bind(this, this._onInsert));
 | 
			
		||||
        hbox.add(button);
 | 
			
		||||
 | 
			
		||||
        if (this._previousObj != null) {
 | 
			
		||||
            button = new St.Button({ label: 'Back', style_class: 'lg-obj-inspector-button' });
 | 
			
		||||
            button.connect('clicked', this._onBack.bind(this));
 | 
			
		||||
            button.connect('clicked', Lang.bind(this, this._onBack));
 | 
			
		||||
            hbox.add(button);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        button = new St.Button({ style_class: 'window-close' });
 | 
			
		||||
        button.connect('clicked', this.close.bind(this));
 | 
			
		||||
        button.connect('clicked', Lang.bind(this, this.close));
 | 
			
		||||
        hbox.add(button);
 | 
			
		||||
        if (typeof(obj) == typeof({})) {
 | 
			
		||||
            let properties = [];
 | 
			
		||||
@@ -437,7 +435,7 @@ var ObjInspector = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    open(sourceActor) {
 | 
			
		||||
    open: function(sourceActor) {
 | 
			
		||||
        if (this._open)
 | 
			
		||||
            return;
 | 
			
		||||
        this._previousObj = null;
 | 
			
		||||
@@ -453,7 +451,7 @@ var ObjInspector = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    close() {
 | 
			
		||||
    close: function() {
 | 
			
		||||
        if (!this._open)
 | 
			
		||||
            return;
 | 
			
		||||
        this._open = false;
 | 
			
		||||
@@ -462,13 +460,13 @@ var ObjInspector = new Lang.Class({
 | 
			
		||||
        this._obj = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onInsert() {
 | 
			
		||||
    _onInsert: function() {
 | 
			
		||||
        let obj = this._obj;
 | 
			
		||||
        this.close();
 | 
			
		||||
        this._lookingGlass.insertObject(obj);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onBack() {
 | 
			
		||||
    _onBack: function() {
 | 
			
		||||
        this.selectObject(this._previousObj, true);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -477,7 +475,7 @@ var RedBorderEffect = new Lang.Class({
 | 
			
		||||
    Name: 'RedBorderEffect',
 | 
			
		||||
    Extends: Clutter.Effect,
 | 
			
		||||
 | 
			
		||||
    vfunc_paint() {
 | 
			
		||||
    vfunc_paint: function() {
 | 
			
		||||
        let actor = this.get_actor();
 | 
			
		||||
        actor.continue_paint();
 | 
			
		||||
 | 
			
		||||
@@ -502,10 +500,10 @@ var RedBorderEffect = new Lang.Class({
 | 
			
		||||
var Inspector = new Lang.Class({
 | 
			
		||||
    Name: 'Inspector',
 | 
			
		||||
 | 
			
		||||
    _init(lookingGlass) {
 | 
			
		||||
    _init: function(lookingGlass) {
 | 
			
		||||
        let container = new Shell.GenericContainer({ width: 0,
 | 
			
		||||
                                                     height: 0 });
 | 
			
		||||
        container.connect('allocate', this._allocate.bind(this));
 | 
			
		||||
        container.connect('allocate', Lang.bind(this, this._allocate));
 | 
			
		||||
        Main.uiGroup.add_actor(container);
 | 
			
		||||
 | 
			
		||||
        let eventHandler = new St.BoxLayout({ name: 'LookingGlassDialog',
 | 
			
		||||
@@ -516,10 +514,10 @@ var Inspector = new Lang.Class({
 | 
			
		||||
        this._displayText = new St.Label();
 | 
			
		||||
        eventHandler.add(this._displayText, { expand: true });
 | 
			
		||||
 | 
			
		||||
        eventHandler.connect('key-press-event', this._onKeyPressEvent.bind(this));
 | 
			
		||||
        eventHandler.connect('button-press-event', this._onButtonPressEvent.bind(this));
 | 
			
		||||
        eventHandler.connect('scroll-event', this._onScrollEvent.bind(this));
 | 
			
		||||
        eventHandler.connect('motion-event', this._onMotionEvent.bind(this));
 | 
			
		||||
        eventHandler.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
 | 
			
		||||
        eventHandler.connect('button-press-event', Lang.bind(this, this._onButtonPressEvent));
 | 
			
		||||
        eventHandler.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
 | 
			
		||||
        eventHandler.connect('motion-event', Lang.bind(this, this._onMotionEvent));
 | 
			
		||||
        Clutter.grab_pointer(eventHandler);
 | 
			
		||||
        Clutter.grab_keyboard(eventHandler);
 | 
			
		||||
 | 
			
		||||
@@ -534,7 +532,7 @@ var Inspector = new Lang.Class({
 | 
			
		||||
        this._lookingGlass = lookingGlass;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _allocate(actor, box, flags) {
 | 
			
		||||
    _allocate: function(actor, box, flags) {
 | 
			
		||||
        if (!this._eventHandler)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -551,7 +549,7 @@ var Inspector = new Lang.Class({
 | 
			
		||||
        this._eventHandler.allocate(childBox, flags);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _close() {
 | 
			
		||||
    _close: function() {
 | 
			
		||||
        Clutter.ungrab_pointer();
 | 
			
		||||
        Clutter.ungrab_keyboard();
 | 
			
		||||
        this._eventHandler.destroy();
 | 
			
		||||
@@ -559,13 +557,13 @@ var Inspector = new Lang.Class({
 | 
			
		||||
        this.emit('closed');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onKeyPressEvent(actor, event) {
 | 
			
		||||
    _onKeyPressEvent: function (actor, event) {
 | 
			
		||||
        if (event.get_key_symbol() == Clutter.Escape)
 | 
			
		||||
            this._close();
 | 
			
		||||
        return Clutter.EVENT_STOP;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onButtonPressEvent(actor, event) {
 | 
			
		||||
    _onButtonPressEvent: function (actor, event) {
 | 
			
		||||
        if (this._target) {
 | 
			
		||||
            let [stageX, stageY] = event.get_coords();
 | 
			
		||||
            this.emit('target', this._target, stageX, stageY);
 | 
			
		||||
@@ -574,7 +572,7 @@ var Inspector = new Lang.Class({
 | 
			
		||||
        return Clutter.EVENT_STOP;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onScrollEvent(actor, event) {
 | 
			
		||||
    _onScrollEvent: function (actor, event) {
 | 
			
		||||
        switch (event.get_scroll_direction()) {
 | 
			
		||||
        case Clutter.ScrollDirection.UP:
 | 
			
		||||
            // select parent
 | 
			
		||||
@@ -608,12 +606,12 @@ var Inspector = new Lang.Class({
 | 
			
		||||
        return Clutter.EVENT_STOP;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onMotionEvent(actor, event) {
 | 
			
		||||
    _onMotionEvent: function (actor, event) {
 | 
			
		||||
        this._update(event);
 | 
			
		||||
        return Clutter.EVENT_STOP;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _update(event) {
 | 
			
		||||
    _update: function(event) {
 | 
			
		||||
        let [stageX, stageY] = event.get_coords();
 | 
			
		||||
        let target = global.stage.get_actor_at_pos(Clutter.PickMode.ALL,
 | 
			
		||||
                                                   stageX,
 | 
			
		||||
@@ -636,7 +634,7 @@ Signals.addSignalMethods(Inspector.prototype);
 | 
			
		||||
var Extensions = new Lang.Class({
 | 
			
		||||
    Name: 'Extensions',
 | 
			
		||||
 | 
			
		||||
    _init(lookingGlass) {
 | 
			
		||||
    _init: function(lookingGlass) {
 | 
			
		||||
        this._lookingGlass = lookingGlass;
 | 
			
		||||
        this.actor = new St.BoxLayout({ vertical: true,
 | 
			
		||||
                                        name: 'lookingGlassExtensions' });
 | 
			
		||||
@@ -652,10 +650,10 @@ var Extensions = new Lang.Class({
 | 
			
		||||
            this._loadExtension(null, uuid);
 | 
			
		||||
 | 
			
		||||
        ExtensionSystem.connect('extension-loaded',
 | 
			
		||||
                                this._loadExtension.bind(this));
 | 
			
		||||
                                Lang.bind(this, this._loadExtension));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _loadExtension(o, uuid) {
 | 
			
		||||
    _loadExtension: function(o, uuid) {
 | 
			
		||||
        let extension = ExtensionUtils.extensions[uuid];
 | 
			
		||||
        // There can be cases where we create dummy extension metadata
 | 
			
		||||
        // that's not really a proper extension. Don't bother with these.
 | 
			
		||||
@@ -670,20 +668,20 @@ var Extensions = new Lang.Class({
 | 
			
		||||
        this._extensionsList.add(extensionDisplay);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onViewSource(actor) {
 | 
			
		||||
    _onViewSource: function (actor) {
 | 
			
		||||
        let extension = actor._extension;
 | 
			
		||||
        let uri = extension.dir.get_uri();
 | 
			
		||||
        Gio.app_info_launch_default_for_uri(uri, global.create_app_launch_context(0, -1));
 | 
			
		||||
        this._lookingGlass.close();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onWebPage(actor) {
 | 
			
		||||
    _onWebPage: function (actor) {
 | 
			
		||||
        let extension = actor._extension;
 | 
			
		||||
        Gio.app_info_launch_default_for_uri(extension.metadata.url, global.create_app_launch_context(0, -1));
 | 
			
		||||
        this._lookingGlass.close();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onViewErrors(actor) {
 | 
			
		||||
    _onViewErrors: function (actor) {
 | 
			
		||||
        let extension = actor._extension;
 | 
			
		||||
        let shouldShow = !actor._isShowing;
 | 
			
		||||
 | 
			
		||||
@@ -711,7 +709,7 @@ var Extensions = new Lang.Class({
 | 
			
		||||
        actor._isShowing = shouldShow;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _stateToString(extensionState) {
 | 
			
		||||
    _stateToString: function(extensionState) {
 | 
			
		||||
        switch (extensionState) {
 | 
			
		||||
            case ExtensionSystem.ExtensionState.ENABLED:
 | 
			
		||||
                return _("Enabled");
 | 
			
		||||
@@ -728,7 +726,7 @@ var Extensions = new Lang.Class({
 | 
			
		||||
        return 'Unknown'; // Not translated, shouldn't appear
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createExtensionDisplay(extension) {
 | 
			
		||||
    _createExtensionDisplay: function(extension) {
 | 
			
		||||
        let box = new St.BoxLayout({ style_class: 'lg-extension', vertical: true });
 | 
			
		||||
        let name = new St.Label({ style_class: 'lg-extension-name',
 | 
			
		||||
                                   text: extension.metadata.name });
 | 
			
		||||
@@ -749,7 +747,7 @@ var Extensions = new Lang.Class({
 | 
			
		||||
                                         style_class: 'shell-link',
 | 
			
		||||
                                         label: _("View Source") });
 | 
			
		||||
        viewsource._extension = extension;
 | 
			
		||||
        viewsource.connect('clicked', this._onViewSource.bind(this));
 | 
			
		||||
        viewsource.connect('clicked', Lang.bind(this, this._onViewSource));
 | 
			
		||||
        metaBox.add(viewsource);
 | 
			
		||||
 | 
			
		||||
        if (extension.metadata.url) {
 | 
			
		||||
@@ -758,7 +756,7 @@ var Extensions = new Lang.Class({
 | 
			
		||||
                                          style_class: 'shell-link',
 | 
			
		||||
                                          label: _("Web Page") });
 | 
			
		||||
            webpage._extension = extension;
 | 
			
		||||
            webpage.connect('clicked', this._onWebPage.bind(this));
 | 
			
		||||
            webpage.connect('clicked', Lang.bind(this, this._onWebPage));
 | 
			
		||||
            metaBox.add(webpage);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -769,7 +767,7 @@ var Extensions = new Lang.Class({
 | 
			
		||||
        viewerrors._extension = extension;
 | 
			
		||||
        viewerrors._parentBox = box;
 | 
			
		||||
        viewerrors._isShowing = false;
 | 
			
		||||
        viewerrors.connect('clicked', this._onViewErrors.bind(this));
 | 
			
		||||
        viewerrors.connect('clicked', Lang.bind(this, this._onViewErrors));
 | 
			
		||||
        metaBox.add(viewerrors);
 | 
			
		||||
 | 
			
		||||
        return box;
 | 
			
		||||
@@ -779,7 +777,7 @@ var Extensions = new Lang.Class({
 | 
			
		||||
var LookingGlass = new Lang.Class({
 | 
			
		||||
    Name: 'LookingGlass',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init : function() {
 | 
			
		||||
        this._borderPaintTarget = null;
 | 
			
		||||
        this._redBorderEffect = new RedBorderEffect();
 | 
			
		||||
 | 
			
		||||
@@ -797,11 +795,11 @@ var LookingGlass = new Lang.Class({
 | 
			
		||||
                                        vertical: true,
 | 
			
		||||
                                        visible: false,
 | 
			
		||||
                                        reactive: true });
 | 
			
		||||
        this.actor.connect('key-press-event', this._globalKeyPressEvent.bind(this));
 | 
			
		||||
        this.actor.connect('key-press-event', Lang.bind(this, this._globalKeyPressEvent));
 | 
			
		||||
 | 
			
		||||
        this._interfaceSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
 | 
			
		||||
        this._interfaceSettings.connect('changed::monospace-font-name',
 | 
			
		||||
                                        this._updateFont.bind(this));
 | 
			
		||||
                                        Lang.bind(this, this._updateFont));
 | 
			
		||||
        this._updateFont();
 | 
			
		||||
 | 
			
		||||
        // We want it to appear to slide out from underneath the panel
 | 
			
		||||
@@ -809,9 +807,9 @@ var LookingGlass = new Lang.Class({
 | 
			
		||||
        Main.uiGroup.set_child_below_sibling(this.actor,
 | 
			
		||||
                                             Main.layoutManager.panelBox);
 | 
			
		||||
        Main.layoutManager.panelBox.connect('allocation-changed',
 | 
			
		||||
                                            this._queueResize.bind(this));
 | 
			
		||||
                                            Lang.bind(this, this._queueResize));
 | 
			
		||||
        Main.layoutManager.keyboardBox.connect('allocation-changed',
 | 
			
		||||
                                               this._queueResize.bind(this));
 | 
			
		||||
                                               Lang.bind(this, this._queueResize));
 | 
			
		||||
 | 
			
		||||
        this._objInspector = new ObjInspector(this);
 | 
			
		||||
        Main.uiGroup.add_actor(this._objInspector.actor);
 | 
			
		||||
@@ -823,34 +821,34 @@ var LookingGlass = new Lang.Class({
 | 
			
		||||
                                        icon_size: 24 });
 | 
			
		||||
        toolbar.add_actor(inspectIcon);
 | 
			
		||||
        inspectIcon.reactive = true;
 | 
			
		||||
        inspectIcon.connect('button-press-event', () => {
 | 
			
		||||
        inspectIcon.connect('button-press-event', Lang.bind(this, function () {
 | 
			
		||||
            let inspector = new Inspector(this);
 | 
			
		||||
            inspector.connect('target', (i, target, stageX, stageY) => {
 | 
			
		||||
            inspector.connect('target', Lang.bind(this, function(i, target, stageX, stageY) {
 | 
			
		||||
                this._pushResult('inspect(' + Math.round(stageX) + ', ' + Math.round(stageY) + ')', target);
 | 
			
		||||
            });
 | 
			
		||||
            inspector.connect('closed', () => {
 | 
			
		||||
            }));
 | 
			
		||||
            inspector.connect('closed', Lang.bind(this, function() {
 | 
			
		||||
                this.actor.show();
 | 
			
		||||
                global.stage.set_key_focus(this._entry);
 | 
			
		||||
            });
 | 
			
		||||
            }));
 | 
			
		||||
            this.actor.hide();
 | 
			
		||||
            return Clutter.EVENT_STOP;
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        let gcIcon = new St.Icon({ icon_name: 'user-trash-full',
 | 
			
		||||
                                   icon_size: 24 });
 | 
			
		||||
        toolbar.add_actor(gcIcon);
 | 
			
		||||
        gcIcon.reactive = true;
 | 
			
		||||
        gcIcon.connect('button-press-event', () => {
 | 
			
		||||
        gcIcon.connect('button-press-event', Lang.bind(this, function () {
 | 
			
		||||
           gcIcon.icon_name = 'user-trash';
 | 
			
		||||
           System.gc();
 | 
			
		||||
           this._timeoutId = Mainloop.timeout_add(500, () => {
 | 
			
		||||
           this._timeoutId = Mainloop.timeout_add(500, Lang.bind(this, function () {
 | 
			
		||||
                gcIcon.icon_name = 'user-trash-full';
 | 
			
		||||
                this._timeoutId = 0;
 | 
			
		||||
                return GLib.SOURCE_REMOVE;
 | 
			
		||||
           });
 | 
			
		||||
           }));
 | 
			
		||||
           GLib.Source.set_name_by_id(this._timeoutId, '[gnome-shell] gcIcon.icon_name = \'user-trash-full\'');
 | 
			
		||||
           return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        let notebook = new Notebook();
 | 
			
		||||
        this._notebook = notebook;
 | 
			
		||||
@@ -882,7 +880,7 @@ var LookingGlass = new Lang.Class({
 | 
			
		||||
        this._extensions = new Extensions(this);
 | 
			
		||||
        notebook.appendPage('Extensions', this._extensions.actor);
 | 
			
		||||
 | 
			
		||||
        this._entry.clutter_text.connect('activate', (o, e) => {
 | 
			
		||||
        this._entry.clutter_text.connect('activate', Lang.bind(this, function (o, e) {
 | 
			
		||||
            // Hide any completions we are currently showing
 | 
			
		||||
            this._hideCompletions();
 | 
			
		||||
 | 
			
		||||
@@ -896,26 +894,26 @@ var LookingGlass = new Lang.Class({
 | 
			
		||||
                return true;
 | 
			
		||||
            this._evaluate(text);
 | 
			
		||||
            return true;
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY, 
 | 
			
		||||
                                                     entry: this._entry.clutter_text });
 | 
			
		||||
 | 
			
		||||
        this._autoComplete = new AutoComplete(this._entry);
 | 
			
		||||
        this._autoComplete.connect('suggest', (a, e) => {
 | 
			
		||||
        this._autoComplete.connect('suggest', Lang.bind(this, function(a,e) {
 | 
			
		||||
            this._showCompletions(e.completions);
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
        // If a completion is completed unambiguously, the currently-displayed completion
 | 
			
		||||
        // suggestions become irrelevant.
 | 
			
		||||
        this._autoComplete.connect('completion', (a, e) => {
 | 
			
		||||
        this._autoComplete.connect('completion', Lang.bind(this, function(a,e) {
 | 
			
		||||
            if (e.type == 'whole-word')
 | 
			
		||||
                this._hideCompletions();
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._resize();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateFont() {
 | 
			
		||||
    _updateFont: function() {
 | 
			
		||||
        let fontName = this._interfaceSettings.get_string('monospace-font-name');
 | 
			
		||||
        let fontDesc = Pango.FontDescription.from_string(fontName);
 | 
			
		||||
        // We ignore everything but size and style; you'd be crazy to set your system-wide
 | 
			
		||||
@@ -925,7 +923,7 @@ var LookingGlass = new Lang.Class({
 | 
			
		||||
            + 'font-family: "' + fontDesc.get_family() + '";';
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setBorderPaintTarget(obj) {
 | 
			
		||||
    setBorderPaintTarget: function(obj) {
 | 
			
		||||
        if (this._borderPaintTarget != null)
 | 
			
		||||
            this._borderPaintTarget.remove_effect(this._redBorderEffect);
 | 
			
		||||
        this._borderPaintTarget = obj;
 | 
			
		||||
@@ -933,7 +931,7 @@ var LookingGlass = new Lang.Class({
 | 
			
		||||
            this._borderPaintTarget.add_effect(this._redBorderEffect);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _pushResult(command, obj) {
 | 
			
		||||
    _pushResult: function(command, obj) {
 | 
			
		||||
        let index = this._results.length + this._offset;
 | 
			
		||||
        let result = new Result(this, CHEVRON + command, obj, index);
 | 
			
		||||
        this._results.push(result);
 | 
			
		||||
@@ -953,7 +951,7 @@ var LookingGlass = new Lang.Class({
 | 
			
		||||
        this._notebook.scrollToBottom(0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _showCompletions(completions) {
 | 
			
		||||
    _showCompletions: function(completions) {
 | 
			
		||||
        if (!this._completionActor) {
 | 
			
		||||
            this._completionActor = new St.Label({ name: 'LookingGlassAutoCompletionText', style_class: 'lg-completions-text' });
 | 
			
		||||
            this._completionActor.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
 | 
			
		||||
@@ -982,21 +980,21 @@ var LookingGlass = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _hideCompletions() {
 | 
			
		||||
    _hideCompletions: function() {
 | 
			
		||||
        if (this._completionActor) {
 | 
			
		||||
            Tweener.removeTweens(this._completionActor);
 | 
			
		||||
            Tweener.addTween(this._completionActor, { time: AUTO_COMPLETE_SHOW_COMPLETION_ANIMATION_DURATION / St.get_slow_down_factor(),
 | 
			
		||||
                                                      transition: 'easeOutQuad',
 | 
			
		||||
                                                      height: 0,
 | 
			
		||||
                                                      opacity: 0,
 | 
			
		||||
                                                      onComplete: () => {
 | 
			
		||||
                                                      onComplete: Lang.bind(this, function () {
 | 
			
		||||
                                                          this._completionActor.hide();
 | 
			
		||||
                                                      }
 | 
			
		||||
                                                      })
 | 
			
		||||
                                                    });
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _evaluate(command) {
 | 
			
		||||
    _evaluate : function(command) {
 | 
			
		||||
        this._history.addItem(command);
 | 
			
		||||
 | 
			
		||||
        let fullCmd = commandHeader + command;
 | 
			
		||||
@@ -1012,30 +1010,31 @@ var LookingGlass = new Lang.Class({
 | 
			
		||||
        this._entry.text = '';
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    inspect(x, y) {
 | 
			
		||||
    inspect: function(x, y) {
 | 
			
		||||
        return global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getIt() {
 | 
			
		||||
    getIt: function () {
 | 
			
		||||
        return this._it;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getResult(idx) {
 | 
			
		||||
    getResult: function(idx) {
 | 
			
		||||
        return this._results[idx - this._offset].o;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    toggle() {
 | 
			
		||||
    toggle: function() {
 | 
			
		||||
        if (this._open)
 | 
			
		||||
            this.close();
 | 
			
		||||
        else
 | 
			
		||||
            this.open();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _queueResize() {
 | 
			
		||||
        Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { this._resize(); });
 | 
			
		||||
    _queueResize: function() {
 | 
			
		||||
        Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
 | 
			
		||||
                       Lang.bind(this, function () { this._resize(); }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _resize() {
 | 
			
		||||
    _resize: function() {
 | 
			
		||||
        let primary = Main.layoutManager.primaryMonitor;
 | 
			
		||||
        let myWidth = primary.width * 0.7;
 | 
			
		||||
        let availableHeight = primary.height - Main.layoutManager.keyboardBox.height;
 | 
			
		||||
@@ -1051,17 +1050,17 @@ var LookingGlass = new Lang.Class({
 | 
			
		||||
                                              this._targetY + Math.floor(myHeight * 0.1));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    insertObject(obj) {
 | 
			
		||||
    insertObject: function(obj) {
 | 
			
		||||
        this._pushResult('<insert>', obj);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    inspectObject(obj, sourceActor) {
 | 
			
		||||
    inspectObject: function(obj, sourceActor) {
 | 
			
		||||
        this._objInspector.open(sourceActor);
 | 
			
		||||
        this._objInspector.selectObject(obj);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Handle key events which are relevant for all tabs of the LookingGlass
 | 
			
		||||
    _globalKeyPressEvent(actor, event) {
 | 
			
		||||
    _globalKeyPressEvent : function(actor, event) {
 | 
			
		||||
        let symbol = event.get_key_symbol();
 | 
			
		||||
        let modifierState = event.get_state();
 | 
			
		||||
        if (symbol == Clutter.Escape) {
 | 
			
		||||
@@ -1083,7 +1082,7 @@ var LookingGlass = new Lang.Class({
 | 
			
		||||
        return Clutter.EVENT_PROPAGATE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    open() {
 | 
			
		||||
    open : function() {
 | 
			
		||||
        if (this._open)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -1105,7 +1104,7 @@ var LookingGlass = new Lang.Class({
 | 
			
		||||
                                     });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    close() {
 | 
			
		||||
    close : function() {
 | 
			
		||||
        if (!this._open)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -1121,9 +1120,9 @@ var LookingGlass = new Lang.Class({
 | 
			
		||||
        Tweener.addTween(this.actor, { time: Math.min(0.5 / St.get_slow_down_factor(), 0.5),
 | 
			
		||||
                                       transition: 'easeOutQuad',
 | 
			
		||||
                                       y: this._hiddenY,
 | 
			
		||||
                                       onComplete: () => {
 | 
			
		||||
                                       onComplete: Lang.bind(this, function () {
 | 
			
		||||
                                           this.actor.hide();
 | 
			
		||||
                                       }
 | 
			
		||||
                                       })
 | 
			
		||||
                                     });
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -101,7 +101,7 @@ let _zoomRegionInstanceCount = 0;
 | 
			
		||||
var ShellMagnifier = new Lang.Class({
 | 
			
		||||
    Name: 'ShellMagnifier',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._zoomers = {};
 | 
			
		||||
 | 
			
		||||
        this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(MagnifierIface, this);
 | 
			
		||||
@@ -112,7 +112,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * setActive:
 | 
			
		||||
     * @activate:   Boolean to activate or de-activate the magnifier.
 | 
			
		||||
     */
 | 
			
		||||
    setActive(activate) {
 | 
			
		||||
    setActive: function(activate) {
 | 
			
		||||
        Main.magnifier.setActive(activate);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -120,7 +120,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * isActive:
 | 
			
		||||
     * @return  Whether the magnifier is active (boolean).
 | 
			
		||||
     */
 | 
			
		||||
    isActive() {
 | 
			
		||||
    isActive: function() {
 | 
			
		||||
        return Main.magnifier.isActive();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -128,7 +128,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * showCursor:
 | 
			
		||||
     * Show the system mouse pointer.
 | 
			
		||||
     */
 | 
			
		||||
    showCursor() {
 | 
			
		||||
    showCursor: function() {
 | 
			
		||||
        Main.magnifier.showSystemCursor();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -136,7 +136,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * hideCursor:
 | 
			
		||||
     * Hide the system mouse pointer.
 | 
			
		||||
     */
 | 
			
		||||
    hideCursor() {
 | 
			
		||||
    hideCursor: function() {
 | 
			
		||||
        Main.magnifier.hideSystemCursor();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -160,7 +160,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     *
 | 
			
		||||
     * @return          The newly created ZoomRegion.
 | 
			
		||||
     */
 | 
			
		||||
    createZoomRegion(xMagFactor, yMagFactor, roi, viewPort) {
 | 
			
		||||
    createZoomRegion: function(xMagFactor, yMagFactor, roi, viewPort) {
 | 
			
		||||
        let ROI = { x: roi[0], y: roi[1], width: roi[2] - roi[0], height: roi[3] - roi[1] };
 | 
			
		||||
        let viewBox = { x: viewPort[0], y: viewPort[1], width: viewPort[2] - viewPort[0], height: viewPort[3] - viewPort[1] };
 | 
			
		||||
        let realZoomRegion = Main.magnifier.createZoomRegion(xMagFactor, yMagFactor, ROI, viewBox);
 | 
			
		||||
@@ -180,7 +180,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * Append the given ZoomRegion to the magnifier's list of ZoomRegions.
 | 
			
		||||
     * @zoomerObjectPath:   The object path for the zoom region proxy.
 | 
			
		||||
     */
 | 
			
		||||
    addZoomRegion(zoomerObjectPath) {
 | 
			
		||||
    addZoomRegion: function(zoomerObjectPath) {
 | 
			
		||||
        let proxyAndZoomRegion = this._zoomers[zoomerObjectPath];
 | 
			
		||||
        if (proxyAndZoomRegion && proxyAndZoomRegion.zoomRegion) {
 | 
			
		||||
            Main.magnifier.addZoomRegion(proxyAndZoomRegion.zoomRegion);
 | 
			
		||||
@@ -196,14 +196,14 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * @return:     The Magnifier's zoom region list as an array of DBus object
 | 
			
		||||
     *              paths.
 | 
			
		||||
     */
 | 
			
		||||
    getZoomRegions() {
 | 
			
		||||
    getZoomRegions: function() {
 | 
			
		||||
        // There may be more ZoomRegions in the magnifier itself than have
 | 
			
		||||
        // been added through dbus.  Make sure all of them are associated with
 | 
			
		||||
        // an object path and proxy.
 | 
			
		||||
        let zoomRegions = Main.magnifier.getZoomRegions();
 | 
			
		||||
        let objectPaths = [];
 | 
			
		||||
        let thoseZoomers = this._zoomers;
 | 
			
		||||
        zoomRegions.forEach ((aZoomRegion, index, array) => {
 | 
			
		||||
        zoomRegions.forEach (function(aZoomRegion, index, array) {
 | 
			
		||||
            let found = false;
 | 
			
		||||
            for (let objectPath in thoseZoomers) {
 | 
			
		||||
                let proxyAndZoomRegion = thoseZoomers[objectPath];
 | 
			
		||||
@@ -232,7 +232,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * clearAllZoomRegions:
 | 
			
		||||
     * Remove all the zoom regions from this Magnfier's ZoomRegion list.
 | 
			
		||||
     */
 | 
			
		||||
    clearAllZoomRegions() {
 | 
			
		||||
    clearAllZoomRegions: function() {
 | 
			
		||||
        Main.magnifier.clearAllZoomRegions();
 | 
			
		||||
        for (let objectPath in this._zoomers) {
 | 
			
		||||
            let proxyAndZoomer = this._zoomers[objectPath];
 | 
			
		||||
@@ -249,7 +249,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * Consult if the Magnifier can magnify in full-screen mode.
 | 
			
		||||
     * @return  Always return true.
 | 
			
		||||
     */
 | 
			
		||||
    fullScreenCapable() {
 | 
			
		||||
    fullScreenCapable: function() {
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -258,7 +258,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * Set the crosswire size of all ZoomRegions.
 | 
			
		||||
     * @size:   The thickness of each line in the cross wire.
 | 
			
		||||
     */
 | 
			
		||||
     setCrosswireSize(size) {
 | 
			
		||||
     setCrosswireSize: function(size) {
 | 
			
		||||
        Main.magnifier.setCrosshairsThickness(size);
 | 
			
		||||
     },
 | 
			
		||||
 | 
			
		||||
@@ -267,7 +267,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * Get the crosswire size of all ZoomRegions.
 | 
			
		||||
     * @return:   The thickness of each line in the cross wire.
 | 
			
		||||
     */
 | 
			
		||||
     getCrosswireSize() {
 | 
			
		||||
     getCrosswireSize: function() {
 | 
			
		||||
        return Main.magnifier.getCrosshairsThickness();
 | 
			
		||||
     },
 | 
			
		||||
 | 
			
		||||
@@ -276,7 +276,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * Set the crosswire length of all zoom-regions..
 | 
			
		||||
     * @size:   The length of each line in the cross wire.
 | 
			
		||||
     */
 | 
			
		||||
     setCrosswireLength(length) {
 | 
			
		||||
     setCrosswireLength: function(length) {
 | 
			
		||||
        Main.magnifier.setCrosshairsLength(length);
 | 
			
		||||
     },
 | 
			
		||||
 | 
			
		||||
@@ -285,7 +285,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * Set the crosswire size of all zoom-regions.
 | 
			
		||||
     * @size:   The thickness of each line in the cross wire.
 | 
			
		||||
     */
 | 
			
		||||
     getCrosswireLength() {
 | 
			
		||||
     getCrosswireLength: function() {
 | 
			
		||||
        return Main.magnifier.getCrosshairsLength();
 | 
			
		||||
     },
 | 
			
		||||
 | 
			
		||||
@@ -294,7 +294,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * Set if the crosswire will be clipped by the cursor image..
 | 
			
		||||
     * @clip:   Flag to indicate whether to clip the crosswire.
 | 
			
		||||
     */
 | 
			
		||||
     setCrosswireClip(clip) {
 | 
			
		||||
     setCrosswireClip: function(clip) {
 | 
			
		||||
        Main.magnifier.setCrosshairsClip(clip);
 | 
			
		||||
     },
 | 
			
		||||
 | 
			
		||||
@@ -303,7 +303,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * Get the crosswire clip value.
 | 
			
		||||
     * @return:   Whether the crosswire is clipped by the cursor image.
 | 
			
		||||
     */
 | 
			
		||||
     getCrosswireClip() {
 | 
			
		||||
     getCrosswireClip: function() {
 | 
			
		||||
        return Main.magnifier.getCrosshairsClip();
 | 
			
		||||
     },
 | 
			
		||||
 | 
			
		||||
@@ -312,7 +312,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * Set the crosswire color of all ZoomRegions.
 | 
			
		||||
     * @color:   Unsigned int of the form rrggbbaa.
 | 
			
		||||
     */
 | 
			
		||||
     setCrosswireColor(color) {
 | 
			
		||||
     setCrosswireColor: function(color) {
 | 
			
		||||
        Main.magnifier.setCrosshairsColor('#%08x'.format(color));
 | 
			
		||||
     },
 | 
			
		||||
 | 
			
		||||
@@ -321,7 +321,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
     * Get the crosswire color of all ZoomRegions.
 | 
			
		||||
     * @return:   The crosswire color as an unsigned int in the form rrggbbaa.
 | 
			
		||||
     */
 | 
			
		||||
     getCrosswireColor() {
 | 
			
		||||
     getCrosswireColor: function() {
 | 
			
		||||
        let colorString = Main.magnifier.getCrosshairsColor();
 | 
			
		||||
        // Drop the leading '#'.
 | 
			
		||||
        return parseInt(colorString.slice(1), 16);
 | 
			
		||||
@@ -337,7 +337,7 @@ var ShellMagnifier = new Lang.Class({
 | 
			
		||||
var ShellMagnifierZoomRegion = new Lang.Class({
 | 
			
		||||
    Name: 'ShellMagnifierZoomRegion',
 | 
			
		||||
 | 
			
		||||
    _init(zoomerObjectPath, zoomRegion) {
 | 
			
		||||
    _init: function(zoomerObjectPath, zoomRegion) {
 | 
			
		||||
        this._zoomRegion = zoomRegion;
 | 
			
		||||
 | 
			
		||||
        this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ZoomRegionIface, this);
 | 
			
		||||
@@ -352,7 +352,7 @@ var ShellMagnifierZoomRegion = new Lang.Class({
 | 
			
		||||
     * @yMagFactor:     The power to set the vertical magnification factor to
 | 
			
		||||
     *                  of the magnified view.
 | 
			
		||||
     */
 | 
			
		||||
    setMagFactor(xMagFactor, yMagFactor) {
 | 
			
		||||
    setMagFactor: function(xMagFactor, yMagFactor) {
 | 
			
		||||
        this._zoomRegion.setMagFactor(xMagFactor, yMagFactor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -363,7 +363,7 @@ var ShellMagnifierZoomRegion = new Lang.Class({
 | 
			
		||||
     *          magnification.  A value of 2.0 means the contents are doubled
 | 
			
		||||
     *          in size, and so on.
 | 
			
		||||
     */
 | 
			
		||||
    getMagFactor() {
 | 
			
		||||
    getMagFactor: function() {
 | 
			
		||||
        return this._zoomRegion.getMagFactor();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -374,7 +374,7 @@ var ShellMagnifierZoomRegion = new Lang.Class({
 | 
			
		||||
     *          screen to magnify. The values are in screen (unmagnified)
 | 
			
		||||
     *          coordinate space.
 | 
			
		||||
     */
 | 
			
		||||
    setRoi(roi) {
 | 
			
		||||
    setRoi: function(roi) {
 | 
			
		||||
        let roiObject = { x: roi[0], y: roi[1], width: roi[2] - roi[0], height: roi[3] - roi[1] };
 | 
			
		||||
        this._zoomRegion.setROI(roiObject);
 | 
			
		||||
    },
 | 
			
		||||
@@ -387,7 +387,7 @@ var ShellMagnifierZoomRegion = new Lang.Class({
 | 
			
		||||
     * @return  an array, [left, top, right, bottom], representing the bounding
 | 
			
		||||
     *          rectangle of what is shown in the magnified view.
 | 
			
		||||
     */
 | 
			
		||||
    getRoi() {
 | 
			
		||||
    getRoi: function() {
 | 
			
		||||
        let roi = this._zoomRegion.getROI();
 | 
			
		||||
        roi[2] += roi[0];
 | 
			
		||||
        roi[3] += roi[1];
 | 
			
		||||
@@ -402,7 +402,7 @@ var ShellMagnifierZoomRegion = new Lang.Class({
 | 
			
		||||
     * @return  Whether the shift was successful (for GS-mag, this is always
 | 
			
		||||
     *          true).
 | 
			
		||||
     */
 | 
			
		||||
    shiftContentsTo(x, y) {
 | 
			
		||||
    shiftContentsTo: function(x, y) {
 | 
			
		||||
        this._zoomRegion.scrollContentsTo(x, y);
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
@@ -413,12 +413,12 @@ var ShellMagnifierZoomRegion = new Lang.Class({
 | 
			
		||||
     * @viewPort    Array, [left, top, right, bottom], defining the position and
 | 
			
		||||
     *              size on screen to place the zoom region.
 | 
			
		||||
     */
 | 
			
		||||
    moveResize(viewPort) {
 | 
			
		||||
    moveResize: function(viewPort) {
 | 
			
		||||
        let viewRect = { x: viewPort[0], y: viewPort[1], width: viewPort[2] - viewPort[0], height: viewPort[3] - viewPort[1] };
 | 
			
		||||
        this._zoomRegion.setViewPort(viewRect);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
    destroy: function() {
 | 
			
		||||
        this._dbusImpl.unexport();
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||