Compare commits
	
		
			2 Commits
		
	
	
		
	
	| 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 | ||||
							
								
								
									
										197
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						| @@ -1,200 +1,3 @@ | ||||
| 3.29.92 | ||||
| ======= | ||||
| * Choose some actors to cache on the GPU [Daniel; #792633] | ||||
| * inputMethod: Hide preedit text if requested [Takao; #431] | ||||
| * Fix forced fallback app-menus on wayland [Jonas; #276] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Takao Fujiwara, Mohammed Sadiq, Marco Trevisan (Treviño), | ||||
|   Daniel van Vugt | ||||
|  | ||||
| Translators: | ||||
|   Baurzhan Muftakhidinov [kk], Kukuh Syafaat [id], Milo Casagrande [it], | ||||
|   Changwoo Ryu [ko], Marek Cernocky [cs] | ||||
|  | ||||
| 3.29.91 | ||||
| ======= | ||||
| * Fix handling of 0/false options in ShowOSD D-Bus API [Florian; #791669] | ||||
| * overview: Fix handling of confirmation dialogs on wayland [verdre; !180] | ||||
| * Avoid some full relayout/redraws [Carlos; !197] | ||||
| * Keep workspace switcher slid out when workspaces are in use [Florian; !161] | ||||
| * Ignore auto-repeat for some keybindings [Andrea; #373] | ||||
| * Misc. bug fixes [Carlos, Florian, Pascal; #464, !189, !191, !192, !162] | ||||
|  | ||||
| Contributors: | ||||
|   Andrea Azzarone, Olivier Blin, Carlos Garnacho, Florian Müllner, | ||||
|   Pascal Nowack, verdre | ||||
|  | ||||
| Translators: | ||||
|   Bruno Lopes da Silva [pt_BR], Matej Urbančič [sl], Piotr Drąg [pl], | ||||
|   Aurimas Černius [lt], Emin Tufan Çetin [tr], Fabio Tomat [fur], | ||||
|   Alexandre Franke [fr], Yi-Jyun Pan [zh_TW], Bernd Homuth [de], | ||||
|   Andre Klapper [cs], Jordi Mas [ca], Daniel Șerbănescu [ro], | ||||
|   Bruce Cowan [en_GB] | ||||
|  | ||||
| 3.29.90 | ||||
| ======= | ||||
| * Add remote access indication on wayland [Jonas; !160] | ||||
| * Fix wrong window positions in overview on wayland [Marco; #776588] | ||||
| * Add gesture to unfullscreen a window [Jan-Michael; !123] | ||||
| * Add PickColor method to screenshot D-Bus interface [Florian; #286] | ||||
| * Consider "new-window" action when opening new windows [Florian; #756844] | ||||
| * Make workspace switching gestures follow motion [Carlos; #788994] | ||||
| * Support audio volumes above 100% [Didier; #790280] | ||||
| * Misc. bug fixes [Florian, Daniel; #424, !132, !182, #433, !179, #786496] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Jan-Michael Brummer, Piotr Drąg, Daniel Drake, Carlos Garnacho, | ||||
|   Florian Müllner, Georges Basile Stavracas Neto, Didier Roche, Jakub Steiner, | ||||
|   Marco Trevisan (Treviño) | ||||
|  | ||||
| Translators: | ||||
|   Charles Monzat [fr], Daniel Mustieles [es] | ||||
|  | ||||
| 3.29.4 | ||||
| ====== | ||||
| * Fix "Clear All" for calendar events [Florian; #325] | ||||
| * Allow cancelling direct switch operations [Xavier; #315] | ||||
| * Support being started by systemd --user [Iain; !137, !138] | ||||
| * Support key event forwarding required by some input methods [Carlos; #275] | ||||
| * Misc. bug fixes and cleanups [Jasper, Andrea, Florian; #663461, #372, !112, | ||||
|   #414, !151] | ||||
|  | ||||
| Contributors: | ||||
|   Andrea Azzarone, Carlos Garnacho, Xavier Johnson, Iain Lane, Florian Müllner, | ||||
|   Jasper St. Pierre | ||||
|  | ||||
| Translators: | ||||
|   Stas Solovey [ru] | ||||
|  | ||||
| 3.29.3 | ||||
| ====== | ||||
| * Save creation time in screenshot metadata [Florian; #790481] | ||||
| * Improve consistency between ctrl- and middle-click on app icons [Xavier; #316] | ||||
| * Add support for font-feature-settings CSS property [Ryan; #34] | ||||
| * Adjust to MetaScreen removal [Jonas; #759538] | ||||
| * Misc. bug fixes [Florian, Marco, Sam; #298, #788931, #26, #76, !54, #788882, | ||||
|   #791233] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Ryan Hendrickson, Xavier Johnson, Florian Müllner, Joe Rabinoff, | ||||
|   Sam Spilsbury, Marco Trevisan (Treviño) | ||||
|  | ||||
| Translators: | ||||
|   Gun Chleoc [gd], Yi-Jyun Pan [zh_TW], Cédric Valmary [oc], Jordi Mas [ca] | ||||
|  | ||||
| 3.29.2 | ||||
| ====== | ||||
| * Guard against untimely keyboard map changes [Carlos; #240] | ||||
| * Fix icons in search provider results [Florian; #249] | ||||
| * Fix blurriness of OSD under some resolutions [Silvère; #782011] | ||||
| * Fix lagging pointer when zoomed [Daniel; #682013] | ||||
| * Misc. bug fixes [Milan, Xiaoguang, Florian, Mario, Ole; #244, #787871, | ||||
|   #781471, #136, #214, #294] | ||||
|  | ||||
| Contributors: | ||||
|   Ole Jørgen Brønner, Milan Crha, Carlos Garnacho, Yussuf Khalil, | ||||
|   Silvère Latchurié, Florian Müllner, Mario Sanchez Prada, Ray Strode, | ||||
|   Daniel van Vugt, Xiaoguang Wang | ||||
|  | ||||
| Translators: | ||||
|   Rafael Fontenelle [pt_BR], Kukuh Syafaat [id], Marcos Lans [gl], | ||||
|   Anders Jonsson [sv], Mingcong Bai [zh_CN] | ||||
|  | ||||
| 3.29.1 | ||||
| ====== | ||||
| * Support icons in app-menu [Florian; #760985] | ||||
| * Misc. bug fixes [Marco, Florian, Lubomir; #792687, #221, !63] | ||||
|  | ||||
| Contributors: | ||||
|   Piotr Drąg, Takao Fujiwara, Christian Kellner, Florian Müllner, | ||||
|   Mario Sanchez Prada, Lubomir Rintel, Didier Roche, Marco Trevisan (Treviño), | ||||
|   verdre | ||||
|  | ||||
| Translators: | ||||
|   gogo [hr], Stas Solovey [ru], Matej Urbančič [sl], Daniel Șerbănescu [ro], | ||||
|   Fabio Tomat [fur], Marek Cernocky [cs], Daniel Mustieles [es] | ||||
|  | ||||
| 3.28.1 | ||||
| ====== | ||||
| * Fix compose characters in shell entries [Carlos; #115] | ||||
| * Don't show authentication dialogs on lock screen [Florian; #179, #166] | ||||
| * Fix handling of UTC timezone in world clock [Florian; #150] | ||||
| * Fix keyboard navigation in overview when hovering windows [Florian; #50] | ||||
| * Misc. bug fixes [Florian; #127, #788908, #763886, !39] | ||||
|  | ||||
| Contributors: | ||||
|   Jeremy Bicha, Carlos Garnacho, Andy Holmes, Florian Müllner, Bastien Nocera | ||||
|  | ||||
| Translators: | ||||
|   Stas Solovey [ru], Daniel Șerbănescu [ro], Dušan Kazik [sk], | ||||
|   Rafael Fontenelle [pt_BR], Nathan Follens [nl], Dz Chen [zh_CN], | ||||
|   Matej Urbančič [sl], Hannie Dumoleyn [nl], Khaled Hosny [ar], | ||||
|   Guillaume Bernard [fr] | ||||
|  | ||||
| 3.28.0 | ||||
| ====== | ||||
|  | ||||
| Translators: | ||||
|   A S Alam [pa], gogo [hr], Chao-Hsiung Liao [zh_TW], Jordi Mas [ca], | ||||
|   Anders Jonsson [sv], Balázs Úr [hu] | ||||
|  | ||||
| 3.27.92 | ||||
| ======= | ||||
| * Misc. bug fixes [Florian; #64, #66, #72] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Christian Kellner, Florian Müllner | ||||
|  | ||||
| Translators: | ||||
|   Daniel Mustieles [es], Wolfgang Stöggl [de], Cheng-Chia Tseng [zh_TW], | ||||
|   Dušan Kazik [sk], Changwoo Ryu [ko], Furkan Ahmet Kara [tr], Balázs Úr [hu], | ||||
|   Trần Ngọc Quân [vi], Milo Casagrande [it], GNOME Translation Robot [gd, nl], | ||||
|   Marek Cernocky [cs], Aurimas Černius [lt], Alain Lojewski [fr], | ||||
|   Rūdolfs Mazurs [lv], Stas Solovey [ru], Alan Mortensen [da] | ||||
|  | ||||
| 3.27.91 | ||||
| ======= | ||||
| * Fix wrong bluetooth state when disabled by HW airplane mode [Mario; #789110] | ||||
| * Dump javascript stack on aborts, traps and segfaults [Marco; #789237] | ||||
| * Allow Escape to "cancel" top bar focus [Stefano; #671121] | ||||
| * Fix leaving the overview erroneously on window hover [Carlos; #784545] | ||||
| * Add keyboard accessibility dialog [Olivier; #788564] | ||||
| * Port to libnm [Lubomir, Florian; #789811] | ||||
| * Don't pop up on-screen-keyboard on touch events [Florian, Carlos; #788188] | ||||
| * Improve the on-screen-keyboard [Carlos; !9, #46] | ||||
| * Add Thunderbolt support [Christian; !14] | ||||
| * Don't lock immediately on login after a wayland session crash [Florian; !17] | ||||
| * Respect cursor's hot x/y coordinates when recording [Florian Z.; #792860] | ||||
| * Allow closing windows and apps during <alt>Tab [Florian, Mario; #620106] | ||||
| * Fix small app folder icons when using HiDPI [Nikita; #792259] | ||||
| * Make sassc a mandatory build dependency [Mario; #792822] | ||||
| * Misc. bug fixes [Florian, Marco, Alessandro, Gautier, Jeremy, Bastien, Ray, | ||||
|   Carlos, Didier, Exalm, Rafal; #789231, #789277, #788542, #789103, #779974, | ||||
|   #788931, #776940, #786987, #791007, #791233, #791148, #706191, #791655, | ||||
|   #791487, #779413, #787845, #10, #788627, #792354, #792616, #781329, #780957, | ||||
|   #33, #740142, !38, !23] | ||||
|  | ||||
| Contributors: | ||||
|   Jeremy Bicha, Alessandro Bono, Nikita Churaev, Piotr Drąg, Exalm, | ||||
|   Stefano Facchini, Olivier Fourdan, Carlos Garnacho, Christian Kellner, | ||||
|   Rafal Luzynski, Iñigo Martínez, Florian Müllner, Bastien Nocera, | ||||
|   Gautier Pelloux-Prayer, Mario Sanchez Prada, Lubomir Rintel, Didier Roche, | ||||
|   Jakub Steiner, Ray Strode, Marco Trevisan (Treviño), Florian Zwoch | ||||
|  | ||||
| Translators: | ||||
|   Mingcong Bai [zh_CN], Hannie Dumoleyn [nl], Khaled Hosny [ar], | ||||
|   Kjartan Maraas [nb], Petr Kovar [cs], Marek Cernocky [cs], | ||||
|   Aurimas Černius [lt], Yosef Or Boczko [he], Kukuh Syafaat [id], | ||||
|   Sveinn í Felli [is], Jordi Mas [ca], Daniel Mustieles [es], Fabio Tomat [fur], | ||||
|   Rūdolfs Mazurs [lv], Emin Tufan Çetin [tr], Anders Jonsson [sv], | ||||
|   Matej Urbančič [sl], Jiri Grönroos [fi], Tim Sabsch [de], Gil Forcada [ca], | ||||
|   Dušan Kazik [sk], Balázs Meskó [hu], Piotr Drąg [pl], Tong Hui [zh_CN], | ||||
|   Fran Dieguez [gl], Enrico Nicoletto [pt_BR], gogo [hr], | ||||
|   Baurzhan Muftakhidinov [kk], Robert Antoni Buj Gelonch [ca], | ||||
|   Bruce Cowan [en_GB], Борисав Живановић [sr], Милош Поповић [sr@latin], | ||||
|   Марко Костић [sr] | ||||
|  | ||||
| 3.27.1 | ||||
| ====== | ||||
| * Fix using icon-name strings with PopupImageMenuItems [Florian; #789018] | ||||
|   | ||||
| @@ -1,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 | ||||
| @@ -24,9 +24,3 @@ | ||||
|  | ||||
| /* Define if _NL_TIME_FIRST_WEEKDATE is available */ | ||||
| #mesondefine HAVE__NL_TIME_FIRST_WEEKDAY | ||||
|  | ||||
| /* Define if you have the `g_desktop_app_info_launch_uris_as_manager_with_fds` function */ | ||||
| #mesondefine HAVE_GIO_DESKTOP_LAUNCH_URIS_WITH_FDS | ||||
|  | ||||
| /* Define if fdwalk is available in libc */ | ||||
| #mesondefine HAVE_FDWALK | ||||
|   | ||||
| @@ -1,6 +0,0 @@ | ||||
| [org.gnome.mutter:GNOME] | ||||
| attach-modal-dialogs=true | ||||
| edge-tiling=true | ||||
| dynamic-workspaces=true | ||||
| workspaces-only-on-primary=true | ||||
| focus-change-on-pointer-rest=true | ||||
| @@ -22,7 +22,6 @@ | ||||
|     <file>id.json</file> | ||||
|     <file>il.json</file> | ||||
|     <file>in+bolnagri.json</file> | ||||
|     <file>in+mal.json</file> | ||||
|     <file>ir.json</file> | ||||
|     <file>is.json</file> | ||||
|     <file>it.json</file> | ||||
|   | ||||
| @@ -1,5 +0,0 @@ | ||||
| [Desktop Entry] | ||||
| Type=Application | ||||
| Name=GNOME settings overrides migration | ||||
| NoDisplay=true | ||||
| Exec=@libexecdir@/gnome-shell-overrides-migration.sh | ||||
| @@ -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 | ||||
| @@ -92,33 +92,6 @@ schema = configure_file( | ||||
|   configuration: schemaconf, | ||||
|   install_dir: schemadir | ||||
| ) | ||||
| install_data('00_org.gnome.shell.gschema.override', install_dir: schemadir) | ||||
|  | ||||
| overrides_migration_conf = configuration_data() | ||||
| overrides_migration_conf.set('libexecdir', libexecdir) | ||||
| overrides_migration = configure_file( | ||||
|   input: 'gnome-shell-overrides-migration.desktop.in', | ||||
|   output: 'gnome-shell-overrides-migration.desktop', | ||||
|   configuration: overrides_migration_conf, | ||||
|   install_dir: autostartdir | ||||
| ) | ||||
|  | ||||
| if have_systemd | ||||
|   unitconf = configuration_data() | ||||
|   unitconf.set('bindir', bindir) | ||||
|  | ||||
|   unit = configure_file( | ||||
|     input: 'gnome-shell.service.in', | ||||
|     output: 'gnome-shell.service', | ||||
|     configuration: unitconf, | ||||
|     install_dir: systemduserunitdir | ||||
|   ) | ||||
|  | ||||
|   units = files('gnome-shell-wayland.target', | ||||
|                 'gnome-shell-x11.target') | ||||
|  | ||||
|   install_data(units, install_dir: systemduserunitdir) | ||||
| endif | ||||
|  | ||||
| # for unit tests - gnome.compile_schemas() only looks in srcdir | ||||
| custom_target('compile-schemas', | ||||
|   | ||||
| @@ -91,23 +91,6 @@ | ||||
|       <arg type="s" direction="out" name="filename_used"/> | ||||
|     </method> | ||||
|  | ||||
|     <!-- | ||||
|         PickColor: | ||||
|  | ||||
|         Picks a color and returns the result. | ||||
|  | ||||
|         The @result vardict contains: | ||||
|         <variablelist> | ||||
|           <varlistentry> | ||||
|             <term>color (ddd)</term> | ||||
|             <listitem><para>The color, RGB values in the range [0,1].</para></listitem> | ||||
|           </varlistentry> | ||||
|         </variablelist> | ||||
|     --> | ||||
|     <method name="PickColor"> | ||||
|       <arg type="a{sv}" direction="out" name="result"/> | ||||
|     </method> | ||||
|  | ||||
|     <!-- | ||||
|         FlashArea: | ||||
|         @x: the X coordinate of the area to flash | ||||
|   | ||||
| @@ -190,7 +190,6 @@ | ||||
|     </key> | ||||
|   </schema> | ||||
|  | ||||
|   <!-- unused, change 00_org.gnome.shell.gschema.override instead --> | ||||
|   <schema id="org.gnome.shell.overrides" path="/org/gnome/shell/overrides/" | ||||
| 	  gettext-domain="@GETTEXT_PACKAGE@"> | ||||
|     <key name="attach-modal-dialogs" type="b"> | ||||
|   | ||||
| @@ -1,559 +0,0 @@ | ||||
| { | ||||
|   "levels": [ | ||||
|     { | ||||
|       "level": "", | ||||
|       "mode": "default", | ||||
|       "rows": [ | ||||
|         [ | ||||
|           [ | ||||
|             "െ" | ||||
|           ], | ||||
|           [ | ||||
|             "ൌ" | ||||
|           ], | ||||
|           [ | ||||
|             "ൈ" | ||||
|           ], | ||||
|           [ | ||||
|             "ാ" | ||||
|           ], | ||||
|           [ | ||||
|             "ീ" | ||||
|           ], | ||||
|           [ | ||||
|             "ൂ" | ||||
|           ], | ||||
|           [ | ||||
|             "ബ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഹ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഗ" | ||||
|           ], | ||||
|           [ | ||||
|             "ദ" | ||||
|           ], | ||||
|           [ | ||||
|             "ജ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഡ" | ||||
|           ], | ||||
|           [ | ||||
|             "" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "ോ" | ||||
|           ], | ||||
|           [ | ||||
|             "േ" | ||||
|           ], | ||||
|           [ | ||||
|             "്" | ||||
|           ], | ||||
|           [ | ||||
|             "ി" | ||||
|           ], | ||||
|           [ | ||||
|             "ു" | ||||
|           ], | ||||
|           [ | ||||
|             "പ" | ||||
|           ], | ||||
|           [ | ||||
|             "ര" | ||||
|           ], | ||||
|           [ | ||||
|             "ക" | ||||
|           ], | ||||
|           [ | ||||
|             "ത" | ||||
|           ], | ||||
|           [ | ||||
|             "ച" | ||||
|           ], | ||||
|           [ | ||||
|             "ട" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "െ" | ||||
|           ], | ||||
|           [ | ||||
|             "ം" | ||||
|           ], | ||||
|           [ | ||||
|             "മ", | ||||
|             "ç" | ||||
|           ], | ||||
|           [ | ||||
|             "ന" | ||||
|           ], | ||||
|           [ | ||||
|             "വ" | ||||
|           ], | ||||
|           [ | ||||
|             "ല", | ||||
|             "ñ" | ||||
|           ], | ||||
|           [ | ||||
|             "സ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഷ" | ||||
|           ], | ||||
|           [ | ||||
|             "യ" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "," | ||||
|           ], | ||||
|           [ | ||||
|             " " | ||||
|           ], | ||||
|           [ | ||||
|             ".", | ||||
|             "#", | ||||
|             "!", | ||||
|             ",", | ||||
|             "?", | ||||
|             "-", | ||||
|             ":", | ||||
|             "'", | ||||
|             "@" | ||||
|           ] | ||||
|         ] | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "level": "shift", | ||||
|       "mode": "latched", | ||||
|       "rows": [ | ||||
|         [ | ||||
|           [ | ||||
|             "ഔ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഐ" | ||||
|           ], | ||||
|           [ | ||||
|             "ആ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഈ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഊ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഭ" | ||||
|           ], | ||||
|           [ | ||||
|             "ങ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഘ" | ||||
|           ], | ||||
|           [ | ||||
|             "ധ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഝ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഢ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഞ" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "ഓ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഏ" | ||||
|           ], | ||||
|           [ | ||||
|             "അ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഇ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഉ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഫ" | ||||
|           ], | ||||
|           [ | ||||
|             "റ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഖ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഥ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഛ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഠ" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "എ" | ||||
|           ], | ||||
|           [ | ||||
|             "" | ||||
|           ], | ||||
|           [ | ||||
|             "ണ" | ||||
|           ], | ||||
|           [ | ||||
|             "ന" | ||||
|           ], | ||||
|           [ | ||||
|             "ഴ" | ||||
|           ], | ||||
|           [ | ||||
|             "ള" | ||||
|           ], | ||||
|           [ | ||||
|             "ശ" | ||||
|           ], | ||||
|           [ | ||||
|             "ഷ" | ||||
|           ], | ||||
|           [ | ||||
|             "യ" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "," | ||||
|           ], | ||||
|           [ | ||||
|             " " | ||||
|           ], | ||||
|           [ | ||||
|             ".", | ||||
|             "#", | ||||
|             "!", | ||||
|             ",", | ||||
|             "?", | ||||
|             "-", | ||||
|             ":", | ||||
|             "'", | ||||
|             "@" | ||||
|           ] | ||||
|         ] | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "level": "opt", | ||||
|       "mode": "locked", | ||||
|       "rows": [ | ||||
|         [ | ||||
|           [ | ||||
|             "൧", | ||||
|             "1", | ||||
|             "¹", | ||||
|             "½", | ||||
|             "⅓", | ||||
|             "¼", | ||||
|             "⅛" | ||||
|           ], | ||||
|           [ | ||||
|             "൨", | ||||
|             "2", | ||||
|             "²", | ||||
|             "⅔" | ||||
|           ], | ||||
|           [ | ||||
|             "൩", | ||||
|             "3", | ||||
|             "³", | ||||
|             "¾", | ||||
|             "⅜" | ||||
|           ], | ||||
|           [ | ||||
|             "൪", | ||||
|             "4", | ||||
|             "⁴" | ||||
|           ], | ||||
|           [ | ||||
|             "൫", | ||||
|             "5", | ||||
|             "⅝" | ||||
|           ], | ||||
|           [ | ||||
|             "൬", | ||||
|             "6" | ||||
|           ], | ||||
|           [ | ||||
|             "൭", | ||||
|             "7", | ||||
|             "⅞" | ||||
|           ], | ||||
|           [ | ||||
|             "൮", | ||||
|             "8" | ||||
|           ], | ||||
|           [ | ||||
|             "൯", | ||||
|             "9" | ||||
|           ], | ||||
|           [ | ||||
|             "൦", | ||||
|             "0", | ||||
|             "ⁿ", | ||||
|             "∅" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "@" | ||||
|           ], | ||||
|           [ | ||||
|             "#" | ||||
|           ], | ||||
|           [ | ||||
|             "₹", | ||||
|             "$", | ||||
|             "¢", | ||||
|             "£", | ||||
|             "€", | ||||
|             "¥", | ||||
|             "₱" | ||||
|           ], | ||||
|           [ | ||||
|             "%", | ||||
|             "‰" | ||||
|           ], | ||||
|           [ | ||||
|             "&" | ||||
|           ], | ||||
|           [ | ||||
|             "-", | ||||
|             "_", | ||||
|             "–", | ||||
|             "—", | ||||
|             "·" | ||||
|           ], | ||||
|           [ | ||||
|             "+", | ||||
|             "±" | ||||
|           ], | ||||
|           [ | ||||
|             "(", | ||||
|             "<", | ||||
|             "{", | ||||
|             "[" | ||||
|           ], | ||||
|           [ | ||||
|             ")", | ||||
|             ">", | ||||
|             "}", | ||||
|             "]" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "*", | ||||
|             "†", | ||||
|             "‡", | ||||
|             "★" | ||||
|           ], | ||||
|           [ | ||||
|             "\"", | ||||
|             "“", | ||||
|             "”", | ||||
|             "«", | ||||
|             "»" | ||||
|           ], | ||||
|           [ | ||||
|             "'", | ||||
|             "‘", | ||||
|             "’", | ||||
|             "‹", | ||||
|             "›" | ||||
|           ], | ||||
|           [ | ||||
|             ":" | ||||
|           ], | ||||
|           [ | ||||
|             ";" | ||||
|           ], | ||||
|           [ | ||||
|             "!", | ||||
|             "¡" | ||||
|           ], | ||||
|           [ | ||||
|             "?", | ||||
|             "¿" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "_" | ||||
|           ], | ||||
|           [ | ||||
|             "/" | ||||
|           ], | ||||
|           [ | ||||
|             " " | ||||
|           ], | ||||
|           [ | ||||
|             "," | ||||
|           ], | ||||
|           [ | ||||
|             ".", | ||||
|             "…" | ||||
|           ] | ||||
|         ] | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "level": "opt+shift", | ||||
|       "mode": "locked", | ||||
|       "rows": [ | ||||
|         [ | ||||
|           [ | ||||
|             "~" | ||||
|           ], | ||||
|           [ | ||||
|             "`" | ||||
|           ], | ||||
|           [ | ||||
|             "|" | ||||
|           ], | ||||
|           [ | ||||
|             "•", | ||||
|             "♪", | ||||
|             "♥", | ||||
|             "♠", | ||||
|             "♦", | ||||
|             "♣" | ||||
|           ], | ||||
|           [ | ||||
|             "√" | ||||
|           ], | ||||
|           [ | ||||
|             "Π", | ||||
|             "π" | ||||
|           ], | ||||
|           [ | ||||
|             "÷" | ||||
|           ], | ||||
|           [ | ||||
|             "×" | ||||
|           ], | ||||
|           [ | ||||
|             "¶", | ||||
|             "§" | ||||
|           ], | ||||
|           [ | ||||
|             "∆" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "£" | ||||
|           ], | ||||
|           [ | ||||
|             "¢" | ||||
|           ], | ||||
|           [ | ||||
|             "€" | ||||
|           ], | ||||
|           [ | ||||
|             "¥" | ||||
|           ], | ||||
|           [ | ||||
|             "^", | ||||
|             "↑", | ||||
|             "↓", | ||||
|             "←", | ||||
|             "→" | ||||
|           ], | ||||
|           [ | ||||
|             "°", | ||||
|             "′", | ||||
|             "″" | ||||
|           ], | ||||
|           [ | ||||
|             "=", | ||||
|             "≠", | ||||
|             "≈", | ||||
|             "∞" | ||||
|           ], | ||||
|           [ | ||||
|             "{" | ||||
|           ], | ||||
|           [ | ||||
|             "}" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "\\" | ||||
|           ], | ||||
|           [ | ||||
|             "©" | ||||
|           ], | ||||
|           [ | ||||
|             "®" | ||||
|           ], | ||||
|           [ | ||||
|             "™" | ||||
|           ], | ||||
|           [ | ||||
|             "℅" | ||||
|           ], | ||||
|           [ | ||||
|             "[" | ||||
|           ], | ||||
|           [ | ||||
|             "]" | ||||
|           ] | ||||
|         ], | ||||
|         [ | ||||
|           [ | ||||
|             "<", | ||||
|             "‹", | ||||
|             "≤", | ||||
|             "«" | ||||
|           ], | ||||
|           [ | ||||
|             ">", | ||||
|             "›", | ||||
|             "≥", | ||||
|             "»" | ||||
|           ], | ||||
|           [ | ||||
|             " " | ||||
|           ], | ||||
|           [ | ||||
|             "," | ||||
|           ], | ||||
|           [ | ||||
|             ".", | ||||
|             "…" | ||||
|           ] | ||||
|         ] | ||||
|       ] | ||||
|     } | ||||
|   ], | ||||
|   "locale": "ml", | ||||
|   "name": "Malayalam" | ||||
| } | ||||
							
								
								
									
										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 | ||||
| @@ -50,7 +50,8 @@ gnome.gtkdoc('shell', | ||||
|     join_paths(meson.build_root(), 'src') | ||||
|   ], | ||||
|   scan_args: [ | ||||
|     '--ignore-headers=' + ' '.join(private_headers + exclude_directories) | ||||
|     '--ignore-headers=' + ' '.join(private_headers + exclude_directories), | ||||
|     '--rebuild-types' | ||||
|   ], | ||||
|   install: true | ||||
| ) | ||||
|   | ||||
| @@ -17,7 +17,8 @@ gnome.gtkdoc('st', | ||||
|   ], | ||||
|   scan_args: [ | ||||
|     '--ignore-headers=' + ' '.join(private_headers), | ||||
|     '--rebuild-sections' | ||||
|     '--rebuild-sections', | ||||
|     '--rebuild-types' | ||||
|   ], | ||||
|   install: true | ||||
| ) | ||||
|   | ||||
| @@ -14,16 +14,15 @@ const _ = Gettext.gettext; | ||||
| const Config = imports.misc.config; | ||||
| const ExtensionUtils = imports.misc.extensionUtils; | ||||
|  | ||||
| const GnomeShellIface = ` | ||||
| <node> | ||||
| <interface name="org.gnome.Shell.Extensions"> | ||||
| <signal name="ExtensionStatusChanged"> | ||||
|     <arg type="s" name="uuid"/> | ||||
|     <arg type="i" name="state"/> | ||||
|     <arg type="s" name="error"/> | ||||
| </signal> | ||||
| </interface> | ||||
| </node>`; | ||||
| const GnomeShellIface = '<node> \ | ||||
| <interface name="org.gnome.Shell.Extensions"> \ | ||||
| <signal name="ExtensionStatusChanged"> \ | ||||
|     <arg type="s" name="uuid"/> \ | ||||
|     <arg type="i" name="state"/> \ | ||||
|     <arg type="s" name="error"/> \ | ||||
| </signal> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| const GnomeShellProxy = Gio.DBusProxy.makeProxyWrapper(GnomeShellIface); | ||||
|  | ||||
| @@ -35,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 = {}; | ||||
|  | ||||
| @@ -53,7 +52,7 @@ var Application = new Lang.Class({ | ||||
|         this._skipMainWindow = false; | ||||
|     }, | ||||
|  | ||||
|     _extensionAvailable(uuid) { | ||||
|     _extensionAvailable: function(uuid) { | ||||
|         let extension = ExtensionUtils.extensions[uuid]; | ||||
|  | ||||
|         if (!extension) | ||||
| @@ -65,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)) | ||||
| @@ -80,7 +79,7 @@ var Application = new Lang.Class({ | ||||
|         return prefsModule; | ||||
|     }, | ||||
|  | ||||
|     _selectExtension(uuid) { | ||||
|     _selectExtension: function(uuid) { | ||||
|         if (!this._extensionAvailable(uuid)) | ||||
|             return; | ||||
|  | ||||
| @@ -115,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) | ||||
| @@ -128,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 }); | ||||
| @@ -141,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 }); | ||||
|  | ||||
| @@ -163,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; | ||||
|  | ||||
| @@ -192,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; | ||||
| @@ -219,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(); | ||||
|  | ||||
| @@ -255,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); | ||||
| @@ -267,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, | ||||
| @@ -325,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'); | ||||
|  | ||||
| @@ -343,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; | ||||
| @@ -357,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) | ||||
| @@ -374,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,36 +246,36 @@ var AuthPrompt = new Lang.Class({ | ||||
|             this.reset(); | ||||
|     }, | ||||
|  | ||||
|     _onShowMessage(userVerifier, message, type) { | ||||
|     _onShowMessage: function(userVerifier, message, type) { | ||||
|         this.setMessage(message, type); | ||||
|         this.emit('prompted'); | ||||
|     }, | ||||
|  | ||||
|     _onVerificationFailed(userVerifier, canRetry) { | ||||
|     _onVerificationFailed: function() { | ||||
|         this._queryingService = null; | ||||
|         this.clear(); | ||||
|  | ||||
|         this.updateSensitivity(canRetry); | ||||
|         this.updateSensitivity(true); | ||||
|         this.setActorInDefaultButtonWell(null); | ||||
|         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,12 +443,11 @@ var AuthPrompt = new Lang.Class({ | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     reset() { | ||||
|     reset: function() { | ||||
|         let oldStatus = this.verificationStatus; | ||||
|         this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; | ||||
|         this.cancelButton.reactive = true; | ||||
|         this.nextButton.label = _("Next"); | ||||
|         this._preemptiveAnswer = null; | ||||
|  | ||||
|         if (this._userVerifier) | ||||
|             this._userVerifier.cancel(); | ||||
| @@ -472,7 +480,7 @@ var AuthPrompt = new Lang.Class({ | ||||
|         this.emit('reset', beginRequestType); | ||||
|     }, | ||||
|  | ||||
|     addCharacter(unichar) { | ||||
|     addCharacter: function(unichar) { | ||||
|         if (!this._entry.visible) | ||||
|             return; | ||||
|  | ||||
| @@ -480,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 }); | ||||
|  | ||||
| @@ -494,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 | ||||
|   | ||||
| @@ -5,14 +5,13 @@ const Lang = imports.lang; | ||||
| const Shell = imports.gi.Shell; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const FprintManagerIface = ` | ||||
| <node> | ||||
| <interface name="net.reactivated.Fprint.Manager"> | ||||
| <method name="GetDefaultDevice"> | ||||
|     <arg type="o" direction="out" /> | ||||
| </method> | ||||
| </interface> | ||||
| </node>`; | ||||
| const FprintManagerIface = '<node> \ | ||||
| <interface name="net.reactivated.Fprint.Manager"> \ | ||||
| <method name="GetDefaultDevice"> \ | ||||
|     <arg type="o" direction="out" /> \ | ||||
| </method> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| const FprintManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(FprintManagerIface); | ||||
|  | ||||
|   | ||||
| @@ -4,13 +4,13 @@ const Gio = imports.gi.Gio; | ||||
| const Lang = imports.lang; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const OVirtCredentialsIface =`<node> | ||||
| <interface name="org.ovirt.vdsm.Credentials"> | ||||
| <signal name="UserAuthenticated"> | ||||
|     <arg type="s" name="token"/> | ||||
| </signal> | ||||
| </interface> | ||||
| </node>`; | ||||
| const OVirtCredentialsIface = '<node> \ | ||||
| <interface name="org.ovirt.vdsm.Credentials"> \ | ||||
| <signal name="UserAuthenticated"> \ | ||||
|     <arg type="s" name="token"/> \ | ||||
| </signal> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| const OVirtCredentialsInfo = Gio.DBusInterfaceInfo.new_for_xml(OVirtCredentialsIface); | ||||
|  | ||||
| @@ -29,28 +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; | ||||
|     } | ||||
| }); | ||||
|   | ||||
							
								
								
									
										136
									
								
								js/gdm/realmd.js
									
									
									
									
									
								
							
							
						
						| @@ -5,81 +5,78 @@ const Lang = imports.lang; | ||||
| const Shell = imports.gi.Shell; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const ProviderIface = ` | ||||
| <node> | ||||
| <interface name="org.freedesktop.realmd.Provider"> | ||||
|     <property name="Name" type="s" access="read"/> | ||||
|     <property name="Version" type="s" access="read"/> | ||||
|     <property name="Realms" type="ao" access="read"/> | ||||
|     <method name="Discover"> | ||||
|         <arg name="string" type="s" direction="in"/> | ||||
|         <arg name="options" type="a{sv}" direction="in"/> | ||||
|         <arg name="relevance" type="i" direction="out"/> | ||||
|         <arg name="realm" type="ao" direction="out"/> | ||||
|     </method> | ||||
| </interface> | ||||
| </node>`; | ||||
| const ProviderIface = '<node> \ | ||||
| <interface name="org.freedesktop.realmd.Provider"> \ | ||||
|     <property name="Name" type="s" access="read"/> \ | ||||
|     <property name="Version" type="s" access="read"/> \ | ||||
|     <property name="Realms" type="ao" access="read"/> \ | ||||
|     <method name="Discover"> \ | ||||
|         <arg name="string" type="s" direction="in"/> \ | ||||
|         <arg name="options" type="a{sv}" direction="in"/> \ | ||||
|         <arg name="relevance" type="i" direction="out"/> \ | ||||
|         <arg name="realm" type="ao" direction="out"/> \ | ||||
|     </method> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
| const Provider = Gio.DBusProxy.makeProxyWrapper(ProviderIface); | ||||
|  | ||||
| const ServiceIface = ` | ||||
| <node> | ||||
| <interface name="org.freedesktop.realmd.Service"> | ||||
|     <method name="Cancel"> | ||||
|         <arg name="operation" type="s" direction="in"/> | ||||
|     </method> | ||||
|     <method name="Release" /> | ||||
|     <method name="SetLocale"> | ||||
|         <arg name="locale" type="s" direction="in"/> | ||||
|     </method> | ||||
|     <signal name="Diagnostics"> | ||||
|         <arg name="data" type="s"/> | ||||
|         <arg name="operation" type="s"/> | ||||
|     </signal> | ||||
| </interface> | ||||
| </node>`; | ||||
| const ServiceIface = '<node> \ | ||||
| <interface name="org.freedesktop.realmd.Service"> \ | ||||
|     <method name="Cancel"> \ | ||||
|         <arg name="operation" type="s" direction="in"/> \ | ||||
|     </method> \ | ||||
|     <method name="Release" /> \ | ||||
|     <method name="SetLocale"> \ | ||||
|         <arg name="locale" type="s" direction="in"/> \ | ||||
|     </method> \ | ||||
|     <signal name="Diagnostics"> \ | ||||
|         <arg name="data" type="s"/> \ | ||||
|         <arg name="operation" type="s"/> \ | ||||
|     </signal> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
| const Service = Gio.DBusProxy.makeProxyWrapper(ServiceIface); | ||||
|  | ||||
| const RealmIface = ` | ||||
| <node> | ||||
| <interface name="org.freedesktop.realmd.Realm"> | ||||
|     <property name="Name" type="s" access="read"/> | ||||
|     <property name="Configured" type="s" access="read"/> | ||||
|     <property name="Details" type="a(ss)" access="read"/> | ||||
|     <property name="LoginFormats" type="as" access="read"/> | ||||
|     <property name="LoginPolicy" type="s" access="read"/> | ||||
|     <property name="PermittedLogins" type="as" access="read"/> | ||||
|     <property name="SupportedInterfaces" type="as" access="read"/> | ||||
|     <method name="ChangeLoginPolicy"> | ||||
|         <arg name="login_policy" type="s" direction="in"/> | ||||
|         <arg name="permitted_add" type="as" direction="in"/> | ||||
|         <arg name="permitted_remove" type="as" direction="in"/> | ||||
|         <arg name="options" type="a{sv}" direction="in"/> | ||||
|     </method> | ||||
|     <method name="Deconfigure"> | ||||
|         <arg name="options" type="a{sv}" direction="in"/> | ||||
|     </method> | ||||
| </interface> | ||||
| </node>`; | ||||
| const RealmIface = '<node> \ | ||||
| <interface name="org.freedesktop.realmd.Realm"> \ | ||||
|     <property name="Name" type="s" access="read"/> \ | ||||
|     <property name="Configured" type="s" access="read"/> \ | ||||
|     <property name="Details" type="a(ss)" access="read"/> \ | ||||
|     <property name="LoginFormats" type="as" access="read"/> \ | ||||
|     <property name="LoginPolicy" type="s" access="read"/> \ | ||||
|     <property name="PermittedLogins" type="as" access="read"/> \ | ||||
|     <property name="SupportedInterfaces" type="as" access="read"/> \ | ||||
|     <method name="ChangeLoginPolicy"> \ | ||||
|         <arg name="login_policy" type="s" direction="in"/> \ | ||||
|         <arg name="permitted_add" type="as" direction="in"/> \ | ||||
|         <arg name="permitted_remove" type="as" direction="in"/> \ | ||||
|         <arg name="options" type="a{sv}" direction="in"/> \ | ||||
|     </method> \ | ||||
|     <method name="Deconfigure"> \ | ||||
|         <arg name="options" type="a{sv}" direction="in"/> \ | ||||
|     </method> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
| const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface); | ||||
|  | ||||
| var Manager = new Lang.Class({ | ||||
|     Name: 'Manager', | ||||
|  | ||||
|     _init(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) | ||||
| @@ -89,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()]; | ||||
| @@ -106,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) { | ||||
| @@ -144,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(); | ||||
|   | ||||
							
								
								
									
										196
									
								
								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,55 +514,56 @@ 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, when in login mode we allow ALLOWED_FAILURES attempts. | ||||
|         // After that, we go back to the welcome screen. | ||||
|         // Otherwise, we allow ALLOWED_FAILURES attempts. After that, we | ||||
|         // go back to the welcome screen. | ||||
|  | ||||
|         this._failCounter++; | ||||
|         let canRetry = retry && this._userName && | ||||
|             (this._reauthOnly || | ||||
|              this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY)); | ||||
|             this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY); | ||||
|  | ||||
|         if (canRetry) { | ||||
|             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', canRetry); | ||||
|         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. | ||||
|   | ||||
| @@ -9,6 +9,8 @@ | ||||
|     <file>gdm/realmd.js</file> | ||||
|     <file>gdm/util.js</file> | ||||
|  | ||||
|     <file>extensionPrefs/main.js</file> | ||||
|  | ||||
|     <file>misc/config.js</file> | ||||
|     <file>misc/extensionUtils.js</file> | ||||
|     <file>misc/fileUtils.js</file> | ||||
| @@ -31,6 +33,8 @@ | ||||
|     <file>perf/core.js</file> | ||||
|     <file>perf/hwtest.js</file> | ||||
|  | ||||
|     <file>portalHelper/main.js</file> | ||||
|  | ||||
|     <file>ui/accessDialog.js</file> | ||||
|     <file>ui/altTab.js</file> | ||||
|     <file>ui/animation.js</file> | ||||
| @@ -39,7 +43,6 @@ | ||||
|     <file>ui/audioDeviceSelection.js</file> | ||||
|     <file>ui/backgroundMenu.js</file> | ||||
|     <file>ui/background.js</file> | ||||
|     <file>ui/barLevel.js</file> | ||||
|     <file>ui/boxpointer.js</file> | ||||
|     <file>ui/calendar.js</file> | ||||
|     <file>ui/checkBox.js</file> | ||||
| @@ -127,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> | ||||
|   | ||||
| @@ -6,17 +6,3 @@ js_resources = gnome.compile_resources( | ||||
|   c_name: 'shell_js_resources', | ||||
|   dependencies: [config_js] | ||||
| ) | ||||
|  | ||||
| portal_resources = gnome.compile_resources( | ||||
|   'portal-resources', 'portal-resources.gresource.xml', | ||||
|   source_dir: ['.', meson.current_build_dir()], | ||||
|   c_name: 'portal_js_resources', | ||||
|   dependencies: [config_js] | ||||
| ) | ||||
|  | ||||
| prefs_resources = gnome.compile_resources( | ||||
|   'prefs-resources', 'prefs-resources.gresource.xml', | ||||
|   source_dir: ['.', meson.current_build_dir()], | ||||
|   c_name: 'prefs_js_resources', | ||||
|   dependencies: [config_js] | ||||
| ) | ||||
|   | ||||
| @@ -112,8 +112,6 @@ function createExtensionObject(uuid, dir, type) { | ||||
|     let metadataContents, success, tag; | ||||
|     try { | ||||
|         [success, metadataContents, tag] = metadataFile.load_contents(null); | ||||
|         if (metadataContents instanceof Uint8Array) | ||||
|             metadataContents = imports.byteArray.toString(metadataContents); | ||||
|     } catch (e) { | ||||
|         throw new Error('Failed to load metadata.json: ' + e); | ||||
|     } | ||||
| @@ -163,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; | ||||
| @@ -186,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); | ||||
|   | ||||
| @@ -4,18 +4,17 @@ const Gio = imports.gi.Gio; | ||||
| const Lang = imports.lang; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const PresenceIface = ` | ||||
| <node> | ||||
| <interface name="org.gnome.SessionManager.Presence"> | ||||
| <method name="SetStatus"> | ||||
|     <arg type="u" direction="in"/> | ||||
| </method> | ||||
| <property name="status" type="u" access="readwrite"/> | ||||
| <signal name="StatusChanged"> | ||||
|     <arg type="u" direction="out"/> | ||||
| </signal> | ||||
| </interface> | ||||
| </node>`; | ||||
| const PresenceIface = '<node> \ | ||||
| <interface name="org.gnome.SessionManager.Presence"> \ | ||||
| <method name="SetStatus"> \ | ||||
|     <arg type="u" direction="in"/> \ | ||||
| </method> \ | ||||
| <property name="status" type="u" access="readwrite"/> \ | ||||
| <signal name="StatusChanged"> \ | ||||
|     <arg type="u" direction="out"/> \ | ||||
| </signal> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| var PresenceStatus = { | ||||
|     AVAILABLE: 0, | ||||
| @@ -33,17 +32,16 @@ function Presence(initCallback, cancellable) { | ||||
| // Note inhibitors are immutable objects, so they don't | ||||
| // change at runtime (changes always come in the form | ||||
| // of new inhibitors) | ||||
| const InhibitorIface = ` | ||||
| <node> | ||||
| <interface name="org.gnome.SessionManager.Inhibitor"> | ||||
| <method name="GetAppId"> | ||||
|     <arg type="s" direction="out" /> | ||||
| </method> | ||||
| <method name="GetReason"> | ||||
|     <arg type="s" direction="out" /> | ||||
| </method> | ||||
| </interface> | ||||
| </node>`; | ||||
| const InhibitorIface = '<node> \ | ||||
| <interface name="org.gnome.SessionManager.Inhibitor"> \ | ||||
| <method name="GetAppId"> \ | ||||
|     <arg type="s" direction="out" /> \ | ||||
| </method> \ | ||||
| <method name="GetReason"> \ | ||||
|     <arg type="s" direction="out" /> \ | ||||
| </method> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| var InhibitorProxy = Gio.DBusProxy.makeProxyWrapper(InhibitorIface); | ||||
| function Inhibitor(objectPath, initCallback, cancellable) { | ||||
| @@ -51,30 +49,29 @@ function Inhibitor(objectPath, initCallback, cancellable) { | ||||
| } | ||||
|  | ||||
| // Not the full interface, only the methods we use | ||||
| const SessionManagerIface = ` | ||||
| <node> | ||||
| <interface name="org.gnome.SessionManager"> | ||||
| <method name="Logout"> | ||||
|     <arg type="u" direction="in" /> | ||||
| </method> | ||||
| <method name="Shutdown" /> | ||||
| <method name="Reboot" /> | ||||
| <method name="CanShutdown"> | ||||
|     <arg type="b" direction="out" /> | ||||
| </method> | ||||
| <method name="IsInhibited"> | ||||
|     <arg type="u" direction="in" /> | ||||
|     <arg type="b" direction="out" /> | ||||
| </method> | ||||
| <property name="SessionIsActive" type="b" access="read"/> | ||||
| <signal name="InhibitorAdded"> | ||||
|     <arg type="o" direction="out"/> | ||||
| </signal> | ||||
| <signal name="InhibitorRemoved"> | ||||
|     <arg type="o" direction="out"/> | ||||
| </signal> | ||||
| </interface> | ||||
| </node>`; | ||||
| const SessionManagerIface = '<node> \ | ||||
| <interface name="org.gnome.SessionManager"> \ | ||||
| <method name="Logout"> \ | ||||
|     <arg type="u" direction="in" /> \ | ||||
| </method> \ | ||||
| <method name="Shutdown" /> \ | ||||
| <method name="Reboot" /> \ | ||||
| <method name="CanShutdown"> \ | ||||
|     <arg type="b" direction="out" /> \ | ||||
| </method> \ | ||||
| <method name="IsInhibited"> \ | ||||
|     <arg type="u" direction="in" /> \ | ||||
|     <arg type="b" direction="out" /> \ | ||||
| </method> \ | ||||
| <property name="SessionIsActive" type="b" access="read"/> \ | ||||
| <signal name="InhibitorAdded"> \ | ||||
|     <arg type="o" direction="out"/> \ | ||||
| </signal> \ | ||||
| <signal name="InhibitorRemoved"> \ | ||||
|     <arg type="o" direction="out"/> \ | ||||
| </signal> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| var SessionManagerProxy = Gio.DBusProxy.makeProxyWrapper(SessionManagerIface); | ||||
| function SessionManager(initCallback, cancellable) { | ||||
|   | ||||
| @@ -10,7 +10,7 @@ var DEFAULT_LIMIT = 512; | ||||
| var HistoryManager = new Lang.Class({ | ||||
|     Name: 'HistoryManager', | ||||
|  | ||||
|     _init(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,29 +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._preeditStr = ''; | ||||
|         this._preeditPos = 0; | ||||
|         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(); | ||||
|     }, | ||||
| @@ -40,7 +33,7 @@ var InputMethod = new Lang.Class({ | ||||
|         return this._currentFocus; | ||||
|     }, | ||||
|  | ||||
|     _updateCapabilities() { | ||||
|     _updateCapabilities: function() { | ||||
|         let caps = 0; | ||||
|  | ||||
|         if (this.can_show_preedit) | ||||
| @@ -55,89 +48,55 @@ 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('show-preedit-text', this._onShowPreeditText.bind(this)); | ||||
|         this._context.connect('hide-preedit-text', this._onHidePreeditText.bind(this)); | ||||
|         this._context.connect('forward-key-event', this._onForwardKeyEvent.bind(this)); | ||||
|         this._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; | ||||
|         this._preeditStr = '' | ||||
|         this._preeditPos = 0; | ||||
|     }, | ||||
|  | ||||
|     _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) { | ||||
|         if (text == null) | ||||
|             return; | ||||
|         this._preeditStr = text.get_text(); | ||||
|         this._preeditPos = pos; | ||||
|         if (visible) | ||||
|             this.set_preedit_text(this._preeditStr, pos); | ||||
|         else | ||||
|             this.set_preedit_text(null, pos); | ||||
|     _onUpdatePreeditText: function (context, text, pos, visible) { | ||||
|         let str = null; | ||||
|         if (visible && text != null) | ||||
|             str = text.get_text(); | ||||
|  | ||||
|         this.set_preedit_text(str, pos); | ||||
|     }, | ||||
|  | ||||
|     _onShowPreeditText(context) { | ||||
|         this.set_preedit_text(this._preeditStr, this._preeditPos); | ||||
|     }, | ||||
|  | ||||
|     _onHidePreeditText(context) { | ||||
|         this.set_preedit_text(null, this._preeditPos); | ||||
|     }, | ||||
|  | ||||
|     _onForwardKeyEvent(context, keyval, keycode, state) { | ||||
|         let press = (state & IBus.ModifierType.RELEASE_MASK) == 0; | ||||
|  | ||||
|         if (this._currentEvent) { | ||||
|             // If we are handling this same event in filter_key_press(), | ||||
|             // just let it go through, sending the same event again will | ||||
|             // be silenced away because the key counts as pressed. | ||||
|             if (this._currentEvent.get_key_symbol() == keyval && | ||||
|                 (this._currentEvent.type() == Clutter.EventType.KEY_PRESS) == press) { | ||||
|                 this._doForwardEvent = true; | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         this._virtualDevice.notify_key(Clutter.get_current_event_time(), keycode, | ||||
|                                        press ? Clutter.KeyState.PRESSED : Clutter.KeyState.RELEASED); | ||||
|     }, | ||||
|  | ||||
|     vfunc_focus_in(focus) { | ||||
|     vfunc_focus_in: function(focus) { | ||||
|         this._currentFocus = focus; | ||||
|         if (this._context) { | ||||
|             this._context.focus_in(); | ||||
| @@ -146,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(); | ||||
| @@ -157,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(); | ||||
| @@ -167,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()); | ||||
| @@ -175,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; | ||||
| @@ -200,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; | ||||
| @@ -226,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(); | ||||
| @@ -238,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; | ||||
|     } | ||||
|   | ||||
| @@ -7,60 +7,47 @@ const Mainloop = imports.mainloop; | ||||
| const Shell = imports.gi.Shell; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const SystemdLoginManagerIface = ` | ||||
| <node> | ||||
| <interface name="org.freedesktop.login1.Manager"> | ||||
| <method name="Suspend"> | ||||
|     <arg type="b" direction="in"/> | ||||
| </method> | ||||
| <method name="CanSuspend"> | ||||
|     <arg type="s" direction="out"/> | ||||
| </method> | ||||
| <method name="Inhibit"> | ||||
|     <arg type="s" direction="in"/> | ||||
|     <arg type="s" direction="in"/> | ||||
|     <arg type="s" direction="in"/> | ||||
|     <arg type="s" direction="in"/> | ||||
|     <arg type="h" direction="out"/> | ||||
| </method> | ||||
| <method name="GetSession"> | ||||
|     <arg type="s" direction="in"/> | ||||
|     <arg type="o" direction="out"/> | ||||
| </method> | ||||
| <method name="ListSessions"> | ||||
|     <arg name="sessions" type="a(susso)" direction="out"/> | ||||
| </method> | ||||
| <signal name="PrepareForSleep"> | ||||
|     <arg type="b" direction="out"/> | ||||
| </signal> | ||||
| </interface> | ||||
| </node>`; | ||||
| const SystemdLoginManagerIface = '<node> \ | ||||
| <interface name="org.freedesktop.login1.Manager"> \ | ||||
| <method name="Suspend"> \ | ||||
|     <arg type="b" direction="in"/> \ | ||||
| </method> \ | ||||
| <method name="CanSuspend"> \ | ||||
|     <arg type="s" direction="out"/> \ | ||||
| </method> \ | ||||
| <method name="Inhibit"> \ | ||||
|     <arg type="s" direction="in"/> \ | ||||
|     <arg type="s" direction="in"/> \ | ||||
|     <arg type="s" direction="in"/> \ | ||||
|     <arg type="s" direction="in"/> \ | ||||
|     <arg type="h" direction="out"/> \ | ||||
| </method> \ | ||||
| <method name="GetSession"> \ | ||||
|     <arg type="s" direction="in"/> \ | ||||
|     <arg type="o" direction="out"/> \ | ||||
| </method> \ | ||||
| <method name="ListSessions"> \ | ||||
|     <arg name="sessions" type="a(susso)" direction="out"/> \ | ||||
| </method> \ | ||||
| <signal name="PrepareForSleep"> \ | ||||
|     <arg type="b" direction="out"/> \ | ||||
| </signal> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| const SystemdLoginSessionIface = ` | ||||
| <node> | ||||
| <interface name="org.freedesktop.login1.Session"> | ||||
| <signal name="Lock" /> | ||||
| <signal name="Unlock" /> | ||||
| <property name="Active" type="b" access="read" /> | ||||
| <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 SystemdLoginSessionIface = '<node> \ | ||||
| <interface name="org.freedesktop.login1.Session"> \ | ||||
| <signal name="Lock" /> \ | ||||
| <signal name="Unlock" /> \ | ||||
| <property name="Active" type="b" access="read" /> \ | ||||
| <method name="SetLockedHint"> \ | ||||
|     <arg type="b" direction="in"/> \ | ||||
| </method> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| const 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; | ||||
| @@ -118,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; | ||||
| @@ -137,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 { | ||||
| @@ -188,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 | ||||
| @@ -197,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); | ||||
| @@ -218,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); | ||||
|     } | ||||
| }); | ||||
| @@ -230,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); | ||||
|     } | ||||
| }); | ||||
|   | ||||
| @@ -92,65 +92,63 @@ function _findProviderForSid(sid) { | ||||
| // The following are not the complete interfaces, just the methods we need | ||||
| // (or may need in the future) | ||||
|  | ||||
| const ModemGsmNetworkInterface = ` | ||||
| <node> | ||||
| <interface name="org.freedesktop.ModemManager.Modem.Gsm.Network"> | ||||
| <method name="GetRegistrationInfo"> | ||||
|     <arg type="(uss)" direction="out" /> | ||||
| </method> | ||||
| <method name="GetSignalQuality"> | ||||
|     <arg type="u" direction="out" /> | ||||
| </method> | ||||
| <property name="AccessTechnology" type="u" access="read" /> | ||||
| <signal name="SignalQuality"> | ||||
|     <arg type="u" direction="out" /> | ||||
| </signal> | ||||
| <signal name="RegistrationInfo"> | ||||
|     <arg type="u" direction="out" /> | ||||
|     <arg type="s" direction="out" /> | ||||
|     <arg type="s" direction="out" /> | ||||
| </signal> | ||||
| </interface> | ||||
| </node>`; | ||||
| const ModemGsmNetworkInterface = '<node> \ | ||||
| <interface name="org.freedesktop.ModemManager.Modem.Gsm.Network"> \ | ||||
| <method name="GetRegistrationInfo"> \ | ||||
|     <arg type="(uss)" direction="out" /> \ | ||||
| </method> \ | ||||
| <method name="GetSignalQuality"> \ | ||||
|     <arg type="u" direction="out" /> \ | ||||
| </method> \ | ||||
| <property name="AccessTechnology" type="u" access="read" /> \ | ||||
| <signal name="SignalQuality"> \ | ||||
|     <arg type="u" direction="out" /> \ | ||||
| </signal> \ | ||||
| <signal name="RegistrationInfo"> \ | ||||
|     <arg type="u" direction="out" /> \ | ||||
|     <arg type="s" direction="out" /> \ | ||||
|     <arg type="s" direction="out" /> \ | ||||
| </signal> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| const ModemGsmNetworkProxy = Gio.DBusProxy.makeProxyWrapper(ModemGsmNetworkInterface); | ||||
|  | ||||
| const ModemCdmaInterface = ` | ||||
| <node> | ||||
| <interface name="org.freedesktop.ModemManager.Modem.Cdma"> | ||||
| <method name="GetSignalQuality"> | ||||
|     <arg type="u" direction="out" /> | ||||
| </method> | ||||
| <method name="GetServingSystem"> | ||||
|     <arg type="(usu)" direction="out" /> | ||||
| </method> | ||||
| <signal name="SignalQuality"> | ||||
|     <arg type="u" direction="out" /> | ||||
| </signal> | ||||
| </interface> | ||||
| </node>`; | ||||
| const ModemCdmaInterface = '<node> \ | ||||
| <interface name="org.freedesktop.ModemManager.Modem.Cdma"> \ | ||||
| <method name="GetSignalQuality"> \ | ||||
|     <arg type="u" direction="out" /> \ | ||||
| </method> \ | ||||
| <method name="GetServingSystem"> \ | ||||
|     <arg type="(usu)" direction="out" /> \ | ||||
| </method> \ | ||||
| <signal name="SignalQuality"> \ | ||||
|     <arg type="u" direction="out" /> \ | ||||
| </signal> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface); | ||||
|  | ||||
| var ModemGsm = new Lang.Class({ | ||||
|     Name: 'ModemGsm', | ||||
|  | ||||
|     _init(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; | ||||
| @@ -159,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; | ||||
| @@ -169,7 +167,7 @@ var ModemGsm = new Lang.Class({ | ||||
|                 this.signal_quality = quality; | ||||
|             } | ||||
|             this.emit('notify::signal-quality'); | ||||
|         }); | ||||
|         })); | ||||
|     } | ||||
| }); | ||||
| Signals.addSignalMethods(ModemGsm.prototype); | ||||
| @@ -177,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'); | ||||
|  | ||||
| @@ -190,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; | ||||
| @@ -200,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; | ||||
| @@ -214,7 +212,7 @@ var ModemCdma = new Lang.Class({ | ||||
|                 this.operator_name = _findProviderForSid(sid) | ||||
|             } | ||||
|             this.emit('notify::operator-name'); | ||||
|         }); | ||||
|         })); | ||||
|     } | ||||
| }); | ||||
| Signals.addSignalMethods(ModemCdma.prototype); | ||||
| @@ -224,68 +222,65 @@ Signals.addSignalMethods(ModemCdma.prototype); | ||||
| // Support for the new ModemManager1 interface (MM >= 0.7) | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| const BroadbandModemInterface = ` | ||||
| <node> | ||||
| <interface name="org.freedesktop.ModemManager1.Modem"> | ||||
| <property name="SignalQuality" type="(ub)" access="read" /> | ||||
| </interface> | ||||
| </node>`; | ||||
| const BroadbandModemInterface = '<node> \ | ||||
| <interface name="org.freedesktop.ModemManager1.Modem"> \ | ||||
| <property name="SignalQuality" type="(ub)" access="read" /> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
| const BroadbandModemProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemInterface); | ||||
|  | ||||
| const BroadbandModem3gppInterface = ` | ||||
| <node> | ||||
| <interface name="org.freedesktop.ModemManager1.Modem.Modem3gpp"> | ||||
| <property name="OperatorCode" type="s" access="read" /> | ||||
| <property name="OperatorName" type="s" access="read" /> | ||||
| </interface> | ||||
| </node>`; | ||||
| const BroadbandModem3gppInterface = '<node> \ | ||||
| <interface name="org.freedesktop.ModemManager1.Modem.Modem3gpp"> \ | ||||
| <property name="OperatorCode" type="s" access="read" /> \ | ||||
| <property name="OperatorName" type="s" access="read" /> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
| const BroadbandModem3gppProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModem3gppInterface); | ||||
|  | ||||
| const BroadbandModemCdmaInterface = ` | ||||
| <node> | ||||
| <interface name="org.freedesktop.ModemManager1.Modem.ModemCdma"> | ||||
| <property name="Sid" type="u" access="read" /> | ||||
| </interface> | ||||
| </node>`; | ||||
| const BroadbandModemCdmaInterface = '<node> \ | ||||
| <interface name="org.freedesktop.ModemManager1.Modem.ModemCdma"> \ | ||||
| <property name="Sid" type="u" access="read" /> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
| const BroadbandModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemCdmaInterface); | ||||
|  | ||||
| var BroadbandModem = new Lang.Class({ | ||||
|     Name: 'BroadbandModem', | ||||
|  | ||||
|     _init(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; | ||||
| @@ -300,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(); | ||||
|   | ||||
| @@ -8,28 +8,27 @@ const Signals = imports.signals; | ||||
|  | ||||
| // Specified in the D-Bus specification here: | ||||
| // http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager | ||||
| const ObjectManagerIface = ` | ||||
| <node> | ||||
| <interface name="org.freedesktop.DBus.ObjectManager"> | ||||
|   <method name="GetManagedObjects"> | ||||
|     <arg name="objects" type="a{oa{sa{sv}}}" direction="out"/> | ||||
|   </method> | ||||
|   <signal name="InterfacesAdded"> | ||||
|     <arg name="objectPath" type="o"/> | ||||
|     <arg name="interfaces" type="a{sa{sv}}" /> | ||||
|   </signal> | ||||
|   <signal name="InterfacesRemoved"> | ||||
|     <arg name="objectPath" type="o"/> | ||||
|     <arg name="interfaces" type="as" /> | ||||
|   </signal> | ||||
| </interface> | ||||
| </node>`; | ||||
| const ObjectManagerIface = '<node> \ | ||||
| <interface name="org.freedesktop.DBus.ObjectManager"> \ | ||||
|   <method name="GetManagedObjects"> \ | ||||
|     <arg name="objects" type="a{oa{sa{sv}}}" direction="out"/> \ | ||||
|   </method> \ | ||||
|   <signal name="InterfacesAdded"> \ | ||||
|     <arg name="objectPath" type="o"/> \ | ||||
|     <arg name="interfaces" type="a{sa{sv}}" /> \ | ||||
|   </signal> \ | ||||
|   <signal name="InterfacesRemoved"> \ | ||||
|     <arg name="objectPath" type="o"/> \ | ||||
|     <arg name="interfaces" type="as" /> \ | ||||
|   </signal> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| const ObjectManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ObjectManagerIface); | ||||
|  | ||||
| var ObjectManager = new Lang.Class({ | ||||
|     Name: 'ObjectManager', | ||||
|     _init(params) { | ||||
|     _init: function(params) { | ||||
|         params = Params.parse(params, { connection: null, | ||||
|                                         name: null, | ||||
|                                         objectPath: null, | ||||
| @@ -62,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; | ||||
|  | ||||
| @@ -76,7 +75,7 @@ var ObjectManager = new Lang.Class({ | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     _addInterface(objectPath, interfaceName, onFinished) { | ||||
|     _addInterface: function(objectPath, interfaceName, onFinished) { | ||||
|         let info = this._interfaceInfos[interfaceName]; | ||||
|  | ||||
|         if (!info) { | ||||
| @@ -94,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); | ||||
| @@ -128,10 +127,10 @@ var ObjectManager = new Lang.Class({ | ||||
|  | ||||
|                if (onFinished) | ||||
|                    onFinished(); | ||||
|         }); | ||||
|         })); | ||||
|     }, | ||||
|  | ||||
|     _removeInterface(objectPath, interfaceName) { | ||||
|     _removeInterface: function(objectPath, interfaceName) { | ||||
|         if (!this._objects[objectPath]) | ||||
|             return; | ||||
|  | ||||
| @@ -157,7 +156,7 @@ var ObjectManager = new Lang.Class({ | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     _onManagerProxyLoaded(initable, result) { | ||||
|     _onManagerProxyLoaded: function(initable, result) { | ||||
|         let error = null; | ||||
|         try { | ||||
|             initable.init_finish(result); | ||||
| @@ -169,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); | ||||
| @@ -227,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]; | ||||
| @@ -249,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) | ||||
| @@ -265,7 +264,7 @@ var ObjectManager = new Lang.Class({ | ||||
|         return object[interfaceName]; | ||||
|     }, | ||||
|  | ||||
|     getProxiesForInterface(interfaceName) { | ||||
|     getProxiesForInterface: function(interfaceName) { | ||||
|         let proxyList = this._interfaces[interfaceName]; | ||||
|  | ||||
|         if (!proxyList) | ||||
| @@ -274,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 | ||||
|   | ||||
| @@ -2,31 +2,30 @@ | ||||
|  | ||||
| const Gio = imports.gi.Gio; | ||||
|  | ||||
| const PermissionStoreIface = ` | ||||
| <node> | ||||
|   <interface name="org.freedesktop.impl.portal.PermissionStore"> | ||||
|     <method name="Lookup"> | ||||
|       <arg name="table" type="s" direction="in"/> | ||||
|       <arg name="id" type="s" direction="in"/> | ||||
|       <arg name="permissions" type="a{sas}" direction="out"/> | ||||
|       <arg name="data" type="v" direction="out"/> | ||||
|     </method> | ||||
|     <method name="Set"> | ||||
|       <arg name="table" type="s" direction="in"/> | ||||
|       <arg name="create" type="b" direction="in"/> | ||||
|       <arg name="id" type="s" direction="in"/> | ||||
|       <arg name="app_permissions" type="a{sas}" direction="in"/> | ||||
|       <arg name="data" type="v" direction="in"/> | ||||
|     </method> | ||||
|     <signal name="Changed"> | ||||
|       <arg name="table" type="s" direction="out"/> | ||||
|       <arg name="id" type="s" direction="out"/> | ||||
|       <arg name="deleted" type="b" direction="out"/> | ||||
|       <arg name="data" type="v" direction="out"/> | ||||
|       <arg name="permissions" type="a{sas}" direction="out"/> | ||||
|     </signal> | ||||
|   </interface> | ||||
| </node>`; | ||||
| const PermissionStoreIface = '<node> \ | ||||
|   <interface name="org.freedesktop.impl.portal.PermissionStore"> \ | ||||
|     <method name="Lookup"> \ | ||||
|       <arg name="table" type="s" direction="in"/> \ | ||||
|       <arg name="id" type="s" direction="in"/> \ | ||||
|       <arg name="permissions" type="a{sas}" direction="out"/> \ | ||||
|       <arg name="data" type="v" direction="out"/> \ | ||||
|     </method> \ | ||||
|     <method name="Set"> \ | ||||
|       <arg name="table" type="s" direction="in"/> \ | ||||
|       <arg name="create" type="b" direction="in"/> \ | ||||
|       <arg name="id" type="s" direction="in"/> \ | ||||
|       <arg name="app_permissions" type="a{sas}" direction="in"/> \ | ||||
|       <arg name="data" type="v" direction="in"/> \ | ||||
|     </method> \ | ||||
|     <signal name="Changed"> \ | ||||
|       <arg name="table" type="s" direction="out"/> \ | ||||
|       <arg name="id" type="s" direction="out"/> \ | ||||
|       <arg name="deleted" type="b" direction="out"/> \ | ||||
|       <arg name="data" type="v" direction="out"/> \ | ||||
|       <arg name="permissions" type="a{sas}" direction="out"/> \ | ||||
|     </signal> \ | ||||
|   </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| const PermissionStoreProxy = Gio.DBusProxy.makeProxyWrapper(PermissionStoreIface); | ||||
|  | ||||
|   | ||||
| @@ -7,15 +7,14 @@ const Signals = imports.signals; | ||||
|  | ||||
| const ObjectManager = imports.misc.objectManager; | ||||
|  | ||||
| const SmartcardTokenIface = ` | ||||
| <node> | ||||
| <interface name="org.gnome.SettingsDaemon.Smartcard.Token"> | ||||
|   <property name="Name" type="s" access="read"/> | ||||
|   <property name="Driver" type="o" access="read"/> | ||||
|   <property name="IsInserted" type="b" access="read"/> | ||||
|   <property name="UsedToLogin" type="b" access="read"/> | ||||
| </interface> | ||||
| </node>`; | ||||
| const SmartcardTokenIface = '<node> \ | ||||
| <interface name="org.gnome.SettingsDaemon.Smartcard.Token"> \ | ||||
|   <property name="Name" type="s" access="read"/> \ | ||||
|   <property name="Driver" type="o" access="read"/> \ | ||||
|   <property name="IsInserted" type="b" access="read"/> \ | ||||
|   <property name="UsedToLogin" type="b" access="read"/> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| let _smartcardManager = null; | ||||
|  | ||||
| @@ -28,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]; | ||||
| @@ -67,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) { | ||||
| @@ -101,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; | ||||
|  | ||||
|   | ||||
| @@ -22,12 +22,11 @@ const ALWAYS_SHOW_LOG_OUT_KEY = 'always-show-log-out'; | ||||
| const SENSOR_BUS_NAME = 'net.hadess.SensorProxy'; | ||||
| const SENSOR_OBJECT_PATH = '/net/hadess/SensorProxy'; | ||||
|  | ||||
| const SensorProxyInterface = ` | ||||
| <node> | ||||
| <interface name="net.hadess.SensorProxy"> | ||||
|   <property name="HasAccelerometer" type="b" access="read"/> | ||||
| </interface> | ||||
| </node>`; | ||||
| const SensorProxyInterface = '<node> \ | ||||
| <interface name="net.hadess.SensorProxy"> \ | ||||
|   <property name="HasAccelerometer" type="b" access="read"/> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| const POWER_OFF_ACTION_ID        = 'power-off'; | ||||
| const LOCK_SCREEN_ACTION_ID      = 'lock-screen'; | ||||
| @@ -88,7 +87,7 @@ const SystemActions = new Lang.Class({ | ||||
|                                                           null) | ||||
|     }, | ||||
|  | ||||
|     _init() { | ||||
|     _init: function() { | ||||
|         this.parent(); | ||||
|  | ||||
|         this._canHavePowerOff = true; | ||||
| @@ -219,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) { | ||||
| @@ -232,7 +231,7 @@ const SystemActions = new Lang.Class({ | ||||
|             }); | ||||
|     }, | ||||
|  | ||||
|     _updateOrientationLock() { | ||||
|     _updateOrientationLock: function() { | ||||
|         let available = false; | ||||
|         if (this._sensorProxy) | ||||
|             available = this._sensorProxy.HasAccelerometer && | ||||
| @@ -243,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'; | ||||
| @@ -252,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 | ||||
| @@ -267,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(); }); | ||||
|  | ||||
| @@ -280,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(); | ||||
| @@ -318,7 +317,7 @@ const SystemActions = new Lang.Class({ | ||||
|         this.notify('can-lock-screen'); | ||||
|     }, | ||||
|  | ||||
|     _updateHaveShutdown() { | ||||
|     _updateHaveShutdown: function() { | ||||
|         this._session.CanShutdownRemote((result, error) => { | ||||
|             if (error) | ||||
|                 return; | ||||
| @@ -328,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)); | ||||
| @@ -336,7 +335,7 @@ const SystemActions = new Lang.Class({ | ||||
|         this.notify('can-power-off'); | ||||
|     }, | ||||
|  | ||||
|     _updateHaveSuspend() { | ||||
|     _updateHaveSuspend: function() { | ||||
|         this._loginManager.canSuspend( | ||||
|             (canSuspend, needsAuth) => { | ||||
|                 this._canHaveSuspend = canSuspend; | ||||
| @@ -345,7 +344,7 @@ const SystemActions = new Lang.Class({ | ||||
|             }); | ||||
|     }, | ||||
|  | ||||
|     _updateSuspend() { | ||||
|     _updateSuspend: function() { | ||||
|         let disabled = (Main.sessionMode.isLocked && | ||||
|                         this._suspendNeedsAuth) || | ||||
|                        (Main.sessionMode.isGreeter && | ||||
| @@ -354,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; | ||||
| @@ -371,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); | ||||
| @@ -389,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!'); | ||||
|  | ||||
| @@ -397,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!'); | ||||
|  | ||||
| @@ -425,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; | ||||
|   | ||||
| @@ -1,7 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <gresources> | ||||
|   <gresource prefix="/org/gnome/shell"> | ||||
|     <file>misc/config.js</file> | ||||
|     <file>portalHelper/main.js</file> | ||||
|   </gresource> | ||||
| </gresources> | ||||
| @@ -30,32 +30,31 @@ const CONNECTIVITY_CHECK_HOST = 'nmcheck.gnome.org'; | ||||
| const CONNECTIVITY_CHECK_URI = 'http://' + CONNECTIVITY_CHECK_HOST; | ||||
| const CONNECTIVITY_RECHECK_RATELIMIT_TIMEOUT = 30 * GLib.USEC_PER_SEC; | ||||
|  | ||||
| const HelperDBusInterface = ` | ||||
| <node> | ||||
| <interface name="org.gnome.Shell.PortalHelper"> | ||||
| <method name="Authenticate"> | ||||
|     <arg type="o" direction="in" name="connection" /> | ||||
|     <arg type="s" direction="in" name="url" /> | ||||
|     <arg type="u" direction="in" name="timestamp" /> | ||||
| </method> | ||||
| <method name="Close"> | ||||
|     <arg type="o" direction="in" name="connection" /> | ||||
| </method> | ||||
| <method name="Refresh"> | ||||
|     <arg type="o" direction="in" name="connection" /> | ||||
| </method> | ||||
| <signal name="Done"> | ||||
|     <arg type="o" name="connection" /> | ||||
|     <arg type="u" name="result" /> | ||||
| </signal> | ||||
| </interface> | ||||
| </node>`; | ||||
| const HelperDBusInterface = '<node> \ | ||||
| <interface name="org.gnome.Shell.PortalHelper"> \ | ||||
| <method name="Authenticate"> \ | ||||
|     <arg type="o" direction="in" name="connection" /> \ | ||||
|     <arg type="s" direction="in" name="url" /> \ | ||||
|     <arg type="u" direction="in" name="timestamp" /> \ | ||||
| </method> \ | ||||
| <method name="Close"> \ | ||||
|     <arg type="o" direction="in" name="connection" /> \ | ||||
| </method> \ | ||||
| <method name="Refresh"> \ | ||||
|     <arg type="o" direction="in" name="connection" /> \ | ||||
| </method> \ | ||||
| <signal name="Done"> \ | ||||
|     <arg type="o" name="connection" /> \ | ||||
|     <arg type="u" name="result" /> \ | ||||
| </signal> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| var PortalHeaderBar = new Lang.Class({ | ||||
|     Name: 'PortalHeaderBar', | ||||
|     Extends: Gtk.HeaderBar, | ||||
|  | ||||
|     _init() { | ||||
|     _init: function() { | ||||
|         this.parent({ show_close_button: true }); | ||||
|  | ||||
|         // See ephy-title-box.c in epiphany for the layout | ||||
| @@ -93,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(); | ||||
| @@ -120,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); | ||||
| @@ -147,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); | ||||
| @@ -164,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)); | ||||
| @@ -176,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 | ||||
| @@ -189,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) { | ||||
| @@ -203,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()); | ||||
| @@ -215,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()) { | ||||
| @@ -287,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 }); | ||||
| @@ -300,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]; | ||||
|  | ||||
| @@ -338,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]; | ||||
|  | ||||
| @@ -350,7 +349,7 @@ var WebPortalHelper = new Lang.Class({ | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     _processQueue() { | ||||
|     _processQueue: function() { | ||||
|         if (this._queue.length == 0) | ||||
|             return; | ||||
|  | ||||
| @@ -358,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])); | ||||
|         }); | ||||
|         })); | ||||
|     }, | ||||
| }); | ||||
|  | ||||
|   | ||||
| @@ -1,11 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <gresources> | ||||
|   <gresource prefix="/org/gnome/shell"> | ||||
|     <file>extensionPrefs/main.js</file> | ||||
|  | ||||
|     <file>misc/config.js</file> | ||||
|     <file>misc/extensionUtils.js</file> | ||||
|     <file>misc/fileUtils.js</file> | ||||
|     <file>misc/params.js</file> | ||||
|   </gresource> | ||||
| </gresources> | ||||
| @@ -10,29 +10,27 @@ const CheckBox = imports.ui.checkBox; | ||||
| const Dialog = imports.ui.dialog; | ||||
| const ModalDialog = imports.ui.modalDialog; | ||||
|  | ||||
| const RequestIface = ` | ||||
| <node> | ||||
| <interface name="org.freedesktop.impl.portal.Request"> | ||||
| <method name="Close"/> | ||||
| </interface> | ||||
| </node>`; | ||||
| const RequestIface = '<node> \ | ||||
| <interface name="org.freedesktop.impl.portal.Request"> \ | ||||
| <method name="Close"/> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| const AccessIface = ` | ||||
| <node> | ||||
| <interface name="org.freedesktop.impl.portal.Access"> | ||||
| <method name="AccessDialog"> | ||||
|   <arg type="o" name="handle" direction="in"/> | ||||
|   <arg type="s" name="app_id" direction="in"/> | ||||
|   <arg type="s" name="parent_window" direction="in"/> | ||||
|   <arg type="s" name="title" direction="in"/> | ||||
|   <arg type="s" name="subtitle" direction="in"/> | ||||
|   <arg type="s" name="body" direction="in"/> | ||||
|   <arg type="a{sv}" name="options" direction="in"/> | ||||
|   <arg type="u" name="response" direction="out"/> | ||||
|   <arg type="a{sv}" name="results" direction="out"/> | ||||
| </method> | ||||
| </interface> | ||||
| </node>`; | ||||
| const AccessIface = '<node> \ | ||||
| <interface name="org.freedesktop.impl.portal.Access"> \ | ||||
| <method name="AccessDialog"> \ | ||||
|   <arg type="o" name="handle" direction="in"/> \ | ||||
|   <arg type="s" name="app_id" direction="in"/> \ | ||||
|   <arg type="s" name="parent_window" direction="in"/> \ | ||||
|   <arg type="s" name="title" direction="in"/> \ | ||||
|   <arg type="s" name="subtitle" direction="in"/> \ | ||||
|   <arg type="s" name="body" direction="in"/> \ | ||||
|   <arg type="a{sv}" name="options" direction="in"/> \ | ||||
|   <arg type="u" name="response" direction="out"/> \ | ||||
|   <arg type="a{sv}" name="results" direction="out"/> \ | ||||
| </method> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| var DialogResponse = { | ||||
|     OK: 0, | ||||
| @@ -44,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; | ||||
| @@ -59,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"); | ||||
| @@ -99,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, | ||||
| @@ -117,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; | ||||
| @@ -142,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(); | ||||
| @@ -153,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); | ||||
|                                                            }) | ||||
|                                  }); | ||||
|     } | ||||
| }); | ||||
|   | ||||
| @@ -15,25 +15,24 @@ var AudioDevice = { | ||||
|     MICROPHONE: 1 << 2 | ||||
| }; | ||||
|  | ||||
| const AudioDeviceSelectionIface = ` | ||||
| <node> | ||||
| <interface name="org.gnome.Shell.AudioDeviceSelection"> | ||||
| <method name="Open"> | ||||
|     <arg name="devices" direction="in" type="as" /> | ||||
| </method> | ||||
| <method name="Close"> | ||||
| </method> | ||||
| <signal name="DeviceSelected"> | ||||
|     <arg name="device" type="s" /> | ||||
| </signal> | ||||
| </interface> | ||||
| </node>`; | ||||
| const AudioDeviceSelectionIface = '<node> \ | ||||
| <interface name="org.gnome.Shell.AudioDeviceSelection"> \ | ||||
| <method name="Open"> \ | ||||
|     <arg name="devices" direction="in" type="as" /> \ | ||||
| </method> \ | ||||
| <method name="Close"> \ | ||||
| </method> \ | ||||
| <signal name="DeviceSelected"> \ | ||||
|     <arg name="device" type="s" /> \ | ||||
| </signal> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| var AudioDeviceSelectionDialog = new Lang.Class({ | ||||
|     Name: 'AudioDeviceSelectionDialog', | ||||
|     Extends: ModalDialog.ModalDialog, | ||||
|  | ||||
|     _init(devices) { | ||||
|     _init: function(devices) { | ||||
|         this.parent({ styleClass: 'audio-device-selection-dialog' }); | ||||
|  | ||||
|         this._deviceItems = {}; | ||||
| @@ -51,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 }); | ||||
| @@ -66,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"); | ||||
| @@ -86,7 +85,7 @@ var AudioDeviceSelectionDialog = new Lang.Class({ | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     _getDeviceIcon(device) { | ||||
|     _getDeviceIcon: function(device) { | ||||
|         switch(device) { | ||||
|             case AudioDevice.HEADPHONES: | ||||
|                 return 'audio-headphones-symbolic'; | ||||
| @@ -99,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) }); | ||||
| @@ -122,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); | ||||
|  | ||||
| @@ -147,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); | ||||
| @@ -156,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, | ||||
| @@ -173,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; | ||||
| @@ -181,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 { | ||||
| @@ -192,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; | ||||
|   | ||||
| @@ -1,210 +0,0 @@ | ||||
| /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ | ||||
|  | ||||
| const Atk = imports.gi.Atk; | ||||
| const Cairo = imports.cairo; | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Lang = imports.lang; | ||||
| const St = imports.gi.St; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| var BarLevel = new Lang.Class({ | ||||
|     Name: "BarLevel", | ||||
|  | ||||
|     _init(value, params) { | ||||
|         if (isNaN(value)) | ||||
|             // Avoid spreading NaNs around | ||||
|             throw TypeError('The bar level value must be a number'); | ||||
|         this._maxValue = 1; | ||||
|         this._value = Math.max(Math.min(value, this._maxValue), 0); | ||||
|         this._overdriveStart = 1; | ||||
|         this._barLevelWidth = 0; | ||||
|  | ||||
|         if (params == undefined) | ||||
|             params = {} | ||||
|  | ||||
|         this.actor = new St.DrawingArea({ styleClass: params['styleClass'] || 'barlevel', | ||||
|                                           can_focus: params['canFocus'] || false, | ||||
|                                           reactive: params['reactive'] || false, | ||||
|                                           accessible_role: params['accessibleRole'] || Atk.Role.LEVEL_BAR }); | ||||
|         this.actor.connect('repaint', this._barLevelRepaint.bind(this)); | ||||
|         this.actor.connect('allocation-changed', (actor, box) => { | ||||
|             this._barLevelWidth = box.get_width(); | ||||
|         }); | ||||
|  | ||||
|         this._customAccessible = St.GenericAccessible.new_for_actor(this.actor); | ||||
|         this.actor.set_accessible(this._customAccessible); | ||||
|  | ||||
|         this._customAccessible.connect('get-current-value', this._getCurrentValue.bind(this)); | ||||
|         this._customAccessible.connect('get-minimum-value', this._getMinimumValue.bind(this)); | ||||
|         this._customAccessible.connect('get-maximum-value', this._getMaximumValue.bind(this)); | ||||
|         this._customAccessible.connect('set-current-value', this._setCurrentValue.bind(this)); | ||||
|  | ||||
|         this.connect('value-changed', this._valueChanged.bind(this)); | ||||
|     }, | ||||
|  | ||||
|     setValue(value) { | ||||
|         if (isNaN(value)) | ||||
|             throw TypeError('The bar level value must be a number'); | ||||
|  | ||||
|         this._value = Math.max(Math.min(value, this._maxValue), 0); | ||||
|         this.actor.queue_repaint(); | ||||
|     }, | ||||
|  | ||||
|     setMaximumValue(value) { | ||||
|         if (isNaN(value)) | ||||
|             throw TypeError('The bar level max value must be a number'); | ||||
|  | ||||
|         this._maxValue = Math.max(value, 1); | ||||
|         this._overdriveStart = Math.min(this._overdriveStart, this._maxValue); | ||||
|         this.actor.queue_repaint(); | ||||
|     }, | ||||
|  | ||||
|     setOverdriveStart(value) { | ||||
|         if (isNaN(value)) | ||||
|             throw TypeError('The overdrive limit value must be a number'); | ||||
|         if (value > this._maxValue) | ||||
|             throw new Error(`Tried to set overdrive value to ${value}, ` + | ||||
|                 `which is a number greater than the maximum allowed value ${this._maxValue}`); | ||||
|  | ||||
|         this._overdriveStart = value; | ||||
|         this._value = Math.max(Math.min(value, this._maxValue), 0); | ||||
|         this.actor.queue_repaint(); | ||||
|     }, | ||||
|  | ||||
|     _barLevelRepaint(area) { | ||||
|         let cr = area.get_context(); | ||||
|         let themeNode = area.get_theme_node(); | ||||
|         let [width, height] = area.get_surface_size(); | ||||
|  | ||||
|         let barLevelHeight = themeNode.get_length('-barlevel-height'); | ||||
|         let barLevelBorderRadius = Math.min(width, barLevelHeight) / 2; | ||||
|         let fgColor = themeNode.get_foreground_color(); | ||||
|  | ||||
|         let barLevelColor = themeNode.get_color('-barlevel-background-color'); | ||||
|         let barLevelActiveColor = themeNode.get_color('-barlevel-active-background-color'); | ||||
|         let barLevelOverdriveColor = themeNode.get_color('-barlevel-overdrive-color'); | ||||
|  | ||||
|         let barLevelBorderWidth = Math.min(themeNode.get_length('-barlevel-border-width'), 1); | ||||
|         let [hasBorderColor, barLevelBorderColor] = | ||||
|             themeNode.lookup_color('-barlevel-border-color', false); | ||||
|         if (!hasBorderColor) | ||||
|             barLevelBorderColor = barLevelColor; | ||||
|         let [hasActiveBorderColor, barLevelActiveBorderColor] = | ||||
|             themeNode.lookup_color('-barlevel-active-border-color', false); | ||||
|         if (!hasActiveBorderColor) | ||||
|             barLevelActiveBorderColor = barLevelActiveColor; | ||||
|         let [hasOverdriveBorderColor, barLevelOverdriveBorderColor] = | ||||
|             themeNode.lookup_color('-barlevel-overdrive-border-color', false); | ||||
|         if (!hasOverdriveBorderColor) | ||||
|             barLevelOverdriveBorderColor = barLevelOverdriveColor; | ||||
|  | ||||
|         const TAU = Math.PI * 2; | ||||
|  | ||||
|         let endX = 0; | ||||
|         if (this._maxValue > 0) | ||||
|             endX = barLevelBorderRadius + (width - 2 * barLevelBorderRadius) * this._value / this._maxValue; | ||||
|  | ||||
|         let overdriveSeparatorX = barLevelBorderRadius + (width - 2 * barLevelBorderRadius) * this._overdriveStart / this._maxValue; | ||||
|         let overdriveActive = this._overdriveStart !== this._maxValue; | ||||
|         let overdriveSeparatorWidth = 0; | ||||
|         if (overdriveActive) | ||||
|             overdriveSeparatorWidth = themeNode.get_length('-barlevel-overdrive-separator-width'); | ||||
|  | ||||
|         /* background bar */ | ||||
|         cr.arc(width - barLevelBorderRadius - barLevelBorderWidth, height / 2, barLevelBorderRadius, TAU * 3 / 4, TAU * 1 / 4); | ||||
|         cr.lineTo(endX, (height + barLevelHeight) / 2); | ||||
|         cr.lineTo(endX, (height - barLevelHeight) / 2); | ||||
|         cr.lineTo(width - barLevelBorderRadius - barLevelBorderWidth, (height - barLevelHeight) / 2); | ||||
|         Clutter.cairo_set_source_color(cr, barLevelColor); | ||||
|         cr.fillPreserve(); | ||||
|         Clutter.cairo_set_source_color(cr, barLevelBorderColor); | ||||
|         cr.setLineWidth(barLevelBorderWidth); | ||||
|         cr.stroke(); | ||||
|  | ||||
|         /* normal progress bar */ | ||||
|         let x = Math.min(endX, overdriveSeparatorX - overdriveSeparatorWidth / 2); | ||||
|         cr.arc(barLevelBorderRadius + barLevelBorderWidth, height / 2, barLevelBorderRadius, TAU * 1 / 4, TAU * 3 / 4); | ||||
|         cr.lineTo(x, (height - barLevelHeight) / 2); | ||||
|         cr.lineTo(x, (height + barLevelHeight) / 2); | ||||
|         cr.lineTo(barLevelBorderRadius + barLevelBorderWidth, (height + barLevelHeight) / 2); | ||||
|         Clutter.cairo_set_source_color(cr, barLevelActiveColor); | ||||
|         cr.fillPreserve(); | ||||
|         Clutter.cairo_set_source_color(cr, barLevelActiveBorderColor); | ||||
|         cr.setLineWidth(barLevelBorderWidth); | ||||
|         cr.stroke(); | ||||
|  | ||||
|         /* overdrive progress barLevel */ | ||||
|         x = Math.min(endX, overdriveSeparatorX) + overdriveSeparatorWidth / 2; | ||||
|         if (this._value > this._overdriveStart) { | ||||
|             cr.moveTo(x, (height - barLevelHeight) / 2); | ||||
|             cr.lineTo(endX, (height - barLevelHeight) / 2); | ||||
|             cr.lineTo(endX, (height + barLevelHeight) / 2); | ||||
|             cr.lineTo(x, (height + barLevelHeight) / 2); | ||||
|             cr.lineTo(x, (height - barLevelHeight) / 2); | ||||
|             Clutter.cairo_set_source_color(cr, barLevelOverdriveColor); | ||||
|             cr.fillPreserve(); | ||||
|             Clutter.cairo_set_source_color(cr, barLevelOverdriveBorderColor); | ||||
|             cr.setLineWidth(barLevelBorderWidth); | ||||
|             cr.stroke(); | ||||
|         } | ||||
|  | ||||
|         /* end progress bar arc */ | ||||
|         if (this._value <= this._overdriveStart) | ||||
|             Clutter.cairo_set_source_color(cr, barLevelActiveColor); | ||||
|         else | ||||
|             Clutter.cairo_set_source_color(cr, barLevelOverdriveColor); | ||||
|         cr.arc(endX, height / 2, barLevelBorderRadius, TAU * 3 / 4, TAU * 1 / 4); | ||||
|         cr.lineTo(Math.floor(endX), (height + barLevelHeight) / 2); | ||||
|         cr.lineTo(Math.floor(endX), (height - barLevelHeight) / 2); | ||||
|         cr.lineTo(endX, (height - barLevelHeight) / 2); | ||||
|         cr.fillPreserve(); | ||||
|         cr.setLineWidth(barLevelBorderWidth); | ||||
|         cr.stroke(); | ||||
|  | ||||
|         /* draw overdrive separator */ | ||||
|         if (overdriveActive) { | ||||
|             cr.moveTo(overdriveSeparatorX - overdriveSeparatorWidth / 2, (height - barLevelHeight) / 2); | ||||
|             cr.lineTo(overdriveSeparatorX + overdriveSeparatorWidth / 2, (height - barLevelHeight) / 2); | ||||
|             cr.lineTo(overdriveSeparatorX + overdriveSeparatorWidth / 2, (height + barLevelHeight) / 2); | ||||
|             cr.lineTo(overdriveSeparatorX - overdriveSeparatorWidth / 2, (height + barLevelHeight) / 2); | ||||
|             cr.lineTo(overdriveSeparatorX - overdriveSeparatorWidth / 2, (height - barLevelHeight) / 2); | ||||
|             if (this._value <= this._overdriveStart) | ||||
|                 Clutter.cairo_set_source_color(cr, fgColor); | ||||
|             else | ||||
|                 Clutter.cairo_set_source_color(cr, barLevelColor); | ||||
|             cr.fill(); | ||||
|         } | ||||
|  | ||||
|         cr.$dispose(); | ||||
|     }, | ||||
|  | ||||
|     _getCurrentValue(actor) { | ||||
|         return this._value; | ||||
|     }, | ||||
|  | ||||
|     _getOverdriveStart(actor) { | ||||
|         return this._overdriveStart; | ||||
|     }, | ||||
|  | ||||
|     _getMinimumValue(actor) { | ||||
|         return 0; | ||||
|     }, | ||||
|  | ||||
|     _getMaximumValue(actor) { | ||||
|         return this._maxValue; | ||||
|     }, | ||||
|  | ||||
|     _setCurrentValue(actor, value) { | ||||
|         this._value = value; | ||||
|     }, | ||||
|  | ||||
|     _valueChanged(barLevel, value, property) { | ||||
|         this._customAccessible.notify("accessible-value"); | ||||
|     }, | ||||
|  | ||||
|     get value() { | ||||
|         return this._value; | ||||
|     } | ||||
| }); | ||||
|  | ||||
| Signals.addSignalMethods(BarLevel.prototype); | ||||
| @@ -35,7 +35,7 @@ var POPUP_ANIMATION_TIME = 0.15; | ||||
| var BoxPointer = new Lang.Class({ | ||||
|     Name: 'BoxPointer', | ||||
|  | ||||
|     _init(arrowSide, binProperties) { | ||||
|     _init: function(arrowSide, binProperties) { | ||||
|         this._arrowSide = arrowSide; | ||||
|         this._userArrowSide = arrowSide; | ||||
|         this._arrowOrigin = 0; | ||||
| @@ -44,14 +44,13 @@ var BoxPointer = new Lang.Class({ | ||||
|                                   y_fill: true }); | ||||
|         this._container = new Shell.GenericContainer(); | ||||
|         this.actor.set_child(this._container); | ||||
|         this.actor.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS); | ||||
|         this._container.connect('get-preferred-width', this._getPreferredWidth.bind(this)); | ||||
|         this._container.connect('get-preferred-height', this._getPreferredHeight.bind(this)); | ||||
|         this._container.connect('allocate', this._allocate.bind(this)); | ||||
|         this._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; | ||||
| @@ -67,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; | ||||
| @@ -113,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; | ||||
|  | ||||
| @@ -157,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; | ||||
| @@ -181,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); | ||||
| @@ -197,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'); | ||||
| @@ -237,7 +236,7 @@ var BoxPointer = new Lang.Class({ | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     _drawBorder(area) { | ||||
|     _drawBorder: function(area) { | ||||
|         let themeNode = this.actor.get_theme_node(); | ||||
|  | ||||
|         if (this._arrowActor) { | ||||
| @@ -419,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(); | ||||
| @@ -431,7 +430,7 @@ var BoxPointer = new Lang.Class({ | ||||
|         this._updateFlip(); | ||||
|     }, | ||||
|  | ||||
|     setSourceAlignment(alignment) { | ||||
|     setSourceAlignment: function(alignment) { | ||||
|         this._sourceAlignment = alignment; | ||||
|  | ||||
|         if (!this._sourceActor) | ||||
| @@ -440,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; | ||||
|  | ||||
| @@ -557,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(); | ||||
| @@ -567,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 | ||||
| @@ -585,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; | ||||
| @@ -619,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'); | ||||
|         } | ||||
| @@ -659,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,45 +108,44 @@ 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; | ||||
|     } | ||||
| }); | ||||
| Signals.addSignalMethods(EmptyEventSource.prototype); | ||||
|  | ||||
| const CalendarServerIface = ` | ||||
| <node> | ||||
| <interface name="org.gnome.Shell.CalendarServer"> | ||||
| <method name="GetEvents"> | ||||
|     <arg type="x" direction="in" /> | ||||
|     <arg type="x" direction="in" /> | ||||
|     <arg type="b" direction="in" /> | ||||
|     <arg type="a(sssbxxa{sv})" direction="out" /> | ||||
| </method> | ||||
| <property name="HasCalendars" type="b" access="read" /> | ||||
| <signal name="Changed" /> | ||||
| </interface> | ||||
| </node>`; | ||||
| const CalendarServerIface = '<node> \ | ||||
| <interface name="org.gnome.Shell.CalendarServer"> \ | ||||
| <method name="GetEvents"> \ | ||||
|     <arg type="x" direction="in" /> \ | ||||
|     <arg type="x" direction="in" /> \ | ||||
|     <arg type="b" direction="in" /> \ | ||||
|     <arg type="a(sssbxxa{sv})" direction="out" /> \ | ||||
| </method> \ | ||||
| <property name="HasCalendars" type="b" access="read" /> \ | ||||
| <signal name="Changed" /> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| const CalendarServerInfo  = Gio.DBusInterfaceInfo.new_for_xml(CalendarServerIface); | ||||
|  | ||||
| @@ -180,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; | ||||
| @@ -189,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 { | ||||
| @@ -216,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(); | ||||
|     }, | ||||
|  | ||||
| @@ -248,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) { | ||||
| @@ -283,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; | ||||
| @@ -291,7 +293,7 @@ var DBusEventSource = new Lang.Class({ | ||||
|         this.emit('changed'); | ||||
|     }, | ||||
|  | ||||
|     _loadEvents(forceReload) { | ||||
|     _loadEvents: function(forceReload) { | ||||
|         // Ignore while loading | ||||
|         if (!this._initialized) | ||||
|             return; | ||||
| @@ -300,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; | ||||
|  | ||||
| @@ -315,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; | ||||
| @@ -326,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]; | ||||
| @@ -338,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; | ||||
| @@ -347,7 +349,7 @@ var DBusEventSource = new Lang.Class({ | ||||
|         return result; | ||||
|     }, | ||||
|  | ||||
|     hasEvents(day) { | ||||
|     hasEvents: function(day) { | ||||
|         let dayBegin = _getBeginningOfDay(day); | ||||
|         let dayEnd = _getEndOfDay(day); | ||||
|  | ||||
| @@ -364,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); | ||||
|  | ||||
|         /** | ||||
| @@ -399,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; | ||||
|  | ||||
| @@ -426,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(); | ||||
| @@ -447,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 }); | ||||
| @@ -457,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... | ||||
|         // | ||||
| @@ -488,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: | ||||
| @@ -502,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) { | ||||
| @@ -526,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) { | ||||
| @@ -550,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 | ||||
| @@ -615,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'; | ||||
| @@ -678,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)) | ||||
| @@ -689,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) | ||||
| @@ -697,7 +699,7 @@ var Calendar = new Lang.Class({ | ||||
|             } | ||||
|             else | ||||
|                 button.remove_style_pseudo_class('selected'); | ||||
|         }); | ||||
|         })); | ||||
|     } | ||||
| }); | ||||
| Signals.addSignalMethods(Calendar.prototype); | ||||
| @@ -706,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; | ||||
|  | ||||
| @@ -721,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 && | ||||
| @@ -754,7 +756,7 @@ var EventMessage = new Lang.Class({ | ||||
|         return title; | ||||
|     }, | ||||
|  | ||||
|     canClose() { | ||||
|     canClose: function() { | ||||
|         return isToday(this._date); | ||||
|     } | ||||
| }); | ||||
| @@ -763,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); | ||||
| @@ -771,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 }); | ||||
| @@ -791,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; | ||||
| @@ -817,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', | ||||
| @@ -832,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) | ||||
| @@ -872,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; | ||||
| @@ -930,7 +920,7 @@ var EventsSection = new Lang.Class({ | ||||
|         return this._calendarApp; | ||||
|     }, | ||||
|  | ||||
|     _onTitleClicked() { | ||||
|     _onTitleClicked: function() { | ||||
|         Main.overview.hide(); | ||||
|         Main.panel.closeCalendar(); | ||||
|  | ||||
| @@ -940,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; | ||||
|  | ||||
| @@ -962,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() { | ||||
| @@ -981,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 }); | ||||
| @@ -992,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 | ||||
| @@ -1038,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; | ||||
|  | ||||
| @@ -1054,7 +1046,7 @@ var NotificationSection = new Lang.Class({ | ||||
|                 message.notification.acknowledged = true; | ||||
|     }, | ||||
|  | ||||
|     _shouldShow() { | ||||
|     _shouldShow: function() { | ||||
|         return !this.empty && isToday(this._date); | ||||
|     } | ||||
| }); | ||||
| @@ -1062,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 }); | ||||
|  | ||||
| @@ -1082,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; | ||||
| @@ -1109,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 }); | ||||
| @@ -1154,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, | ||||
| @@ -1165,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); | ||||
| @@ -1195,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; | ||||
|         }); | ||||
|   | ||||
| @@ -74,15 +74,14 @@ function startAppForMount(app, mount) { | ||||
|  | ||||
| /******************************************/ | ||||
|  | ||||
| const HotplugSnifferIface = ` | ||||
| <node> | ||||
| <interface name="org.gnome.Shell.HotplugSniffer"> | ||||
| <method name="SniffURI"> | ||||
|     <arg type="s" direction="in" /> | ||||
|     <arg type="as" direction="out" /> | ||||
| </method> | ||||
| </interface> | ||||
| </node>`; | ||||
| const HotplugSnifferIface = '<node> \ | ||||
| <interface name="org.gnome.Shell.HotplugSniffer"> \ | ||||
| <method name="SniffURI"> \ | ||||
|     <arg type="s" direction="in" /> \ | ||||
|     <arg type="as" direction="out" /> \ | ||||
| </method> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
| const HotplugSnifferProxy = Gio.DBusProxy.makeProxyWrapper(HotplugSnifferIface); | ||||
| function HotplugSniffer() { | ||||
| @@ -94,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 { | ||||
| @@ -129,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) | ||||
| @@ -162,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); | ||||
|     } | ||||
| }); | ||||
| @@ -199,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; | ||||
| @@ -221,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 | ||||
| @@ -233,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)) | ||||
| @@ -243,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; | ||||
| @@ -281,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 | ||||
| @@ -297,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; | ||||
| @@ -311,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'); | ||||
|     } | ||||
| }); | ||||
| @@ -324,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' }); | ||||
| @@ -363,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; | ||||
| @@ -506,12 +506,8 @@ var VPNRequestHandler = new Lang.Class({ | ||||
|         try { | ||||
|             data = this._dataStdout.peek_buffer(); | ||||
|  | ||||
|             if (data instanceof Uint8Array) | ||||
|                 data = imports.byteArray.toGBytes(data); | ||||
|             else | ||||
|                 data = data.toGBytes(); | ||||
|  | ||||
|             keyfile.load_from_bytes(data, GLib.KeyFileFlags.NONE); | ||||
|             keyfile.load_from_data(data.toString(), data.length, | ||||
|                                    GLib.KeyFileFlags.NONE); | ||||
|  | ||||
|             if (keyfile.get_integer(VPN_UI_GROUP, 'Version') != 2) | ||||
|                 throw new Error('Invalid plugin keyfile version, is %d'); | ||||
| @@ -562,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'); | ||||
| @@ -588,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 | ||||
| @@ -606,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) | ||||
| @@ -649,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'); | ||||
|  | ||||
| @@ -664,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; | ||||
| @@ -697,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(); | ||||
| @@ -745,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; | ||||
|  | ||||
| @@ -761,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 }); | ||||
|  | ||||
|   | ||||
							
								
								
									
										199
									
								
								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; | ||||
| @@ -402,7 +403,6 @@ var Dash = new Lang.Class({ | ||||
|                                        clip_to_allocation: true }); | ||||
|         this._box._delegate = this; | ||||
|         this._container.add_actor(this._box); | ||||
|         this._container.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS); | ||||
|  | ||||
|         this._showAppsIcon = new ShowAppsIcon(); | ||||
|         this._showAppsIcon.childScale = 1; | ||||
| @@ -415,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); | ||||
|  | ||||
| @@ -458,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; | ||||
| @@ -496,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); | ||||
| @@ -561,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) { | ||||
| @@ -574,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); | ||||
| @@ -600,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 && | ||||
| @@ -654,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++) { | ||||
| @@ -700,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 = []; | ||||
|  | ||||
| @@ -777,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); | ||||
| @@ -829,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 | ||||
| @@ -926,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 | ||||
| @@ -962,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, | ||||
| @@ -40,7 +40,6 @@ var Dialog = new Lang.Class({ | ||||
|         // mode accordingly so wrapped labels are handled correctly during | ||||
|         // size requests. | ||||
|         this._dialog.request_mode = Clutter.RequestMode.HEIGHT_FOR_WIDTH; | ||||
|         this._dialog.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS); | ||||
|  | ||||
|         this.contentLayout = new St.BoxLayout({ vertical: true, | ||||
|                                                 style_class: "modal-dialog-content-box" }); | ||||
| @@ -57,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) { | ||||
| @@ -89,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); | ||||
|  | ||||
| @@ -105,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; | ||||
| @@ -146,7 +145,7 @@ var Dialog = new Lang.Class({ | ||||
|         return button; | ||||
|     }, | ||||
|  | ||||
|     clearButtons() { | ||||
|     clearButtons: function () { | ||||
|         this.buttonLayout.destroy_all_children(); | ||||
|         this._buttonKeys = {}; | ||||
|     }, | ||||
| @@ -174,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(); | ||||
| @@ -244,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); | ||||
|   | ||||