Compare commits
	
		
			12 Commits
		
	
	
		
			3.19.3
			...
			wip/notif-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 672a4a56bd | ||
|   | 50421ede37 | ||
|   | 826a7fa02a | ||
|   | d7844bc7f4 | ||
|   | 485444a451 | ||
|   | e5318d5235 | ||
|   | e6e15489aa | ||
|   | 0951d36e8f | ||
|   | c38939902f | ||
|   | 97974a3f2a | ||
|   | 8b6cab741d | ||
|   | 2aad0eac31 | 
							
								
								
									
										13
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -17,20 +17,17 @@ config.status | |||||||
| config | config | ||||||
| configure | configure | ||||||
| data/50-gnome-shell-*.xml | data/50-gnome-shell-*.xml | ||||||
| data/org.gnome.Shell.desktop | data/gnome-shell.desktop | ||||||
| data/org.gnome.Shell.desktop.in | data/gnome-shell.desktop.in | ||||||
|  | data/gnome-shell-wayland.desktop | ||||||
|  | data/gnome-shell-wayland.desktop.in | ||||||
| data/gnome-shell-extension-prefs.desktop | data/gnome-shell-extension-prefs.desktop | ||||||
| data/gnome-shell-extension-prefs.desktop.in | data/gnome-shell-extension-prefs.desktop.in | ||||||
| data/gnome-shell-theme.gresource |  | ||||||
| data/gschemas.compiled | data/gschemas.compiled | ||||||
| data/perf-background.xml |  | ||||||
| data/org.gnome.shell.gschema.xml | data/org.gnome.shell.gschema.xml | ||||||
| data/org.gnome.shell.gschema.valid | data/org.gnome.shell.gschema.valid | ||||||
| data/org.gnome.shell.evolution.calendar.gschema.xml | data/org.gnome.shell.evolution.calendar.gschema.xml | ||||||
| data/org.gnome.shell.evolution.calendar.gschema.valid | data/org.gnome.shell.evolution.calendar.gschema.valid | ||||||
| data/org.gnome.Shell.PortalHelper.desktop |  | ||||||
| data/org.gnome.Shell.PortalHelper.service |  | ||||||
| data/theme/.sass-cache |  | ||||||
| docs/reference/*/*.args | docs/reference/*/*.args | ||||||
| docs/reference/*/*.bak | docs/reference/*/*.bak | ||||||
| docs/reference/*/*.hierarchy | docs/reference/*/*.hierarchy | ||||||
| @@ -83,9 +80,7 @@ src/gnome-shell-extension-tool | |||||||
| src/gnome-shell-hotplug-sniffer | src/gnome-shell-hotplug-sniffer | ||||||
| src/gnome-shell-perf-helper | src/gnome-shell-perf-helper | ||||||
| src/gnome-shell-perf-tool | src/gnome-shell-perf-tool | ||||||
| src/gnome-shell-portal-helper |  | ||||||
| src/hotplug-sniffer/org.gnome.Shell.HotplugSniffer.service | src/hotplug-sniffer/org.gnome.Shell.HotplugSniffer.service | ||||||
| src/org-gtk-application.[ch] |  | ||||||
| src/run-js-test | src/run-js-test | ||||||
| src/test-recorder | src/test-recorder | ||||||
| src/test-recorder.ogg | src/test-recorder.ogg | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,6 +1,3 @@ | |||||||
| [submodule "src/gvc"] | [submodule "src/gvc"] | ||||||
| 	path = src/gvc | 	path = src/gvc | ||||||
| 	url = git://git.gnome.org/libgnome-volume-control | 	url = git://git.gnome.org/libgnome-volume-control | ||||||
| [submodule "data/theme/gnome-shell-sass"] |  | ||||||
| 	path = data/theme/gnome-shell-sass |  | ||||||
| 	url = git://git.gnome.org/gnome-shell-sass |  | ||||||
|   | |||||||
							
								
								
									
										607
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						| @@ -1,610 +1,3 @@ | |||||||
| 3.19.3 |  | ||||||
| ====== |  | ||||||
| * Fix thumbnail scaling in window switcher on HiDPI [Florian; #758676] |  | ||||||
| * Update animated backgrounds on timezone changes [Florian; #758939] |  | ||||||
| * loginDialog: Update user list on user changes [Michael; #758568] |  | ||||||
| * Fix touch interaction on wayland [Carlos; #756748] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Michael Catanzaro, Carlos Garnacho, Kalev Lember, Florian Müllner |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Daniel Korostil [uk], Muhammet Kara [tr], Dušan Kazik [sk], |  | ||||||
|   Baurzhan Muftakhidinov [kk], Marek Černocký [cs] |  | ||||||
|  |  | ||||||
| 3.19.2 |  | ||||||
| ====== |  | ||||||
| * Make gnome-shell DBus activatable [Ray; #741666] |  | ||||||
| * Fix browser plugin crash in Firefox [Carlos; #737932, #757940] |  | ||||||
| * Optionally show battery percentage in system status area [Bastien; #735771] |  | ||||||
| * Misc. bug fixes [Kalev, Florian, Bastien; #757418, #757668, #757779, #757816, |  | ||||||
|   #745626, #758220] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Michael Biebl, Michael Catanzaro, Piotr Drąg, Carlos Garcia Campos, |  | ||||||
|   Kalev Lember, Florian Müllner, Bastien Nocera, Ray Strode |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Pedro Albuquerque [pt], liushuyu [zh_CN], Yosef Or Boczko [he], |  | ||||||
|   Jiri Grönroos [fi], Kjartan Maraas [nb], GNOME Translation Robot [gd], |  | ||||||
|   Daniel Mustieles [es], Marek Černocký [cs], Kristjan SCHMIDT [eo], |  | ||||||
|   Stas Solovey [ru] |  | ||||||
|  |  | ||||||
| 3.19.1 |  | ||||||
| ====== |  | ||||||
| * Respect text-scaling factor under wayland [Owen; #756447] |  | ||||||
| * Show the Bluetooth submenu when there were setup devices [Bastien; #723848] |  | ||||||
| * Misc. bug fixes [Florian, Cosimo, Rui, Ray, Owen, Jakub, Bastien; |  | ||||||
|   #756697, #756714, #756605, #754814, #738942, #756983, #756925, |  | ||||||
|   #757011, #673235, #757150] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Cosimo Cecchi, Rui Matos, Florian Müllner, Bastien Nocera, Jakub Steiner, |  | ||||||
|   Ray Strode, Owen W. Taylor |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Kjartan Maraas [nb], Khaled Hosny [ar], Balázs Meskó [hu], |  | ||||||
|   Daniel Șerbănescu [ro], Marek Černocký [cs] |  | ||||||
|  |  | ||||||
| 3.18.1 |  | ||||||
| ====== |  | ||||||
| * Fix screen freezes when a notification is pushed [Carlos; #755425] |  | ||||||
| * Fix overzealous ellipsization in system status menu [Adel, Florian; #708472] |  | ||||||
| * Hide app menu when disabled by setting [Florian; #745919] |  | ||||||
| * Fix lightbox effect when animations are disabled [Rui; #755827] |  | ||||||
| * Do not mark hotplug notifications as critical [Florian; #657923] |  | ||||||
| * Fix icons getting cut off in dash [Florian; #745649] |  | ||||||
| * Animate fullscreen/unfullscreen operations [Cosimo; #707248] |  | ||||||
| * Misc. bug fixes [Florian, Owen; #748919, #674799, #754581] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Emmanuele Bassi, Michael Catanzaro, Cosimo Cecchi, Matthias Clasen, |  | ||||||
|   Adel Gadllah, Carlos Garnacho, Ekaterina Gerasimova, Rui Matos, |  | ||||||
|   Florian Müllner, Owen W. Taylor |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Марко Костић [sr], Милош Поповић [sr@latin], Khaled Hosny [ar], |  | ||||||
|   Trần Ngọc Quân [vi], Petr Kovar [cs], Alexandre Franke [fr], |  | ||||||
|   Fran Dieguez [gl], Anders Jonsson [sv], Piotr Drąg [pl], Dušan Kazik [sk], |  | ||||||
|   Milo Casagrande [it], Changwoo Ryu [ko], Stas Solovey [ru], |  | ||||||
|   Rafael Fontenelle [pt_BR], Tom Tryfonidis [el], Aurimas Černius [lt], |  | ||||||
|   Seán de Búrca [ga], Christian Kirbach [de], Jiri Grönroos [fi], |  | ||||||
|   Pedro Albuquerque [pt], Baurzhan Muftakhidinov [kk], Daniel Mustieles [es], |  | ||||||
|   Marek Černocký [cs], Ask Hjorth Larsen [da], Inaki Larranaga Murgoitio [eu] |  | ||||||
|  |  | ||||||
| 3.18.0 |  | ||||||
| ====== |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Sendy Aditya Suryana [id], Kris Thomsen [da], Seán de Búrca [ga], |  | ||||||
|   Andika Triwidada [id], Enrico Nicoletto [pt_BR], Anders Jonsson [sv], |  | ||||||
|   Rūdolfs Mazurs [lv] |  | ||||||
|  |  | ||||||
| 3.17.92 |  | ||||||
| ======= |  | ||||||
| * Fix race when loading multiple background animations [Josselin; #741453] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Michael Biebl, Josselin Mouette, Florian Müllner |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Baurzhan Muftakhidinov [kk], Changwoo Ryu [ko], Christian Kirbach [de], |  | ||||||
|   Kjartan Maraas [nb], Jiri Grönroos [fi], Arash Mousavi [fa], |  | ||||||
|   Jiro Matsuzawa [ja], Marek Černocký [cs], Milo Casagrande [it] |  | ||||||
|  |  | ||||||
| 3.17.91 |  | ||||||
| ======= |  | ||||||
| * Fix login screen spinner causing wakeups while VT-switched away |  | ||||||
|   [Ray, Rui; #753891] |  | ||||||
| * Fix scrolling of user list on login screen [Florian; #754525] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Piotr Drąg, Rui Matos, Florian Müllner, Ray Strode |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Dušan Kazik [sk], Jordi Mas [ca], Aurimas Černius [lt], Stas Solovey [ru], |  | ||||||
|   Piotr Drąg [pl], Pedro Albuquerque [pt], Daniel Mustieles [es], |  | ||||||
|   Chao-Hsiung Liao [zh_TW], Muhammet Kara [tr], Fran Dieguez [gl], |  | ||||||
|   Hannie Dumoleyn [nl], Yosef Or Boczko [he], Tom Tryfonidis [el], |  | ||||||
|   A S Alam [pa], Balázs Úr [hu], Alexandre Franke [fr], Frédéric Péters [fr] |  | ||||||
|  |  | ||||||
| 3.17.90 |  | ||||||
| ======= |  | ||||||
| * Avoid caret/focus viewport changes during pointer movement [Rui; #752138] |  | ||||||
| * Match GTK+'s modal dialogs for system modal dialogs [Carlos; #746108] |  | ||||||
| * Refine message list style [Florian; #749958] |  | ||||||
| * Fix type-ahead behavior for backspace and compose key [Rui; #753319, #753320] |  | ||||||
| * Refine the system status menu [Florian; #751377] |  | ||||||
| * Misc. bug fixes and cleanups [Bastien, Ray, Florian, Jakub; #752779, #752739, |  | ||||||
|   #741366, #651503, #753064, #753181, #752881] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Rui Matos, Florian Müllner, Bastien Nocera, Carlos Soriano, Jakub Steiner, |  | ||||||
|   Ray Strode, Rico Tzschichholz |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Marek Černocký [cs], Kjartan Maraas [nb], Jordi Mas [ca], Muhammet Kara [tr], |  | ||||||
|   Enrico Nicoletto [pt_BR] |  | ||||||
|  |  | ||||||
| 3.17.4 |  | ||||||
| ====== |  | ||||||
| * Fix fuzziness of app menu icon [Jakub; #747932] |  | ||||||
| * Implement 4 finger swipe gesture for touchpads [Carlos; #752250] |  | ||||||
| * Misc. bug fixes [Florian, Alexandre, Piotr, Ray, Mario; #751921, #659969, |  | ||||||
|   #752438, #752675] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Piotr Drąg, Alexandre Franke, Carlos Garnacho, Florian Müllner, |  | ||||||
|   Mario Sanchez Prada, Jakub Steiner, Jasper St. Pierre, Ray Strode |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Benjamin Steinwender [de], Pedro Albuquerque [pt], Fabio Tomat [fur], |  | ||||||
|   Matej Urbančič [sl], Daniel Mustieles [es], Yosef Or Boczko [he], |  | ||||||
|   Daniel Martinez [an] |  | ||||||
|  |  | ||||||
| 3.17.3 |  | ||||||
| ====== |  | ||||||
| * Handle touch events in OSK on wayland [Rui; #750287] |  | ||||||
| * Reinstate left/right movement to window menu [Ron; #751344] |  | ||||||
| * Allow extensions to disable "Window is ready" notification [Adel; #748846] |  | ||||||
| * Misc. bug fixes [Watson, Michael, Ray, Rui, Florian, Cosimo; #750465, |  | ||||||
|   #751016, #751517, #750714, #751541, #751599] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Michael Biebl, Cosimo Cecchi, Adel Gadllah, Rui Matos, Florian Müllner, |  | ||||||
|   Ray Strode, Wim Taymans, Ron Yorston, Watson Yuuma Sato |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Sebastian Rasmussen [sv], Dimitris Spingos [el], Muhammet Kara [tr], |  | ||||||
|   Stas Solovey [ru], Benjamin Steinwender [de], Balázs Úr [hu], |  | ||||||
|   Victor Ibragimov [tg], Dušan Kazik [sk], Pedro Albuquerque [pt] |  | ||||||
|  |  | ||||||
| 3.17.2 |  | ||||||
| ====== |  | ||||||
| * Remove StTable widget [Florian; #703833] |  | ||||||
| * Increase visibility of expanders in alt-tab popup [Jakub; #745058] |  | ||||||
| * Ensure suspend inhibitors are released when VT switched away [Rui; #749228] |  | ||||||
| * Use iio-sensor-proxy directly for orientation lock [Bastien; #749671] |  | ||||||
| * Misc. bug fixes [Florian, Lan, Carlos; #749279, #749383, #749529, #749490, |  | ||||||
|   #749742] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Carlos Garnacho, Ting-Wei Lan, Rui Matos, Florian Müllner, Bastien Nocera, |  | ||||||
|   Jakub Steiner |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Yosef Or Boczko [he], sun [zh_CN], Felipe Braga [pt_BR], |  | ||||||
|   Victor Ibragimov [tg], Gábor Kelemen [hu], Cédric Valmary [oc], |  | ||||||
|   Dušan Kazik [sk], Kjartan Maraas [nb], Bruno Ramalhete [pt], |  | ||||||
|   Matej Urbančič [sl], Daniel Mustieles [es] |  | ||||||
|  |  | ||||||
| 3.17.1 |  | ||||||
| ====== |  | ||||||
| * Add Display Settings entry to background menu [Meet; #697346] |  | ||||||
| * Add window menu option to move to different monitor [Isaac; #633994] |  | ||||||
| * Improve switch style in default/highContrast themes [Jakub; #746294, #747912] |  | ||||||
| * Make event highlight in calendar more prominent [Jakub; #747715] |  | ||||||
| * Fix keyboard focus when focusing a notification banner [Florian; #747205] |  | ||||||
| * Move notification banners below the dateMenu [Meet, Florian; #745910] |  | ||||||
| * Misc. bug fixes [Mario, Rui; #748338, #748541] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Isaac Ge, Rui Matos, Florian Müllner, Meet Parikh, Mario Sanchez Prada, |  | ||||||
|   Jakub Steiner, Jasper St. Pierre |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Sveinn í Felli [is], Marek Černocký [cs], laurent Soleil [oc] |  | ||||||
|  |  | ||||||
| 3.16.1 |  | ||||||
| ====== |  | ||||||
| * gdm: Move long session chooser menus to the side [Florian; #734352] |  | ||||||
| * Work around background corruption with NVIDIA driver [Rui; #739178] |  | ||||||
| * Don't allow move-to-workspace for always-sticky windows [Florian; #746782] |  | ||||||
| * Allow switching workspaces with PgUp/PgDown in overview [Devyani; #742581] |  | ||||||
| * Bump time PAM messages are displayed [Sarvjeet; #720885] |  | ||||||
| * Fix "stutter" when moving window past the last workspace [Shivam; #712778] |  | ||||||
| * Fix blurred text on login screen [Clément; #746912] |  | ||||||
| * keyboard: Restore whole MRU list after password mode [Rui; #746605] |  | ||||||
| * Pass event timestamps when activating remote actions [Owen; #747323] |  | ||||||
| * Fix hung login screen when password is typed too quickly [Shivam; #737586] |  | ||||||
| * Make on-screen keyboard work for shell chrome on wayland [Rui; #747274] |  | ||||||
| * Implement reexec_self() for FreeBSD [Ting-Wei; #747788] |  | ||||||
| * Allow to dismiss resident notifications [Florian; #746860] |  | ||||||
| * Temporarily reveal legacy tray when icons are added [Florian; #746025] |  | ||||||
| * Make concealed tray smaller to minimize overlap with apps [Florian; #746787] |  | ||||||
| * Misc. bug fixes [Florian, Rui, Giovanni; #746323, #746579, #746902, #746364, |  | ||||||
|   #746509, #747636] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Sarvjeet, Giovanni Campagna, Adel Gadllah, Clément Guérin, Devyani Kota, |  | ||||||
|   Ting-Wei Lan, Rui Matos, Shivam Mishra, Florian Müllner, Owen W. Taylor |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Khaled Hosny [ar], Dušan Kazik [sk], Yuri Myasoedov [ru], Stas Solovey [ru], |  | ||||||
|   Hannie Dumoleyn [nl], Rūdolfs Mazurs [lv] |  | ||||||
|  |  | ||||||
| 3.16.0 |  | ||||||
| ====== |  | ||||||
| * Revert erroneous login dialog changes [Ray; #740142] |  | ||||||
| * Improve accessibility of legacy tray [Florian; #746487] |  | ||||||
| * Fix legacy status icons leaking into other monitors [Florian; #745824] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Florian Müllner, Ray Strode |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Daniel Martinez [an], Sebastian Rasmussen [sv], Fran Dieguez [gl], |  | ||||||
|   Andika Triwidada [id], Jordi Mas [ca], Kjartan Maraas [nb], |  | ||||||
|   Inaki Larranaga Murgoitio [eu], Muhammet Kara [tr], Khaled Hosny [ar], |  | ||||||
|   Bernd Homuth [de], Jiro Matsuzawa [ja] |  | ||||||
|  |  | ||||||
| 3.15.92 |  | ||||||
| ======= |  | ||||||
| * gdm: Fix user list accessibility [Florian; #729603] |  | ||||||
| * Handle multiline questions in mount operations [Ross; #745713] |  | ||||||
| * Improve classic theme [Jakub; #745686, #745687] |  | ||||||
| * Fix ordering of calendar events [Florian; #745988] |  | ||||||
| * Pick first input source for new windows when per-window [Rui; #746037] |  | ||||||
| * networkAgent: Show a notification for non-user-initiated password requests |  | ||||||
|   [Giovanni; #660293] |  | ||||||
| * Fix dismissing calendar events [Florian; #744927] |  | ||||||
| * Add legacy tray to ctrl-alt-tab popup [Florian; #746022] |  | ||||||
| * Manage on-screen-keyboard visibility in gnome-shell [Carlos; #745977] |  | ||||||
| * Add pointer barriers to legacy tray [Cosimo; #746026] |  | ||||||
| * Use fallback when app icon cannot be resolved [Cosimo; #746219] |  | ||||||
| * Fix handling of removed smartcard at startup [Ray; #740143] |  | ||||||
| * gdm: Don't pick a random session for the user [Jasper; #740142] |  | ||||||
| * Make menu selection behavior consistent with GTK [Florian; #745246] |  | ||||||
| * gdm: Fix empty user list on user switching [Ray; #719418] |  | ||||||
| * Misc bug fixes [Florian, Giovanni, Clément, Rui; #745666, #746019, #745861, |  | ||||||
|   #746027, #746223, #737502, #746343, #746288] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Giovanni Campagna, Cosimo Cecchi, Piotr Drąg, Adel Gadllah, Carlos Garnacho, |  | ||||||
|   Clément Guérin, Ross Lagerwall, Rui Matos, Florian Müllner, Jakub Steiner, |  | ||||||
|   Jasper St. Pierre, Ray Strode |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Piotr Drąg [pl], Changwoo Ryu [ko], Milo Casagrande [it], |  | ||||||
|   Baurzhan Muftakhidinov [kk], Мирослав Николић [sr, sr@latin], Balázs Úr [hu], |  | ||||||
|   IWAI, Masaharu [ja], Daniel Korostil [uk], Aurimas Černius [lt], |  | ||||||
|   Matej Urbančič [sl], Daniel Mustieles [es], Kjartan Maraas [nb], |  | ||||||
|   Victor Ibragimov [tg], Claude Paroz [fr], Jordi Mas [ca], Bernd Homuth [de], |  | ||||||
|   Muhammet Kara [tr], Frédéric Péters [fr], Jiri Grönroos [fi], |  | ||||||
|   Alexander Shopov [bg], Stas Solovey [ru], Trần Ngọc Quân [vi], |  | ||||||
|   Samir Ribic [bs], Dušan Kazik [sk], Enrico Nicoletto [pt_BR], |  | ||||||
|   Marek Černocký [cs], A S Alam [pa], Ask Hjorth Larsen [da], |  | ||||||
|   Tom Tryfonidis [el], Alexandre Franke [fr], Yosef Or Boczko [he], |  | ||||||
|   Chao-Hsiung Liao [zh_TW] |  | ||||||
|  |  | ||||||
| 3.15.91 |  | ||||||
| ======= |  | ||||||
| * Don't disable all shortcuts while non-panel menus are open [Florian; #745039] |  | ||||||
| * Do not wake up the screen for disabled notifications [Florian; #744114] |  | ||||||
| * Add unminimize animation [Florian; #702662] |  | ||||||
| * Change default shortcut for viewing notifications [Florian; #687986] |  | ||||||
| * Add shortcut to dismiss notifications from list [Florian; #745279] |  | ||||||
| * Use Polari instead of Empathy for IRC conversations [Giovanni; #745431] |  | ||||||
| * Add a hideable bottom tray for legacy status icons [Florian; #745162] |  | ||||||
| * Improve accessibility of calendar/message list [Florian; #706903, #745393] |  | ||||||
| * Fix window thumbnail scaling in overview [Sebastian; #744883] |  | ||||||
| * Stop handling non-chat notifications for Empathy [Giovanni; #745503] |  | ||||||
| * Fix mouse interaction with ibus candidate window [Rui; #745167, #745245] |  | ||||||
| * Misc bug fixes and cleanups [Giovanni, Florian, Miguel, Cosimo, Jakub, |  | ||||||
|   Michele, Raul, Matthias, Rui; #677412, #744880, #744900, #744894, #744907, |  | ||||||
|   #745061, #741111, #744912, #745175, #745246, #744959, #744575, #745570, |  | ||||||
|   #652742, #659187, #745412, #745521, #745521, #741665, #745574, #745627, |  | ||||||
|   #745494, #745111, #745132, #745110] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Michele, Giovanni Campagna, Cosimo Cecchi, Matthias Clasen, |  | ||||||
|   Raul Gutierrez Segales, Sebastian Keller, David Liang, Rui Matos, |  | ||||||
|   Florian Müllner, Yosef Or Boczko, Jakub Steiner, Jasper St. Pierre, |  | ||||||
|   Rico Tzschichholz, Miguel Vaello Martínez |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Dušan Kazik [sk], Chao-Hsiung Liao [zh_TW], Muhammet Kara [tr], |  | ||||||
|   Balázs Úr [hu], Daniel Mustieles [es], Frédéric Péters [fr], |  | ||||||
|   Rafael Ferreira [pt_BR], Aurimas Černius [lt], Milo Casagrande [it], |  | ||||||
|   Yosef Or Boczko [he], Stas Solovey [ru], Baurzhan Muftakhidinov [kk], |  | ||||||
|   Daniel Korostil [uk], Fran Dieguez [gl], Kjartan Maraas [nb], |  | ||||||
|   Tom Tryfonidis [el], Cheng-Chia Tseng [zh_TW], Friedel Wolff [af], |  | ||||||
|   Alexandre Franke [fr], Efstathios Iosifidis [el], Aron Xu [zh_CN], |  | ||||||
|   Marek Černocký [cs], Enrico Nicoletto [pt_BR] |  | ||||||
|  |  | ||||||
| 3.15.90 |  | ||||||
| ======= |  | ||||||
| * gdm: Fix reactivity of first user in user list [Ray; #743370] |  | ||||||
| * Prevent DND to dash when favorites are locked down [David; #741325] |  | ||||||
| * Prevent DND in app picker when favorites are locked down [Murray; #741325] |  | ||||||
| * Implement Display panel's OSD monitor labels in the shell [Rui; #743744] |  | ||||||
| * Remove GSystem dependency [Colin; #744457] |  | ||||||
| * Do not duplicate "New Window" action in dash [Florian; #744446] |  | ||||||
| * Fix 'draw-cursor' option of screen recorder [Alexander; #744599] |  | ||||||
| * Fix screencast timestamps [Sebastian; #744642] |  | ||||||
| * Allow keybindings for switching to VT8-VT12 [Ray; #744800] |  | ||||||
| * Implement notification redesign [Florian; #744498, #744815, #744817, #744850] |  | ||||||
| * Fix struts computation of chrome on non-primary monitors [Sylvain; #744183] |  | ||||||
| * Visual refresh based on GTK+ theme redesign [Jakub, Carlos; #737785, #744680] |  | ||||||
| * Misc. bug fixes and cleanups [Ray, Bastien, Cosimo, Rui, Florian; #743371, |  | ||||||
|   #736182, #744013, #743993, #744665] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Cosimo Cecchi, Murray Cumming, Sebastian Dröge, David King, |  | ||||||
|   Alexander Larsson, Rui Matos, Florian Müllner, Bastien Nocera, |  | ||||||
|   Sylvain Pasche, Carlos Soriano, Jakub Steiner, Jasper St. Pierre, Ray Strode, |  | ||||||
|   Colin Walters |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Daniel Martinez [an], Sveinn í Felli [is], GNOME Translation Robot [de], |  | ||||||
|   Yosef Or Boczko [he], Kristjan SCHMIDT [eo], Dušan Kazik [sk], |  | ||||||
|   Andika Triwidada [id], Marek Černocký [cs], Muhammet Kara [tr], |  | ||||||
|   Matej Urbančič [sl], Milo Casagrande [it], Anders Jonsson [sv] |  | ||||||
|  |  | ||||||
| 3.15.4 |  | ||||||
| ====== |  | ||||||
| * Add mode parameter to AcceleratorActivated signal [Florian; #711682] |  | ||||||
| * Fix PID based window/app association [Sebastian; #736527] |  | ||||||
| * Fix current day highlight on day change [Sebastian; #742492] |  | ||||||
| * Switch to vp9 for screencast recordings [Adel; #742744] |  | ||||||
| * Disable IBus input sources on password entries [Takao; #730628] |  | ||||||
| * Make slider scrolling smoother [Adel; #742648] |  | ||||||
| * Allow move-up shortcut to move window above top workspace [Florian; #665764] |  | ||||||
| * Misc. bug fixes [Adel, Rui; #742748, #742824, #741114] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Cosimo Cecchi, Takao Fujiwara, Adel Gadllah, Sebastian Keller, Rui Matos, |  | ||||||
|   Florian Müllner, Jasper St. Pierre |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Andika Triwidada [id], Matej Urbančič [sl], Saibal Ray [bn_IN], |  | ||||||
|   Inaki Larranaga Murgoitio [eu], Stas Solovey [ru], Kjartan Maraas [nb], |  | ||||||
|   Balázs Úr [hu], Marek Černocký [cs], Rafael Ferreira [pt_BR], |  | ||||||
|   Bernd Homuth [de], Daniel Mustieles [es], Fabio Tomat [fur] |  | ||||||
|  |  | ||||||
| 3.15.3 |  | ||||||
| ====== |  | ||||||
| * Add support for high-contrast themes [Florian; #740447] |  | ||||||
| * Fix banner message on login screen without user list [Ray; #703972] |  | ||||||
| * Fix flicker when activating windows on another workspace [Florian; #741680] |  | ||||||
| * Misc. bug fixes [Giovanni, Florian; #735308, #740237] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Giovanni Campagna, Florian Müllner, Jasper St. Pierre, Ray Strode |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Balázs Úr [hu], Josef Andersson [sv], Muhammet Kara [tr], |  | ||||||
|   Baurzhan Muftakhidinov [kk], Inaki Larranaga Murgoitio [eu] |  | ||||||
|  |  | ||||||
| 3.15.2 |  | ||||||
| ====== |  | ||||||
| * Fix visual glitch of window preview outline in overview [Chris; #699044] |  | ||||||
| * Change user facing name of "Captive Portal" to "Network Login" [Elad; #737198] |  | ||||||
| * Port to Python 3 [Slavek; #732478] |  | ||||||
| * Hide Airplane mode indicator when g-s-d says so [Cosimo; #736292] |  | ||||||
| * Allow translators to change non-work days [Lavi; #664645] |  | ||||||
| * Delay invocation of caribou daemon until really needed [Daiki; #739712] |  | ||||||
| * Don't lock screen after crash if locking is disabled [Adel; #704884] |  | ||||||
| * Improve layout of extension installation dialog [William; #739888] |  | ||||||
| * Fix workspace changes from app picker [Yuki; #737534] |  | ||||||
| * Preload all ibus input sources in user configuration [Takao; #695428] |  | ||||||
| * Properly remove network connections from list [Ryan; #740227] |  | ||||||
| * Support CSS margin property [Carlos; #728437] |  | ||||||
| * Improve handling of BUSY application state [Phillip; #736492] |  | ||||||
| * Fix erroneous week numbers in calendar [Florian; #736722] |  | ||||||
| * Misc. bugfixes and cleanups [Darcy, Yuki, Alexander, Eskild, Bastien, Cosimo, Colin, |  | ||||||
|   Ray; #738725, #739497, #739241, #672500, #739822, #740074, #704163, #740141] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Yuki, Lavi .A, Elad Alfassa, Cosimo Cecchi, Takao Fujiwara, Adel Gadllah, |  | ||||||
|   Eskild Hustvedt, Chris Johns, William Jon McCann, Slavek Kabrda, Ryan Lortie, |  | ||||||
|   Florian Müllner, Bastien Nocera, Christian Persch, Carlos Soriano, |  | ||||||
|   Jasper St. Pierre, Ray Strode, Alexander Tsoy, Daiki Ueno, Colin Walters, |  | ||||||
|   Phillip Wood |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Jorge Perez Perez [an], Daniel Martinez [an], Daniel Mustieles [es], |  | ||||||
|   Trần Ngọc Quân [vi], Changwoo Ryu [ko], Kjartan Maraas [nb], |  | ||||||
|   Yosef Or Boczko [he], Marek Černocký [cs] |  | ||||||
|  |  | ||||||
| 3.15.1 |  | ||||||
| ====== |  | ||||||
| * Use GResources for theme loading [Cosimo; #736936] |  | ||||||
| * Reset the OSK to primary on monitor changes [Rui; #738536] |  | ||||||
| * Use LC_TIME locale for format string translations [Florian; #738640] |  | ||||||
| * Summarize queued up notifications [Devyani; #702460] |  | ||||||
| * Improve handling of multi-day events [Andreas; #727302] |  | ||||||
| * Support EXTERNAL scroll policy type [Florian; #739379] |  | ||||||
| * Misc. bugfixes [Owen, Rui; #738652, #739252] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Andreas Brauchli, Cosimo Cecchi, Devyani Kota, Rui Matos, Florian Müllner, |  | ||||||
|   Jasper St. Pierre, Owen W. Taylor |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Bahodir Mansurov [uz@cyrillic] |  | ||||||
|  |  | ||||||
| 3.14.1 |  | ||||||
| ====== |  | ||||||
| * Fix pulse animation for scrolled app folders [Florian; #736885] |  | ||||||
| * Fix updating background on file changes [Owen; #710756] |  | ||||||
| * Obtain keyboard variant from IBus [Jinkyu; #735066] |  | ||||||
| * Implement Ctrl-u / Ctrl-k keybindings in entries [Florian; #737346] |  | ||||||
| * Pass VPN hints to auth dialog [Dan; #737592] |  | ||||||
| * Only allow one screenshot request at a time [Adel; #737456] |  | ||||||
| * Respect disable-save-to-disc lockdown setting [Florian; #737846] |  | ||||||
| * Respect scaling-factor for profile pictures [Darcy; #735419] |  | ||||||
| * Focus login screen after lifting the lock screen shield [Ray; #708105] |  | ||||||
| * Speed up pulse animation for few items [Carlos S.; #737017] |  | ||||||
| * Fix gap between workspace switcher and screen edge [Florian; #728899] |  | ||||||
| * Disable unredirection during recordings [Adel; #738226] |  | ||||||
| * Ensure there's always at least one input source [Rui; #738303] |  | ||||||
| * Restrict width of dash icons' context menus [Adel; #738054] |  | ||||||
| * Misc. bug fixes [Jasper, Florian, Carlos G., Owen; #736999, #737382, #737001, |  | ||||||
|   #738314, #738256, #738147] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Darcy Beurle, Cosimo Cecchi, Adel Gadllah, Carlos Garnacho, Rui Matos, |  | ||||||
|   Florian Müllner, Carlos Soriano, Jasper St. Pierre, Ray Strode, Patrick Ward, |  | ||||||
|   Dan Williams, Owen W. Taylor, Jinkyu Yi |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Мирослав Николић po/sr, sr@latin.po, Fran Diéguez [gl], Marek Černocký [cs], |  | ||||||
|   Saibal Ray [bn_IN], Rajesh Ranjan [hi], Friedel Wolff [af], |  | ||||||
|   Zhou Fang [zh_CN], Krishnababu Krothapalli [te], Kjartan Maraas [nb], |  | ||||||
|   Rūdolfs Mazurs [lv], Sweta Kothari [gu], Christian Kirbach [de], |  | ||||||
|   Cheng-Chia Tseng [zh_TW], Pedro Albuquerque [pt], Daniel Mustieles [es], |  | ||||||
|   Luca Ferretti [it], Baurzhan Muftakhidinov [kk], Arash Mousavi [fa], |  | ||||||
|   Milo Casagrande [it] |  | ||||||
|  |  | ||||||
| 3.14.0 |  | ||||||
| ====== |  | ||||||
| * Fix exposure of the accessible tree [Alejandro; #736821] |  | ||||||
| * Hide empty app folders in app picker [Florian; #736910] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Florian Müllner, Alejandro Piñeiro |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Yuri Myasoedov [ru], Pawan Chitrakar [ne], Manoj Kumar Giri [or], |  | ||||||
|   Daniel Mustieles [es], GNOME Translation Robot [de], Rajesh Ranjan [hi], |  | ||||||
|   Shankar Prasad [kn], Kenneth Nielsen [da], Daniel Korostil [uk], |  | ||||||
|   Changwoo Ryu [ko], A S Alam [pa], Tom Tryfonidis [el], Petr Kovar [cs] |  | ||||||
|  |  | ||||||
| 3.13.92 |  | ||||||
| ======= |  | ||||||
| * Fix submenu arrow animations [Hashem; #728927] |  | ||||||
| * Always initialize clutter accessibility [Alejandro; #735908] |  | ||||||
| * Adapt to mutter background changes [Owen; #735638] |  | ||||||
| * Improve handling of outOfDate extensions in prefs [Florian; #736185] |  | ||||||
| * Port offline updates to PackageKit's DBus interface [Kalev; #736337] |  | ||||||
| * location: Translate accuracy levels for geoclue [Zeeshan; #736479] |  | ||||||
| * Implement input source switching [Rui; #736435] |  | ||||||
| * Fix crash when dragging window from workspace switcher [Carlos G.; #735972] |  | ||||||
| * Clean out list of default favorites [Elad; #735682] |  | ||||||
| * Add settings link to location submenu [Florian; #736542] |  | ||||||
| * Fix keynav of message tray menu button [Florian; #707799] |  | ||||||
| * Misc. bug fixes [Carlos G., Florian, Rui; #736110, #736329, #736343, |  | ||||||
|   #735927, #735976] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Elad Alfassa, Zeeshan Ali (Khattak), Michael Catanzaro, Adel Gadllah, |  | ||||||
|   Carlos Garnacho, Kalev Lember, Rui Matos, Florian Müllner, Hashem Nasarat, |  | ||||||
|   Alejandro Piñeiro, Carlos Soriano, Jasper St. Pierre, Owen W. Taylor |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Piotr Drąg [pl], Changwoo Ryu [ko], Yuri Myasoedov [ru], Zhou Fang [ja], |  | ||||||
|   Peter Mráz [sk], Ville-Pekka Vainio [fi], Sweta Kothari [gu], |  | ||||||
|   Marek Černocký [cs], A S Alam [pa], Christian Kirbach [de], |  | ||||||
|   Alexandre Franke [fr], Aurimas Černius [lt], Khaled Hosny [ar], |  | ||||||
|   Enrico Nicoletto [pt_BR], Andika Triwidada [id], Shantha kumar [ta], |  | ||||||
|   Matej Urbančič [sl], Pawan Chitrakar [ne], Yosef Or Boczko [he], |  | ||||||
|   Balázs Úr [hu], Dušan Kazik [sk], Gil Forcada [ca], |  | ||||||
|   Carles Ferrando [ca@valencia], Nilamdyuti Goswami [as], Ivaylo Valkov [bg], |  | ||||||
|   Sandeep Sheshrao Shedmake [mr], Umarzuki Bin Mochlis Moktar [ms], |  | ||||||
|   Muhammet Kara [tr], Jiro Matsuzawa [ja], Kris Thomsen [da], |  | ||||||
|   Mattias Eriksson [sv] |  | ||||||
|  |  | ||||||
| 3.13.91 |  | ||||||
| ======= |  | ||||||
| * Fix keynav into session menu on login screen [Florian; #735614] |  | ||||||
| * Add gesture to summon message tray [Carlos G.; #735625] |  | ||||||
| * Accept scrolls/swipes either way on the screen shield [Jasper; #734874] |  | ||||||
| * Animate opening the app picker and improve app folder animations |  | ||||||
|   [Carlos S.; #734726] |  | ||||||
| * Animate app icons on launching a new window [Carlos S., Florian; #734726] |  | ||||||
| * Show the on-screen keyboard when touch input is being used [David; #702015] |  | ||||||
| * Misc. bug fixes [Bastien, Owen, Florian, Carlos G.; #735190, #735385, |  | ||||||
|   #735608, #735681] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Carlos Garnacho, David King, Kalev Lember, Florian Müllner, Bastien Nocera, |  | ||||||
|   Carlos Soriano, Jasper St. Pierre, Owen W. Taylor |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Fran Diéguez [gl], Sweta Kothari [gu], Manoj Kumar Giri [or], |  | ||||||
|   Alain Lojewski [fr], Praveen Illa [te], Arash Mousavi [fa], |  | ||||||
|   Andika Triwidada [id] |  | ||||||
|  |  | ||||||
| 3.13.90 |  | ||||||
| ======= |  | ||||||
| * Make use of GLSL optional [Adel; #733623] |  | ||||||
| * Update on-screen-keyboard position on monitor changes [Cosimo; #733790] |  | ||||||
| * Improve window manager animations [Giovanni; #732857] |  | ||||||
| * Handle touch events [Carlos G.; #733633] |  | ||||||
| * Try to not show "New Window" action for single-window apps |  | ||||||
|   [Giovanni; #722554] |  | ||||||
| * Fix overview exceeding screen size with many apps installed |  | ||||||
|   [Carlos S.; #723496] |  | ||||||
| * Add Software to default favorites [Mathieu; #734406] |  | ||||||
| * Improve app picker <-> desktop transition [Carlos S.; #732901] |  | ||||||
| * Remove <shift>-magic for switcher popups [Christophe; #732296] |  | ||||||
| * Add a special background to use for performance testing [Owen; #734610] |  | ||||||
| * Add support for default disabled search providers [Giovanni; #734110] |  | ||||||
| * Fix portals that don't redirect properly [Giovanni; #733848] |  | ||||||
| * Fix history trimming in chat notifications [Giovanni; #733899] |  | ||||||
| * Try to use default calendar application [Florian; #722333] |  | ||||||
| * Only show location menu when geolocation is in use [Zeeshan; #731122] |  | ||||||
| * Misc. bug fixes and cleanups [Giovanni, Carlos G., Zeeshan, Carlos S., |  | ||||||
|   Cosimo; #711682, #733840, #734483, #734680, #733813, #735062] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Zeeshan Ali (Khattak), Mathieu Bridon, Giovanni Campagna, Cosimo Cecchi, |  | ||||||
|   Piotr Drąg, Christophe Fergeau, Adel Gadllah, Carlos Garnacho, |  | ||||||
|   Florian Müllner, Carlos Soriano, Jasper St. Pierre, Olav Vitters, |  | ||||||
|   Owen W. Taylor |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Aurimas Černius [lt], MarMav [el], Inaki Larranaga Murgoitio [eu], |  | ||||||
|   Reinout van Schouwen [nl], ngoswami [as], Fabio Tomat [fur], |  | ||||||
|   Chao-Hsiung Liao [zh_HK, zh_TW] |  | ||||||
|  |  | ||||||
| 3.13.4 |  | ||||||
| ====== |  | ||||||
| * Handle portal login requests [Giovanni; #704416] |  | ||||||
| * Scale fonts on wayland on hiDPI devices [Adel; #732537] |  | ||||||
| * Fix default ibus candidate index labels [Rui; #702944] |  | ||||||
| * Add gestures for various system actions [Carlos G.] |  | ||||||
| * Add performance test script for the perf.gnome.org [Owen; #732350] |  | ||||||
| * Use new restart framework to improve restart visuals [Owen; #733026] |  | ||||||
| * Improve keynav in app folder popups [Carlos S.; #731477] |  | ||||||
| * Fix truncation of app search results [Carlos S.; #732416] |  | ||||||
| * Automatically update renamed desktop files in favorites [Kalev; #729429] |  | ||||||
| * Misc. bug fixes and cleanups [Giovanni, Yosef, Owen, Bastien, Javier; |  | ||||||
|   #729823, #726401, #732301, #732348, #732349, #733498, #733540] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Giovanni Campagna, Adel Gadllah, Carlos Garnacho, Javier Hernández, |  | ||||||
|   Kalev Lember, Rui Matos, Florian Müllner, Bastien Nocera, Yosef Or Boczko, |  | ||||||
|   Carlos Soriano, Jasper St. Pierre, Owen W. Taylor |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Yuri Myasoedov [ru], Daniel Mustieles [es], Fran Diéguez [gl], |  | ||||||
|   Cheng-Chia Tseng [zh_TW], A S Alam [pa], Benjamin Steinwender [de], |  | ||||||
|   Enrico Nicoletto [pt_BR], MarMav [el], Yosef Or Boczko [he], |  | ||||||
|   Kjartan Maraas [nb] |  | ||||||
|  |  | ||||||
| 3.13.3 |  | ||||||
| ====== |  | ||||||
| * Don't allow closing windows with attached modals [Florian; #729886] |  | ||||||
| * Fix self-restarting on OpenBSD [Antoine; #727763] |  | ||||||
| * Improve behavior of window buttons with compositor menus [Florian; #731058] |  | ||||||
| * Work around atspi-related performance regression [Alejandro; #730118] |  | ||||||
| * Misc bug fixes and cleanups [Florian, Lan, Jasper, Christophe, Debarshi, |  | ||||||
|   Zeeshan; #728271, #726460, #703833, #731118, #731220, #695487, #730527, |  | ||||||
|   #728170, #731619, #731738, #731882, #731923] |  | ||||||
|  |  | ||||||
| Contributors: |  | ||||||
|   Zeeshan Ali (Khattak), Christophe Fergeau, Adel Gadllah, Antoine Jacoutot, |  | ||||||
|   Ting-Wei Lan, Florian Müllner, Alejandro Piñeiro, Debarshi Ray, |  | ||||||
|   Carlos Soriano, Jasper St. Pierre, Wim Taymans, Rico Tzschichholz |  | ||||||
|  |  | ||||||
| Translations: |  | ||||||
|   Philip Withnall [en_GB], Milo Casagrande [it], Aurimas Černius [lt], |  | ||||||
|   Enrico Nicoletto [pt_BR], Kjartan Maraas [nb], Balázs Meskó [hu], |  | ||||||
|   Muhammet Kara [tr], Daniel Mustieles [es], Yosef Or Boczko [he], |  | ||||||
|   Matej Urbančič [sl], Mattias Eriksson [sv] |  | ||||||
|  |  | ||||||
| 3.13.2 | 3.13.2 | ||||||
| ====== | ====== | ||||||
| * Make airplane mode menu insensitive in lock screen [Giovanni; #729224] | * Make airplane mode menu insensitive in lock screen [Giovanni; #729224] | ||||||
|   | |||||||
| @@ -4,6 +4,8 @@ | |||||||
| srcdir=`dirname $0` | srcdir=`dirname $0` | ||||||
| test -z "$srcdir" && srcdir=. | test -z "$srcdir" && srcdir=. | ||||||
|  |  | ||||||
|  | PKG_NAME="gnome-shell" | ||||||
|  |  | ||||||
| (test -f $srcdir/configure.ac \ | (test -f $srcdir/configure.ac \ | ||||||
|   && test -d $srcdir/src) || { |   && test -d $srcdir/src) || { | ||||||
|     echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" |     echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" | ||||||
| @@ -12,7 +14,7 @@ test -z "$srcdir" && srcdir=. | |||||||
| } | } | ||||||
|  |  | ||||||
| # Fetch submodules if needed | # Fetch submodules if needed | ||||||
| if test ! -f src/gvc/Makefile.am || test ! -f data/theme/gnome-shell-sass/COPYING; | if test ! -f src/gvc/Makefile.am; | ||||||
| then | then | ||||||
|   echo "+ Setting up submodules" |   echo "+ Setting up submodules" | ||||||
|   git submodule init |   git submodule init | ||||||
| @@ -24,4 +26,4 @@ which gnome-autogen.sh || { | |||||||
|     echo "your OS vendor's package manager)." |     echo "your OS vendor's package manager)." | ||||||
|     exit 1 |     exit 1 | ||||||
| } | } | ||||||
| . gnome-autogen.sh | USE_GNOME2_MACROS=1 USE_COMMON_DOC_BUILD=yes . gnome-autogen.sh | ||||||
|   | |||||||
| @@ -3,10 +3,7 @@ mozillalibdir = $(BROWSER_PLUGIN_DIR) | |||||||
|  |  | ||||||
| mozillalib_LTLIBRARIES = libgnome-shell-browser-plugin.la | mozillalib_LTLIBRARIES = libgnome-shell-browser-plugin.la | ||||||
|  |  | ||||||
| # Browsers can unload and reload the module while browsing, which is not supported by GObject. | libgnome_shell_browser_plugin_la_LDFLAGS = -module -avoid-version -no-undefined | ||||||
| # We pass -Wl,-z,nodelete to the linker to ensure the module is never unloaded. |  | ||||||
| # https://bugzilla.gnome.org/show_bug.cgi?id=737932 |  | ||||||
| libgnome_shell_browser_plugin_la_LDFLAGS = -module -avoid-version -no-undefined -Wl,-z,nodelete |  | ||||||
|  |  | ||||||
| libgnome_shell_browser_plugin_la_LIBADD = 	\ | libgnome_shell_browser_plugin_la_LIBADD = 	\ | ||||||
| 	$(BROWSER_PLUGIN_LIBS) | 	$(BROWSER_PLUGIN_LIBS) | ||||||
|   | |||||||
| @@ -33,16 +33,20 @@ | |||||||
| #include <json-glib/json-glib.h> | #include <json-glib/json-glib.h> | ||||||
|  |  | ||||||
| #define ORIGIN "extensions.gnome.org" | #define ORIGIN "extensions.gnome.org" | ||||||
| #define PLUGIN_NAME "GNOME Shell Integration" | #define PLUGIN_NAME "Gnome Shell Integration" | ||||||
| #define PLUGIN_DESCRIPTION "This plugin provides integration with GNOME Shell " \ | #define PLUGIN_DESCRIPTION "This plugin provides integration with Gnome Shell " \ | ||||||
|       "for live extension enabling and disabling. " \ |       "for live extension enabling and disabling. " \ | ||||||
|       "It can be used only by extensions.gnome.org" |       "It can be used only by extensions.gnome.org" | ||||||
| #define PLUGIN_MIME_STRING "application/x-gnome-shell-integration::GNOME Shell Integration Dummy Content-Type"; | #define PLUGIN_MIME_STRING "application/x-gnome-shell-integration::Gnome Shell Integration Dummy Content-Type"; | ||||||
|  |  | ||||||
| #define PLUGIN_API_VERSION 5 | #define PLUGIN_API_VERSION 5 | ||||||
|  |  | ||||||
| #define EXTENSION_DISABLE_VERSION_CHECK_KEY "disable-extension-version-validation" | #define EXTENSION_DISABLE_VERSION_CHECK_KEY "disable-extension-version-validation" | ||||||
|  |  | ||||||
|  | typedef struct { | ||||||
|  |   GDBusProxy *proxy; | ||||||
|  | } PluginData; | ||||||
|  |  | ||||||
| static NPNetscapeFuncs funcs; | static NPNetscapeFuncs funcs; | ||||||
|  |  | ||||||
| static inline gchar * | static inline gchar * | ||||||
| @@ -141,6 +145,121 @@ check_origin_and_protocol (NPP instance) | |||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* =============== public entry points =================== */ | ||||||
|  |  | ||||||
|  | NPError | ||||||
|  | NP_Initialize(NPNetscapeFuncs *pfuncs, NPPluginFuncs *plugin) | ||||||
|  | { | ||||||
|  |   /* global initialization routine, called once when plugin | ||||||
|  |      is loaded */ | ||||||
|  |  | ||||||
|  |   g_debug ("plugin loaded"); | ||||||
|  |  | ||||||
|  |   memcpy (&funcs, pfuncs, sizeof (funcs)); | ||||||
|  |  | ||||||
|  |   plugin->size = sizeof(NPPluginFuncs); | ||||||
|  |   plugin->newp = NPP_New; | ||||||
|  |   plugin->destroy = NPP_Destroy; | ||||||
|  |   plugin->getvalue = NPP_GetValue; | ||||||
|  |   plugin->setwindow = NPP_SetWindow; | ||||||
|  |  | ||||||
|  |   return NPERR_NO_ERROR; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | NPError | ||||||
|  | NP_Shutdown(void) | ||||||
|  | { | ||||||
|  |   return NPERR_NO_ERROR; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const char* | ||||||
|  | NP_GetMIMEDescription(void) | ||||||
|  | { | ||||||
|  |   return PLUGIN_MIME_STRING; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | NPError | ||||||
|  | NP_GetValue(void         *instance, | ||||||
|  |             NPPVariable   variable, | ||||||
|  |             void         *value) | ||||||
|  | { | ||||||
|  |   switch (variable) { | ||||||
|  |   case NPPVpluginNameString: | ||||||
|  |     *(char**)value = PLUGIN_NAME; | ||||||
|  |     break; | ||||||
|  |   case NPPVpluginDescriptionString: | ||||||
|  |     *(char**)value = PLUGIN_DESCRIPTION; | ||||||
|  |     break; | ||||||
|  |   default: | ||||||
|  |     ; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return NPERR_NO_ERROR; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | NPError | ||||||
|  | NPP_New(NPMIMEType    mimetype, | ||||||
|  |         NPP           instance, | ||||||
|  |         uint16_t      mode, | ||||||
|  |         int16_t       argc, | ||||||
|  |         char        **argn, | ||||||
|  |         char        **argv, | ||||||
|  |         NPSavedData  *saved) | ||||||
|  | { | ||||||
|  |   /* instance initialization function */ | ||||||
|  |   PluginData *data; | ||||||
|  |   GError *error = NULL; | ||||||
|  |  | ||||||
|  |   g_debug ("plugin created"); | ||||||
|  |  | ||||||
|  |   if (!check_origin_and_protocol (instance)) | ||||||
|  |     return NPERR_GENERIC_ERROR; | ||||||
|  |  | ||||||
|  |   data = g_slice_new (PluginData); | ||||||
|  |   instance->pdata = data; | ||||||
|  |  | ||||||
|  |   data->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, | ||||||
|  |                                                G_DBUS_PROXY_FLAGS_NONE, | ||||||
|  |                                                NULL, /* interface info */ | ||||||
|  |                                                "org.gnome.Shell", | ||||||
|  |                                                "/org/gnome/Shell", | ||||||
|  |                                                "org.gnome.Shell.Extensions", | ||||||
|  |                                                NULL, /* GCancellable */ | ||||||
|  |                                                &error); | ||||||
|  |   if (!data->proxy) | ||||||
|  |     { | ||||||
|  |       /* ignore error if the shell is not running, otherwise warn */ | ||||||
|  |       if (error->domain != G_DBUS_ERROR || | ||||||
|  |           error->code != G_DBUS_ERROR_NAME_HAS_NO_OWNER) | ||||||
|  |         { | ||||||
|  |           g_warning ("Failed to set up Shell proxy: %s", error->message); | ||||||
|  |         } | ||||||
|  |       g_clear_error (&error); | ||||||
|  |       return NPERR_GENERIC_ERROR; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   g_debug ("plugin created successfully"); | ||||||
|  |  | ||||||
|  |   return NPERR_NO_ERROR; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | NPError | ||||||
|  | NPP_Destroy(NPP           instance, | ||||||
|  | 	    NPSavedData **saved) | ||||||
|  | { | ||||||
|  |   /* instance finalization function */ | ||||||
|  |  | ||||||
|  |   PluginData *data = instance->pdata; | ||||||
|  |  | ||||||
|  |   g_debug ("plugin destroyed"); | ||||||
|  |  | ||||||
|  |   g_object_unref (data->proxy); | ||||||
|  |  | ||||||
|  |   g_slice_free (PluginData, data); | ||||||
|  |  | ||||||
|  |   return NPERR_NO_ERROR; | ||||||
|  | } | ||||||
|  |  | ||||||
| /* =================== scripting interface =================== */ | /* =================== scripting interface =================== */ | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
| @@ -211,10 +330,24 @@ static NPObject * | |||||||
| plugin_object_allocate (NPP      instance, | plugin_object_allocate (NPP      instance, | ||||||
|                         NPClass *klass) |                         NPClass *klass) | ||||||
| { | { | ||||||
|   PluginObject *obj = (PluginObject *) funcs.memalloc (sizeof (PluginObject)); |   PluginData *data = instance->pdata; | ||||||
|  |   PluginObject *obj = g_slice_new0 (PluginObject); | ||||||
|  |  | ||||||
|   memset (obj, 0, sizeof (PluginObject)); |  | ||||||
|   obj->instance = instance; |   obj->instance = instance; | ||||||
|  |   obj->proxy = g_object_ref (data->proxy); | ||||||
|  |   obj->settings = g_settings_new (SHELL_SCHEMA); | ||||||
|  |   obj->signal_id = g_signal_connect (obj->proxy, "g-signal", | ||||||
|  |                                      G_CALLBACK (on_shell_signal), obj); | ||||||
|  |  | ||||||
|  |   obj->watch_name_id = g_bus_watch_name (G_BUS_TYPE_SESSION, | ||||||
|  |                                          "org.gnome.Shell", | ||||||
|  |                                          G_BUS_NAME_WATCHER_FLAGS_NONE, | ||||||
|  |                                          on_shell_appeared, | ||||||
|  |                                          NULL, | ||||||
|  |                                          obj, | ||||||
|  |                                          NULL); | ||||||
|  |  | ||||||
|  |   g_debug ("plugin object created"); | ||||||
|  |  | ||||||
|   return (NPObject*)obj; |   return (NPObject*)obj; | ||||||
| } | } | ||||||
| @@ -222,7 +355,20 @@ plugin_object_allocate (NPP      instance, | |||||||
| static void | static void | ||||||
| plugin_object_deallocate (NPObject *npobj) | plugin_object_deallocate (NPObject *npobj) | ||||||
| { | { | ||||||
|   funcs.memfree (npobj); |   PluginObject *obj = (PluginObject*)npobj; | ||||||
|  |  | ||||||
|  |   g_signal_handler_disconnect (obj->proxy, obj->signal_id); | ||||||
|  |   g_object_unref (obj->proxy); | ||||||
|  |  | ||||||
|  |   if (obj->listener) | ||||||
|  |     funcs.releaseobject (obj->listener); | ||||||
|  |  | ||||||
|  |   if (obj->watch_name_id) | ||||||
|  |     g_bus_unwatch_name (obj->watch_name_id); | ||||||
|  |  | ||||||
|  |   g_debug ("plugin object destroyed"); | ||||||
|  |  | ||||||
|  |   g_slice_free (PluginObject, obj); | ||||||
| } | } | ||||||
|  |  | ||||||
| static inline gboolean | static inline gboolean | ||||||
| @@ -873,149 +1019,6 @@ init_methods_and_properties (void) | |||||||
|   onextension_changed_id = funcs.getstringidentifier ("onchange"); |   onextension_changed_id = funcs.getstringidentifier ("onchange"); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* =============== public entry points =================== */ |  | ||||||
|  |  | ||||||
| NPError |  | ||||||
| NP_Initialize(NPNetscapeFuncs *pfuncs, NPPluginFuncs *plugin) |  | ||||||
| { |  | ||||||
|   /* global initialization routine, called once when plugin |  | ||||||
|      is loaded */ |  | ||||||
|  |  | ||||||
|   g_debug ("plugin loaded"); |  | ||||||
|  |  | ||||||
|   memcpy (&funcs, pfuncs, sizeof (funcs)); |  | ||||||
|  |  | ||||||
|   plugin->size = sizeof(NPPluginFuncs); |  | ||||||
|   plugin->newp = NPP_New; |  | ||||||
|   plugin->destroy = NPP_Destroy; |  | ||||||
|   plugin->getvalue = NPP_GetValue; |  | ||||||
|   plugin->setwindow = NPP_SetWindow; |  | ||||||
|   plugin->event = NPP_HandleEvent; |  | ||||||
|  |  | ||||||
|   return NPERR_NO_ERROR; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| NPError |  | ||||||
| NP_Shutdown(void) |  | ||||||
| { |  | ||||||
|   return NPERR_NO_ERROR; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const char* |  | ||||||
| NP_GetMIMEDescription(void) |  | ||||||
| { |  | ||||||
|   return PLUGIN_MIME_STRING; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| NPError |  | ||||||
| NP_GetValue(void         *instance, |  | ||||||
|             NPPVariable   variable, |  | ||||||
|             void         *value) |  | ||||||
| { |  | ||||||
|   switch (variable) { |  | ||||||
|   case NPPVpluginNameString: |  | ||||||
|     *(char**)value = PLUGIN_NAME; |  | ||||||
|     break; |  | ||||||
|   case NPPVpluginDescriptionString: |  | ||||||
|     *(char**)value = PLUGIN_DESCRIPTION; |  | ||||||
|     break; |  | ||||||
|   default: |  | ||||||
|     ; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return NPERR_NO_ERROR; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| NPError |  | ||||||
| NPP_New(NPMIMEType    mimetype, |  | ||||||
|         NPP           instance, |  | ||||||
|         uint16_t      mode, |  | ||||||
|         int16_t       argc, |  | ||||||
|         char        **argn, |  | ||||||
|         char        **argv, |  | ||||||
|         NPSavedData  *saved) |  | ||||||
| { |  | ||||||
|   /* instance initialization function */ |  | ||||||
|   PluginObject *obj; |  | ||||||
|   GError *error = NULL; |  | ||||||
|  |  | ||||||
|   g_debug ("plugin created"); |  | ||||||
|  |  | ||||||
|   if (!check_origin_and_protocol (instance)) |  | ||||||
|     return NPERR_GENERIC_ERROR; |  | ||||||
|  |  | ||||||
|   /* set windowless mode */ |  | ||||||
|   funcs.setvalue(instance, NPPVpluginWindowBool, NULL); |  | ||||||
|  |  | ||||||
|   g_debug ("creating scriptable object"); |  | ||||||
|   init_methods_and_properties (); |  | ||||||
|   obj = (PluginObject *) funcs.createobject (instance, &plugin_class); |  | ||||||
|   instance->pdata = obj; |  | ||||||
|  |  | ||||||
|   obj->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, |  | ||||||
|                                               G_DBUS_PROXY_FLAGS_NONE, |  | ||||||
|                                               NULL, /* interface info */ |  | ||||||
|                                               "org.gnome.Shell", |  | ||||||
|                                               "/org/gnome/Shell", |  | ||||||
|                                               "org.gnome.Shell.Extensions", |  | ||||||
|                                               NULL, /* GCancellable */ |  | ||||||
|                                               &error); |  | ||||||
|   if (!obj->proxy) |  | ||||||
|     { |  | ||||||
|       /* ignore error if the shell is not running, otherwise warn */ |  | ||||||
|       if (!g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER)) |  | ||||||
|         { |  | ||||||
|           g_warning ("Failed to set up Shell proxy: %s", error->message); |  | ||||||
|         } |  | ||||||
|       g_clear_error (&error); |  | ||||||
|       return NPERR_GENERIC_ERROR; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   obj->settings = g_settings_new (SHELL_SCHEMA); |  | ||||||
|   obj->signal_id = g_signal_connect (obj->proxy, "g-signal", |  | ||||||
|                                      G_CALLBACK (on_shell_signal), obj); |  | ||||||
|   obj->watch_name_id = g_bus_watch_name (G_BUS_TYPE_SESSION, |  | ||||||
|                                          "org.gnome.Shell", |  | ||||||
|                                          G_BUS_NAME_WATCHER_FLAGS_NONE, |  | ||||||
|                                          on_shell_appeared, |  | ||||||
|                                          NULL, |  | ||||||
|                                          obj, |  | ||||||
|                                          NULL); |  | ||||||
|  |  | ||||||
|   g_debug ("plugin created successfully"); |  | ||||||
|  |  | ||||||
|   return NPERR_NO_ERROR; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| NPError |  | ||||||
| NPP_Destroy(NPP           instance, |  | ||||||
| 	    NPSavedData **saved) |  | ||||||
| { |  | ||||||
|   /* instance finalization function */ |  | ||||||
|   PluginObject *obj = (PluginObject *) instance->pdata; |  | ||||||
|  |  | ||||||
|   if (!obj) |  | ||||||
|     return NPERR_INVALID_INSTANCE_ERROR; |  | ||||||
|  |  | ||||||
|   g_debug ("plugin destroyed"); |  | ||||||
|  |  | ||||||
|   g_signal_handler_disconnect (obj->proxy, obj->signal_id); |  | ||||||
|   g_object_unref (obj->proxy); |  | ||||||
|  |  | ||||||
|   if (obj->listener) |  | ||||||
|     funcs.releaseobject (obj->listener); |  | ||||||
|  |  | ||||||
|   if (obj->restart_listener) |  | ||||||
|     funcs.releaseobject (obj->restart_listener); |  | ||||||
|  |  | ||||||
|   if (obj->watch_name_id) |  | ||||||
|     g_bus_unwatch_name (obj->watch_name_id); |  | ||||||
|  |  | ||||||
|   funcs.releaseobject((NPObject *)obj); |  | ||||||
|  |  | ||||||
|   return NPERR_NO_ERROR; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| NPError | NPError | ||||||
| NPP_GetValue(NPP          instance, | NPP_GetValue(NPP          instance, | ||||||
| 	     NPPVariable  variable, | 	     NPPVariable  variable, | ||||||
| @@ -1026,10 +1029,13 @@ NPP_GetValue(NPP          instance, | |||||||
|   switch (variable) { |   switch (variable) { | ||||||
|   case NPPVpluginScriptableNPObject: |   case NPPVpluginScriptableNPObject: | ||||||
|     g_debug ("creating scriptable object"); |     g_debug ("creating scriptable object"); | ||||||
|     if (!instance->pdata) |     init_methods_and_properties (); | ||||||
|       return NPERR_INVALID_INSTANCE_ERROR; |  | ||||||
|  |  | ||||||
|     *(NPObject**)value = instance->pdata; |     *(NPObject**)value = funcs.createobject (instance, &plugin_class); | ||||||
|  |     break; | ||||||
|  |  | ||||||
|  |   case NPPVpluginNeedsXEmbed: | ||||||
|  |     *(bool *)value = TRUE; | ||||||
|     break; |     break; | ||||||
|  |  | ||||||
|   default: |   default: | ||||||
| @@ -1047,11 +1053,3 @@ NPP_SetWindow(NPP          instance, | |||||||
| { | { | ||||||
|   return NPERR_NO_ERROR; |   return NPERR_NO_ERROR; | ||||||
| } | } | ||||||
|  |  | ||||||
| int16_t |  | ||||||
| NPP_HandleEvent(NPP   instance, |  | ||||||
|                 void *event) |  | ||||||
| { |  | ||||||
|   /* Ignore the event */ |  | ||||||
|   return FALSE; |  | ||||||
| } |  | ||||||
|   | |||||||
							
								
								
									
										45
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						| @@ -1,6 +1,5 @@ | |||||||
| AC_PREREQ(2.63) | AC_PREREQ(2.63) | ||||||
| AC_INIT([gnome-shell],[3.19.3],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell]) | AC_INIT([gnome-shell],[3.13.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell]) | ||||||
| AX_IS_RELEASE([git-directory]) |  | ||||||
|  |  | ||||||
| AC_CONFIG_HEADERS([config.h]) | AC_CONFIG_HEADERS([config.h]) | ||||||
| AC_CONFIG_SRCDIR([src/shell-global.c]) | AC_CONFIG_SRCDIR([src/shell-global.c]) | ||||||
| @@ -38,7 +37,7 @@ AC_PATH_PROG([XSLTPROC], [xsltproc]) | |||||||
| GLIB_GSETTINGS | GLIB_GSETTINGS | ||||||
|  |  | ||||||
| # Get a value to substitute into gnome-shell.in | # Get a value to substitute into gnome-shell.in | ||||||
| AM_PATH_PYTHON([3]) | AM_PATH_PYTHON([2.5]) | ||||||
| AC_SUBST(PYTHON) | AC_SUBST(PYTHON) | ||||||
|  |  | ||||||
| # We need at least this, since gst_plugin_register_static() was added | # We need at least this, since gst_plugin_register_static() was added | ||||||
| @@ -64,8 +63,8 @@ AC_ARG_ENABLE([systemd], | |||||||
|               [enable_systemd=$enableval], |               [enable_systemd=$enableval], | ||||||
|               [enable_systemd=auto]) |               [enable_systemd=auto]) | ||||||
| AS_IF([test x$enable_systemd != xno], [ | AS_IF([test x$enable_systemd != xno], [ | ||||||
|   AC_MSG_CHECKING([for libsystemd]) |   AC_MSG_CHECKING([for libsystemd-journal]) | ||||||
|   PKG_CHECK_EXISTS([libsystemd], |   PKG_CHECK_EXISTS([libsystemd-journal], | ||||||
|                    [have_systemd=yes |                    [have_systemd=yes | ||||||
|                     AC_DEFINE([HAVE_SYSTEMD], [1], [Define if we have systemd])], |                     AC_DEFINE([HAVE_SYSTEMD], [1], [Define if we have systemd])], | ||||||
|                    [have_systemd=no]) |                    [have_systemd=no]) | ||||||
| @@ -74,14 +73,14 @@ AS_IF([test x$enable_systemd != xno], [ | |||||||
|  |  | ||||||
| AC_MSG_RESULT($enable_systemd) | AC_MSG_RESULT($enable_systemd) | ||||||
|  |  | ||||||
| CLUTTER_MIN_VERSION=1.21.5 | CLUTTER_MIN_VERSION=1.15.90 | ||||||
| GOBJECT_INTROSPECTION_MIN_VERSION=1.45.4 | GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1 | ||||||
| GJS_MIN_VERSION=1.39.0 | GJS_MIN_VERSION=1.39.0 | ||||||
| MUTTER_MIN_VERSION=3.19.3 | MUTTER_MIN_VERSION=3.13.2 | ||||||
| GTK_MIN_VERSION=3.15.0 | GTK_MIN_VERSION=3.7.9 | ||||||
| GIO_MIN_VERSION=2.45.3 | GIO_MIN_VERSION=2.37.0 | ||||||
| LIBECAL_MIN_VERSION=3.5.3 | LIBECAL_MIN_VERSION=3.5.3 | ||||||
| LIBEDATASERVER_MIN_VERSION=3.17.2 | LIBEDATASERVER_MIN_VERSION=3.5.3 | ||||||
| TELEPATHY_GLIB_MIN_VERSION=0.17.5 | TELEPATHY_GLIB_MIN_VERSION=0.17.5 | ||||||
| POLKIT_MIN_VERSION=0.100 | POLKIT_MIN_VERSION=0.100 | ||||||
| STARTUP_NOTIFICATION_MIN_VERSION=0.11 | STARTUP_NOTIFICATION_MIN_VERSION=0.11 | ||||||
| @@ -98,6 +97,7 @@ SHARED_PCS="gio-unix-2.0 >= $GIO_MIN_VERSION | |||||||
|             gjs-internals-1.0 >= $GJS_MIN_VERSION |             gjs-internals-1.0 >= $GJS_MIN_VERSION | ||||||
|             $recorder_modules |             $recorder_modules | ||||||
|             gdk-x11-3.0 libsoup-2.4 |             gdk-x11-3.0 libsoup-2.4 | ||||||
|  |             xtst | ||||||
|             clutter-x11-1.0 >= $CLUTTER_MIN_VERSION |             clutter-x11-1.0 >= $CLUTTER_MIN_VERSION | ||||||
|             clutter-glx-1.0 >= $CLUTTER_MIN_VERSION |             clutter-glx-1.0 >= $CLUTTER_MIN_VERSION | ||||||
|             libstartup-notification-1.0 >= $STARTUP_NOTIFICATION_MIN_VERSION |             libstartup-notification-1.0 >= $STARTUP_NOTIFICATION_MIN_VERSION | ||||||
| @@ -107,7 +107,7 @@ SHARED_PCS="gio-unix-2.0 >= $GIO_MIN_VERSION | |||||||
|             polkit-agent-1 >= $POLKIT_MIN_VERSION |             polkit-agent-1 >= $POLKIT_MIN_VERSION | ||||||
|             gcr-base-3 >= $GCR_MIN_VERSION" |             gcr-base-3 >= $GCR_MIN_VERSION" | ||||||
| if test x$have_systemd = xyes; then | if test x$have_systemd = xyes; then | ||||||
|   SHARED_PCS="${SHARED_PCS} libsystemd" |   SHARED_PCS="${SHARED_PCS} libsystemd-journal" | ||||||
| fi | fi | ||||||
|  |  | ||||||
| PKG_CHECK_MODULES(GNOME_SHELL, $SHARED_PCS) | PKG_CHECK_MODULES(GNOME_SHELL, $SHARED_PCS) | ||||||
| @@ -117,9 +117,10 @@ PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION) | |||||||
| PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11) | PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11) | ||||||
| PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0) | PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0) | ||||||
| PKG_CHECK_MODULES(SHELL_HOTPLUG_SNIFFER, gio-2.0 gdk-pixbuf-2.0) | PKG_CHECK_MODULES(SHELL_HOTPLUG_SNIFFER, gio-2.0 gdk-pixbuf-2.0) | ||||||
| PKG_CHECK_MODULES(TRAY, clutter-1.0 gtk+-3.0) | PKG_CHECK_MODULES(TRAY, gtk+-3.0) | ||||||
| PKG_CHECK_MODULES(GVC, libpulse >= $PULSE_MIN_VERS libpulse-mainloop-glib gobject-2.0) | PKG_CHECK_MODULES(GVC, libpulse >= $PULSE_MIN_VERS libpulse-mainloop-glib gobject-2.0) | ||||||
| PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.19.2) | PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.7.4) | ||||||
|  | PKG_CHECK_MODULES(CARIBOU, caribou-1.0 >= 0.4.8) | ||||||
|  |  | ||||||
| AC_ARG_ENABLE(browser-plugin, | AC_ARG_ENABLE(browser-plugin, | ||||||
|               [AS_HELP_STRING([--enable-browser-plugin], |               [AS_HELP_STRING([--enable-browser-plugin], | ||||||
| @@ -221,7 +222,7 @@ if test "$enable_man" != no; then | |||||||
| fi | fi | ||||||
| AM_CONDITIONAL(ENABLE_MAN, test "$enable_man" != no) | AM_CONDITIONAL(ENABLE_MAN, test "$enable_man" != no) | ||||||
|  |  | ||||||
| AX_COMPILER_FLAGS() | GNOME_COMPILE_WARNINGS([error]) | ||||||
| case "$WARN_CFLAGS" in | case "$WARN_CFLAGS" in | ||||||
|     *-Werror*) |     *-Werror*) | ||||||
|         WARN_CFLAGS="$WARN_CFLAGS -Wno-error=deprecated-declarations" |         WARN_CFLAGS="$WARN_CFLAGS -Wno-error=deprecated-declarations" | ||||||
| @@ -231,19 +232,9 @@ esac | |||||||
| AM_CFLAGS="$AM_CFLAGS $WARN_CFLAGS" | AM_CFLAGS="$AM_CFLAGS $WARN_CFLAGS" | ||||||
| AC_SUBST(AM_CFLAGS) | AC_SUBST(AM_CFLAGS) | ||||||
|  |  | ||||||
| if test -z "${BROWSER_PLUGIN_DIR}"; then | BROWSER_PLUGIN_DIR="${BROWSER_PLUGIN_DIR:-"\${libdir}/mozilla/plugins"}" | ||||||
|   BROWSER_PLUGIN_DIR="\${libdir}/mozilla/plugins" |  | ||||||
| fi |  | ||||||
| AC_ARG_VAR([BROWSER_PLUGIN_DIR],[Where to install the plugin to]) | AC_ARG_VAR([BROWSER_PLUGIN_DIR],[Where to install the plugin to]) | ||||||
|  |  | ||||||
| AC_ARG_VAR([GDBUS_CODEGEN],[the gdbus-codegen programme]) |  | ||||||
| AC_PATH_PROG([GDBUS_CODEGEN],[gdbus-codegen],[]) |  | ||||||
| if test -z "$GDBUS_CODEGEN"; then |  | ||||||
|   AC_MSG_ERROR([gdbus-codegen not found]) |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| AC_PATH_PROG([SASS],[sass],[]) |  | ||||||
|  |  | ||||||
| AC_CONFIG_FILES([ | AC_CONFIG_FILES([ | ||||||
|   Makefile |   Makefile | ||||||
|   data/Makefile |   data/Makefile | ||||||
| @@ -270,7 +261,7 @@ Build configuration: | |||||||
|        Prefix:                                 ${prefix} |        Prefix:                                 ${prefix} | ||||||
|        Source code location:                   ${srcdir} |        Source code location:                   ${srcdir} | ||||||
|        Compiler:                               ${CC} |        Compiler:                               ${CC} | ||||||
|        Compiler Warnings:                      $ax_enable_compile_warnings |        Compiler Warnings:                      $enable_compile_warnings | ||||||
|  |  | ||||||
|        Support for NetworkManager:             $have_networkmanager |        Support for NetworkManager:             $have_networkmanager | ||||||
|        Support for GStreamer recording:        $build_recorder |        Support for GStreamer recording:        $build_recorder | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ | |||||||
|                 package="gnome-shell"> |                 package="gnome-shell"> | ||||||
|  |  | ||||||
| 	<KeyListEntry name="toggle-message-tray" | 	<KeyListEntry name="toggle-message-tray" | ||||||
|                       _description="Show the notification list"/> |                       _description="Show the message tray"/> | ||||||
|  |  | ||||||
| 	<KeyListEntry name="focus-active-notification" | 	<KeyListEntry name="focus-active-notification" | ||||||
|                       _description="Focus the active notification"/> |                       _description="Focus the active notification"/> | ||||||
|   | |||||||
							
								
								
									
										126
									
								
								data/Makefile.am
									
									
									
									
									
								
							
							
						
						| @@ -1,25 +1,5 @@ | |||||||
| CLEANFILES = |  | ||||||
| NULL = |  | ||||||
|  |  | ||||||
| desktopdir=$(datadir)/applications | desktopdir=$(datadir)/applications | ||||||
| desktop_DATA = org.gnome.Shell.desktop gnome-shell-extension-prefs.desktop | desktop_DATA = gnome-shell.desktop gnome-shell-wayland.desktop  gnome-shell-extension-prefs.desktop | ||||||
|  |  | ||||||
| if HAVE_NETWORKMANAGER |  | ||||||
| desktop_DATA += org.gnome.Shell.PortalHelper.desktop |  | ||||||
|  |  | ||||||
| servicedir = $(datadir)/dbus-1/services |  | ||||||
| service_DATA = org.gnome.Shell.PortalHelper.service |  | ||||||
|  |  | ||||||
| CLEANFILES += \ |  | ||||||
| 	org.gnome.Shell.PortalHelper.service \ |  | ||||||
| 	org.gnome.Shell.PortalHelper.desktop \ |  | ||||||
| 	$(NULL) |  | ||||||
|  |  | ||||||
| endif |  | ||||||
|  |  | ||||||
| %.service: %.service.in |  | ||||||
| 	$(AM_V_GEN) sed -e "s|@libexecdir[@]|$(libexecdir)|" \ |  | ||||||
| 	    $< > $@ || rm $@ |  | ||||||
|  |  | ||||||
| # We substitute in bindir so it works as an autostart | # We substitute in bindir so it works as an autostart | ||||||
| # file when built in a non-system prefix | # file when built in a non-system prefix | ||||||
| @@ -35,49 +15,47 @@ introspection_DATA =				\ | |||||||
| 	org.gnome.Shell.Screencast.xml		\ | 	org.gnome.Shell.Screencast.xml		\ | ||||||
| 	org.gnome.Shell.Screenshot.xml		\ | 	org.gnome.Shell.Screenshot.xml		\ | ||||||
| 	org.gnome.ShellSearchProvider.xml	\ | 	org.gnome.ShellSearchProvider.xml	\ | ||||||
| 	org.gnome.ShellSearchProvider2.xml	\ | 	org.gnome.ShellSearchProvider2.xml | ||||||
| 	$(NULL) |  | ||||||
|  |  | ||||||
| theme_sources = 						\ | themedir = $(pkgdatadir)/theme | ||||||
| 	theme/gnome-shell-high-contrast.scss			\ | dist_theme_DATA =				\ | ||||||
| 	theme/gnome-shell.scss					\ | 	theme/calendar-arrow-left.svg		\ | ||||||
| 	theme/gnome-shell-sass/_colors.scss			\ | 	theme/calendar-arrow-right.svg		\ | ||||||
| 	theme/gnome-shell-sass/_common.scss			\ | 	theme/calendar-today.svg		\ | ||||||
| 	theme/gnome-shell-sass/_drawing.scss			\ | 	theme/checkbox-focused.svg		\ | ||||||
| 	theme/gnome-shell-sass/_high-contrast-colors.scss	\ | 	theme/checkbox-off-focused.svg		\ | ||||||
| 	$(NULL) | 	theme/checkbox-off.svg			\ | ||||||
|  | 	theme/checkbox.svg			\ | ||||||
| dist_theme_files =						\ | 	theme/close-window.svg			\ | ||||||
| 	$(theme_sources)					\ | 	theme/close.svg				\ | ||||||
| 	theme/Gemfile						\ | 	theme/corner-ripple-ltr.png		\ | ||||||
| 	theme/HACKING						\ | 	theme/corner-ripple-rtl.png		\ | ||||||
| 	theme/README						\ | 	theme/dash-placeholder.svg		\ | ||||||
| 	theme/gnome-shell-sass/COPYING				\ | 	theme/filter-selected-ltr.svg		\ | ||||||
| 	theme/gnome-shell-sass/HACKING				\ | 	theme/filter-selected-rtl.svg		\ | ||||||
| 	theme/gnome-shell-sass/NEWS				\ | 	theme/gnome-shell.css			\ | ||||||
| 	theme/gnome-shell-sass/README				\ | 	theme/logged-in-indicator.svg		\ | ||||||
| 	theme/gnome-shell-sass/gnome-shell-sass.doap		\ | 	theme/menu-arrow-symbolic.svg		    \ | ||||||
| 	theme/parse-sass.sh					\ | 	theme/message-tray-background.png	\ | ||||||
| 	$(NULL) | 	theme/more-results.svg			\ | ||||||
|  | 	theme/noise-texture.png			\ | ||||||
| %.css: %.scss $(theme_sources) | 	theme/page-indicator-active.svg		\ | ||||||
| 	@if test -n "$(SASS)"; then \ | 	theme/page-indicator-inactive.svg	\ | ||||||
| 		if $(AM_V_P); then PS4= set -x; else echo "  GEN      $@"; fi; \ | 	theme/page-indicator-checked.svg	\ | ||||||
| 		$(SASS) --sourcemap=none -f -q --update $<; \ | 	theme/page-indicator-hover.svg		\ | ||||||
| 	fi | 	theme/panel-button-border.svg		\ | ||||||
|  | 	theme/panel-button-highlight-narrow.svg	\ | ||||||
| resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir)/theme --generate-dependencies $(srcdir)/gnome-shell-theme.gresource.xml) | 	theme/panel-button-highlight-wide.svg	\ | ||||||
| gnome-shell-theme.gresource: gnome-shell-theme.gresource.xml $(resource_files) | 	theme/process-working.svg		\ | ||||||
| 	$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir)/theme $< | 	theme/running-indicator.svg		\ | ||||||
| resourcedir = $(pkgdatadir) | 	theme/source-button-border.svg		\ | ||||||
| resource_DATA = gnome-shell-theme.gresource | 	theme/summary-counter.svg		\ | ||||||
|  | 	theme/toggle-off-us.svg			\ | ||||||
| backgrounddir = $(pkgdatadir) | 	theme/toggle-off-intl.svg		\ | ||||||
| background_DATA = perf-background.xml | 	theme/toggle-on-us.svg			\ | ||||||
|  | 	theme/toggle-on-intl.svg		\ | ||||||
| perf-background.xml: perf-background.xml.in | 	theme/ws-switch-arrow-up.png		\ | ||||||
| 	$(AM_V_GEN) sed -e "s|@datadir[@]|$(datadir)|" \ | 	theme/ws-switch-arrow-down.png | ||||||
| 	    $< > $@ || rm $@ |  | ||||||
|  |  | ||||||
| keysdir = @GNOME_KEYBINDINGS_KEYSDIR@ | keysdir = @GNOME_KEYBINDINGS_KEYSDIR@ | ||||||
| keys_in_files = 50-gnome-shell-system.xml.in | keys_in_files = 50-gnome-shell-system.xml.in | ||||||
| @@ -104,30 +82,22 @@ convertdir = $(datadir)/GConf/gsettings | |||||||
| convert_DATA = gnome-shell-overrides.convert | convert_DATA = gnome-shell-overrides.convert | ||||||
|  |  | ||||||
| EXTRA_DIST =						\ | EXTRA_DIST =						\ | ||||||
| 	org.gnome.Shell.desktop.in.in			\ | 	gnome-shell.desktop.in.in			\ | ||||||
|  | 	gnome-shell-wayland.desktop.in.in		\ | ||||||
| 	gnome-shell-extension-prefs.desktop.in.in	\ | 	gnome-shell-extension-prefs.desktop.in.in	\ | ||||||
| 	$(introspection_DATA)				\ | 	$(introspection_DATA)				\ | ||||||
| 	$(menu_DATA)					\ | 	$(menu_DATA)					\ | ||||||
| 	$(convert_DATA)					\ | 	$(convert_DATA)					\ | ||||||
| 	$(keys_in_files)				\ | 	$(keys_in_files)				\ | ||||||
| 	$(dist_theme_files)				\ | 	org.gnome.shell.gschema.xml.in.in | ||||||
| 	perf-background.xml.in				\ |  | ||||||
| 	org.gnome.Shell.PortalHelper.desktop.in		\ |  | ||||||
| 	org.gnome.Shell.PortalHelper.service.in		\ |  | ||||||
| 	org.gnome.shell.gschema.xml.in.in		\ |  | ||||||
| 	gnome-shell-theme.gresource.xml 		\ |  | ||||||
| 	$(resource_files)				\ |  | ||||||
| 	$(NULL) |  | ||||||
|  |  | ||||||
| CLEANFILES +=						\ | CLEANFILES =						\ | ||||||
| 	org.gnome.Shell.desktop.in			\ | 	gnome-shell.desktop.in				\ | ||||||
|  | 	gnome-shell-wayland.desktop.in			\ | ||||||
| 	gnome-shell-extension-prefs.in			\ | 	gnome-shell-extension-prefs.in			\ | ||||||
| 	$(desktop_DATA)					\ | 	$(desktop_DATA)					\ | ||||||
| 	$(keys_DATA)					\ | 	$(keys_DATA)					\ | ||||||
| 	$(gsettings_SCHEMAS)				\ | 	$(gsettings_SCHEMAS)				\ | ||||||
| 	perf-background.xml				\ |  | ||||||
| 	gschemas.compiled				\ | 	gschemas.compiled				\ | ||||||
| 	org.gnome.shell.gschema.valid			\ | 	org.gnome.shell.gschema.valid			\ | ||||||
| 	org.gnome.shell.gschema.xml.in			\ | 	org.gnome.shell.gschema.xml.in | ||||||
| 	gnome-shell-theme.gresource			\ |  | ||||||
| 	$(NULL) |  | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| [org.gnome.shell.overrides] | [org.gnome.shell.overrides] | ||||||
| attach-modal-dialogs = /desktop/gnome/shell/windows/attach_modal_dialogs | attach-modal-dialogs = /desktop/gnome/shell/windows/attach_modal_dialogs | ||||||
|  | button-layout = /desktop/gnome/shell/windows/button_layout | ||||||
| edge-tiling = /desktop/gnome/shell/windows/edge_tiling | edge-tiling = /desktop/gnome/shell/windows/edge_tiling | ||||||
| workspaces-only-on-primary = /desktop/gnome/shell/windows/workspaces_only_on_primary | workspaces-only-on-primary = /desktop/gnome/shell/windows/workspaces_only_on_primary | ||||||
|   | |||||||
| @@ -1,42 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <gresources> |  | ||||||
|   <gresource prefix="/org/gnome/shell/theme"> |  | ||||||
|     <file>calendar-arrow-left.svg</file> |  | ||||||
|     <file>calendar-arrow-right.svg</file> |  | ||||||
|     <file>calendar-today.svg</file> |  | ||||||
|     <file>checkbox-focused.svg</file> |  | ||||||
|     <file>checkbox-off-focused.svg</file> |  | ||||||
|     <file>checkbox-off.svg</file> |  | ||||||
|     <file>checkbox.svg</file> |  | ||||||
|     <file>close-window.svg</file> |  | ||||||
|     <file>close.svg</file> |  | ||||||
|     <file>corner-ripple-ltr.png</file> |  | ||||||
|     <file>corner-ripple-rtl.png</file> |  | ||||||
|     <file>dash-placeholder.svg</file> |  | ||||||
|     <file>filter-selected-ltr.svg</file> |  | ||||||
|     <file>filter-selected-rtl.svg</file> |  | ||||||
|     <file>gnome-shell.css</file> |  | ||||||
|     <file>gnome-shell-high-contrast.css</file> |  | ||||||
|     <file>logged-in-indicator.svg</file> |  | ||||||
|     <file>more-results.svg</file> |  | ||||||
|     <file>no-events.svg</file> |  | ||||||
|     <file>no-notifications.svg</file> |  | ||||||
|     <file>noise-texture.png</file> |  | ||||||
|     <file>page-indicator-active.svg</file> |  | ||||||
|     <file>page-indicator-inactive.svg</file> |  | ||||||
|     <file>page-indicator-checked.svg</file> |  | ||||||
|     <file>page-indicator-hover.svg</file> |  | ||||||
|     <file>process-working.svg</file> |  | ||||||
|     <file>running-indicator.svg</file> |  | ||||||
|     <file>source-button-border.svg</file> |  | ||||||
|     <file>summary-counter.svg</file> |  | ||||||
|     <file>toggle-off-us.svg</file> |  | ||||||
|     <file>toggle-off-intl.svg</file> |  | ||||||
|     <file>toggle-off-hc.svg</file> |  | ||||||
|     <file>toggle-on-us.svg</file> |  | ||||||
|     <file>toggle-on-intl.svg</file> |  | ||||||
|     <file>toggle-on-hc.svg</file> |  | ||||||
|     <file>ws-switch-arrow-up.png</file> |  | ||||||
|     <file>ws-switch-arrow-down.png</file> |  | ||||||
|   </gresource> |  | ||||||
| </gresources> |  | ||||||
							
								
								
									
										15
									
								
								data/gnome-shell-wayland.desktop.in.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,15 @@ | |||||||
|  | [Desktop Entry] | ||||||
|  | Type=Application | ||||||
|  | _Name=GNOME Shell (wayland compositor) | ||||||
|  | _Comment=Window management and application launching | ||||||
|  | Exec=@bindir@/gnome-shell --wayland --display-server | ||||||
|  | X-GNOME-Bugzilla-Bugzilla=GNOME | ||||||
|  | X-GNOME-Bugzilla-Product=gnome-shell | ||||||
|  | X-GNOME-Bugzilla-Component=general | ||||||
|  | X-GNOME-Bugzilla-Version=@VERSION@ | ||||||
|  | Categories=GNOME;GTK;Core; | ||||||
|  | OnlyShowIn=GNOME; | ||||||
|  | NoDisplay=true | ||||||
|  | X-GNOME-Autostart-Phase=DisplayServer | ||||||
|  | X-GNOME-Autostart-Notify=true | ||||||
|  | X-GNOME-AutoRestart=false | ||||||
| @@ -10,7 +10,7 @@ X-GNOME-Bugzilla-Version=@VERSION@ | |||||||
| Categories=GNOME;GTK;Core; | Categories=GNOME;GTK;Core; | ||||||
| OnlyShowIn=GNOME; | OnlyShowIn=GNOME; | ||||||
| NoDisplay=true | NoDisplay=true | ||||||
| X-GNOME-Autostart-Phase=DisplayServer | X-GNOME-Autostart-Phase=WindowManager | ||||||
| X-GNOME-Provides=panel;windowmanager; | X-GNOME-Provides=panel;windowmanager; | ||||||
| X-GNOME-Autostart-Notify=true | X-GNOME-Autostart-Notify=true | ||||||
| X-GNOME-AutoRestart=false | X-GNOME-AutoRestart=false | ||||||
| @@ -1,9 +0,0 @@ | |||||||
| [Desktop Entry] |  | ||||||
| _Name=Network Login |  | ||||||
| Type=Application |  | ||||||
| Exec=gapplication launch org.gnome.Shell.PortalHelper |  | ||||||
| DBusActivatable=true |  | ||||||
| NoDisplay=true |  | ||||||
| Icon=network-workgroup |  | ||||||
| StartupNotify=true |  | ||||||
| OnlyShowIn=GNOME; |  | ||||||
| @@ -1,3 +0,0 @@ | |||||||
| [D-BUS Service] |  | ||||||
| Name=org.gnome.Shell.PortalHelper |  | ||||||
| Exec=@libexecdir@/gnome-shell-portal-helper |  | ||||||
| @@ -38,6 +38,7 @@ | |||||||
|     <method name="Screencast"> |     <method name="Screencast"> | ||||||
|       <arg type="s" direction="in" name="file_template"/> |       <arg type="s" direction="in" name="file_template"/> | ||||||
|       <arg type="a{sv}" direction="in" name="options"/> |       <arg type="a{sv}" direction="in" name="options"/> | ||||||
|  |       <arg type="b" direction="in" name="flash"/> | ||||||
|       <arg type="b" direction="out" name="success"/> |       <arg type="b" direction="out" name="success"/> | ||||||
|       <arg type="s" direction="out" name="filename_used"/> |       <arg type="s" direction="out" name="filename_used"/> | ||||||
|     </method> |     </method> | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ | |||||||
|       </_description> |       </_description> | ||||||
|     </key> |     </key> | ||||||
|     <key name="favorite-apps" type="as"> |     <key name="favorite-apps" type="as"> | ||||||
|       <default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default> |       <default>[ 'epiphany.desktop', 'evolution.desktop', 'empathy.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'libreoffice-writer.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Documents.desktop' ]</default> | ||||||
|       <_summary>List of desktop file IDs for favorite applications</_summary> |       <_summary>List of desktop file IDs for favorite applications</_summary> | ||||||
|       <_description> |       <_description> | ||||||
|         The applications corresponding to these identifiers |         The applications corresponding to these identifiers | ||||||
| @@ -40,10 +40,10 @@ | |||||||
|     </key> |     </key> | ||||||
|     <key name="app-picker-view" type="u"> |     <key name="app-picker-view" type="u"> | ||||||
|       <default>0</default> |       <default>0</default> | ||||||
|       <_summary>App Picker View</_summary> |       <summary>App Picker View</summary> | ||||||
|       <_description> |       <description> | ||||||
|         Index of the currently selected view in the application picker. |         Index of the currently selected view in the application picker. | ||||||
|       </_description> |       </description> | ||||||
|     </key> |     </key> | ||||||
|     <key name="command-history" type="as"> |     <key name="command-history" type="as"> | ||||||
|       <default>[]</default> |       <default>[]</default> | ||||||
| @@ -51,7 +51,6 @@ | |||||||
|     </key> |     </key> | ||||||
|     <key name="looking-glass-history" type="as"> |     <key name="looking-glass-history" type="as"> | ||||||
|       <default>[]</default> |       <default>[]</default> | ||||||
|       <!-- Translators: looking glass is a debugger and inspector tool, see https://live.gnome.org/GnomeShell/LookingGlass --> |  | ||||||
|       <_summary>History for the looking glass dialog</_summary> |       <_summary>History for the looking glass dialog</_summary> | ||||||
|     </key> |     </key> | ||||||
|     <key name="always-show-log-out" type="b"> |     <key name="always-show-log-out" type="b"> | ||||||
| @@ -72,19 +71,10 @@ | |||||||
|         This key sets the default state of the checkbox. |         This key sets the default state of the checkbox. | ||||||
|       </_description> |       </_description> | ||||||
|     </key> |     </key> | ||||||
|     <key name="had-bluetooth-devices-setup" type="b"> |  | ||||||
|       <default>false</default> |  | ||||||
|       <_summary>Whether the default Bluetooth adapter had set up devices associated to it</_summary> |  | ||||||
|       <_description> |  | ||||||
|         The shell will only show a Bluetooth menu item if a Bluetooth |  | ||||||
|         adapter is powered, or if there were devices set up associated |  | ||||||
|         with the default adapter. This will be reset if the default |  | ||||||
|         adapter is ever seen not to have devices associated to it. |  | ||||||
|       </_description> |  | ||||||
|     </key> |  | ||||||
|     <child name="calendar" schema="org.gnome.shell.calendar"/> |     <child name="calendar" schema="org.gnome.shell.calendar"/> | ||||||
|     <child name="keybindings" schema="org.gnome.shell.keybindings"/> |     <child name="keybindings" schema="org.gnome.shell.keybindings"/> | ||||||
|     <child name="keyboard" schema="org.gnome.shell.keyboard"/> |     <child name="keyboard" schema="org.gnome.shell.keyboard"/> | ||||||
|  |     <child name="location" schema="org.gnome.shell.location"/> | ||||||
|   </schema> |   </schema> | ||||||
|  |  | ||||||
|   <schema id="org.gnome.shell.calendar" path="/org/gnome/shell/calendar/" |   <schema id="org.gnome.shell.calendar" path="/org/gnome/shell/calendar/" | ||||||
| @@ -123,10 +113,10 @@ | |||||||
|       </_description> |       </_description> | ||||||
|     </key> |     </key> | ||||||
|     <key name="toggle-message-tray" type="as"> |     <key name="toggle-message-tray" type="as"> | ||||||
|       <default>["<Super>v","<Super>m"]</default> |       <default>["<Super>m"]</default> | ||||||
|       <_summary>Keybinding to toggle the visibility of the notification list</_summary> |       <_summary>Keybinding to toggle the visibility of the message tray</_summary> | ||||||
|       <_description> |       <_description> | ||||||
|         Keybinding to toggle the visibility of the notification list. |         Keybinding to toggle the visibility of the message tray. | ||||||
|       </_description> |       </_description> | ||||||
|     </key> |     </key> | ||||||
|     <key name="focus-active-notification" type="as"> |     <key name="focus-active-notification" type="as"> | ||||||
| @@ -138,8 +128,8 @@ | |||||||
|     </key> |     </key> | ||||||
|     <key name="pause-resume-tweens" type="as"> |     <key name="pause-resume-tweens" type="as"> | ||||||
|       <default>[]</default> |       <default>[]</default> | ||||||
|       <_summary>Keybinding that pauses and resumes all running tweens, for debugging purposes</_summary> |       <summary>Keybinding that pauses and resumes all running tweens, for debugging purposes</summary> | ||||||
|       <_description></_description> |       <description></description> | ||||||
|     </key> |     </key> | ||||||
|   </schema> |   </schema> | ||||||
|  |  | ||||||
| @@ -154,16 +144,42 @@ | |||||||
|     </key> |     </key> | ||||||
|   </schema> |   </schema> | ||||||
|  |  | ||||||
|  |   <enum id="org.gnome.shell.geoclue.AccuracyLevel"> | ||||||
|  |     <value value="0" nick="off"/> | ||||||
|  |     <value value="1" nick="country"/> | ||||||
|  |     <value value="4" nick="city"/> | ||||||
|  |     <value value="5" nick="neighborhood"/> | ||||||
|  |     <value value="6" nick="street"/> | ||||||
|  |     <value value="8" nick="exact"/> | ||||||
|  |   </enum> | ||||||
|  |   <schema id="org.gnome.shell.location" | ||||||
|  |           path="/org/gnome/shell/location/" | ||||||
|  |           gettext-domain="@GETTEXT_PACKAGE@"> | ||||||
|  |     <key name="max-accuracy-level" enum="org.gnome.shell.geoclue.AccuracyLevel"> | ||||||
|  |       <default>'exact'</default> | ||||||
|  |       <_summary>The maximum accuracy level of location.</_summary> | ||||||
|  |       <_description> | ||||||
|  |         Configures the maximum level of location accuracy applications are | ||||||
|  |         allowed to see. Valid options are 'off' (disable location tracking), | ||||||
|  |         'country', 'city', 'neighborhood', 'street', and 'exact' (typically | ||||||
|  |         requires GPS receiver). Please keep in mind that this only controls | ||||||
|  |         what GeoClue will allow applications to see and they can find user's | ||||||
|  |         location on their own using network resources (albeit with street-level | ||||||
|  |         accuracy at best). | ||||||
|  |       </_description> | ||||||
|  |     </key> | ||||||
|  |   </schema> | ||||||
|  |  | ||||||
|   <schema id="org.gnome.shell.app-switcher" |   <schema id="org.gnome.shell.app-switcher" | ||||||
|           path="/org/gnome/shell/app-switcher/" |           path="/org/gnome/shell/app-switcher/" | ||||||
|           gettext-domain="@GETTEXT_PACKAGE@"> |           gettext-domain="@GETTEXT_PACKAGE@"> | ||||||
|     <key type="b" name="current-workspace-only"> |     <key type="b" name="current-workspace-only"> | ||||||
|       <default>false</default> |       <default>false</default> | ||||||
|       <_summary>Limit switcher to current workspace.</_summary> |       <summary>Limit switcher to current workspace.</summary> | ||||||
|       <_description> |       <description> | ||||||
| 	If true, only applications that have windows on the current workspace are shown in the switcher. | 	If true, only applications that have windows on the current workspace are shown in the switcher. | ||||||
| 	Otherwise, all applications are included. | 	Otherwise, all applications are included. | ||||||
|       </_description> |       </description> | ||||||
|     </key> |     </key> | ||||||
|   </schema> |   </schema> | ||||||
|  |  | ||||||
| @@ -186,11 +202,11 @@ | |||||||
|     </key> |     </key> | ||||||
|     <key type="b" name="current-workspace-only"> |     <key type="b" name="current-workspace-only"> | ||||||
|       <default>true</default> |       <default>true</default> | ||||||
|       <_summary>Limit switcher to current workspace.</_summary> |       <summary>Limit switcher to current workspace.</summary> | ||||||
|       <_description> |       <description> | ||||||
| 	If true, only windows from the current workspace are shown in the switcher. | 	If true, only windows from the current workspace are shown in the switcher. | ||||||
| 	Otherwise, all windows are included. | 	Otherwise, all windows are included. | ||||||
|       </_description> |       </description> | ||||||
|     </key> |     </key> | ||||||
|   </schema> |   </schema> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,31 +0,0 @@ | |||||||
| <!-- With an animated background, performance will differ depending on whether |  | ||||||
|      one layer or two layers are being blended together. This messes up our |  | ||||||
|      benchmarks. We could just benchmark a single image, but since blended |  | ||||||
|      images are present for much of the day with the GNOME default background, |  | ||||||
|      we want to make sure that also performs well; for that reason we ship |  | ||||||
|      an "animated" background that animates super-slowly to use during |  | ||||||
|      performance tests; it will be in the blended state until 2030. --> |  | ||||||
| <background> |  | ||||||
|   <starttime> |  | ||||||
|     <year>1990</year> |  | ||||||
|     <month>1</month> |  | ||||||
|     <day>1</day> |  | ||||||
|     <hour>0</hour> |  | ||||||
|     <minute>00</minute> |  | ||||||
|     <second>00</second> |  | ||||||
|   </starttime> |  | ||||||
|  |  | ||||||
| <!-- One transition that takes 40 years --> |  | ||||||
| <transition type="overlay"> |  | ||||||
| <duration>1261440000.0</duration> |  | ||||||
| <from>@datadir@/backgrounds/gnome/adwaita-morning.jpg</from> |  | ||||||
| <to>@datadir@/backgrounds/gnome/adwaita-day.jpg</to> |  | ||||||
| </transition> |  | ||||||
|  |  | ||||||
| <!-- A single slide doesn't work, so another slide for 1 minute after 40 years --> |  | ||||||
| <static> |  | ||||||
| <duration>60</duration> |  | ||||||
| <file>/usr/share/backgrounds/gnome/Sandstone.jpg</file> |  | ||||||
| </static> |  | ||||||
|  |  | ||||||
| </background> |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| gem "sass", "~> 3.4.0" |  | ||||||
| @@ -1,3 +0,0 @@ | |||||||
| To generate the css files, from the project directory: |  | ||||||
|  |  | ||||||
| sass --sourcemap=none --update . |  | ||||||
| @@ -1,36 +0,0 @@ | |||||||
| Summary |  | ||||||
| ------- |  | ||||||
|  |  | ||||||
| * Do not edit the CSS directly, edit the source SCSS files and process them with SASS (running |  | ||||||
|   `make` should do that when you have the required software installed, as described below; |  | ||||||
|   run `/.parse-sass.sh` manually if it doesn't) |  | ||||||
| * To be able to use the lates/adequate version of sass, install ruby, gem, sass & bundle.  |  | ||||||
|   On Fedora F20, this is done with `sudo dnf install rubygems && gem install bundle && bundle install` |  | ||||||
|   from the same directory this README resides in. |  | ||||||
|  |  | ||||||
| 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 the ./parse-sass.sh script or keep SASS watching for changes as you |  | ||||||
| edit. This is done by running `bundle exec sass --watch --sourcemap=none .` If sass is out of date, or is |  | ||||||
| missing, you can install it with `bundle install`. |  | ||||||
| @@ -10,11 +10,11 @@ | |||||||
|    xmlns:xlink="http://www.w3.org/1999/xlink" |    xmlns:xlink="http://www.w3.org/1999/xlink" | ||||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|    width="24" |    width="29" | ||||||
|    height="24" |    height="29" | ||||||
|    id="svg10621" |    id="svg10621" | ||||||
|    version="1.1" |    version="1.1" | ||||||
|    inkscape:version="0.91 r13725" |    inkscape:version="0.48.2 r9819" | ||||||
|    sodipodi:docname="calendar-today.svg"> |    sodipodi:docname="calendar-today.svg"> | ||||||
|   <defs |   <defs | ||||||
|      id="defs10623"> |      id="defs10623"> | ||||||
| @@ -118,6 +118,17 @@ | |||||||
|        fx="51" |        fx="51" | ||||||
|        fy="30" |        fy="30" | ||||||
|        r="42" /> |        r="42" /> | ||||||
|  |     <radialGradient | ||||||
|  |        inkscape:collect="always" | ||||||
|  |        xlink:href="#linearGradient34508-1-3" | ||||||
|  |        id="radialGradient3113" | ||||||
|  |        gradientUnits="userSpaceOnUse" | ||||||
|  |        gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)" | ||||||
|  |        cx="51" | ||||||
|  |        cy="30" | ||||||
|  |        fx="51" | ||||||
|  |        fy="30" | ||||||
|  |        r="42" /> | ||||||
|   </defs> |   </defs> | ||||||
|   <sodipodi:namedview |   <sodipodi:namedview | ||||||
|      id="base" |      id="base" | ||||||
| @@ -126,23 +137,22 @@ | |||||||
|      borderopacity="1.0" |      borderopacity="1.0" | ||||||
|      inkscape:pageopacity="0" |      inkscape:pageopacity="0" | ||||||
|      inkscape:pageshadow="2" |      inkscape:pageshadow="2" | ||||||
|      inkscape:zoom="8" |      inkscape:zoom="15.839192" | ||||||
|      inkscape:cx="-23.537329" |      inkscape:cx="20.652108" | ||||||
|      inkscape:cy="-31.442864" |      inkscape:cy="11.839084" | ||||||
|      inkscape:document-units="px" |      inkscape:document-units="px" | ||||||
|      inkscape:current-layer="layer1" |      inkscape:current-layer="layer1" | ||||||
|      showgrid="false" |      showgrid="true" | ||||||
|      fit-margin-top="0" |      fit-margin-top="0" | ||||||
|      fit-margin-left="0" |      fit-margin-left="0" | ||||||
|      fit-margin-right="0" |      fit-margin-right="0" | ||||||
|      fit-margin-bottom="0" |      fit-margin-bottom="0" | ||||||
|      inkscape:window-width="2133" |      inkscape:window-width="1280" | ||||||
|      inkscape:window-height="1241" |      inkscape:window-height="741" | ||||||
|      inkscape:window-x="238" |      inkscape:window-x="0" | ||||||
|      inkscape:window-y="88" |      inkscape:window-y="27" | ||||||
|      inkscape:window-maximized="0" |      inkscape:window-maximized="1" | ||||||
|      borderlayer="true" |      borderlayer="true"> | ||||||
|      inkscape:showpageshadow="false"> |  | ||||||
|     <inkscape:grid |     <inkscape:grid | ||||||
|        type="xygrid" |        type="xygrid" | ||||||
|        id="grid3109" |        id="grid3109" | ||||||
| @@ -159,7 +169,7 @@ | |||||||
|         <dc:format>image/svg+xml</dc:format> |         <dc:format>image/svg+xml</dc:format> | ||||||
|         <dc:type |         <dc:type | ||||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||||
|         <dc:title></dc:title> |         <dc:title /> | ||||||
|       </cc:Work> |       </cc:Work> | ||||||
|     </rdf:RDF> |     </rdf:RDF> | ||||||
|   </metadata> |   </metadata> | ||||||
| @@ -167,12 +177,28 @@ | |||||||
|      inkscape:label="Layer 1" |      inkscape:label="Layer 1" | ||||||
|      inkscape:groupmode="layer" |      inkscape:groupmode="layer" | ||||||
|      id="layer1" |      id="layer1" | ||||||
|      transform="translate(-469.08263,-537.99307)"> |      transform="translate(-469.08263,-532.99307)"> | ||||||
|     <circle |     <path | ||||||
|        style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:0.23756906;fill-rule:nonzero;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;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" |        sodipodi:type="arc" | ||||||
|        id="path7305" |        style="opacity:0.4625;color:#000000;fill:url(#radialGradient3113);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||||||
|        cx="481.57138" |        id="path34506-3" | ||||||
|        cy="559.4649" |        sodipodi:cx="51" | ||||||
|        r="1.5" /> |        sodipodi:cy="30" | ||||||
|  |        sodipodi:rx="42" | ||||||
|  |        sodipodi:ry="16" | ||||||
|  |        d="M 9,29.999999 A 42,16 0 0 1 93,30 l -42,0 z" | ||||||
|  |        sodipodi:start="3.1415927" | ||||||
|  |        sodipodi:end="6.2831853" | ||||||
|  |        transform="matrix(0.43692393,0,0,1.3783114,461.29951,517.6437)" | ||||||
|  |        inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/motion/textures/panel.png" | ||||||
|  |        inkscape:export-xdpi="90" | ||||||
|  |        inkscape:export-ydpi="90" /> | ||||||
|  |     <rect | ||||||
|  |        style="fill:#ffffff;fill-opacity:0.50196078;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none" | ||||||
|  |        id="rect2996" | ||||||
|  |        width="31" | ||||||
|  |        height="3" | ||||||
|  |        x="468.08264" | ||||||
|  |        y="558.99304" /> | ||||||
|   </g> |   </g> | ||||||
| </svg> | </svg> | ||||||
|   | |||||||
| Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 6.1 KiB | 
| @@ -14,7 +14,7 @@ | |||||||
|    height="22" |    height="22" | ||||||
|    id="svg3199" |    id="svg3199" | ||||||
|    version="1.1" |    version="1.1" | ||||||
|    inkscape:version="0.48.5 r10040" |    inkscape:version="0.48.1 r9760" | ||||||
|    sodipodi:docname="checkbox.svg"> |    sodipodi:docname="checkbox.svg"> | ||||||
|   <defs |   <defs | ||||||
|      id="defs3201"> |      id="defs3201"> | ||||||
| @@ -132,54 +132,51 @@ | |||||||
|        xlink:href="#linearGradient10597-5" |        xlink:href="#linearGradient10597-5" | ||||||
|        inkscape:collect="always" /> |        inkscape:collect="always" /> | ||||||
|     <linearGradient |     <linearGradient | ||||||
|        inkscape:collect="always" |        y2="-388.72955" | ||||||
|        xlink:href="#linearGradient5581-5-2-4-6-8-7-35-8" |        x2="-93.031357" | ||||||
|        id="linearGradient11811" |        y1="-396.34738" | ||||||
|  |        x1="-93.031357" | ||||||
|  |        gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.685418)" | ||||||
|        gradientUnits="userSpaceOnUse" |        gradientUnits="userSpaceOnUse" | ||||||
|        gradientTransform="matrix(3.0317573,0,0,1.0053174,-102.66338,-0.82153381)" |        id="linearGradient14219-6" | ||||||
|        x1="63.568954" |        xlink:href="#linearGradient15404-9" | ||||||
|        y1="127.16142" |        inkscape:collect="always" /> | ||||||
|        x2="63.568954" |  | ||||||
|        y2="152.6618" /> |  | ||||||
|     <linearGradient |     <linearGradient | ||||||
|        id="linearGradient5581-5-2-4-6-8-7-35-8"> |        id="linearGradient15404-9" | ||||||
|  |        inkscape:collect="always"> | ||||||
|       <stop |       <stop | ||||||
|          id="stop5583-0-92-8-0-7-6-5-1" |          id="stop15406-6" | ||||||
|          offset="0" |          offset="0" | ||||||
|          style="stop-color:#454c4c;stop-opacity:1;" /> |          style="stop-color:#515151;stop-opacity:1" /> | ||||||
|       <stop |       <stop | ||||||
|          style="stop-color:#393f3f;stop-opacity:1;" |          id="stop15408-7" | ||||||
|          offset="0.40000001" |  | ||||||
|          id="stop5585-4-7-2-7-9-9-92-0" /> |  | ||||||
|       <stop |  | ||||||
|          id="stop5587-6-7-2-0-3-1-21-5" |  | ||||||
|          offset="1" |          offset="1" | ||||||
|          style="stop-color:#2d3232;stop-opacity:1;" /> |          style="stop-color:#292929;stop-opacity:1" /> | ||||||
|     </linearGradient> |     </linearGradient> | ||||||
|   </defs> |   </defs> | ||||||
|   <sodipodi:namedview |   <sodipodi:namedview | ||||||
|      id="base" |      id="base" | ||||||
|      pagecolor="#a2a2a2" |      pagecolor="#000000" | ||||||
|      bordercolor="#2d2d2d" |      bordercolor="#2d2d2d" | ||||||
|      borderopacity="1" |      borderopacity="1" | ||||||
|      inkscape:pageopacity="1" |      inkscape:pageopacity="1" | ||||||
|      inkscape:pageshadow="2" |      inkscape:pageshadow="2" | ||||||
|      inkscape:zoom="22.627417" |      inkscape:zoom="1" | ||||||
|      inkscape:cx="9.6447897" |      inkscape:cx="71.516955" | ||||||
|      inkscape:cy="12.591409" |      inkscape:cy="5.8710559" | ||||||
|      inkscape:document-units="px" |      inkscape:document-units="px" | ||||||
|      inkscape:current-layer="layer1" |      inkscape:current-layer="layer1" | ||||||
|      showgrid="false" |      showgrid="false" | ||||||
|      inkscape:window-width="1412" |      inkscape:window-width="1412" | ||||||
|      inkscape:window-height="1067" |      inkscape:window-height="1067" | ||||||
|      inkscape:window-x="184" |      inkscape:window-x="2635" | ||||||
|      inkscape:window-y="233" |      inkscape:window-y="226" | ||||||
|      inkscape:window-maximized="0" |      inkscape:window-maximized="0" | ||||||
|      borderlayer="true" |      borderlayer="true" | ||||||
|      inkscape:showpageshadow="false" |      inkscape:showpageshadow="false" | ||||||
|      inkscape:snap-nodes="false" |      inkscape:snap-nodes="false" | ||||||
|      inkscape:snap-bbox="true" |      inkscape:snap-bbox="true" | ||||||
|      showborder="true"> |      showborder="false"> | ||||||
|     <inkscape:grid |     <inkscape:grid | ||||||
|        type="xygrid" |        type="xygrid" | ||||||
|        id="grid14843" |        id="grid14843" | ||||||
| @@ -206,56 +203,87 @@ | |||||||
|      id="layer1" |      id="layer1" | ||||||
|      transform="translate(-342.5,-521.36218)"> |      transform="translate(-342.5,-521.36218)"> | ||||||
|     <g |     <g | ||||||
|        style="display:inline" |        transform="matrix(0.80230061,0,0,0.80230061,-87.624044,-453.10297)" | ||||||
|        id="use5671" |        id="g14586-0" | ||||||
|        transform="matrix(1.3594109,0,0,1.3564242,319.2059,481.99447)"> |        style="stroke-width:2.3714385;stroke-miterlimit:4;stroke-dasharray:none"> | ||||||
|  |       <g | ||||||
|  |          inkscape:export-ydpi="90" | ||||||
|  |          inkscape:export-xdpi="90" | ||||||
|  |          inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png" | ||||||
|  |          transform="matrix(1.9969286,0,0,1.9969286,-397.05491,877.00482)" | ||||||
|  |          id="g15291-9-6" | ||||||
|  |          style="stroke-width:1.18754292;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"> | ||||||
|  |         <g | ||||||
|  |            transform="translate(877.50354,-102.83507)" | ||||||
|  |            id="g16853-4-9" | ||||||
|  |            style="stroke-width:1.18754292;stroke-miterlimit:4;stroke-dasharray:none;enable-background:new"> | ||||||
|           <rect |           <rect | ||||||
|          transform="matrix(0.47304779,0,0,0.4807373,-6.3607039,-29.396216)" |              transform="scale(1,-1)" | ||||||
|          rx="4.4136767" |              style="color:#000000;fill:url(#linearGradient14219-6);fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:1.24833274;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" | ||||||
|          y="125.3458" |              id="rect6506-6" | ||||||
|          x="50.440369" |              width="11.281681" | ||||||
|          height="29.154205" |              height="11.26221" | ||||||
|          width="29.559635" |              x="-409.59354" | ||||||
|          id="rect11803" |              y="-284.40115" | ||||||
|          style="color:#000000;fill:url(#linearGradient11811);fill-opacity:1;stroke:#3465a4;stroke-width:1.54426003000000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |              rx="1.0052766" | ||||||
|          ry="4.4233952" /> |              ry="1.0052764" /> | ||||||
|       <path |  | ||||||
|          inkscape:connector-curvature="0" |  | ||||||
|          id="path11809" |  | ||||||
|          d="m 17.87105,33.844107 0,-0.773112 c 0,-1.031264 0.807171,-1.836142 1.811982,-1.836142 l 9.612456,0 c 1.004811,0 1.787822,0.804878 1.787822,1.836142 l 0,0.773112 c 0,-1.031264 -0.783011,-1.836142 -1.787822,-1.836142 l -9.612456,0 c -1.004811,0 -1.811982,0.804878 -1.811982,1.836142 z" |  | ||||||
|          style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" |  | ||||||
|          sodipodi:nodetypes="csssscssc" /> |  | ||||||
|       <path |  | ||||||
|          sodipodi:nodetypes="csssscssc" |  | ||||||
|          style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" |  | ||||||
|          d="m 17.87105,41.158551 0,0.773112 c 0,1.031264 0.807171,1.836142 1.811982,1.836142 l 9.612456,0 c 1.004811,0 1.787822,-0.804878 1.787822,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z" |  | ||||||
|          id="path11867" |  | ||||||
|          inkscape:connector-curvature="0" /> |  | ||||||
|       <path |  | ||||||
|          inkscape:connector-curvature="0" |  | ||||||
|          id="path11869" |  | ||||||
|          d="m 17.87105,41.895784 0,0.773112 c 0,1.031264 0.644622,1.836142 1.649433,1.836142 l 10.067593,0 c 1.004811,0 1.495234,-0.804878 1.495234,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z" |  | ||||||
|          style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#000000;fill-opacity:0.85253451;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" |  | ||||||
|          sodipodi:nodetypes="csssscssc" /> |  | ||||||
|         </g> |         </g> | ||||||
|     <rect |       </g> | ||||||
|        style="color:#000000;fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |       <g | ||||||
|        id="rect17347" |          inkscape:export-ydpi="90" | ||||||
|        width="21.943846" |          inkscape:export-xdpi="90" | ||||||
|        height="21.943846" |          inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png" | ||||||
|        x="342.29913" |          transform="translate(343.99999,987.99997)" | ||||||
|        y="521.58435" /> |          id="g5886-5" | ||||||
|  |          style="stroke-width:2.3714385;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new" /> | ||||||
|  |     </g> | ||||||
|  |     <g | ||||||
|  |        transform="matrix(0.84337,0,0,0.84337,-110.16632,-503.56182)" | ||||||
|  |        id="g14586"> | ||||||
|  |       <g | ||||||
|  |          inkscape:export-ydpi="90" | ||||||
|  |          inkscape:export-xdpi="90" | ||||||
|  |          inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png" | ||||||
|  |          transform="matrix(1.9969286,0,0,1.9969286,-397.05491,877.00482)" | ||||||
|  |          id="g15291-9" | ||||||
|  |          style="display:inline;enable-background:new"> | ||||||
|  |         <g | ||||||
|  |            transform="translate(877.50354,-102.83507)" | ||||||
|  |            id="g16853-4" | ||||||
|  |            style="enable-background:new" /> | ||||||
|  |       </g> | ||||||
|  |       <g | ||||||
|  |          inkscape:export-ydpi="90" | ||||||
|  |          inkscape:export-xdpi="90" | ||||||
|  |          inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png" | ||||||
|  |          transform="translate(343.99999,987.99997)" | ||||||
|  |          id="g5886" | ||||||
|  |          style="display:inline;enable-background:new"> | ||||||
|  |         <path | ||||||
|  |            style="fill:none;stroke:url(#linearGradient5891-0-4);stroke-width:7.11431503;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" | ||||||
|  |            d="m 198.5,240 5.25,5.25 13.98616,-14.43081" | ||||||
|  |            id="path5835" | ||||||
|  |            inkscape:path-effect="#path-effect5837-4-6" | ||||||
|  |            inkscape:original-d="m 198.5,240 5.25,5.25 13.98616,-14.43081" | ||||||
|  |            inkscape:connector-curvature="0" | ||||||
|  |            sodipodi:nodetypes="ccc" /> | ||||||
|         <path |         <path | ||||||
|            inkscape:connector-curvature="0" |            inkscape:connector-curvature="0" | ||||||
|        style="opacity:0.8;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |            inkscape:original-d="m 198.5,240 5.25,5.25 13.91205,-14.31964" | ||||||
|        d="m 359.97505,524.8252 -7.88606,7.71465 -2.57155,-2.57155 -2.91442,-0.0427 0,2.35727 4.02875,3.98587 c 0.80342,0.80309 2.111,0.80309 2.91442,0 l 8.18609,-8.22894 0,-0.38573 c 0,-1.24128 0.19944,-1.76801 -0.82915,-2.29836 z" |            inkscape:path-effect="#path-effect5837-4-6" | ||||||
|        id="rect5147-9-1-5-7-6-5-8-7" |            id="path5880" | ||||||
|        sodipodi:nodetypes="ccccccccscc" /> |            d="m 198.5,240 5.25,5.25 13.91205,-14.31964" | ||||||
|  |            style="fill:none;stroke:#4787c8;stroke-width:3.55715752;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" | ||||||
|  |            sodipodi:nodetypes="ccc" /> | ||||||
|         <path |         <path | ||||||
|        style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#eeeeec;fill-opacity:1;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:sans-serif;-inkscape-font-specification:sans-serif" |            style="fill:none;stroke:#7ea7d3;stroke-width:1.18571913px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||||
|        d="m 361.65223,524.52745 -9.5602,9.36735 -2.56345,-2.56344 -2.92846,-0.0214 0.0153,2.32639 4.02203,4.02206 c 0.80341,0.80309 2.10565,0.80309 2.90906,0 l 10.95049,-11.05765 0.003,-2.1502 z" |            d="m 197.45937,240.47455 c -0.17828,-0.29362 -0.20087,-0.67548 -0.0603,-0.98892 0.14055,-0.31344 0.43739,-0.54812 0.77144,-0.62817 0.33405,-0.08 0.69314,-0.01 0.99635,0.15175 0.30321,0.16144 0.55146,0.40727 0.79165,0.65284 l 3.66429,3.74643 12.87946,-12.98973 c 0.20796,-0.20974 0.42306,-0.41969 0.68548,-0.55522 0.26242,-0.13553 0.57293,-0.19052 0.85827,-0.11426 0.14267,0.0381 0.27708,0.10787 0.38874,0.20452 0.11167,0.0966 0.20021,0.22004 0.25479,0.35726 0.0546,0.13722 0.075,0.28793 0.0585,0.43468 -0.0165,0.14674 -0.07,0.28919 -0.15422,0.41052" | ||||||
|        id="path12830-4-17-0" |            id="path5882" | ||||||
|  |            inkscape:path-effect="#path-effect5884-4-7" | ||||||
|  |            inkscape:original-d="m 197.45937,240.47455 c 0.65604,-0.56057 2.02485,-1.34847 2.49911,-0.8125 l 3.66429,3.74643 12.87946,-12.98973 c 0.6875,-0.6875 2.09152,0.7375 2.09152,0.7375" | ||||||
|            inkscape:connector-curvature="0" |            inkscape:connector-curvature="0" | ||||||
|        sodipodi:nodetypes="cccccccccc" /> |            sodipodi:nodetypes="csccc" /> | ||||||
|  |       </g> | ||||||
|  |     </g> | ||||||
|   </g> |   </g> | ||||||
| </svg> | </svg> | ||||||
|   | |||||||
| Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB | 
| @@ -14,10 +14,22 @@ | |||||||
|    height="22" |    height="22" | ||||||
|    id="svg3199" |    id="svg3199" | ||||||
|    version="1.1" |    version="1.1" | ||||||
|    inkscape:version="0.48.5 r10040" |    inkscape:version="0.48.1 r9760" | ||||||
|    sodipodi:docname="checkbox-off.svg"> |    sodipodi:docname="checkbox-off.svg"> | ||||||
|   <defs |   <defs | ||||||
|      id="defs3201"> |      id="defs3201"> | ||||||
|  |     <linearGradient | ||||||
|  |        id="linearGradient15404" | ||||||
|  |        inkscape:collect="always"> | ||||||
|  |       <stop | ||||||
|  |          id="stop15406" | ||||||
|  |          offset="0" | ||||||
|  |          style="stop-color:#515151;stop-opacity:1" /> | ||||||
|  |       <stop | ||||||
|  |          id="stop15408" | ||||||
|  |          offset="1" | ||||||
|  |          style="stop-color:#292929;stop-opacity:1" /> | ||||||
|  |     </linearGradient> | ||||||
|     <inkscape:perspective |     <inkscape:perspective | ||||||
|        sodipodi:type="inkscape:persp3d" |        sodipodi:type="inkscape:persp3d" | ||||||
|        inkscape:vp_x="0 : 526.18109 : 1" |        inkscape:vp_x="0 : 526.18109 : 1" | ||||||
| @@ -44,6 +56,16 @@ | |||||||
|        effect="spiro" |        effect="spiro" | ||||||
|        id="path-effect5884-4-7" |        id="path-effect5884-4-7" | ||||||
|        is_visible="true" /> |        is_visible="true" /> | ||||||
|  |     <linearGradient | ||||||
|  |        y2="-388.72955" | ||||||
|  |        x2="-93.031357" | ||||||
|  |        y1="-396.34738" | ||||||
|  |        x1="-93.031357" | ||||||
|  |        gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.685418)" | ||||||
|  |        gradientUnits="userSpaceOnUse" | ||||||
|  |        id="linearGradient14219" | ||||||
|  |        xlink:href="#linearGradient15404" | ||||||
|  |        inkscape:collect="always" /> | ||||||
|     <linearGradient |     <linearGradient | ||||||
|        inkscape:collect="always" |        inkscape:collect="always" | ||||||
|        id="linearGradient10013-4-63-6"> |        id="linearGradient10013-4-63-6"> | ||||||
| @@ -88,55 +110,30 @@ | |||||||
|        id="linearGradient15376" |        id="linearGradient15376" | ||||||
|        xlink:href="#linearGradient10597-5" |        xlink:href="#linearGradient10597-5" | ||||||
|        inkscape:collect="always" /> |        inkscape:collect="always" /> | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient5581-5-2-4-6-8-7-35-8" |  | ||||||
|        id="linearGradient11811" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        gradientTransform="matrix(3.0317573,0,0,1.0053174,-102.66338,-0.82153381)" |  | ||||||
|        x1="63.568954" |  | ||||||
|        y1="127.16142" |  | ||||||
|        x2="63.568954" |  | ||||||
|        y2="152.6618" /> |  | ||||||
|     <linearGradient |  | ||||||
|        id="linearGradient5581-5-2-4-6-8-7-35-8"> |  | ||||||
|       <stop |  | ||||||
|          id="stop5583-0-92-8-0-7-6-5-1" |  | ||||||
|          offset="0" |  | ||||||
|          style="stop-color:#454c4c;stop-opacity:1;" /> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#393f3f;stop-opacity:1;" |  | ||||||
|          offset="0.40000001" |  | ||||||
|          id="stop5585-4-7-2-7-9-9-92-0" /> |  | ||||||
|       <stop |  | ||||||
|          id="stop5587-6-7-2-0-3-1-21-5" |  | ||||||
|          offset="1" |  | ||||||
|          style="stop-color:#2d3232;stop-opacity:1;" /> |  | ||||||
|     </linearGradient> |  | ||||||
|   </defs> |   </defs> | ||||||
|   <sodipodi:namedview |   <sodipodi:namedview | ||||||
|      id="base" |      id="base" | ||||||
|      pagecolor="#a2a2a2" |      pagecolor="#000000" | ||||||
|      bordercolor="#2d2d2d" |      bordercolor="#2d2d2d" | ||||||
|      borderopacity="1" |      borderopacity="1" | ||||||
|      inkscape:pageopacity="1" |      inkscape:pageopacity="1" | ||||||
|      inkscape:pageshadow="2" |      inkscape:pageshadow="2" | ||||||
|      inkscape:zoom="5.6568542" |      inkscape:zoom="1" | ||||||
|      inkscape:cx="19.79113" |      inkscape:cx="6.1225392" | ||||||
|      inkscape:cy="11.232334" |      inkscape:cy="3.6003241" | ||||||
|      inkscape:document-units="px" |      inkscape:document-units="px" | ||||||
|      inkscape:current-layer="layer1" |      inkscape:current-layer="layer1" | ||||||
|      showgrid="false" |      showgrid="false" | ||||||
|      inkscape:window-width="1412" |      inkscape:window-width="1412" | ||||||
|      inkscape:window-height="1067" |      inkscape:window-height="1067" | ||||||
|      inkscape:window-x="184" |      inkscape:window-x="2116" | ||||||
|      inkscape:window-y="233" |      inkscape:window-y="261" | ||||||
|      inkscape:window-maximized="0" |      inkscape:window-maximized="0" | ||||||
|      borderlayer="true" |      borderlayer="true" | ||||||
|      inkscape:showpageshadow="false" |      inkscape:showpageshadow="false" | ||||||
|      inkscape:snap-nodes="false" |      inkscape:snap-nodes="false" | ||||||
|      inkscape:snap-bbox="true" |      inkscape:snap-bbox="true" | ||||||
|      showborder="true"> |      showborder="false"> | ||||||
|     <inkscape:grid |     <inkscape:grid | ||||||
|        type="xygrid" |        type="xygrid" | ||||||
|        id="grid14843" |        id="grid14843" | ||||||
| @@ -163,44 +160,39 @@ | |||||||
|      id="layer1" |      id="layer1" | ||||||
|      transform="translate(-342.5,-521.36218)"> |      transform="translate(-342.5,-521.36218)"> | ||||||
|     <g |     <g | ||||||
|        style="display:inline" |        transform="matrix(0.80230061,0,0,0.80230061,-87.624044,-453.10297)" | ||||||
|        id="use5671" |        id="g14586" | ||||||
|        transform="matrix(1.3594109,0,0,1.3564242,319.2059,481.99447)"> |        style="stroke-width:2.3714385;stroke-miterlimit:4;stroke-dasharray:none"> | ||||||
|  |       <g | ||||||
|  |          inkscape:export-ydpi="90" | ||||||
|  |          inkscape:export-xdpi="90" | ||||||
|  |          inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png" | ||||||
|  |          transform="matrix(1.9969286,0,0,1.9969286,-397.05491,877.00482)" | ||||||
|  |          id="g15291-9" | ||||||
|  |          style="stroke-width:1.18754292;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"> | ||||||
|  |         <g | ||||||
|  |            transform="translate(877.50354,-102.83507)" | ||||||
|  |            id="g16853-4" | ||||||
|  |            style="stroke-width:1.18754292;stroke-miterlimit:4;stroke-dasharray:none;enable-background:new"> | ||||||
|           <rect |           <rect | ||||||
|          transform="matrix(0.47304779,0,0,0.4807373,-6.3607039,-29.396216)" |              transform="scale(1,-1)" | ||||||
|          rx="4.4136767" |              style="color:#000000;fill:url(#linearGradient14219);fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:1.24833274;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" | ||||||
|          y="125.3458" |              id="rect6506-6" | ||||||
|          x="50.440369" |              width="11.281681" | ||||||
|          height="29.154205" |              height="11.26221" | ||||||
|          width="29.559635" |              x="-409.59354" | ||||||
|          id="rect11803" |              y="-284.40115" | ||||||
|          style="color:#000000;fill:url(#linearGradient11811);fill-opacity:1;stroke:#3465a4;stroke-width:1.54426003000000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |              rx="1.0052766" | ||||||
|          ry="4.4233952" /> |              ry="1.0052764" /> | ||||||
|       <path |         </g> | ||||||
|          inkscape:connector-curvature="0" |       </g> | ||||||
|          id="path11809" |       <g | ||||||
|          d="m 17.87105,33.844107 0,-0.773112 c 0,-1.031264 0.807171,-1.836142 1.811982,-1.836142 l 9.612456,0 c 1.004811,0 1.787822,0.804878 1.787822,1.836142 l 0,0.773112 c 0,-1.031264 -0.783011,-1.836142 -1.787822,-1.836142 l -9.612456,0 c -1.004811,0 -1.811982,0.804878 -1.811982,1.836142 z" |          inkscape:export-ydpi="90" | ||||||
|          style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" |          inkscape:export-xdpi="90" | ||||||
|          sodipodi:nodetypes="csssscssc" /> |          inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png" | ||||||
|       <path |          transform="translate(343.99999,987.99997)" | ||||||
|          sodipodi:nodetypes="csssscssc" |          id="g5886" | ||||||
|          style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" |          style="stroke-width:2.3714385;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new" /> | ||||||
|          d="m 17.87105,41.158551 0,0.773112 c 0,1.031264 0.807171,1.836142 1.811982,1.836142 l 9.612456,0 c 1.004811,0 1.787822,-0.804878 1.787822,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z" |  | ||||||
|          id="path11867" |  | ||||||
|          inkscape:connector-curvature="0" /> |  | ||||||
|       <path |  | ||||||
|          inkscape:connector-curvature="0" |  | ||||||
|          id="path11869" |  | ||||||
|          d="m 17.87105,41.895784 0,0.773112 c 0,1.031264 0.644622,1.836142 1.649433,1.836142 l 10.067593,0 c 1.004811,0 1.495234,-0.804878 1.495234,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z" |  | ||||||
|          style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#000000;fill-opacity:0.85253451;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" |  | ||||||
|          sodipodi:nodetypes="csssscssc" /> |  | ||||||
|     </g> |     </g> | ||||||
|     <rect |  | ||||||
|        style="color:#000000;fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |  | ||||||
|        id="rect17347" |  | ||||||
|        width="21.943846" |  | ||||||
|        height="21.943846" |  | ||||||
|        x="342.29913" |  | ||||||
|        y="521.58435" /> |  | ||||||
|   </g> |   </g> | ||||||
| </svg> | </svg> | ||||||
|   | |||||||
| Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 6.5 KiB | 
| @@ -14,10 +14,22 @@ | |||||||
|    height="22" |    height="22" | ||||||
|    id="svg3199" |    id="svg3199" | ||||||
|    version="1.1" |    version="1.1" | ||||||
|    inkscape:version="0.48.5 r10040" |    inkscape:version="0.48.1 r9760" | ||||||
|    sodipodi:docname="checkbox-focused.svg"> |    sodipodi:docname="checkbox.svg"> | ||||||
|   <defs |   <defs | ||||||
|      id="defs3201"> |      id="defs3201"> | ||||||
|  |     <linearGradient | ||||||
|  |        id="linearGradient15404" | ||||||
|  |        inkscape:collect="always"> | ||||||
|  |       <stop | ||||||
|  |          id="stop15406" | ||||||
|  |          offset="0" | ||||||
|  |          style="stop-color:#515151;stop-opacity:1" /> | ||||||
|  |       <stop | ||||||
|  |          id="stop15408" | ||||||
|  |          offset="1" | ||||||
|  |          style="stop-color:#292929;stop-opacity:1" /> | ||||||
|  |     </linearGradient> | ||||||
|     <inkscape:perspective |     <inkscape:perspective | ||||||
|        sodipodi:type="inkscape:persp3d" |        sodipodi:type="inkscape:persp3d" | ||||||
|        inkscape:vp_x="0 : 526.18109 : 1" |        inkscape:vp_x="0 : 526.18109 : 1" | ||||||
| @@ -32,6 +44,27 @@ | |||||||
|        inkscape:vp_y="0 : 1000 : 0" |        inkscape:vp_y="0 : 1000 : 0" | ||||||
|        inkscape:vp_x="0 : 0.5 : 1" |        inkscape:vp_x="0 : 0.5 : 1" | ||||||
|        sodipodi:type="inkscape:persp3d" /> |        sodipodi:type="inkscape:persp3d" /> | ||||||
|  |     <linearGradient | ||||||
|  |        inkscape:collect="always" | ||||||
|  |        xlink:href="#linearGradient5872-5-1" | ||||||
|  |        id="linearGradient5891-0-4" | ||||||
|  |        gradientUnits="userSpaceOnUse" | ||||||
|  |        x1="205.84143" | ||||||
|  |        y1="246.7094" | ||||||
|  |        x2="206.74803" | ||||||
|  |        y2="231.24142" /> | ||||||
|  |     <linearGradient | ||||||
|  |        inkscape:collect="always" | ||||||
|  |        id="linearGradient5872-5-1"> | ||||||
|  |       <stop | ||||||
|  |          style="stop-color:#0b2e52;stop-opacity:1" | ||||||
|  |          offset="0" | ||||||
|  |          id="stop5874-4-4" /> | ||||||
|  |       <stop | ||||||
|  |          style="stop-color:#1862af;stop-opacity:1" | ||||||
|  |          offset="1" | ||||||
|  |          id="stop5876-0-5" /> | ||||||
|  |     </linearGradient> | ||||||
|     <inkscape:path-effect |     <inkscape:path-effect | ||||||
|        effect="spiro" |        effect="spiro" | ||||||
|        id="path-effect5837-4-6" |        id="path-effect5837-4-6" | ||||||
| @@ -44,6 +77,16 @@ | |||||||
|        effect="spiro" |        effect="spiro" | ||||||
|        id="path-effect5884-4-7" |        id="path-effect5884-4-7" | ||||||
|        is_visible="true" /> |        is_visible="true" /> | ||||||
|  |     <linearGradient | ||||||
|  |        y2="-388.72955" | ||||||
|  |        x2="-93.031357" | ||||||
|  |        y1="-396.34738" | ||||||
|  |        x1="-93.031357" | ||||||
|  |        gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.685418)" | ||||||
|  |        gradientUnits="userSpaceOnUse" | ||||||
|  |        id="linearGradient14219" | ||||||
|  |        xlink:href="#linearGradient15404" | ||||||
|  |        inkscape:collect="always" /> | ||||||
|     <linearGradient |     <linearGradient | ||||||
|        inkscape:collect="always" |        inkscape:collect="always" | ||||||
|        id="linearGradient10013-4-63-6"> |        id="linearGradient10013-4-63-6"> | ||||||
| @@ -88,55 +131,30 @@ | |||||||
|        id="linearGradient15376" |        id="linearGradient15376" | ||||||
|        xlink:href="#linearGradient10597-5" |        xlink:href="#linearGradient10597-5" | ||||||
|        inkscape:collect="always" /> |        inkscape:collect="always" /> | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient5581-5-2-4-6-8-7-35-8" |  | ||||||
|        id="linearGradient11811" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        gradientTransform="matrix(3.0317573,0,0,1.0053174,-102.66338,-0.82153381)" |  | ||||||
|        x1="63.568954" |  | ||||||
|        y1="127.16142" |  | ||||||
|        x2="63.568954" |  | ||||||
|        y2="152.6618" /> |  | ||||||
|     <linearGradient |  | ||||||
|        id="linearGradient5581-5-2-4-6-8-7-35-8"> |  | ||||||
|       <stop |  | ||||||
|          id="stop5583-0-92-8-0-7-6-5-1" |  | ||||||
|          offset="0" |  | ||||||
|          style="stop-color:#454c4c;stop-opacity:1;" /> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#393f3f;stop-opacity:1;" |  | ||||||
|          offset="0.40000001" |  | ||||||
|          id="stop5585-4-7-2-7-9-9-92-0" /> |  | ||||||
|       <stop |  | ||||||
|          id="stop5587-6-7-2-0-3-1-21-5" |  | ||||||
|          offset="1" |  | ||||||
|          style="stop-color:#2d3232;stop-opacity:1;" /> |  | ||||||
|     </linearGradient> |  | ||||||
|   </defs> |   </defs> | ||||||
|   <sodipodi:namedview |   <sodipodi:namedview | ||||||
|      id="base" |      id="base" | ||||||
|      pagecolor="#a2a2a2" |      pagecolor="#000000" | ||||||
|      bordercolor="#2d2d2d" |      bordercolor="#2d2d2d" | ||||||
|      borderopacity="1" |      borderopacity="1" | ||||||
|      inkscape:pageopacity="1" |      inkscape:pageopacity="1" | ||||||
|      inkscape:pageshadow="2" |      inkscape:pageshadow="2" | ||||||
|      inkscape:zoom="1" |      inkscape:zoom="4" | ||||||
|      inkscape:cx="9.6447897" |      inkscape:cx="71.247925" | ||||||
|      inkscape:cy="12.591409" |      inkscape:cy="33.339093" | ||||||
|      inkscape:document-units="px" |      inkscape:document-units="px" | ||||||
|      inkscape:current-layer="layer1" |      inkscape:current-layer="layer1" | ||||||
|      showgrid="false" |      showgrid="false" | ||||||
|      inkscape:window-width="1412" |      inkscape:window-width="1412" | ||||||
|      inkscape:window-height="1067" |      inkscape:window-height="1067" | ||||||
|      inkscape:window-x="184" |      inkscape:window-x="2116" | ||||||
|      inkscape:window-y="233" |      inkscape:window-y="261" | ||||||
|      inkscape:window-maximized="0" |      inkscape:window-maximized="0" | ||||||
|      borderlayer="true" |      borderlayer="true" | ||||||
|      inkscape:showpageshadow="false" |      inkscape:showpageshadow="false" | ||||||
|      inkscape:snap-nodes="false" |      inkscape:snap-nodes="false" | ||||||
|      inkscape:snap-bbox="true" |      inkscape:snap-bbox="true" | ||||||
|      showborder="true"> |      showborder="false"> | ||||||
|     <inkscape:grid |     <inkscape:grid | ||||||
|        type="xygrid" |        type="xygrid" | ||||||
|        id="grid14843" |        id="grid14843" | ||||||
| @@ -163,44 +181,38 @@ | |||||||
|      id="layer1" |      id="layer1" | ||||||
|      transform="translate(-342.5,-521.36218)"> |      transform="translate(-342.5,-521.36218)"> | ||||||
|     <g |     <g | ||||||
|        style="display:inline" |        transform="matrix(0.84337,0,0,0.84337,-110.16632,-503.56182)" | ||||||
|        id="use5671" |        id="g14586"> | ||||||
|        transform="matrix(1.3594109,0,0,1.3564242,319.2059,481.99447)"> |       <g | ||||||
|  |          inkscape:export-ydpi="90" | ||||||
|  |          inkscape:export-xdpi="90" | ||||||
|  |          inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png" | ||||||
|  |          transform="matrix(1.9969286,0,0,1.9969286,-397.05491,877.00482)" | ||||||
|  |          id="g15291-9" | ||||||
|  |          style="display:inline;enable-background:new"> | ||||||
|  |         <g | ||||||
|  |            transform="translate(877.50354,-102.83507)" | ||||||
|  |            id="g16853-4" | ||||||
|  |            style="enable-background:new"> | ||||||
|           <rect |           <rect | ||||||
|          transform="matrix(0.47304779,0,0,0.4807373,-6.3607039,-29.396216)" |              transform="scale(1,-1)" | ||||||
|          rx="4.4136767" |              style="color:#000000;fill:url(#linearGradient14219);fill-opacity:1;fill-rule:nonzero;stroke:#868686;stroke-width:0.59377144999999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" | ||||||
|          y="125.3458" |              id="rect6506-6" | ||||||
|          x="50.440369" |              width="11.281681" | ||||||
|          height="29.154205" |              height="11.26221" | ||||||
|          width="29.559635" |              x="-409.59354" | ||||||
|          id="rect11803" |              y="-284.40115" | ||||||
|          style="color:#000000;fill:url(#linearGradient11811);fill-opacity:1;stroke:#1c1f1f;stroke-width:1.54426003;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |              rx="0.95632279" | ||||||
|          ry="4.4233952" /> |              ry="0.95632273" /> | ||||||
|       <path |         </g> | ||||||
|          inkscape:connector-curvature="0" |       </g> | ||||||
|          id="path11809" |       <g | ||||||
|          d="m 17.87105,33.844107 0,-0.773112 c 0,-1.031264 0.807171,-1.836142 1.811982,-1.836142 l 9.612456,0 c 1.004811,0 1.787822,0.804878 1.787822,1.836142 l 0,0.773112 c 0,-1.031264 -0.783011,-1.836142 -1.787822,-1.836142 l -9.612456,0 c -1.004811,0 -1.811982,0.804878 -1.811982,1.836142 z" |          inkscape:export-ydpi="90" | ||||||
|          style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" |          inkscape:export-xdpi="90" | ||||||
|          sodipodi:nodetypes="csssscssc" /> |          inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png" | ||||||
|       <path |          transform="translate(343.99999,987.99997)" | ||||||
|          sodipodi:nodetypes="csssscssc" |          id="g5886" | ||||||
|          style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" |          style="display:inline;enable-background:new" /> | ||||||
|          d="m 17.87105,41.158551 0,0.773112 c 0,1.031264 0.807171,1.836142 1.811982,1.836142 l 9.612456,0 c 1.004811,0 1.787822,-0.804878 1.787822,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z" |  | ||||||
|          id="path11867" |  | ||||||
|          inkscape:connector-curvature="0" /> |  | ||||||
|       <path |  | ||||||
|          inkscape:connector-curvature="0" |  | ||||||
|          id="path11869" |  | ||||||
|          d="m 17.87105,41.895784 0,0.773112 c 0,1.031264 0.644622,1.836142 1.649433,1.836142 l 10.067593,0 c 1.004811,0 1.495234,-0.804878 1.495234,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z" |  | ||||||
|          style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#000000;fill-opacity:0.85253451;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" |  | ||||||
|          sodipodi:nodetypes="csssscssc" /> |  | ||||||
|     </g> |     </g> | ||||||
|     <rect |  | ||||||
|        style="color:#000000;fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |  | ||||||
|        id="rect17347" |  | ||||||
|        width="21.943846" |  | ||||||
|        height="21.943846" |  | ||||||
|        x="342.29913" |  | ||||||
|        y="521.58435" /> |  | ||||||
|   </g> |   </g> | ||||||
| </svg> | </svg> | ||||||
|   | |||||||
| Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 6.8 KiB | 
| @@ -14,8 +14,8 @@ | |||||||
|    height="22" |    height="22" | ||||||
|    id="svg3199" |    id="svg3199" | ||||||
|    version="1.1" |    version="1.1" | ||||||
|    inkscape:version="0.48.5 r10040" |    inkscape:version="0.48.1 r9760" | ||||||
|    sodipodi:docname="checkbox.svg"> |    sodipodi:docname="checkbox-focused.svg"> | ||||||
|   <defs |   <defs | ||||||
|      id="defs3201"> |      id="defs3201"> | ||||||
|     <linearGradient |     <linearGradient | ||||||
| @@ -131,55 +131,30 @@ | |||||||
|        id="linearGradient15376" |        id="linearGradient15376" | ||||||
|        xlink:href="#linearGradient10597-5" |        xlink:href="#linearGradient10597-5" | ||||||
|        inkscape:collect="always" /> |        inkscape:collect="always" /> | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient5581-5-2-4-6-8-7-35-8" |  | ||||||
|        id="linearGradient11811" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        gradientTransform="matrix(3.0317573,0,0,1.0053174,-102.66338,-0.82153381)" |  | ||||||
|        x1="63.568954" |  | ||||||
|        y1="127.16142" |  | ||||||
|        x2="63.568954" |  | ||||||
|        y2="152.6618" /> |  | ||||||
|     <linearGradient |  | ||||||
|        id="linearGradient5581-5-2-4-6-8-7-35-8"> |  | ||||||
|       <stop |  | ||||||
|          id="stop5583-0-92-8-0-7-6-5-1" |  | ||||||
|          offset="0" |  | ||||||
|          style="stop-color:#454c4c;stop-opacity:1;" /> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#393f3f;stop-opacity:1;" |  | ||||||
|          offset="0.40000001" |  | ||||||
|          id="stop5585-4-7-2-7-9-9-92-0" /> |  | ||||||
|       <stop |  | ||||||
|          id="stop5587-6-7-2-0-3-1-21-5" |  | ||||||
|          offset="1" |  | ||||||
|          style="stop-color:#2d3232;stop-opacity:1;" /> |  | ||||||
|     </linearGradient> |  | ||||||
|   </defs> |   </defs> | ||||||
|   <sodipodi:namedview |   <sodipodi:namedview | ||||||
|      id="base" |      id="base" | ||||||
|      pagecolor="#a2a2a2" |      pagecolor="#000000" | ||||||
|      bordercolor="#2d2d2d" |      bordercolor="#2d2d2d" | ||||||
|      borderopacity="1" |      borderopacity="1" | ||||||
|      inkscape:pageopacity="1" |      inkscape:pageopacity="1" | ||||||
|      inkscape:pageshadow="2" |      inkscape:pageshadow="2" | ||||||
|      inkscape:zoom="1" |      inkscape:zoom="1" | ||||||
|      inkscape:cx="-0.17876005" |      inkscape:cx="64.516955" | ||||||
|      inkscape:cy="11.944326" |      inkscape:cy="13.871056" | ||||||
|      inkscape:document-units="px" |      inkscape:document-units="px" | ||||||
|      inkscape:current-layer="layer1" |      inkscape:current-layer="layer1" | ||||||
|      showgrid="false" |      showgrid="false" | ||||||
|      inkscape:window-width="2560" |      inkscape:window-width="1412" | ||||||
|      inkscape:window-height="1375" |      inkscape:window-height="1067" | ||||||
|      inkscape:window-x="0" |      inkscape:window-x="2635" | ||||||
|      inkscape:window-y="27" |      inkscape:window-y="226" | ||||||
|      inkscape:window-maximized="1" |      inkscape:window-maximized="0" | ||||||
|      borderlayer="true" |      borderlayer="true" | ||||||
|      inkscape:showpageshadow="false" |      inkscape:showpageshadow="false" | ||||||
|      inkscape:snap-nodes="false" |      inkscape:snap-nodes="false" | ||||||
|      inkscape:snap-bbox="true" |      inkscape:snap-bbox="true" | ||||||
|      showborder="true"> |      showborder="false"> | ||||||
|     <inkscape:grid |     <inkscape:grid | ||||||
|        type="xygrid" |        type="xygrid" | ||||||
|        id="grid14843" |        id="grid14843" | ||||||
| @@ -196,7 +171,7 @@ | |||||||
|         <dc:format>image/svg+xml</dc:format> |         <dc:format>image/svg+xml</dc:format> | ||||||
|         <dc:type |         <dc:type | ||||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||||
|         <dc:title /> |         <dc:title></dc:title> | ||||||
|       </cc:Work> |       </cc:Work> | ||||||
|     </rdf:RDF> |     </rdf:RDF> | ||||||
|   </metadata> |   </metadata> | ||||||
| @@ -206,56 +181,63 @@ | |||||||
|      id="layer1" |      id="layer1" | ||||||
|      transform="translate(-342.5,-521.36218)"> |      transform="translate(-342.5,-521.36218)"> | ||||||
|     <g |     <g | ||||||
|        style="display:inline" |        transform="matrix(0.84337,0,0,0.84337,-110.16632,-503.56182)" | ||||||
|        id="use5671" |        id="g14586"> | ||||||
|        transform="matrix(1.3594109,0,0,1.3564242,319.2059,481.99447)"> |       <g | ||||||
|  |          inkscape:export-ydpi="90" | ||||||
|  |          inkscape:export-xdpi="90" | ||||||
|  |          inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png" | ||||||
|  |          transform="matrix(1.9969286,0,0,1.9969286,-397.05491,877.00482)" | ||||||
|  |          id="g15291-9" | ||||||
|  |          style="display:inline;enable-background:new"> | ||||||
|  |         <g | ||||||
|  |            transform="translate(877.50354,-102.83507)" | ||||||
|  |            id="g16853-4" | ||||||
|  |            style="enable-background:new"> | ||||||
|           <rect |           <rect | ||||||
|          transform="matrix(0.47304779,0,0,0.4807373,-6.3607039,-29.396216)" |              transform="scale(1,-1)" | ||||||
|          rx="4.4136767" |              style="color:#000000;fill:url(#linearGradient14219);fill-opacity:1;fill-rule:nonzero;stroke:#868686;stroke-width:0.59377144999999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" | ||||||
|          y="125.3458" |              id="rect6506-6" | ||||||
|          x="50.440369" |              width="11.281681" | ||||||
|          height="29.154205" |              height="11.26221" | ||||||
|          width="29.559635" |              x="-409.59354" | ||||||
|          id="rect11803" |              y="-284.40115" | ||||||
|          style="color:#000000;fill:url(#linearGradient11811);fill-opacity:1;stroke:#1c1f1f;stroke-width:1.54426003;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |              rx="0.95632279" | ||||||
|          ry="4.4233952" /> |              ry="0.95632273" /> | ||||||
|       <path |  | ||||||
|          inkscape:connector-curvature="0" |  | ||||||
|          id="path11809" |  | ||||||
|          d="m 17.87105,33.844107 0,-0.773112 c 0,-1.031264 0.807171,-1.836142 1.811982,-1.836142 l 9.612456,0 c 1.004811,0 1.787822,0.804878 1.787822,1.836142 l 0,0.773112 c 0,-1.031264 -0.783011,-1.836142 -1.787822,-1.836142 l -9.612456,0 c -1.004811,0 -1.811982,0.804878 -1.811982,1.836142 z" |  | ||||||
|          style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" |  | ||||||
|          sodipodi:nodetypes="csssscssc" /> |  | ||||||
|       <path |  | ||||||
|          sodipodi:nodetypes="csssscssc" |  | ||||||
|          style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" |  | ||||||
|          d="m 17.87105,41.158551 0,0.773112 c 0,1.031264 0.807171,1.836142 1.811982,1.836142 l 9.612456,0 c 1.004811,0 1.787822,-0.804878 1.787822,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z" |  | ||||||
|          id="path11867" |  | ||||||
|          inkscape:connector-curvature="0" /> |  | ||||||
|       <path |  | ||||||
|          inkscape:connector-curvature="0" |  | ||||||
|          id="path11869" |  | ||||||
|          d="m 17.87105,41.895784 0,0.773112 c 0,1.031264 0.644622,1.836142 1.649433,1.836142 l 10.067593,0 c 1.004811,0 1.495234,-0.804878 1.495234,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z" |  | ||||||
|          style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#000000;fill-opacity:0.85253451;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" |  | ||||||
|          sodipodi:nodetypes="csssscssc" /> |  | ||||||
|         </g> |         </g> | ||||||
|     <rect |       </g> | ||||||
|        style="color:#000000;fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |       <g | ||||||
|        id="rect17347" |          inkscape:export-ydpi="90" | ||||||
|        width="21.943846" |          inkscape:export-xdpi="90" | ||||||
|        height="21.943846" |          inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png" | ||||||
|        x="342.29913" |          transform="translate(343.99999,987.99997)" | ||||||
|        y="521.58435" /> |          id="g5886" | ||||||
|  |          style="display:inline;enable-background:new"> | ||||||
|  |         <path | ||||||
|  |            style="fill:none;stroke:url(#linearGradient5891-0-4);stroke-width:7.11431503;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" | ||||||
|  |            d="m 198.5,240 5.25,5.25 13.98616,-14.43081" | ||||||
|  |            id="path5835" | ||||||
|  |            inkscape:path-effect="#path-effect5837-4-6" | ||||||
|  |            inkscape:original-d="m 198.5,240 5.25,5.25 13.98616,-14.43081" | ||||||
|  |            inkscape:connector-curvature="0" | ||||||
|  |            sodipodi:nodetypes="ccc" /> | ||||||
|         <path |         <path | ||||||
|            inkscape:connector-curvature="0" |            inkscape:connector-curvature="0" | ||||||
|        style="opacity:0.8;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |            inkscape:original-d="m 198.5,240 5.25,5.25 13.91205,-14.31964" | ||||||
|        d="m 359.97505,524.8252 -7.88606,7.71465 -2.57155,-2.57155 -2.91442,-0.0427 0,2.35727 4.02875,3.98587 c 0.80342,0.80309 2.111,0.80309 2.91442,0 l 8.18609,-8.22894 0,-0.38573 c 0,-1.24128 0.19944,-1.76801 -0.82915,-2.29836 z" |            inkscape:path-effect="#path-effect5837-4-6" | ||||||
|        id="rect5147-9-1-5-7-6-5-8-7" |            id="path5880" | ||||||
|        sodipodi:nodetypes="ccccccccscc" /> |            d="m 198.5,240 5.25,5.25 13.91205,-14.31964" | ||||||
|  |            style="fill:none;stroke:#4787c8;stroke-width:3.55715752;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" | ||||||
|  |            sodipodi:nodetypes="ccc" /> | ||||||
|         <path |         <path | ||||||
|        style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#eeeeec;fill-opacity:1;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:sans-serif;-inkscape-font-specification:sans-serif" |            style="fill:none;stroke:#7ea7d3;stroke-width:1.18571913px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||||
|        d="m 361.65223,524.52745 -9.5602,9.36735 -2.56345,-2.56344 -2.92846,-0.0214 0.0153,2.32639 4.02203,4.02206 c 0.80341,0.80309 2.10565,0.80309 2.90906,0 l 10.95049,-11.05765 0.003,-2.1502 z" |            d="m 197.45937,240.47455 c -0.17828,-0.29362 -0.20087,-0.67548 -0.0603,-0.98892 0.14055,-0.31344 0.43739,-0.54812 0.77144,-0.62817 0.33405,-0.08 0.69314,-0.01 0.99635,0.15175 0.30321,0.16144 0.55146,0.40727 0.79165,0.65284 l 3.66429,3.74643 12.87946,-12.98973 c 0.20796,-0.20974 0.42306,-0.41969 0.68548,-0.55522 0.26242,-0.13553 0.57293,-0.19052 0.85827,-0.11426 0.14267,0.0381 0.27708,0.10787 0.38874,0.20452 0.11167,0.0966 0.20021,0.22004 0.25479,0.35726 0.0546,0.13722 0.075,0.28793 0.0585,0.43468 -0.0165,0.14674 -0.07,0.28919 -0.15422,0.41052" | ||||||
|        id="path12830-4-17-0" |            id="path5882" | ||||||
|  |            inkscape:path-effect="#path-effect5884-4-7" | ||||||
|  |            inkscape:original-d="m 197.45937,240.47455 c 0.65604,-0.56057 2.02485,-1.34847 2.49911,-0.8125 l 3.66429,3.74643 12.87946,-12.98973 c 0.6875,-0.6875 2.09152,0.7375 2.09152,0.7375" | ||||||
|            inkscape:connector-curvature="0" |            inkscape:connector-curvature="0" | ||||||
|        sodipodi:nodetypes="cccccccccc" /> |            sodipodi:nodetypes="csccc" /> | ||||||
|  |       </g> | ||||||
|  |     </g> | ||||||
|   </g> |   </g> | ||||||
| </svg> | </svg> | ||||||
|   | |||||||
| Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 8.8 KiB | 
| @@ -1,14 +0,0 @@ | |||||||
| @import "gnome-shell-sass/_high-contrast-colors"; //use gtk colors |  | ||||||
| @import "gnome-shell-sass/_drawing"; |  | ||||||
| @import "gnome-shell-sass/_common"; |  | ||||||
|  |  | ||||||
| //force symbolic icons |  | ||||||
| stage { |  | ||||||
|   -st-icon-style: symbolic; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .toggle-switch { width: 48px; } |  | ||||||
| .toggle-switch-us, .toggle-switch-intl { |  | ||||||
|   background-image: url("resource:///org/gnome/shell/theme/toggle-off-hc.svg"); |  | ||||||
|   &:checked { background-image: url("resource:///org/gnome/shell/theme/toggle-on-hc.svg"); } |  | ||||||
| } |  | ||||||
| @@ -1,5 +0,0 @@ | |||||||
| $variant: 'dark'; |  | ||||||
|  |  | ||||||
| @import "gnome-shell-sass/_colors"; //use gtk colors |  | ||||||
| @import "gnome-shell-sass/_drawing"; |  | ||||||
| @import "gnome-shell-sass/_common"; |  | ||||||
							
								
								
									
										90
									
								
								data/theme/menu-arrow-symbolic.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,90 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||||
|  |  | ||||||
|  | <svg | ||||||
|  |    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||||
|  |    xmlns:cc="http://creativecommons.org/ns#" | ||||||
|  |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|  |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|  |    width="16" | ||||||
|  |    height="16" | ||||||
|  |    id="svg3863" | ||||||
|  |    version="1.1" | ||||||
|  |    inkscape:version="0.48.4 r9939" | ||||||
|  |    sodipodi:docname="menu-arrow.svg"> | ||||||
|  |   <defs | ||||||
|  |      id="defs3865" /> | ||||||
|  |   <sodipodi:namedview | ||||||
|  |      id="base" | ||||||
|  |      pagecolor="#ffffff" | ||||||
|  |      bordercolor="#666666" | ||||||
|  |      borderopacity="1.0" | ||||||
|  |      inkscape:pageopacity="0.0" | ||||||
|  |      inkscape:pageshadow="2" | ||||||
|  |      inkscape:zoom="15.836083" | ||||||
|  |      inkscape:cx="-3.1641676" | ||||||
|  |      inkscape:cy="11.823817" | ||||||
|  |      inkscape:current-layer="layer1" | ||||||
|  |      showgrid="true" | ||||||
|  |      inkscape:grid-bbox="true" | ||||||
|  |      inkscape:document-units="px" | ||||||
|  |      showguides="true" | ||||||
|  |      inkscape:guide-bbox="true" | ||||||
|  |      inkscape:window-width="1366" | ||||||
|  |      inkscape:window-height="702" | ||||||
|  |      inkscape:window-x="0" | ||||||
|  |      inkscape:window-y="27" | ||||||
|  |      inkscape:window-maximized="1" | ||||||
|  |      inkscape:snap-bbox="true"> | ||||||
|  |     <sodipodi:guide | ||||||
|  |        orientation="1,0" | ||||||
|  |        position="15.996443,16.922964" | ||||||
|  |        id="guide3873" /> | ||||||
|  |     <sodipodi:guide | ||||||
|  |        orientation="0,1" | ||||||
|  |        position="28.041217,3.1256134" | ||||||
|  |        id="guide3875" /> | ||||||
|  |     <sodipodi:guide | ||||||
|  |        orientation="0,1" | ||||||
|  |        position="-0.80372916,24.469088" | ||||||
|  |        id="guide3877" /> | ||||||
|  |     <sodipodi:guide | ||||||
|  |        orientation="1,0" | ||||||
|  |        position="3.0363102,34.649657" | ||||||
|  |        id="guide3879" /> | ||||||
|  |     <sodipodi:guide | ||||||
|  |        orientation="1,0" | ||||||
|  |        position="29.023553,28.577037" | ||||||
|  |        id="guide3881" /> | ||||||
|  |     <inkscape:grid | ||||||
|  |        type="xygrid" | ||||||
|  |        id="grid2988" /> | ||||||
|  |   </sodipodi:namedview> | ||||||
|  |   <metadata | ||||||
|  |      id="metadata3868"> | ||||||
|  |     <rdf:RDF> | ||||||
|  |       <cc:Work | ||||||
|  |          rdf:about=""> | ||||||
|  |         <dc:format>image/svg+xml</dc:format> | ||||||
|  |         <dc:type | ||||||
|  |            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||||
|  |         <dc:title></dc:title> | ||||||
|  |       </cc:Work> | ||||||
|  |     </rdf:RDF> | ||||||
|  |   </metadata> | ||||||
|  |   <g | ||||||
|  |      id="layer1" | ||||||
|  |      inkscape:label="Layer 1" | ||||||
|  |      inkscape:groupmode="layer" | ||||||
|  |      transform="translate(0,-16)"> | ||||||
|  |     <path | ||||||
|  |        style="fill:#ffffff;fill-opacity:1;stroke:none" | ||||||
|  |        d="m 4,23 8,0 -4,5 z" | ||||||
|  |        id="path3883" | ||||||
|  |        inkscape:connector-curvature="0" | ||||||
|  |        sodipodi:nodetypes="cccc" /> | ||||||
|  |   </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 2.5 KiB | 
							
								
								
									
										
											BIN
										
									
								
								data/theme/message-tray-background.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 25 KiB | 
| @@ -1,119 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> |  | ||||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> |  | ||||||
|  |  | ||||||
| <svg |  | ||||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" |  | ||||||
|    xmlns:cc="http://creativecommons.org/ns#" |  | ||||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |  | ||||||
|    xmlns:svg="http://www.w3.org/2000/svg" |  | ||||||
|    xmlns="http://www.w3.org/2000/svg" |  | ||||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |  | ||||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |  | ||||||
|    width="64px" |  | ||||||
|    height="64px" |  | ||||||
|    id="svg3471" |  | ||||||
|    version="1.1" |  | ||||||
|    inkscape:version="0.48.5 r10040" |  | ||||||
|    sodipodi:docname="New document 5"> |  | ||||||
|   <defs |  | ||||||
|      id="defs3473" /> |  | ||||||
|   <sodipodi:namedview |  | ||||||
|      id="base" |  | ||||||
|      pagecolor="#ffffff" |  | ||||||
|      bordercolor="#666666" |  | ||||||
|      borderopacity="1.0" |  | ||||||
|      inkscape:pageopacity="0.0" |  | ||||||
|      inkscape:pageshadow="2" |  | ||||||
|      inkscape:zoom="5.5" |  | ||||||
|      inkscape:cx="32" |  | ||||||
|      inkscape:cy="32" |  | ||||||
|      inkscape:current-layer="layer1" |  | ||||||
|      showgrid="true" |  | ||||||
|      inkscape:document-units="px" |  | ||||||
|      inkscape:grid-bbox="true" |  | ||||||
|      inkscape:window-width="1461" |  | ||||||
|      inkscape:window-height="772" |  | ||||||
|      inkscape:window-x="37" |  | ||||||
|      inkscape:window-y="64" |  | ||||||
|      inkscape:window-maximized="0" /> |  | ||||||
|   <metadata |  | ||||||
|      id="metadata3476"> |  | ||||||
|     <rdf:RDF> |  | ||||||
|       <cc:Work |  | ||||||
|          rdf:about=""> |  | ||||||
|         <dc:format>image/svg+xml</dc:format> |  | ||||||
|         <dc:type |  | ||||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |  | ||||||
|         <dc:title></dc:title> |  | ||||||
|       </cc:Work> |  | ||||||
|     </rdf:RDF> |  | ||||||
|   </metadata> |  | ||||||
|   <g |  | ||||||
|      id="layer1" |  | ||||||
|      inkscape:label="Layer 1" |  | ||||||
|      inkscape:groupmode="layer"> |  | ||||||
|     <g |  | ||||||
|        transform="matrix(4,0,0,4,1.9999997,2.3636364)" |  | ||||||
|        id="g19145" |  | ||||||
|        style="fill:#bebebe;fill-opacity:1;display:inline"> |  | ||||||
|       <g |  | ||||||
|          id="g19147" |  | ||||||
|          inkscape:label="status" |  | ||||||
|          style="fill:#bebebe;fill-opacity:1;display:inline" |  | ||||||
|          transform="translate(-541.0002,-301)" /> |  | ||||||
|       <g |  | ||||||
|          style="fill:#bebebe;fill-opacity:1" |  | ||||||
|          id="g19149" |  | ||||||
|          inkscape:label="devices" |  | ||||||
|          transform="translate(-541.0002,-301)" /> |  | ||||||
|       <g |  | ||||||
|          style="fill:#bebebe;fill-opacity:1" |  | ||||||
|          id="g19151" |  | ||||||
|          inkscape:label="apps" |  | ||||||
|          transform="translate(-541.0002,-301)" /> |  | ||||||
|       <g |  | ||||||
|          style="fill:#bebebe;fill-opacity:1" |  | ||||||
|          id="g19153" |  | ||||||
|          inkscape:label="places" |  | ||||||
|          transform="translate(-541.0002,-301)" /> |  | ||||||
|       <g |  | ||||||
|          style="fill:#bebebe;fill-opacity:1" |  | ||||||
|          id="g19155" |  | ||||||
|          inkscape:label="mimetypes" |  | ||||||
|          transform="translate(-541.0002,-301)"> |  | ||||||
|         <path |  | ||||||
|            inkscape:connector-curvature="0" |  | ||||||
|            d="m 543.0002,301 c -1.05237,0 -2,0.84508 -2,1.9375 l 0,11.125 c 0,1.09242 0.94763,1.9375 2,1.9375 l 11,0 c 1.05237,0 2,-0.84508 2,-1.9375 l 0,-11.125 c 0,-1.09242 -0.94763,-1.9375 -2,-1.9375 l -11,0 z m 0,5 3.03125,0 0,2 -3.03125,0 0,-2 z m 4.03125,0 2.96875,0 0,2 -2.96875,0 0,-2 z m 3.96875,0 3,0 0,2 -3,0 0,-2 z m -8,3 3.03125,0 0,2 -3.03125,0 0,-2 z m 4.03125,0 2.96875,0 0,2 -2.96875,0 0,-2 z m 3.96875,0 3,0 0,2 -3,0 0,-2 z m -8,3 3.03125,0 0,2 -3.03125,0 0,-2 z m 4.03125,0 2.96875,0 0,2 -2.96875,0 0,-2 z m 3.96875,0 3,0 0,2 -3,0 0,-2 z" |  | ||||||
|            id="path19157" |  | ||||||
|            style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new;font-family:Sans;-inkscape-font-specification:Sans" /> |  | ||||||
|         <rect |  | ||||||
|            height="1.9999993" |  | ||||||
|            id="rect19159" |  | ||||||
|            style="opacity:0.35;color:#000000;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |  | ||||||
|            width="2.9999993" |  | ||||||
|            x="551.00018" |  | ||||||
|            y="309" /> |  | ||||||
|       </g> |  | ||||||
|       <g |  | ||||||
|          id="g19161" |  | ||||||
|          inkscape:label="emblems" |  | ||||||
|          style="fill:#bebebe;fill-opacity:1;display:inline" |  | ||||||
|          transform="translate(-541.0002,-301)" /> |  | ||||||
|       <g |  | ||||||
|          id="g19163" |  | ||||||
|          inkscape:label="emotes" |  | ||||||
|          style="fill:#bebebe;fill-opacity:1;display:inline" |  | ||||||
|          transform="translate(-541.0002,-301)" /> |  | ||||||
|       <g |  | ||||||
|          id="g19165" |  | ||||||
|          inkscape:label="categories" |  | ||||||
|          style="fill:#bebebe;fill-opacity:1;display:inline" |  | ||||||
|          transform="translate(-541.0002,-301)" /> |  | ||||||
|       <g |  | ||||||
|          id="g19167" |  | ||||||
|          inkscape:label="actions" |  | ||||||
|          style="fill:#bebebe;fill-opacity:1;display:inline" |  | ||||||
|          transform="translate(-541.0002,-301)" /> |  | ||||||
|     </g> |  | ||||||
|   </g> |  | ||||||
| </svg> |  | ||||||
| Before Width: | Height: | Size: 4.7 KiB | 
| @@ -1,114 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> |  | ||||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> |  | ||||||
|  |  | ||||||
| <svg |  | ||||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" |  | ||||||
|    xmlns:cc="http://creativecommons.org/ns#" |  | ||||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |  | ||||||
|    xmlns:svg="http://www.w3.org/2000/svg" |  | ||||||
|    xmlns="http://www.w3.org/2000/svg" |  | ||||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |  | ||||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |  | ||||||
|    width="64px" |  | ||||||
|    height="64px" |  | ||||||
|    id="svg3393" |  | ||||||
|    version="1.1" |  | ||||||
|    inkscape:version="0.48.5 r10040" |  | ||||||
|    sodipodi:docname="New document 2"> |  | ||||||
|   <defs |  | ||||||
|      id="defs3395" /> |  | ||||||
|   <sodipodi:namedview |  | ||||||
|      id="base" |  | ||||||
|      pagecolor="#ffffff" |  | ||||||
|      bordercolor="#666666" |  | ||||||
|      borderopacity="1.0" |  | ||||||
|      inkscape:pageopacity="0.0" |  | ||||||
|      inkscape:pageshadow="2" |  | ||||||
|      inkscape:zoom="5.5" |  | ||||||
|      inkscape:cx="32" |  | ||||||
|      inkscape:cy="32" |  | ||||||
|      inkscape:current-layer="layer1" |  | ||||||
|      showgrid="true" |  | ||||||
|      inkscape:document-units="px" |  | ||||||
|      inkscape:grid-bbox="true" |  | ||||||
|      inkscape:window-width="697" |  | ||||||
|      inkscape:window-height="613" |  | ||||||
|      inkscape:window-x="100" |  | ||||||
|      inkscape:window-y="77" |  | ||||||
|      inkscape:window-maximized="0" /> |  | ||||||
|   <metadata |  | ||||||
|      id="metadata3398"> |  | ||||||
|     <rdf:RDF> |  | ||||||
|       <cc:Work |  | ||||||
|          rdf:about=""> |  | ||||||
|         <dc:format>image/svg+xml</dc:format> |  | ||||||
|         <dc:type |  | ||||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |  | ||||||
|         <dc:title></dc:title> |  | ||||||
|       </cc:Work> |  | ||||||
|     </rdf:RDF> |  | ||||||
|   </metadata> |  | ||||||
|   <g |  | ||||||
|      id="layer1" |  | ||||||
|      inkscape:label="Layer 1" |  | ||||||
|      inkscape:groupmode="layer"> |  | ||||||
|     <g |  | ||||||
|        style="display:inline" |  | ||||||
|        transform="matrix(4,0,0,4,0.29733827,-0.35415646)" |  | ||||||
|        id="g19245"> |  | ||||||
|       <g |  | ||||||
|          id="g19247" |  | ||||||
|          inkscape:label="status" |  | ||||||
|          style="display:inline" |  | ||||||
|          transform="translate(-323.02908,-649.02581)" /> |  | ||||||
|       <g |  | ||||||
|          id="g19249" |  | ||||||
|          inkscape:label="devices" |  | ||||||
|          transform="translate(-323.02908,-649.02581)" /> |  | ||||||
|       <g |  | ||||||
|          id="g19251" |  | ||||||
|          inkscape:label="apps" |  | ||||||
|          transform="translate(-323.02908,-649.02581)"> |  | ||||||
|         <path |  | ||||||
|            inkscape:connector-curvature="0" |  | ||||||
|            d="m 331.9377,653 c 0.0187,0.16677 0.0625,0.32822 0.0625,0.5 0,2.48528 -2.01472,4.5 -4.5,4.5 -0.11769,0 -0.22834,-0.0224 -0.34375,-0.0312 l 0,2.21875 c 0,1.00412 0.80838,1.8125 1.8125,1.8125 l 1.54511,-5e-5 2,2.04688 2.0625,-2.04688 1.61114,0 c 1.00413,0 1.8125,-0.80838 1.8125,-1.8125 l 0,-5.375 c 0,-1.00412 -0.80837,-1.8125 -1.8125,-1.8125 z" |  | ||||||
|            id="path19253" |  | ||||||
|            sodipodi:nodetypes="csscsscccssssc" |  | ||||||
|            style="opacity:0.5;color:#000000;fill:#c3c3c3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |  | ||||||
|         <path |  | ||||||
|            inkscape:connector-curvature="0" |  | ||||||
|            d="m 327.5002,650 c -1.933,0 -3.5,1.567 -3.5,3.5 0,1.933 1.567,3.5 3.5,3.5 1.933,0 3.5,-1.567 3.5,-3.5 0,-1.933 -1.567,-3.5 -3.5,-3.5 z m -0.53125,1 1.03125,0 -0.0625,1.375 a 0.19951718,0.19951718 0 0 0 0,0.0625 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0.125,0.125 0.19951718,0.19951718 0 0 0 0.0312,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 l 1.15625,-0.75 0.5,0.90625 -1.21875,0.625 a 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0312,0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0.0937 0.19951718,0.19951718 0 0 0 0,0.0625 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0.0312,0.0625 0.19951718,0.19951718 0 0 0 0.0312,0.0312 0.19951718,0.19951718 0 0 0 0.0312,0.0312 l 1.25,0.625 -0.53125,0.90625 -1.15625,-0.781 a 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0625,0 0.19951718,0.19951718 0 0 0 -0.125,0.0937 0.19951718,0.19951718 0 0 0 -0.0312,0.0312 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0,0.0625 l 0.0625,1.3751 -1.03125,0 0.0937,-1.375 a 0.19951718,0.19951718 0 0 0 -0.0312,-0.0937 0.19951718,0.19951718 0 0 0 -0.0312,-0.0625 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0937,0.0312 l -1.1875,0.78125 -0.5,-0.90625 1.25,-0.625 a 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 0,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,-0.0625 0.19951718,0.19951718 0 0 0 -0.0312,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0 l -1.25,-0.625 0.5,-0.90625 1.1875,0.75 a 0.19951718,0.19951718 0 0 0 0.0312,0.0312 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0312,0 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 L 326.96895,651 z" |  | ||||||
|            id="path19255" |  | ||||||
|            style="color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |  | ||||||
|       </g> |  | ||||||
|       <g |  | ||||||
|          id="g19257" |  | ||||||
|          inkscape:label="places" |  | ||||||
|          transform="translate(-323.02908,-649.02581)" /> |  | ||||||
|       <g |  | ||||||
|          id="g19259" |  | ||||||
|          inkscape:label="mimetypes" |  | ||||||
|          transform="translate(-323.02908,-649.02581)" /> |  | ||||||
|       <g |  | ||||||
|          id="g19261" |  | ||||||
|          inkscape:label="emblems" |  | ||||||
|          style="display:inline" |  | ||||||
|          transform="translate(-323.02908,-649.02581)" /> |  | ||||||
|       <g |  | ||||||
|          id="g19263" |  | ||||||
|          inkscape:label="emotes" |  | ||||||
|          style="display:inline" |  | ||||||
|          transform="translate(-323.02908,-649.02581)" /> |  | ||||||
|       <g |  | ||||||
|          id="g19265" |  | ||||||
|          inkscape:label="categories" |  | ||||||
|          style="display:inline" |  | ||||||
|          transform="translate(-323.02908,-649.02581)" /> |  | ||||||
|       <g |  | ||||||
|          id="g19267" |  | ||||||
|          inkscape:label="actions" |  | ||||||
|          style="display:inline" |  | ||||||
|          transform="translate(-323.02908,-649.02581)" /> |  | ||||||
|     </g> |  | ||||||
|   </g> |  | ||||||
| </svg> |  | ||||||
| Before Width: | Height: | Size: 6.1 KiB | 
							
								
								
									
										74
									
								
								data/theme/panel-button-border.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,74 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||||
|  |  | ||||||
|  | <svg | ||||||
|  |    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||||
|  |    xmlns:cc="http://creativecommons.org/ns#" | ||||||
|  |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|  |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|  |    width="17" | ||||||
|  |    height="10" | ||||||
|  |    id="svg2" | ||||||
|  |    version="1.1" | ||||||
|  |    inkscape:version="0.48.1 r9760" | ||||||
|  |    sodipodi:docname="panel-button-border.svg"> | ||||||
|  |   <defs | ||||||
|  |      id="defs4" /> | ||||||
|  |   <sodipodi:namedview | ||||||
|  |      id="base" | ||||||
|  |      pagecolor="#000000" | ||||||
|  |      bordercolor="#666666" | ||||||
|  |      borderopacity="1.0" | ||||||
|  |      inkscape:pageopacity="0" | ||||||
|  |      inkscape:pageshadow="2" | ||||||
|  |      inkscape:zoom="44.8" | ||||||
|  |      inkscape:cx="8.6594891" | ||||||
|  |      inkscape:cy="5.7029946" | ||||||
|  |      inkscape:document-units="px" | ||||||
|  |      inkscape:current-layer="layer1" | ||||||
|  |      showgrid="true" | ||||||
|  |      showguides="true" | ||||||
|  |      inkscape:guide-bbox="true" | ||||||
|  |      inkscape:window-width="1440" | ||||||
|  |      inkscape:window-height="843" | ||||||
|  |      inkscape:window-x="0" | ||||||
|  |      inkscape:window-y="26" | ||||||
|  |      inkscape:window-maximized="1" | ||||||
|  |      guidetolerance="10000" | ||||||
|  |      objecttolerance="10000"> | ||||||
|  |     <inkscape:grid | ||||||
|  |        type="xygrid" | ||||||
|  |        id="grid3792" | ||||||
|  |        empspacing="10" | ||||||
|  |        visible="true" | ||||||
|  |        enabled="true" | ||||||
|  |        snapvisiblegridlinesonly="true" /> | ||||||
|  |   </sodipodi:namedview> | ||||||
|  |   <metadata | ||||||
|  |      id="metadata7"> | ||||||
|  |     <rdf:RDF> | ||||||
|  |       <cc:Work | ||||||
|  |          rdf:about=""> | ||||||
|  |         <dc:format>image/svg+xml</dc:format> | ||||||
|  |         <dc:type | ||||||
|  |            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||||
|  |         <dc:title /> | ||||||
|  |       </cc:Work> | ||||||
|  |     </rdf:RDF> | ||||||
|  |   </metadata> | ||||||
|  |   <g | ||||||
|  |      inkscape:label="Layer 1" | ||||||
|  |      inkscape:groupmode="layer" | ||||||
|  |      id="layer1"> | ||||||
|  |     <rect | ||||||
|  |        style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none" | ||||||
|  |        id="rect3796" | ||||||
|  |        width="7" | ||||||
|  |        height="2" | ||||||
|  |        x="5" | ||||||
|  |        y="8" /> | ||||||
|  |   </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 2.0 KiB | 
							
								
								
									
										111
									
								
								data/theme/panel-button-highlight-narrow.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,111 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||||
|  |  | ||||||
|  | <svg | ||||||
|  |    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||||
|  |    xmlns:cc="http://creativecommons.org/ns#" | ||||||
|  |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:xlink="http://www.w3.org/1999/xlink" | ||||||
|  |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|  |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|  |    width="30" | ||||||
|  |    height="25" | ||||||
|  |    id="svg10621" | ||||||
|  |    version="1.1" | ||||||
|  |    inkscape:version="0.48.1 r9760" | ||||||
|  |    sodipodi:docname="panel-button-highlight-narrow.svg"> | ||||||
|  |   <defs | ||||||
|  |      id="defs10623"> | ||||||
|  |     <radialGradient | ||||||
|  |        inkscape:collect="always" | ||||||
|  |        xlink:href="#linearGradient34508-1-3" | ||||||
|  |        id="radialGradient99561-1" | ||||||
|  |        gradientUnits="userSpaceOnUse" | ||||||
|  |        gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)" | ||||||
|  |        cx="51" | ||||||
|  |        cy="30" | ||||||
|  |        fx="51" | ||||||
|  |        fy="30" | ||||||
|  |        r="42" /> | ||||||
|  |     <linearGradient | ||||||
|  |        inkscape:collect="always" | ||||||
|  |        id="linearGradient34508-1-3"> | ||||||
|  |       <stop | ||||||
|  |          style="stop-color:#ffffff;stop-opacity:1;" | ||||||
|  |          offset="0" | ||||||
|  |          id="stop34510-1-9" /> | ||||||
|  |       <stop | ||||||
|  |          style="stop-color:#ffffff;stop-opacity:0;" | ||||||
|  |          offset="1" | ||||||
|  |          id="stop34512-4-5" /> | ||||||
|  |     </linearGradient> | ||||||
|  |     <radialGradient | ||||||
|  |        r="42" | ||||||
|  |        fy="30" | ||||||
|  |        fx="51" | ||||||
|  |        cy="30" | ||||||
|  |        cx="51" | ||||||
|  |        gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)" | ||||||
|  |        gradientUnits="userSpaceOnUse" | ||||||
|  |        id="radialGradient10592" | ||||||
|  |        xlink:href="#linearGradient34508-1-3" | ||||||
|  |        inkscape:collect="always" /> | ||||||
|  |   </defs> | ||||||
|  |   <sodipodi:namedview | ||||||
|  |      id="base" | ||||||
|  |      pagecolor="#000000" | ||||||
|  |      bordercolor="#666666" | ||||||
|  |      borderopacity="1.0" | ||||||
|  |      inkscape:pageopacity="0" | ||||||
|  |      inkscape:pageshadow="2" | ||||||
|  |      inkscape:zoom="1.979899" | ||||||
|  |      inkscape:cx="-171.36384" | ||||||
|  |      inkscape:cy="-53.255157" | ||||||
|  |      inkscape:document-units="px" | ||||||
|  |      inkscape:current-layer="layer1" | ||||||
|  |      showgrid="false" | ||||||
|  |      fit-margin-top="0" | ||||||
|  |      fit-margin-left="0" | ||||||
|  |      fit-margin-right="0" | ||||||
|  |      fit-margin-bottom="0" | ||||||
|  |      inkscape:window-width="1440" | ||||||
|  |      inkscape:window-height="843" | ||||||
|  |      inkscape:window-x="0" | ||||||
|  |      inkscape:window-y="26" | ||||||
|  |      inkscape:window-maximized="1" /> | ||||||
|  |   <metadata | ||||||
|  |      id="metadata10626"> | ||||||
|  |     <rdf:RDF> | ||||||
|  |       <cc:Work | ||||||
|  |          rdf:about=""> | ||||||
|  |         <dc:format>image/svg+xml</dc:format> | ||||||
|  |         <dc:type | ||||||
|  |            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||||
|  |         <dc:title /> | ||||||
|  |       </cc:Work> | ||||||
|  |     </rdf:RDF> | ||||||
|  |   </metadata> | ||||||
|  |   <g | ||||||
|  |      inkscape:label="Layer 1" | ||||||
|  |      inkscape:groupmode="layer" | ||||||
|  |      id="layer1" | ||||||
|  |      transform="translate(-468.08632,-537.03477)"> | ||||||
|  |     <path | ||||||
|  |        sodipodi:type="arc" | ||||||
|  |        style="opacity:0.4625;color:#000000;fill:url(#radialGradient10592);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||||||
|  |        id="path34506-3" | ||||||
|  |        sodipodi:cx="51" | ||||||
|  |        sodipodi:cy="30" | ||||||
|  |        sodipodi:rx="42" | ||||||
|  |        sodipodi:ry="16" | ||||||
|  |        d="M 9,29.999999 C 9.0000011,21.163443 27.804042,14 51.000002,14 74.195961,14 93,21.163444 93,30 l -42,0 z" | ||||||
|  |        sodipodi:start="3.1415927" | ||||||
|  |        sodipodi:end="6.2831853" | ||||||
|  |        transform="matrix(0.35714286,0,0,1.5625,464.87203,515.15977)" | ||||||
|  |        inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/motion/textures/panel.png" | ||||||
|  |        inkscape:export-xdpi="90" | ||||||
|  |        inkscape:export-ydpi="90" /> | ||||||
|  |   </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 3.5 KiB | 
							
								
								
									
										111
									
								
								data/theme/panel-button-highlight-wide.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,111 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||||
|  |  | ||||||
|  | <svg | ||||||
|  |    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||||
|  |    xmlns:cc="http://creativecommons.org/ns#" | ||||||
|  |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:xlink="http://www.w3.org/1999/xlink" | ||||||
|  |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|  |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|  |    width="84" | ||||||
|  |    height="25" | ||||||
|  |    id="svg10621" | ||||||
|  |    version="1.1" | ||||||
|  |    inkscape:version="0.48.0 r9654" | ||||||
|  |    sodipodi:docname="panel-button-highlight-wide.svg"> | ||||||
|  |   <defs | ||||||
|  |      id="defs10623"> | ||||||
|  |     <radialGradient | ||||||
|  |        inkscape:collect="always" | ||||||
|  |        xlink:href="#linearGradient34508-1-3" | ||||||
|  |        id="radialGradient99561-1" | ||||||
|  |        gradientUnits="userSpaceOnUse" | ||||||
|  |        gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)" | ||||||
|  |        cx="51" | ||||||
|  |        cy="30" | ||||||
|  |        fx="51" | ||||||
|  |        fy="30" | ||||||
|  |        r="42" /> | ||||||
|  |     <linearGradient | ||||||
|  |        inkscape:collect="always" | ||||||
|  |        id="linearGradient34508-1-3"> | ||||||
|  |       <stop | ||||||
|  |          style="stop-color:#ffffff;stop-opacity:1;" | ||||||
|  |          offset="0" | ||||||
|  |          id="stop34510-1-9" /> | ||||||
|  |       <stop | ||||||
|  |          style="stop-color:#ffffff;stop-opacity:0;" | ||||||
|  |          offset="1" | ||||||
|  |          id="stop34512-4-5" /> | ||||||
|  |     </linearGradient> | ||||||
|  |     <radialGradient | ||||||
|  |        r="42" | ||||||
|  |        fy="30" | ||||||
|  |        fx="51" | ||||||
|  |        cy="30" | ||||||
|  |        cx="51" | ||||||
|  |        gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)" | ||||||
|  |        gradientUnits="userSpaceOnUse" | ||||||
|  |        id="radialGradient10592" | ||||||
|  |        xlink:href="#linearGradient34508-1-3" | ||||||
|  |        inkscape:collect="always" /> | ||||||
|  |   </defs> | ||||||
|  |   <sodipodi:namedview | ||||||
|  |      id="base" | ||||||
|  |      pagecolor="#000000" | ||||||
|  |      bordercolor="#666666" | ||||||
|  |      borderopacity="1.0" | ||||||
|  |      inkscape:pageopacity="0" | ||||||
|  |      inkscape:pageshadow="2" | ||||||
|  |      inkscape:zoom="1.979899" | ||||||
|  |      inkscape:cx="-118.50071" | ||||||
|  |      inkscape:cy="27.304508" | ||||||
|  |      inkscape:document-units="px" | ||||||
|  |      inkscape:current-layer="layer1" | ||||||
|  |      showgrid="false" | ||||||
|  |      fit-margin-top="0" | ||||||
|  |      fit-margin-left="0" | ||||||
|  |      fit-margin-right="0" | ||||||
|  |      fit-margin-bottom="0" | ||||||
|  |      inkscape:window-width="1440" | ||||||
|  |      inkscape:window-height="843" | ||||||
|  |      inkscape:window-x="0" | ||||||
|  |      inkscape:window-y="26" | ||||||
|  |      inkscape:window-maximized="1" /> | ||||||
|  |   <metadata | ||||||
|  |      id="metadata10626"> | ||||||
|  |     <rdf:RDF> | ||||||
|  |       <cc:Work | ||||||
|  |          rdf:about=""> | ||||||
|  |         <dc:format>image/svg+xml</dc:format> | ||||||
|  |         <dc:type | ||||||
|  |            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||||
|  |         <dc:title /> | ||||||
|  |       </cc:Work> | ||||||
|  |     </rdf:RDF> | ||||||
|  |   </metadata> | ||||||
|  |   <g | ||||||
|  |      inkscape:label="Layer 1" | ||||||
|  |      inkscape:groupmode="layer" | ||||||
|  |      id="layer1" | ||||||
|  |      transform="translate(-441.08632,-537.03477)"> | ||||||
|  |     <path | ||||||
|  |        sodipodi:type="arc" | ||||||
|  |        style="opacity:0.4625;color:#000000;fill:url(#radialGradient10592);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||||||
|  |        id="path34506-3" | ||||||
|  |        sodipodi:cx="51" | ||||||
|  |        sodipodi:cy="30" | ||||||
|  |        sodipodi:rx="42" | ||||||
|  |        sodipodi:ry="16" | ||||||
|  |        d="M 9,29.999999 C 9.0000011,21.163443 27.804042,14 51.000002,14 74.195961,14 93,21.163444 93,30 l -42,0 z" | ||||||
|  |        sodipodi:start="3.1415927" | ||||||
|  |        sodipodi:end="6.2831853" | ||||||
|  |        transform="matrix(1,0,0,1.5625,432.08632,515.15977)" | ||||||
|  |        inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/motion/textures/panel.png" | ||||||
|  |        inkscape:export-xdpi="90" | ||||||
|  |        inkscape:export-ydpi="90" /> | ||||||
|  |   </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 3.5 KiB | 
| @@ -1,3 +0,0 @@ | |||||||
| #!/usr/bin/bash |  | ||||||
|  |  | ||||||
| bundle exec sass --update --sourcemap=none . |  | ||||||
| Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 9.8 KiB | 
| @@ -1,133 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> |  | ||||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> |  | ||||||
|  |  | ||||||
| <svg |  | ||||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" |  | ||||||
|    xmlns:cc="http://creativecommons.org/ns#" |  | ||||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |  | ||||||
|    xmlns:svg="http://www.w3.org/2000/svg" |  | ||||||
|    xmlns="http://www.w3.org/2000/svg" |  | ||||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |  | ||||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |  | ||||||
|    width="48" |  | ||||||
|    height="22" |  | ||||||
|    id="svg2857" |  | ||||||
|    version="1.1" |  | ||||||
|    inkscape:version="0.91 r13725" |  | ||||||
|    sodipodi:docname="toggle-off-hc.svg"> |  | ||||||
|   <defs |  | ||||||
|      id="defs2859"> |  | ||||||
|     <inkscape:perspective |  | ||||||
|        sodipodi:type="inkscape:persp3d" |  | ||||||
|        inkscape:vp_x="0 : 526.18109 : 1" |  | ||||||
|        inkscape:vp_y="0 : 1000 : 0" |  | ||||||
|        inkscape:vp_z="744.09448 : 526.18109 : 1" |  | ||||||
|        inkscape:persp3d-origin="372.04724 : 350.78739 : 1" |  | ||||||
|        id="perspective2865" /> |  | ||||||
|     <inkscape:perspective |  | ||||||
|        id="perspective2843" |  | ||||||
|        inkscape:persp3d-origin="0.5 : 0.33333333 : 1" |  | ||||||
|        inkscape:vp_z="1 : 0.5 : 1" |  | ||||||
|        inkscape:vp_y="0 : 1000 : 0" |  | ||||||
|        inkscape:vp_x="0 : 0.5 : 1" |  | ||||||
|        sodipodi:type="inkscape:persp3d" /> |  | ||||||
|     <inkscape:path-effect |  | ||||||
|        effect="spiro" |  | ||||||
|        id="path-effect77541-4" |  | ||||||
|        is_visible="true" /> |  | ||||||
|   </defs> |  | ||||||
|   <sodipodi:namedview |  | ||||||
|      id="base" |  | ||||||
|      pagecolor="#000000" |  | ||||||
|      bordercolor="#666666" |  | ||||||
|      borderopacity="1.0" |  | ||||||
|      inkscape:pageopacity="1" |  | ||||||
|      inkscape:pageshadow="2" |  | ||||||
|      inkscape:zoom="1" |  | ||||||
|      inkscape:cx="-6.1820581" |  | ||||||
|      inkscape:cy="-16.463788" |  | ||||||
|      inkscape:document-units="px" |  | ||||||
|      inkscape:current-layer="g37994" |  | ||||||
|      showgrid="false" |  | ||||||
|      inkscape:window-width="2560" |  | ||||||
|      inkscape:window-height="1364" |  | ||||||
|      inkscape:window-x="0" |  | ||||||
|      inkscape:window-y="27" |  | ||||||
|      inkscape:window-maximized="1" |  | ||||||
|      borderlayer="true" |  | ||||||
|      inkscape:showpageshadow="false" |  | ||||||
|      inkscape:snap-nodes="false" |  | ||||||
|      inkscape:snap-bbox="true" |  | ||||||
|      showborder="true"> |  | ||||||
|     <inkscape:grid |  | ||||||
|        type="xygrid" |  | ||||||
|        id="grid12954" |  | ||||||
|        empspacing="5" |  | ||||||
|        visible="true" |  | ||||||
|        enabled="true" |  | ||||||
|        snapvisiblegridlinesonly="true" /> |  | ||||||
|   </sodipodi:namedview> |  | ||||||
|   <metadata |  | ||||||
|      id="metadata2862"> |  | ||||||
|     <rdf:RDF> |  | ||||||
|       <cc:Work |  | ||||||
|          rdf:about=""> |  | ||||||
|         <dc:format>image/svg+xml</dc:format> |  | ||||||
|         <dc:type |  | ||||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |  | ||||||
|         <dc:title></dc:title> |  | ||||||
|       </cc:Work> |  | ||||||
|     </rdf:RDF> |  | ||||||
|   </metadata> |  | ||||||
|   <g |  | ||||||
|      inkscape:label="Layer 1" |  | ||||||
|      inkscape:groupmode="layer" |  | ||||||
|      id="layer1" |  | ||||||
|      transform="translate(-444.64286,-781.36218)"> |  | ||||||
|     <g |  | ||||||
|        transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)" |  | ||||||
|        id="g37994"> |  | ||||||
|       <g |  | ||||||
|          transform="matrix(1.5323214,0,0,1.2413968,-324.76058,489.69039)" |  | ||||||
|          id="toggle-off" |  | ||||||
|          inkscape:label="#g8477"> |  | ||||||
|         <circle |  | ||||||
|            cy="1033.993" |  | ||||||
|            cx="571.95966" |  | ||||||
|            id="path8444" |  | ||||||
|            style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#555753;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" |  | ||||||
|            r="7" /> |  | ||||||
|         <rect |  | ||||||
|            ry="2.0108337" |  | ||||||
|            rx="1.9562569" |  | ||||||
|            y="1031.9885" |  | ||||||
|            x="565.0083" |  | ||||||
|            height="4.0216675" |  | ||||||
|            width="34.850178" |  | ||||||
|            id="rect8461" |  | ||||||
|            style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#555753;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> |  | ||||||
|       </g> |  | ||||||
|       <g |  | ||||||
|          transform="matrix(1.5323214,0,0,1.2413968,-324.85635,491.16456)" |  | ||||||
|          id="toggle-on" |  | ||||||
|          inkscape:label="#g8481"> |  | ||||||
|         <rect |  | ||||||
|            style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#3465a4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" |  | ||||||
|            id="rect8475" |  | ||||||
|            width="34.850178" |  | ||||||
|            height="4.0216675" |  | ||||||
|            x="565.0083" |  | ||||||
|            y="1070.9279" |  | ||||||
|            rx="1.9562569" |  | ||||||
|            ry="2.0108337" /> |  | ||||||
|         <circle |  | ||||||
|            transform="scale(-1,1)" |  | ||||||
|            style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#3465a4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" |  | ||||||
|            id="circle8463" |  | ||||||
|            cx="-591.0213" |  | ||||||
|            cy="1072.9402" |  | ||||||
|            r="9" /> |  | ||||||
|       </g> |  | ||||||
|     </g> |  | ||||||
|   </g> |  | ||||||
| </svg> |  | ||||||
| Before Width: | Height: | Size: 6.1 KiB | 
| @@ -7,127 +7,51 @@ | |||||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|    xmlns:svg="http://www.w3.org/2000/svg" |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|    xmlns="http://www.w3.org/2000/svg" |    xmlns="http://www.w3.org/2000/svg" | ||||||
|    xmlns:xlink="http://www.w3.org/1999/xlink" |  | ||||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|    width="65" |    width="65" | ||||||
|    height="22" |    height="22" | ||||||
|    id="svg2857" |    id="svg3273" | ||||||
|    version="1.1" |    version="1.1" | ||||||
|    inkscape:version="0.48.5 r10040" |    inkscape:version="0.47 r22583" | ||||||
|    sodipodi:docname="toggle-off-us.svg"> |    sodipodi:docname="New document 14"> | ||||||
|   <defs |   <defs | ||||||
|      id="defs2859"> |      id="defs3275"> | ||||||
|     <inkscape:perspective |     <inkscape:perspective | ||||||
|        sodipodi:type="inkscape:persp3d" |        sodipodi:type="inkscape:persp3d" | ||||||
|        inkscape:vp_x="0 : 526.18109 : 1" |        inkscape:vp_x="0 : 526.18109 : 1" | ||||||
|        inkscape:vp_y="0 : 1000 : 0" |        inkscape:vp_y="0 : 1000 : 0" | ||||||
|        inkscape:vp_z="744.09448 : 526.18109 : 1" |        inkscape:vp_z="744.09448 : 526.18109 : 1" | ||||||
|        inkscape:persp3d-origin="372.04724 : 350.78739 : 1" |        inkscape:persp3d-origin="372.04724 : 350.78739 : 1" | ||||||
|        id="perspective2865" /> |        id="perspective3281" /> | ||||||
|     <inkscape:perspective |     <inkscape:perspective | ||||||
|        id="perspective2843" |        id="perspective3261" | ||||||
|        inkscape:persp3d-origin="0.5 : 0.33333333 : 1" |        inkscape:persp3d-origin="0.5 : 0.33333333 : 1" | ||||||
|        inkscape:vp_z="1 : 0.5 : 1" |        inkscape:vp_z="1 : 0.5 : 1" | ||||||
|        inkscape:vp_y="0 : 1000 : 0" |        inkscape:vp_y="0 : 1000 : 0" | ||||||
|        inkscape:vp_x="0 : 0.5 : 1" |        inkscape:vp_x="0 : 0.5 : 1" | ||||||
|        sodipodi:type="inkscape:persp3d" /> |        sodipodi:type="inkscape:persp3d" /> | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient76469-7-7-4" |  | ||||||
|        id="linearGradient38024" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)" |  | ||||||
|        x1="6" |  | ||||||
|        y1="102.95528" |  | ||||||
|        x2="6" |  | ||||||
|        y2="84.505203" /> |  | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        id="linearGradient76469-7-7-4"> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#2e3232;stop-opacity:1" |  | ||||||
|          offset="0" |  | ||||||
|          id="stop76471-7-1-5" /> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#3e4545;stop-opacity:1" |  | ||||||
|          offset="1" |  | ||||||
|          id="stop76473-9-0-0" /> |  | ||||||
|     </linearGradient> |  | ||||||
|     <inkscape:path-effect |  | ||||||
|        effect="spiro" |  | ||||||
|        id="path-effect77541-4" |  | ||||||
|        is_visible="true" /> |  | ||||||
|     <inkscape:path-effect |  | ||||||
|        effect="spiro" |  | ||||||
|        id="path-effect77541-4-0" |  | ||||||
|        is_visible="true" /> |  | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient37802-8" |  | ||||||
|        id="linearGradient12311-3-1-0-5-4" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.071426)" |  | ||||||
|        x1="610.13782" |  | ||||||
|        y1="501.43866" |  | ||||||
|        x2="610.13782" |  | ||||||
|        y2="492.52756" /> |  | ||||||
|     <linearGradient |  | ||||||
|        id="linearGradient37802-8" |  | ||||||
|        inkscape:collect="always"> |  | ||||||
|       <stop |  | ||||||
|          id="stop37804-1" |  | ||||||
|          offset="0" |  | ||||||
|          style="stop-color:#2c2c2c;stop-opacity:1" /> |  | ||||||
|       <stop |  | ||||||
|          id="stop37806-8" |  | ||||||
|          offset="1" |  | ||||||
|          style="stop-color:#16191a;stop-opacity:1" /> |  | ||||||
|     </linearGradient> |  | ||||||
|     <linearGradient |  | ||||||
|        y2="492.52756" |  | ||||||
|        x2="610.13782" |  | ||||||
|        y1="501.43866" |  | ||||||
|        x1="610.13782" |  | ||||||
|        gradientTransform="matrix(1.5918367,0,0,0.85714285,-900.56122,-423.92857)" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        id="linearGradient13602" |  | ||||||
|        xlink:href="#linearGradient37802-8" |  | ||||||
|        inkscape:collect="always" /> |  | ||||||
|   </defs> |   </defs> | ||||||
|   <sodipodi:namedview |   <sodipodi:namedview | ||||||
|      id="base" |      id="base" | ||||||
|      pagecolor="#000000" |      pagecolor="#ffffff" | ||||||
|      bordercolor="#666666" |      bordercolor="#666666" | ||||||
|      borderopacity="1.0" |      borderopacity="1.0" | ||||||
|      inkscape:pageopacity="1" |      inkscape:pageopacity="0.0" | ||||||
|      inkscape:pageshadow="2" |      inkscape:pageshadow="2" | ||||||
|      inkscape:zoom="1" |      inkscape:zoom="0.35" | ||||||
|      inkscape:cx="-5.0602834" |      inkscape:cx="32.000004" | ||||||
|      inkscape:cy="16.473273" |      inkscape:cy="10.999997" | ||||||
|      inkscape:document-units="px" |      inkscape:document-units="px" | ||||||
|      inkscape:current-layer="g37994" |      inkscape:current-layer="layer1" | ||||||
|      showgrid="false" |      showgrid="false" | ||||||
|      inkscape:window-width="2560" |      inkscape:window-width="609" | ||||||
|      inkscape:window-height="1375" |      inkscape:window-height="501" | ||||||
|      inkscape:window-x="0" |      inkscape:window-x="0" | ||||||
|      inkscape:window-y="27" |      inkscape:window-y="26" | ||||||
|      inkscape:window-maximized="1" |      inkscape:window-maximized="0" /> | ||||||
|      borderlayer="true" |  | ||||||
|      inkscape:showpageshadow="false" |  | ||||||
|      inkscape:snap-nodes="false" |  | ||||||
|      inkscape:snap-bbox="true" |  | ||||||
|      showborder="false"> |  | ||||||
|     <inkscape:grid |  | ||||||
|        type="xygrid" |  | ||||||
|        id="grid12954" |  | ||||||
|        empspacing="5" |  | ||||||
|        visible="true" |  | ||||||
|        enabled="true" |  | ||||||
|        snapvisiblegridlinesonly="true" /> |  | ||||||
|   </sodipodi:namedview> |  | ||||||
|   <metadata |   <metadata | ||||||
|      id="metadata2862"> |      id="metadata3278"> | ||||||
|     <rdf:RDF> |     <rdf:RDF> | ||||||
|       <cc:Work |       <cc:Work | ||||||
|          rdf:about=""> |          rdf:about=""> | ||||||
| @@ -142,68 +66,61 @@ | |||||||
|      inkscape:label="Layer 1" |      inkscape:label="Layer 1" | ||||||
|      inkscape:groupmode="layer" |      inkscape:groupmode="layer" | ||||||
|      id="layer1" |      id="layer1" | ||||||
|      transform="translate(-444.64286,-781.36218)"> |      transform="translate(-343,-521.36218)"> | ||||||
|     <g |     <g | ||||||
|        transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)" |        id="g17454" | ||||||
|        id="g37994"> |        transform="translate(-453,448.36218)" | ||||||
|       <g |        style="display:inline"> | ||||||
|          id="g37996" |  | ||||||
|          transform="translate(-115,1277)"> |  | ||||||
|       <rect |       <rect | ||||||
|            style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837" |          transform="scale(-1,1)" | ||||||
|            id="rect13475" |          ry="4" | ||||||
|            width="98" |          rx="4" | ||||||
|            height="25" |          y="74.5" | ||||||
|            x="644.5" |          x="-859.5" | ||||||
|            y="484.61118" |          height="19" | ||||||
|            rx="4.7429576" |          width="63.000004" | ||||||
|            ry="3.8424656" /> |          id="rect17456" | ||||||
|  |          style="color:#000000;fill:none;stroke:#2e3436;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> | ||||||
|       <rect |       <rect | ||||||
|            ry="3.8424656" |          transform="scale(-1,1)" | ||||||
|            rx="4.7429576" |          ry="4" | ||||||
|            y="483.5" |          rx="4" | ||||||
|            x="644.5" |          y="74" | ||||||
|            height="25" |          x="-828" | ||||||
|            width="98" |          height="20" | ||||||
|            id="rect38000" |          width="31" | ||||||
|            style="color:#000000;fill:url(#linearGradient12311-3-1-0-5-4);fill-opacity:1;fill-rule:nonzero;stroke:#16191a;stroke-width:1.37920942;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" /> |          id="rect17458" | ||||||
|       </g> |          style="fill:#000000;fill-opacity:1;stroke:#5f5f5f;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" /> | ||||||
|       <g |       <g | ||||||
|          transform="translate(-49.946213,-1.890275)" |          transform="matrix(-1,0,0,1,1619.1239,-33.986291)" | ||||||
|          id="g38002"> |          id="g17460" | ||||||
|         <g |          style="display:inline"> | ||||||
|            transform="translate(-115,1247)" |  | ||||||
|            style="display:inline" |  | ||||||
|            id="g38004"> |  | ||||||
|           <rect |  | ||||||
|              ry="3.7972314" |  | ||||||
|              rx="4.6871223" |  | ||||||
|              y="515.5" |  | ||||||
|              x="694.53046" |  | ||||||
|              height="25" |  | ||||||
|              width="45.969578" |  | ||||||
|              id="rect38006" |  | ||||||
|              style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |  | ||||||
|         <path |         <path | ||||||
|              sodipodi:nodetypes="cc" |            style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" | ||||||
|              style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |            d="m 803.6322,115.48629 0,4.29495" | ||||||
|              d="m 699.09675,516.7365 36.86904,0" |            id="path17462" | ||||||
|              id="path38016" |            inkscape:connector-curvature="0" /> | ||||||
|              inkscape:path-effect="#path-effect77541-4" |         <path | ||||||
|              inkscape:original-d="m 699.09675,516.7365 36.86904,0" |            style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" | ||||||
|  |            d="m 806.62805,115.48629 0,4.29495" | ||||||
|  |            id="path17464" | ||||||
|  |            inkscape:connector-curvature="0" /> | ||||||
|  |         <path | ||||||
|  |            style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" | ||||||
|  |            d="m 809.6239,115.48629 0,4.29495" | ||||||
|  |            id="path17466" | ||||||
|            inkscape:connector-curvature="0" /> |            inkscape:connector-curvature="0" /> | ||||||
|         </g> |  | ||||||
|       </g> |       </g> | ||||||
|       <path |       <path | ||||||
|          sodipodi:type="arc" |          sodipodi:type="arc" | ||||||
|          style="color:#000000;fill:none;stroke:#ffffff;stroke-width:2.15627193;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" |          style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.96875012;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||||||
|          id="path13479" |          id="path18722" | ||||||
|          sodipodi:cx="16.4375" |          sodipodi:cx="47.6875" | ||||||
|          sodipodi:cy="10.8125" |          sodipodi:cy="11.5625" | ||||||
|          sodipodi:rx="4.3125" |          sodipodi:rx="3.9375" | ||||||
|          sodipodi:ry="4.3125" |          sodipodi:ry="3.9375" | ||||||
|          d="m 20.75,10.8125 a 4.3125,4.3125 0 1 1 -8.625,0 4.3125,4.3125 0 1 1 8.625,0 z" |          d="m 51.625,11.5625 c 0,2.174621 -1.762879,3.9375 -3.9375,3.9375 -2.174621,0 -3.9375,-1.762879 -3.9375,-3.9375 0,-2.1746212 1.762879,-3.9375 3.9375,-3.9375 2.174621,0 3.9375,1.7628788 3.9375,3.9375 z" | ||||||
|          transform="matrix(1.4212691,0,0,1.1514287,577.38488,1761.1138)" /> |          transform="matrix(1.0158729,0,0,1.0158729,795.55556,72.25399)" /> | ||||||
|     </g> |     </g> | ||||||
|   </g> |   </g> | ||||||
| </svg> | </svg> | ||||||
|   | |||||||
| Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 4.7 KiB | 
| @@ -7,171 +7,51 @@ | |||||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|    xmlns:svg="http://www.w3.org/2000/svg" |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|    xmlns="http://www.w3.org/2000/svg" |    xmlns="http://www.w3.org/2000/svg" | ||||||
|    xmlns:xlink="http://www.w3.org/1999/xlink" |  | ||||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|    width="65" |    width="65" | ||||||
|    height="22" |    height="22" | ||||||
|    id="svg2857" |    id="svg3012" | ||||||
|    version="1.1" |    version="1.1" | ||||||
|    inkscape:version="0.48.5 r10040" |    inkscape:version="0.47 r22583" | ||||||
|    sodipodi:docname="toggle-on-intl.svg"> |    sodipodi:docname="New document 6"> | ||||||
|   <defs |   <defs | ||||||
|      id="defs2859"> |      id="defs3014"> | ||||||
|     <inkscape:perspective |     <inkscape:perspective | ||||||
|        sodipodi:type="inkscape:persp3d" |        sodipodi:type="inkscape:persp3d" | ||||||
|        inkscape:vp_x="0 : 526.18109 : 1" |        inkscape:vp_x="0 : 526.18109 : 1" | ||||||
|        inkscape:vp_y="0 : 1000 : 0" |        inkscape:vp_y="0 : 1000 : 0" | ||||||
|        inkscape:vp_z="744.09448 : 526.18109 : 1" |        inkscape:vp_z="744.09448 : 526.18109 : 1" | ||||||
|        inkscape:persp3d-origin="372.04724 : 350.78739 : 1" |        inkscape:persp3d-origin="372.04724 : 350.78739 : 1" | ||||||
|        id="perspective2865" /> |        id="perspective3020" /> | ||||||
|     <inkscape:perspective |     <inkscape:perspective | ||||||
|        id="perspective2843" |        id="perspective2997" | ||||||
|        inkscape:persp3d-origin="0.5 : 0.33333333 : 1" |        inkscape:persp3d-origin="0.5 : 0.33333333 : 1" | ||||||
|        inkscape:vp_z="1 : 0.5 : 1" |        inkscape:vp_z="1 : 0.5 : 1" | ||||||
|        inkscape:vp_y="0 : 1000 : 0" |        inkscape:vp_y="0 : 1000 : 0" | ||||||
|        inkscape:vp_x="0 : 0.5 : 1" |        inkscape:vp_x="0 : 0.5 : 1" | ||||||
|        sodipodi:type="inkscape:persp3d" /> |        sodipodi:type="inkscape:persp3d" /> | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient76469-7-7-4" |  | ||||||
|        id="linearGradient38024" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)" |  | ||||||
|        x1="6" |  | ||||||
|        y1="102.95528" |  | ||||||
|        x2="6" |  | ||||||
|        y2="84.505203" /> |  | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        id="linearGradient76469-7-7-4"> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#2e3232;stop-opacity:1" |  | ||||||
|          offset="0" |  | ||||||
|          id="stop76471-7-1-5" /> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#3e4545;stop-opacity:1" |  | ||||||
|          offset="1" |  | ||||||
|          id="stop76473-9-0-0" /> |  | ||||||
|     </linearGradient> |  | ||||||
|     <inkscape:path-effect |  | ||||||
|        effect="spiro" |  | ||||||
|        id="path-effect77541-4" |  | ||||||
|        is_visible="true" /> |  | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient37802" |  | ||||||
|        id="linearGradient12311-3-1-0-5" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.071426)" |  | ||||||
|        x1="610.13782" |  | ||||||
|        y1="501.43866" |  | ||||||
|        x2="610.13782" |  | ||||||
|        y2="492.52756" /> |  | ||||||
|     <linearGradient |  | ||||||
|        id="linearGradient37802" |  | ||||||
|        inkscape:collect="always"> |  | ||||||
|       <stop |  | ||||||
|          id="stop37804" |  | ||||||
|          offset="0" |  | ||||||
|          style="stop-color:#2c2c2c;stop-opacity:1" /> |  | ||||||
|       <stop |  | ||||||
|          id="stop37806" |  | ||||||
|          offset="1" |  | ||||||
|          style="stop-color:#16191a;stop-opacity:1" /> |  | ||||||
|     </linearGradient> |  | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient76469-7-7-4-3" |  | ||||||
|        id="linearGradient77680" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        gradientTransform="matrix(1,0,0,1.0322581,717.71949,428.68472)" |  | ||||||
|        x1="6" |  | ||||||
|        y1="102.95528" |  | ||||||
|        x2="6" |  | ||||||
|        y2="84.505203" /> |  | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        id="linearGradient76469-7-7-4-3"> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#2e3232;stop-opacity:1" |  | ||||||
|          offset="0" |  | ||||||
|          id="stop76471-7-1-5-7" /> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#3e4545;stop-opacity:1" |  | ||||||
|          offset="1" |  | ||||||
|          id="stop76473-9-0-0-9" /> |  | ||||||
|     </linearGradient> |  | ||||||
|     <inkscape:path-effect |  | ||||||
|        effect="spiro" |  | ||||||
|        id="path-effect77541-4-0" |  | ||||||
|        is_visible="true" /> |  | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient37802-8" |  | ||||||
|        id="linearGradient12311-3-1-0-5-4" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.071426)" |  | ||||||
|        x1="610.13782" |  | ||||||
|        y1="501.43866" |  | ||||||
|        x2="610.13782" |  | ||||||
|        y2="492.52756" /> |  | ||||||
|     <linearGradient |  | ||||||
|        id="linearGradient37802-8" |  | ||||||
|        inkscape:collect="always"> |  | ||||||
|       <stop |  | ||||||
|          id="stop37804-1" |  | ||||||
|          offset="0" |  | ||||||
|          style="stop-color:#2c2c2c;stop-opacity:1" /> |  | ||||||
|       <stop |  | ||||||
|          id="stop37806-8" |  | ||||||
|          offset="1" |  | ||||||
|          style="stop-color:#16191a;stop-opacity:1" /> |  | ||||||
|     </linearGradient> |  | ||||||
|     <linearGradient |  | ||||||
|        y2="492.52756" |  | ||||||
|        x2="610.13782" |  | ||||||
|        y1="501.43866" |  | ||||||
|        x1="610.13782" |  | ||||||
|        gradientTransform="matrix(1.5918367,0,0,0.85714285,-900.56122,-423.92857)" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        id="linearGradient13602" |  | ||||||
|        xlink:href="#linearGradient37802-8" |  | ||||||
|        inkscape:collect="always" /> |  | ||||||
|   </defs> |   </defs> | ||||||
|   <sodipodi:namedview |   <sodipodi:namedview | ||||||
|      id="base" |      id="base" | ||||||
|      pagecolor="#000000" |      pagecolor="#ffffff" | ||||||
|      bordercolor="#666666" |      bordercolor="#666666" | ||||||
|      borderopacity="1.0" |      borderopacity="1.0" | ||||||
|      inkscape:pageopacity="1" |      inkscape:pageopacity="0.0" | ||||||
|      inkscape:pageshadow="2" |      inkscape:pageshadow="2" | ||||||
|      inkscape:zoom="1" |      inkscape:zoom="0.35" | ||||||
|      inkscape:cx="16.760995" |      inkscape:cx="32.000004" | ||||||
|      inkscape:cy="21.955673" |      inkscape:cy="10.999997" | ||||||
|      inkscape:document-units="px" |      inkscape:document-units="px" | ||||||
|      inkscape:current-layer="g37994" |      inkscape:current-layer="layer1" | ||||||
|      showgrid="false" |      showgrid="false" | ||||||
|      inkscape:window-width="2560" |      inkscape:window-width="609" | ||||||
|      inkscape:window-height="1375" |      inkscape:window-height="501" | ||||||
|      inkscape:window-x="0" |      inkscape:window-x="0" | ||||||
|      inkscape:window-y="27" |      inkscape:window-y="26" | ||||||
|      inkscape:window-maximized="1" |      inkscape:window-maximized="0" /> | ||||||
|      borderlayer="true" |  | ||||||
|      inkscape:showpageshadow="false" |  | ||||||
|      inkscape:snap-nodes="false" |  | ||||||
|      inkscape:snap-bbox="true" |  | ||||||
|      showborder="false"> |  | ||||||
|     <inkscape:grid |  | ||||||
|        type="xygrid" |  | ||||||
|        id="grid12954" |  | ||||||
|        empspacing="5" |  | ||||||
|        visible="true" |  | ||||||
|        enabled="true" |  | ||||||
|        snapvisiblegridlinesonly="true" /> |  | ||||||
|   </sodipodi:namedview> |  | ||||||
|   <metadata |   <metadata | ||||||
|      id="metadata2862"> |      id="metadata3017"> | ||||||
|     <rdf:RDF> |     <rdf:RDF> | ||||||
|       <cc:Work |       <cc:Work | ||||||
|          rdf:about=""> |          rdf:about=""> | ||||||
| @@ -186,70 +66,73 @@ | |||||||
|      inkscape:label="Layer 1" |      inkscape:label="Layer 1" | ||||||
|      inkscape:groupmode="layer" |      inkscape:groupmode="layer" | ||||||
|      id="layer1" |      id="layer1" | ||||||
|      transform="translate(-444.64286,-781.36218)"> |      transform="translate(-343,-521.36218)"> | ||||||
|     <g |     <g | ||||||
|        transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)" |        id="g17454" | ||||||
|        id="g37994"> |        transform="translate(-453,448.36218)" | ||||||
|       <g |        style="display:inline"> | ||||||
|          id="g37996" |  | ||||||
|          transform="translate(-115,1277)"> |  | ||||||
|       <rect |       <rect | ||||||
|            style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837" |          transform="scale(-1,1)" | ||||||
|            id="rect13475" |          ry="4" | ||||||
|            width="98" |          rx="4" | ||||||
|            height="25" |          y="74.5" | ||||||
|            x="644.5" |          x="-859.5" | ||||||
|            y="484.61118" |          height="19" | ||||||
|            rx="4.7429576" |          width="63.000004" | ||||||
|            ry="3.8424656" /> |          id="rect17456" | ||||||
|  |          style="color:#000000;fill:none;stroke:#2e3436;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> | ||||||
|       <rect |       <rect | ||||||
|            ry="3.8424656" |          transform="scale(-1,1)" | ||||||
|            rx="4.7429576" |          ry="4" | ||||||
|            y="483.5" |          rx="4" | ||||||
|            x="644.5" |          y="74" | ||||||
|            height="25" |          x="-828" | ||||||
|            width="98" |          height="20" | ||||||
|            id="rect38000" |          width="31" | ||||||
|            style="color:#000000;fill:url(#linearGradient12311-3-1-0-5-4);fill-opacity:1;fill-rule:nonzero;stroke:#16191a;stroke-width:1.37920942;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" /> |          id="rect17458" | ||||||
|       </g> |          style="fill:#000000;fill-opacity:1;stroke:#5f5f5f;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" /> | ||||||
|       <g |       <g | ||||||
|          transform="translate(-49.946213,-1.890275)" |          transform="matrix(-1,0,0,1,1619.1239,-33.986291)" | ||||||
|          id="g38002"> |          id="g17460" | ||||||
|         <g |          style="display:inline"> | ||||||
|            transform="translate(-115,1247)" |  | ||||||
|            style="display:inline" |  | ||||||
|            id="g38004"> |  | ||||||
|           <rect |  | ||||||
|              ry="3.7972314" |  | ||||||
|              rx="4.6871223" |  | ||||||
|              y="515.5" |  | ||||||
|              x="694.53046" |  | ||||||
|              height="25" |  | ||||||
|              width="45.969578" |  | ||||||
|              id="rect38006" |  | ||||||
|              style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |  | ||||||
|         <path |         <path | ||||||
|              sodipodi:nodetypes="cc" |            style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" | ||||||
|              style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |            d="m 803.6322,115.48629 0,4.29495" | ||||||
|              d="m 699.09675,516.7365 36.86904,0" |            id="path17462" | ||||||
|              id="path38016" |            inkscape:connector-curvature="0" /> | ||||||
|              inkscape:path-effect="#path-effect77541-4" |         <path | ||||||
|              inkscape:original-d="m 699.09675,516.7365 36.86904,0" |            style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" | ||||||
|  |            d="m 806.62805,115.48629 0,4.29495" | ||||||
|  |            id="path17464" | ||||||
|  |            inkscape:connector-curvature="0" /> | ||||||
|  |         <path | ||||||
|  |            style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" | ||||||
|  |            d="m 809.6239,115.48629 0,4.29495" | ||||||
|  |            id="path17466" | ||||||
|            inkscape:connector-curvature="0" /> |            inkscape:connector-curvature="0" /> | ||||||
|       </g> |       </g> | ||||||
|  |       <g | ||||||
|  |          style="font-size:8.95877075px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold" | ||||||
|  |          id="text17468" | ||||||
|  |          transform="translate(0.34375,0)"> | ||||||
|  |         <path | ||||||
|  |            d="m 837.28518,80.750726 c 0.63282,6e-6 1.19566,0.123947 1.68852,0.371824 0.49284,0.247888 0.8807,0.609505 1.16359,1.084851 0.28287,0.472439 0.42431,1.022155 0.42431,1.649149 0,0.635748 -0.13853,1.200045 -0.41556,1.692892 -0.27706,0.489934 -0.66638,0.870507 -1.16797,1.141719 -0.5016,0.271213 -1.07756,0.406819 -1.72789,0.406819 -0.42869,0 -0.83551,-0.06562 -1.22045,-0.196848 -0.38495,-0.134148 -0.73053,-0.32808 -1.03674,-0.581795 -0.30329,-0.256631 -0.54534,-0.589085 -0.72615,-0.997363 -0.17789,-0.408276 -0.26684,-0.869045 -0.26683,-1.382311 -10e-6,-0.638658 0.13997,-1.200039 0.41994,-1.684144 0.27996,-0.487011 0.66782,-0.858835 1.16359,-1.115472 0.49576,-0.259541 1.06297,-0.389315 1.70164,-0.389321 m 0.57305,1.089225 c -0.20123,-0.05249 -0.40683,-0.07873 -0.61679,-0.07874 -0.20998,5e-6 -0.41412,0.02625 -0.61242,0.07874 -0.19831,0.04958 -0.38933,0.129779 -0.57305,0.240592 -0.18081,0.107907 -0.33974,0.242055 -0.47681,0.402445 -0.13706,0.160399 -0.24642,0.358705 -0.32808,0.594918 -0.0816,0.233306 -0.12248,0.491395 -0.12248,0.774269 0,0.67366 0.20851,1.214627 0.62554,1.622903 0.41702,0.408278 0.93758,0.612416 1.56166,0.612416 0.25954,0 0.51034,-0.04229 0.7524,-0.126858 0.24496,-0.08457 0.47097,-0.20997 0.67803,-0.376198 0.20705,-0.166226 0.37328,-0.392236 0.49868,-0.678032 0.12539,-0.285792 0.18809,-0.610956 0.1881,-0.975492 -10e-6,-0.297455 -0.0437,-0.568668 -0.13123,-0.813638 -0.0875,-0.247878 -0.20415,-0.453475 -0.34995,-0.61679 -0.14291,-0.163307 -0.31059,-0.301829 -0.50306,-0.415568 -0.18956,-0.11373 -0.38641,-0.195385 -0.59054,-0.244967" | ||||||
|  |            style="line-height:125%;fill:#ffffff;fill-opacity:1;marker:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold" | ||||||
|  |            id="path18599" | ||||||
|  |            inkscape:connector-curvature="0" /> | ||||||
|  |         <path | ||||||
|  |            d="m 843.5362,81.831203 0,1.17917 2.94834,0 0,1.014861 -2.94834,0 0,3.00713 -1.10673,0 0,-6.216022 4.31754,0 0,1.014861 -3.21081,0" | ||||||
|  |            style="line-height:125%;fill:#ffffff;fill-opacity:1;marker:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold" | ||||||
|  |            id="path18601" | ||||||
|  |            inkscape:connector-curvature="0" | ||||||
|  |            sodipodi:nodetypes="ccccccccccc" /> | ||||||
|  |         <path | ||||||
|  |            d="m 849.71285,81.831203 0,1.17917 2.94834,0 0,1.014861 -2.94834,0 0,3.00713 -1.10672,0 0,-6.216022 4.31753,0 0,1.014861 -3.21081,0" | ||||||
|  |            style="line-height:125%;fill:#ffffff;fill-opacity:1;marker:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold" | ||||||
|  |            id="path18603" | ||||||
|  |            inkscape:connector-curvature="0" | ||||||
|  |            sodipodi:nodetypes="ccccccccccc" /> | ||||||
|       </g> |       </g> | ||||||
|       <text |  | ||||||
|          xml:space="preserve" |  | ||||||
|          style="font-size:13.79166794px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold" |  | ||||||
|          x="520.29974" |  | ||||||
|          y="1997.0011" |  | ||||||
|          id="text75614" |  | ||||||
|          sodipodi:linespacing="125%" |  | ||||||
|          transform="scale(1.1236771,0.88993537)"><tspan |  | ||||||
|            sodipodi:role="line" |  | ||||||
|            id="tspan75616" |  | ||||||
|            x="520.29974" |  | ||||||
|            y="1997.0011">OFF</tspan></text> |  | ||||||
|     </g> |     </g> | ||||||
|   </g> |   </g> | ||||||
| </svg> | </svg> | ||||||
|   | |||||||
| Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 7.2 KiB | 
| @@ -1,113 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> |  | ||||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> |  | ||||||
|  |  | ||||||
| <svg |  | ||||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" |  | ||||||
|    xmlns:cc="http://creativecommons.org/ns#" |  | ||||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |  | ||||||
|    xmlns:svg="http://www.w3.org/2000/svg" |  | ||||||
|    xmlns="http://www.w3.org/2000/svg" |  | ||||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |  | ||||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |  | ||||||
|    width="48" |  | ||||||
|    height="22" |  | ||||||
|    id="svg2857" |  | ||||||
|    version="1.1" |  | ||||||
|    inkscape:version="0.91 r13725" |  | ||||||
|    sodipodi:docname="toggle-on-hc.svg"> |  | ||||||
|   <defs |  | ||||||
|      id="defs2859"> |  | ||||||
|     <inkscape:perspective |  | ||||||
|        sodipodi:type="inkscape:persp3d" |  | ||||||
|        inkscape:vp_x="0 : 526.18109 : 1" |  | ||||||
|        inkscape:vp_y="0 : 1000 : 0" |  | ||||||
|        inkscape:vp_z="744.09448 : 526.18109 : 1" |  | ||||||
|        inkscape:persp3d-origin="372.04724 : 350.78739 : 1" |  | ||||||
|        id="perspective2865" /> |  | ||||||
|     <inkscape:perspective |  | ||||||
|        id="perspective2843" |  | ||||||
|        inkscape:persp3d-origin="0.5 : 0.33333333 : 1" |  | ||||||
|        inkscape:vp_z="1 : 0.5 : 1" |  | ||||||
|        inkscape:vp_y="0 : 1000 : 0" |  | ||||||
|        inkscape:vp_x="0 : 0.5 : 1" |  | ||||||
|        sodipodi:type="inkscape:persp3d" /> |  | ||||||
|     <inkscape:path-effect |  | ||||||
|        effect="spiro" |  | ||||||
|        id="path-effect77541-4" |  | ||||||
|        is_visible="true" /> |  | ||||||
|   </defs> |  | ||||||
|   <sodipodi:namedview |  | ||||||
|      id="base" |  | ||||||
|      pagecolor="#000000" |  | ||||||
|      bordercolor="#666666" |  | ||||||
|      borderopacity="1.0" |  | ||||||
|      inkscape:pageopacity="1" |  | ||||||
|      inkscape:pageshadow="2" |  | ||||||
|      inkscape:zoom="1" |  | ||||||
|      inkscape:cx="-222.95215" |  | ||||||
|      inkscape:cy="3.9378433" |  | ||||||
|      inkscape:document-units="px" |  | ||||||
|      inkscape:current-layer="g37994" |  | ||||||
|      showgrid="false" |  | ||||||
|      inkscape:window-width="2560" |  | ||||||
|      inkscape:window-height="1364" |  | ||||||
|      inkscape:window-x="0" |  | ||||||
|      inkscape:window-y="27" |  | ||||||
|      inkscape:window-maximized="1" |  | ||||||
|      borderlayer="true" |  | ||||||
|      inkscape:showpageshadow="false" |  | ||||||
|      inkscape:snap-nodes="false" |  | ||||||
|      inkscape:snap-bbox="true" |  | ||||||
|      showborder="true"> |  | ||||||
|     <inkscape:grid |  | ||||||
|        type="xygrid" |  | ||||||
|        id="grid12954" |  | ||||||
|        empspacing="5" |  | ||||||
|        visible="true" |  | ||||||
|        enabled="true" |  | ||||||
|        snapvisiblegridlinesonly="true" /> |  | ||||||
|   </sodipodi:namedview> |  | ||||||
|   <metadata |  | ||||||
|      id="metadata2862"> |  | ||||||
|     <rdf:RDF> |  | ||||||
|       <cc:Work |  | ||||||
|          rdf:about=""> |  | ||||||
|         <dc:format>image/svg+xml</dc:format> |  | ||||||
|         <dc:type |  | ||||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |  | ||||||
|         <dc:title></dc:title> |  | ||||||
|       </cc:Work> |  | ||||||
|     </rdf:RDF> |  | ||||||
|   </metadata> |  | ||||||
|   <g |  | ||||||
|      inkscape:label="Layer 1" |  | ||||||
|      inkscape:groupmode="layer" |  | ||||||
|      id="layer1" |  | ||||||
|      transform="translate(-444.64286,-781.36218)"> |  | ||||||
|     <g |  | ||||||
|        transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)" |  | ||||||
|        id="g37994"> |  | ||||||
|       <g |  | ||||||
|          transform="matrix(1.5323214,0,0,1.2413968,-324.85635,441.50868)" |  | ||||||
|          id="toggle-on" |  | ||||||
|          inkscape:label="#g8481"> |  | ||||||
|         <rect |  | ||||||
|            style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#3465a4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" |  | ||||||
|            id="rect8475" |  | ||||||
|            width="34.850178" |  | ||||||
|            height="4.0216675" |  | ||||||
|            x="565.0083" |  | ||||||
|            y="1070.9279" |  | ||||||
|            rx="1.9562569" |  | ||||||
|            ry="2.0108337" /> |  | ||||||
|         <circle |  | ||||||
|            transform="scale(-1,1)" |  | ||||||
|            style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#3465a4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" |  | ||||||
|            id="circle8463" |  | ||||||
|            cx="-591.0213" |  | ||||||
|            cy="1072.9402" |  | ||||||
|            r="9" /> |  | ||||||
|       </g> |  | ||||||
|     </g> |  | ||||||
|   </g> |  | ||||||
| </svg> |  | ||||||
| Before Width: | Height: | Size: 4.4 KiB | 
| @@ -7,113 +7,51 @@ | |||||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|    xmlns:svg="http://www.w3.org/2000/svg" |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|    xmlns="http://www.w3.org/2000/svg" |    xmlns="http://www.w3.org/2000/svg" | ||||||
|    xmlns:xlink="http://www.w3.org/1999/xlink" |  | ||||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|    width="65" |    width="65" | ||||||
|    height="22" |    height="22" | ||||||
|    id="svg2857" |    id="svg3199" | ||||||
|    version="1.1" |    version="1.1" | ||||||
|    inkscape:version="0.91 r13725" |    inkscape:version="0.48.1 r9760" | ||||||
|    sodipodi:docname="toggle-on-intl.svg"> |    sodipodi:docname="toggle-on-intl.svg"> | ||||||
|   <defs |   <defs | ||||||
|      id="defs2859"> |      id="defs3201"> | ||||||
|     <inkscape:perspective |     <inkscape:perspective | ||||||
|        sodipodi:type="inkscape:persp3d" |        sodipodi:type="inkscape:persp3d" | ||||||
|        inkscape:vp_x="0 : 526.18109 : 1" |        inkscape:vp_x="0 : 526.18109 : 1" | ||||||
|        inkscape:vp_y="0 : 1000 : 0" |        inkscape:vp_y="0 : 1000 : 0" | ||||||
|        inkscape:vp_z="744.09448 : 526.18109 : 1" |        inkscape:vp_z="744.09448 : 526.18109 : 1" | ||||||
|        inkscape:persp3d-origin="372.04724 : 350.78739 : 1" |        inkscape:persp3d-origin="372.04724 : 350.78739 : 1" | ||||||
|        id="perspective2865" /> |        id="perspective3207" /> | ||||||
|     <inkscape:perspective |     <inkscape:perspective | ||||||
|        id="perspective2843" |        id="perspective3187" | ||||||
|        inkscape:persp3d-origin="0.5 : 0.33333333 : 1" |        inkscape:persp3d-origin="0.5 : 0.33333333 : 1" | ||||||
|        inkscape:vp_z="1 : 0.5 : 1" |        inkscape:vp_z="1 : 0.5 : 1" | ||||||
|        inkscape:vp_y="0 : 1000 : 0" |        inkscape:vp_y="0 : 1000 : 0" | ||||||
|        inkscape:vp_x="0 : 0.5 : 1" |        inkscape:vp_x="0 : 0.5 : 1" | ||||||
|        sodipodi:type="inkscape:persp3d" /> |        sodipodi:type="inkscape:persp3d" /> | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient77461" |  | ||||||
|        id="linearGradient77551" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        gradientTransform="matrix(1.3066667,0,0,1,-841.64667,-483)" |  | ||||||
|        x1="1164.7644" |  | ||||||
|        y1="962.93695" |  | ||||||
|        x2="1164.7644" |  | ||||||
|        y2="970.51404" /> |  | ||||||
|     <linearGradient |  | ||||||
|        id="linearGradient77461" |  | ||||||
|        inkscape:collect="always"> |  | ||||||
|       <stop |  | ||||||
|          id="stop77463" |  | ||||||
|          offset="0" |  | ||||||
|          style="stop-color:#182f4c;stop-opacity:1" /> |  | ||||||
|       <stop |  | ||||||
|          id="stop77465" |  | ||||||
|          offset="1" |  | ||||||
|          style="stop-color:#205b9a;stop-opacity:1" /> |  | ||||||
|     </linearGradient> |  | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient76469-7-7-4" |  | ||||||
|        id="linearGradient38024" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)" |  | ||||||
|        x1="6" |  | ||||||
|        y1="102.95528" |  | ||||||
|        x2="6" |  | ||||||
|        y2="84.505203" /> |  | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        id="linearGradient76469-7-7-4"> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#2e3232;stop-opacity:1" |  | ||||||
|          offset="0" |  | ||||||
|          id="stop76471-7-1-5" /> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#3e4545;stop-opacity:1" |  | ||||||
|          offset="1" |  | ||||||
|          id="stop76473-9-0-0" /> |  | ||||||
|     </linearGradient> |  | ||||||
|     <inkscape:path-effect |  | ||||||
|        effect="spiro" |  | ||||||
|        id="path-effect77541-4" |  | ||||||
|        is_visible="true" /> |  | ||||||
|   </defs> |   </defs> | ||||||
|   <sodipodi:namedview |   <sodipodi:namedview | ||||||
|      id="base" |      id="base" | ||||||
|      pagecolor="#000000" |      pagecolor="#ffffff" | ||||||
|      bordercolor="#666666" |      bordercolor="#666666" | ||||||
|      borderopacity="1.0" |      borderopacity="1.0" | ||||||
|      inkscape:pageopacity="1" |      inkscape:pageopacity="0.0" | ||||||
|      inkscape:pageshadow="2" |      inkscape:pageshadow="2" | ||||||
|      inkscape:zoom="1" |      inkscape:zoom="1" | ||||||
|      inkscape:cx="37.410841" |      inkscape:cx="49.147112" | ||||||
|      inkscape:cy="16.009314" |      inkscape:cy="17.532036" | ||||||
|      inkscape:document-units="px" |      inkscape:document-units="px" | ||||||
|      inkscape:current-layer="g37994" |      inkscape:current-layer="layer1" | ||||||
|      showgrid="false" |      showgrid="false" | ||||||
|      inkscape:window-width="2560" |      inkscape:window-width="1412" | ||||||
|      inkscape:window-height="1376" |      inkscape:window-height="1067" | ||||||
|      inkscape:window-x="0" |      inkscape:window-x="0" | ||||||
|      inkscape:window-y="27" |      inkscape:window-y="26" | ||||||
|      inkscape:window-maximized="1" |      inkscape:window-maximized="0" /> | ||||||
|      borderlayer="true" |  | ||||||
|      inkscape:showpageshadow="false" |  | ||||||
|      inkscape:snap-nodes="false" |  | ||||||
|      inkscape:snap-bbox="true" |  | ||||||
|      showborder="false"> |  | ||||||
|     <inkscape:grid |  | ||||||
|        type="xygrid" |  | ||||||
|        id="grid12954" |  | ||||||
|        empspacing="5" |  | ||||||
|        visible="true" |  | ||||||
|        enabled="true" |  | ||||||
|        snapvisiblegridlinesonly="true" /> |  | ||||||
|   </sodipodi:namedview> |  | ||||||
|   <metadata |   <metadata | ||||||
|      id="metadata2862"> |      id="metadata3204"> | ||||||
|     <rdf:RDF> |     <rdf:RDF> | ||||||
|       <cc:Work |       <cc:Work | ||||||
|          rdf:about=""> |          rdf:about=""> | ||||||
| @@ -128,65 +66,57 @@ | |||||||
|      inkscape:label="Layer 1" |      inkscape:label="Layer 1" | ||||||
|      inkscape:groupmode="layer" |      inkscape:groupmode="layer" | ||||||
|      id="layer1" |      id="layer1" | ||||||
|      transform="translate(-444.64286,-781.36218)"> |      transform="translate(-342.5,-521.36218)"> | ||||||
|     <g |     <g | ||||||
|        transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)" |  | ||||||
|        id="g37994"> |  | ||||||
|       <g |  | ||||||
|          id="g37996" |  | ||||||
|          transform="translate(-115,1277)"> |  | ||||||
|         <rect |  | ||||||
|            style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837" |  | ||||||
|            id="rect13475" |  | ||||||
|            width="98" |  | ||||||
|            height="25" |  | ||||||
|            x="644.5" |  | ||||||
|            y="484.61118" |  | ||||||
|            rx="4.7429576" |  | ||||||
|            ry="3.8424656" /> |  | ||||||
|         <rect |  | ||||||
|            ry="3.8424656" |  | ||||||
|            rx="4.7429576" |  | ||||||
|            y="483.5" |  | ||||||
|            x="644.5" |  | ||||||
|            height="25" |  | ||||||
|            width="98" |  | ||||||
|            id="rect38000" |  | ||||||
|            style="color:#000000;fill:url(#linearGradient77551);fill-opacity:1;fill-rule:nonzero;stroke:#182f4c;stroke-width:1.37920964;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |  | ||||||
|       </g> |  | ||||||
|       <g |  | ||||||
|          transform="translate(2.0625,-2)" |  | ||||||
|          id="g38002"> |  | ||||||
|         <g |  | ||||||
|            transform="translate(-115,1247)" |  | ||||||
|        style="display:inline" |        style="display:inline" | ||||||
|            id="g38004"> |        transform="translate(-453.5,448.36218)" | ||||||
|  |        id="g16453"> | ||||||
|       <rect |       <rect | ||||||
|              ry="3.7972314" |          style="color:#000000;fill:#4a90d9;fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:0.99999994000000003;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||||||
|              rx="4.6871223" |          id="rect16256-9-4" | ||||||
|              y="515.5" |          width="63.000004" | ||||||
|              x="694.53046" |          height="19" | ||||||
|              height="25" |          x="-859.5" | ||||||
|              width="45.969578" |          y="74.5" | ||||||
|              id="rect38006" |          rx="4" | ||||||
|              style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |          ry="4" | ||||||
|  |          transform="scale(-1,1)" /> | ||||||
|  |       <rect | ||||||
|  |          style="fill:#000000;fill-opacity:1;stroke:#5f5f5f;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" | ||||||
|  |          id="rect16258-5-4" | ||||||
|  |          width="31" | ||||||
|  |          height="20" | ||||||
|  |          x="-860" | ||||||
|  |          y="74" | ||||||
|  |          rx="4" | ||||||
|  |          ry="4" | ||||||
|  |          transform="scale(-1,1)" /> | ||||||
|  |       <g | ||||||
|  |          style="display:inline" | ||||||
|  |          id="g16298-3-6" | ||||||
|  |          transform="matrix(-1,0,0,1,1651.1322,-33.986291)"> | ||||||
|         <path |         <path | ||||||
|              sodipodi:nodetypes="cc" |            inkscape:connector-curvature="0" | ||||||
|              style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |            id="path16265-3-5" | ||||||
|              d="m 699.09675,516.7365 36.86904,0" |            d="m 803.6322,115.48629 0,4.29495" | ||||||
|              id="path38016" |            style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> | ||||||
|              inkscape:path-effect="#path-effect77541-4" |         <path | ||||||
|              inkscape:original-d="m 699.09675,516.7365 36.86904,0" |            inkscape:connector-curvature="0" | ||||||
|              inkscape:connector-curvature="0" /> |            id="path16265-0-2-0" | ||||||
|  |            d="m 806.62805,115.48629 0,4.29495" | ||||||
|  |            style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" /> | ||||||
|  |         <path | ||||||
|  |            inkscape:connector-curvature="0" | ||||||
|  |            id="path16265-8-7-1" | ||||||
|  |            d="m 809.6239,115.48629 0,4.29495" | ||||||
|  |            style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" /> | ||||||
|       </g> |       </g> | ||||||
|       </g> |       <path | ||||||
|       <rect |          style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||||||
|          style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" |          d="m 16,27.9375 0,10.125" | ||||||
|          id="rect13678" |          id="path19232" | ||||||
|          width="3.0646207" |          inkscape:connector-curvature="0" | ||||||
|          height="12.414008" |          transform="translate(796,51.00002)" /> | ||||||
|          x="554.77728" |  | ||||||
|          y="1767.3566" /> |  | ||||||
|     </g> |     </g> | ||||||
|   </g> |   </g> | ||||||
| </svg> | </svg> | ||||||
|   | |||||||
| Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 4.5 KiB | 
| @@ -7,14 +7,13 @@ | |||||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|    xmlns:svg="http://www.w3.org/2000/svg" |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|    xmlns="http://www.w3.org/2000/svg" |    xmlns="http://www.w3.org/2000/svg" | ||||||
|    xmlns:xlink="http://www.w3.org/1999/xlink" |  | ||||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|    width="65" |    width="65" | ||||||
|    height="22" |    height="22" | ||||||
|    id="svg2857" |    id="svg2857" | ||||||
|    version="1.1" |    version="1.1" | ||||||
|    inkscape:version="0.91 r13725" |    inkscape:version="0.48.1 r9760" | ||||||
|    sodipodi:docname="toggle-on-us.svg"> |    sodipodi:docname="toggle-on-us.svg"> | ||||||
|   <defs |   <defs | ||||||
|      id="defs2859"> |      id="defs2859"> | ||||||
| @@ -32,96 +31,27 @@ | |||||||
|        inkscape:vp_y="0 : 1000 : 0" |        inkscape:vp_y="0 : 1000 : 0" | ||||||
|        inkscape:vp_x="0 : 0.5 : 1" |        inkscape:vp_x="0 : 0.5 : 1" | ||||||
|        sodipodi:type="inkscape:persp3d" /> |        sodipodi:type="inkscape:persp3d" /> | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient76469-7-7-4" |  | ||||||
|        id="linearGradient38024" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)" |  | ||||||
|        x1="6" |  | ||||||
|        y1="102.95528" |  | ||||||
|        x2="6" |  | ||||||
|        y2="84.505203" /> |  | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        id="linearGradient76469-7-7-4"> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#2e3232;stop-opacity:1" |  | ||||||
|          offset="0" |  | ||||||
|          id="stop76471-7-1-5" /> |  | ||||||
|       <stop |  | ||||||
|          style="stop-color:#3e4545;stop-opacity:1" |  | ||||||
|          offset="1" |  | ||||||
|          id="stop76473-9-0-0" /> |  | ||||||
|     </linearGradient> |  | ||||||
|     <inkscape:path-effect |  | ||||||
|        effect="spiro" |  | ||||||
|        id="path-effect77541-4" |  | ||||||
|        is_visible="true" /> |  | ||||||
|     <linearGradient |  | ||||||
|        id="linearGradient77461-1" |  | ||||||
|        inkscape:collect="always"> |  | ||||||
|       <stop |  | ||||||
|          id="stop77463-1" |  | ||||||
|          offset="0" |  | ||||||
|          style="stop-color:#182f4c;stop-opacity:1" /> |  | ||||||
|       <stop |  | ||||||
|          id="stop77465-4" |  | ||||||
|          offset="1" |  | ||||||
|          style="stop-color:#205b9a;stop-opacity:1" /> |  | ||||||
|     </linearGradient> |  | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient77461-1" |  | ||||||
|        id="linearGradient77551-6-5" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        gradientTransform="matrix(0.8527367,0,0,0.80554422,-969.41608,-778.00299)" |  | ||||||
|        x1="1164.7644" |  | ||||||
|        y1="962.93695" |  | ||||||
|        x2="1164.7644" |  | ||||||
|        y2="970.51404" /> |  | ||||||
|     <linearGradient |  | ||||||
|        inkscape:collect="always" |  | ||||||
|        xlink:href="#linearGradient77461-1" |  | ||||||
|        id="linearGradient11198" |  | ||||||
|        gradientUnits="userSpaceOnUse" |  | ||||||
|        gradientTransform="matrix(1.3066667,0,0,1,-1066.3709,794.25325)" |  | ||||||
|        x1="1322.5831" |  | ||||||
|        y1="-312.51855" |  | ||||||
|        x2="1322.5831" |  | ||||||
|        y2="-306.53461" /> |  | ||||||
|   </defs> |   </defs> | ||||||
|   <sodipodi:namedview |   <sodipodi:namedview | ||||||
|      id="base" |      id="base" | ||||||
|      pagecolor="#000000" |      pagecolor="#ffffff" | ||||||
|      bordercolor="#666666" |      bordercolor="#666666" | ||||||
|      borderopacity="1.0" |      borderopacity="1.0" | ||||||
|      inkscape:pageopacity="1" |      inkscape:pageopacity="0.0" | ||||||
|      inkscape:pageshadow="2" |      inkscape:pageshadow="2" | ||||||
|      inkscape:zoom="1" |      inkscape:zoom="1" | ||||||
|      inkscape:cx="-26.798898" |      inkscape:cx="19.689855" | ||||||
|      inkscape:cy="5.3753009" |      inkscape:cy="2.0517979" | ||||||
|      inkscape:document-units="px" |      inkscape:document-units="px" | ||||||
|      inkscape:current-layer="g37994" |      inkscape:current-layer="layer1" | ||||||
|      showgrid="false" |      showgrid="false" | ||||||
|      inkscape:window-width="2560" |      inkscape:window-width="941" | ||||||
|      inkscape:window-height="1376" |      inkscape:window-height="751" | ||||||
|      inkscape:window-x="0" |      inkscape:window-x="2577" | ||||||
|      inkscape:window-y="27" |      inkscape:window-y="206" | ||||||
|      inkscape:window-maximized="1" |      inkscape:window-maximized="0" | ||||||
|      borderlayer="true" |      borderlayer="true" | ||||||
|      inkscape:showpageshadow="false" |      inkscape:showpageshadow="false" /> | ||||||
|      inkscape:snap-nodes="false" |  | ||||||
|      inkscape:snap-bbox="true" |  | ||||||
|      showborder="false"> |  | ||||||
|     <inkscape:grid |  | ||||||
|        type="xygrid" |  | ||||||
|        id="grid12954" |  | ||||||
|        empspacing="5" |  | ||||||
|        visible="true" |  | ||||||
|        enabled="true" |  | ||||||
|        snapvisiblegridlinesonly="true" /> |  | ||||||
|   </sodipodi:namedview> |  | ||||||
|   <metadata |   <metadata | ||||||
|      id="metadata2862"> |      id="metadata2862"> | ||||||
|     <rdf:RDF> |     <rdf:RDF> | ||||||
| @@ -140,68 +70,61 @@ | |||||||
|      id="layer1" |      id="layer1" | ||||||
|      transform="translate(-444.64286,-781.36218)"> |      transform="translate(-444.64286,-781.36218)"> | ||||||
|     <g |     <g | ||||||
|        transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)" |  | ||||||
|        id="g37994"> |  | ||||||
|       <g |  | ||||||
|          id="g37996" |  | ||||||
|          transform="translate(-115,1277)"> |  | ||||||
|         <rect |  | ||||||
|            style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837" |  | ||||||
|            id="rect13475" |  | ||||||
|            width="98" |  | ||||||
|            height="25" |  | ||||||
|            x="644.5" |  | ||||||
|            y="484.61118" |  | ||||||
|            rx="4.7429576" |  | ||||||
|            ry="3.8424656" /> |  | ||||||
|         <rect |  | ||||||
|            ry="3.8424656" |  | ||||||
|            rx="4.7429576" |  | ||||||
|            y="483.5" |  | ||||||
|            x="644.5" |  | ||||||
|            height="25" |  | ||||||
|            width="98" |  | ||||||
|            id="rect38000" |  | ||||||
|            style="color:#000000;fill:url(#linearGradient11198);fill-opacity:1;fill-rule:nonzero;stroke:#182f4c;stroke-width:1.37920964;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;clip-rule:nonzero;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;filter-blend-mode:normal;filter-gaussianBlur-deviation:0;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto" /> |  | ||||||
|       </g> |  | ||||||
|       <g |  | ||||||
|          transform="translate(2.0625,-2)" |  | ||||||
|          id="g38002"> |  | ||||||
|         <g |  | ||||||
|            transform="translate(-115,1247)" |  | ||||||
|        style="display:inline" |        style="display:inline" | ||||||
|            id="g38004"> |        transform="translate(-351.35714,708.36218)" | ||||||
|  |        id="g16453"> | ||||||
|       <rect |       <rect | ||||||
|              ry="3.7972314" |          style="color:#000000;fill:#4a90d9;fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:0.99999994000000003;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||||||
|              rx="4.6871223" |          id="rect16256-9-4" | ||||||
|              y="515.5" |          width="63.000004" | ||||||
|              x="694.53046" |          height="19" | ||||||
|              height="25" |          x="-859.5" | ||||||
|              width="45.969578" |          y="74.5" | ||||||
|              id="rect38006" |          rx="4" | ||||||
|              style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |          ry="4" | ||||||
|  |          transform="scale(-1,1)" /> | ||||||
|  |       <rect | ||||||
|  |          style="fill:#000000;fill-opacity:1;stroke:#5f5f5f;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" | ||||||
|  |          id="rect16258-5-4" | ||||||
|  |          width="31" | ||||||
|  |          height="20" | ||||||
|  |          x="-860" | ||||||
|  |          y="74" | ||||||
|  |          rx="4" | ||||||
|  |          ry="4" | ||||||
|  |          transform="scale(-1,1)" /> | ||||||
|  |       <g | ||||||
|  |          style="display:inline" | ||||||
|  |          id="g16298-3-6" | ||||||
|  |          transform="matrix(-1,0,0,1,1651.1322,-33.986291)"> | ||||||
|         <path |         <path | ||||||
|              sodipodi:nodetypes="cc" |            inkscape:connector-curvature="0" | ||||||
|              style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |            id="path16265-3-5" | ||||||
|              d="m 699.09675,516.7365 36.86904,0" |            d="m 803.6322,115.48629 0,4.29495" | ||||||
|              id="path38016" |            style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> | ||||||
|              inkscape:path-effect="#path-effect77541-4" |         <path | ||||||
|              inkscape:original-d="m 699.09675,516.7365 36.86904,0" |            inkscape:connector-curvature="0" | ||||||
|              inkscape:connector-curvature="0" /> |            id="path16265-0-2-0" | ||||||
|  |            d="m 806.62805,115.48629 0,4.29495" | ||||||
|  |            style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" /> | ||||||
|  |         <path | ||||||
|  |            inkscape:connector-curvature="0" | ||||||
|  |            id="path16265-8-7-1" | ||||||
|  |            d="m 809.6239,115.48629 0,4.29495" | ||||||
|  |            style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" /> | ||||||
|       </g> |       </g> | ||||||
|  |       <g | ||||||
|  |          style="font-size:8.95877075px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold" | ||||||
|  |          id="text42229-3-0"> | ||||||
|  |         <path | ||||||
|  |            d="m 808.01473,80.573953 c 0.63283,6e-6 1.19567,0.123947 1.68852,0.371824 0.49284,0.247888 0.88071,0.609505 1.16359,1.084851 0.28287,0.472439 0.42431,1.022155 0.42432,1.649149 -10e-6,0.635748 -0.13853,1.200045 -0.41557,1.692892 -0.27705,0.489934 -0.66637,0.870506 -1.16796,1.141719 -0.50161,0.271212 -1.07757,0.406819 -1.72789,0.406819 -0.4287,0 -0.83552,-0.06562 -1.22046,-0.196848 -0.38495,-0.134148 -0.73053,-0.32808 -1.03673,-0.581795 -0.3033,-0.256631 -0.54535,-0.589085 -0.72615,-0.997363 -0.1779,-0.408276 -0.26684,-0.869045 -0.26684,-1.382311 0,-0.638658 0.13998,-1.200039 0.41994,-1.684144 0.27996,-0.487011 0.66782,-0.858835 1.16359,-1.115472 0.49576,-0.259541 1.06298,-0.389315 1.70164,-0.389321 m 0.57305,1.089225 c -0.20123,-0.05249 -0.40682,-0.07873 -0.61679,-0.07874 -0.20998,5e-6 -0.41411,0.02625 -0.61242,0.07874 -0.19831,0.04958 -0.38932,0.129779 -0.57304,0.240592 -0.18081,0.107907 -0.33975,0.242055 -0.47681,0.402445 -0.13707,0.160399 -0.24643,0.358705 -0.32808,0.594918 -0.0817,0.233305 -0.12249,0.491395 -0.12249,0.774269 0,0.67366 0.20851,1.214627 0.62554,1.622902 0.41703,0.408279 0.93758,0.612417 1.56166,0.612416 0.25955,10e-7 0.51035,-0.04228 0.7524,-0.126857 0.24496,-0.08457 0.47097,-0.20997 0.67803,-0.376199 0.20705,-0.166225 0.37328,-0.392236 0.49868,-0.678031 0.1254,-0.285792 0.1881,-0.610956 0.1881,-0.975492 0,-0.297455 -0.0437,-0.568668 -0.13123,-0.813638 -0.0875,-0.247878 -0.20414,-0.453475 -0.34995,-0.61679 -0.1429,-0.163307 -0.31059,-0.301829 -0.50306,-0.415568 -0.18956,-0.11373 -0.38641,-0.195385 -0.59054,-0.244967" | ||||||
|  |            style="line-height:125%;fill:#ffffff;fill-opacity:1;marker:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold" | ||||||
|  |            id="path18606" /> | ||||||
|  |         <path | ||||||
|  |            d="m 813.15903,80.639569 1.21608,0 3.4689,4.776844 0,-4.776844 1.10235,0 0,6.216022 -1.22921,0 -3.45577,-4.785594 0,4.785594 -1.10235,0 0,-6.216022" | ||||||
|  |            style="line-height:125%;fill:#ffffff;fill-opacity:1;marker:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold" | ||||||
|  |            id="path18608" /> | ||||||
|       </g> |       </g> | ||||||
|       <text |  | ||||||
|          transform="scale(1.1000946,0.90901274)" |  | ||||||
|          sodipodi:linespacing="125%" |  | ||||||
|          id="text38018" |  | ||||||
|          y="1955.5205" |  | ||||||
|          x="495.94223" |  | ||||||
|          style="font-size:13.29953671px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold" |  | ||||||
|          xml:space="preserve"><tspan |  | ||||||
|            y="1955.5205" |  | ||||||
|            x="495.94223" |  | ||||||
|            id="tspan38020" |  | ||||||
|            sodipodi:role="line">ON</tspan></text> |  | ||||||
|     </g> |     </g> | ||||||
|   </g> |   </g> | ||||||
| </svg> | </svg> | ||||||
|   | |||||||
| Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 6.8 KiB | 
| @@ -17,6 +17,7 @@ | |||||||
|   <chapter> |   <chapter> | ||||||
|     <title>Actors</title> |     <title>Actors</title> | ||||||
|     <xi:include href="xml/shell-generic-container.xml"/> |     <xi:include href="xml/shell-generic-container.xml"/> | ||||||
|  |     <xi:include href="xml/shell-slicer.xml"/> | ||||||
|     <xi:include href="xml/shell-stack.xml"/> |     <xi:include href="xml/shell-stack.xml"/> | ||||||
|   </chapter> |   </chapter> | ||||||
|   <chapter> |   <chapter> | ||||||
| @@ -45,7 +46,7 @@ | |||||||
|     <xi:include href="doc-gen-org.gnome.Shell.SearchProvider.xml"/> |     <xi:include href="doc-gen-org.gnome.Shell.SearchProvider.xml"/> | ||||||
|     <xi:include href="doc-gen-org.gnome.Shell.SearchProvider2.xml"/> |     <xi:include href="doc-gen-org.gnome.Shell.SearchProvider2.xml"/> | ||||||
|     <xi:include href="xml/shell-global.xml"/> |     <xi:include href="xml/shell-global.xml"/> | ||||||
|     <xi:include href="xml/shell-action-modes.xml"/> |     <xi:include href="xml/shell-keybinding-modes.xml"/> | ||||||
|     <xi:include href="xml/shell-wm.xml"/> |     <xi:include href="xml/shell-wm.xml"/> | ||||||
|     <xi:include href="xml/shell-util.xml"/> |     <xi:include href="xml/shell-util.xml"/> | ||||||
|     <xi:include href="xml/shell-mount-operation.xml"/> |     <xi:include href="xml/shell-mount-operation.xml"/> | ||||||
|   | |||||||
| @@ -35,6 +35,7 @@ | |||||||
|       <xi:include href="xml/st-bin.xml"/> |       <xi:include href="xml/st-bin.xml"/> | ||||||
|       <xi:include href="xml/st-box-layout.xml"/> |       <xi:include href="xml/st-box-layout.xml"/> | ||||||
|       <xi:include href="xml/st-scroll-view.xml"/> |       <xi:include href="xml/st-scroll-view.xml"/> | ||||||
|  |       <xi:include href="xml/st-table.xml"/> | ||||||
|     </chapter> |     </chapter> | ||||||
|  |  | ||||||
|     <chapter id="styling"> |     <chapter id="styling"> | ||||||
|   | |||||||
| @@ -27,9 +27,7 @@ its dependencies to build from tarballs.</description> | |||||||
|   <download-page rdf:resource="http://download.gnome.org/sources/gnome-shell/" /> |   <download-page rdf:resource="http://download.gnome.org/sources/gnome-shell/" /> | ||||||
|   <bug-database rdf:resource="https://bugzilla.gnome.org/browse.cgi?product=gnome-shell" /> |   <bug-database rdf:resource="https://bugzilla.gnome.org/browse.cgi?product=gnome-shell" /> | ||||||
|  |  | ||||||
|   <category rdf:resource="http://api.gnome.org/doap-extensions#core" /> |   <category rdf:resource="http://api.gnome.org/doap-extensions#desktop" /> | ||||||
|   <programming-language>JavaScript</programming-language> |  | ||||||
|   <programming-language>C</programming-language> |  | ||||||
|  |  | ||||||
|   <maintainer> |   <maintainer> | ||||||
|     <foaf:Person> |     <foaf:Person> | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ misc/config.js: misc/config.js.in Makefile | |||||||
| 	    -e "s|[@]sysconfdir@|$(sysconfdir)|g" \ | 	    -e "s|[@]sysconfdir@|$(sysconfdir)|g" \ | ||||||
|                $< > $@ |                $< > $@ | ||||||
|  |  | ||||||
| js_resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --sourcedir=$(builddir) --generate-dependencies $(srcdir)/js-resources.gresource.xml) | js_resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/js-resources.gresource.xml) | ||||||
| js-resources.h: js-resources.gresource.xml $(js_resource_files) misc/config.js | js-resources.h: js-resources.gresource.xml $(js_resource_files) misc/config.js | ||||||
| 	$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --sourcedir=$(builddir) --generate --c-name shell_js_resources $< | 	$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --sourcedir=$(builddir) --generate --c-name shell_js_resources $< | ||||||
| js-resources.c: js-resources.gresource.xml $(js_resource_files) misc/config.js | js-resources.c: js-resources.gresource.xml $(js_resource_files) misc/config.js | ||||||
|   | |||||||
| @@ -62,6 +62,9 @@ const Application = new Lang.Class({ | |||||||
|         if (!extension) |         if (!extension) | ||||||
|             return false; |             return false; | ||||||
|  |  | ||||||
|  |         if (ExtensionUtils.isOutOfDate(extension)) | ||||||
|  |             return false; | ||||||
|  |  | ||||||
|         if (!extension.dir.get_child('prefs.js').query_exists(null)) |         if (!extension.dir.get_child('prefs.js').query_exists(null)) | ||||||
|             return false; |             return false; | ||||||
|  |  | ||||||
| @@ -275,15 +278,11 @@ const ExtensionRow = new Lang.Class({ | |||||||
|  |  | ||||||
|         this.uuid = uuid; |         this.uuid = uuid; | ||||||
|  |  | ||||||
|         this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell' }); |         this._settings = new Gio.Settings({ schema: 'org.gnome.shell' }); | ||||||
|         this._settings.connect('changed::enabled-extensions', Lang.bind(this, |         this._settings.connect('changed::enabled-extensions', Lang.bind(this, | ||||||
|             function() { |             function() { | ||||||
|                 this._switch.state = this._isEnabled(); |                 this._switch.state = this._isEnabled(); | ||||||
|             })); |             })); | ||||||
|         this._settings.connect('changed::disable-extension-version-validation', |  | ||||||
|             Lang.bind(this, function() { |  | ||||||
|                 this._switch.sensitive = this._canEnable(); |  | ||||||
|             })); |  | ||||||
|  |  | ||||||
|         this._buildUI(); |         this._buildUI(); | ||||||
|     }, |     }, | ||||||
| @@ -322,7 +321,6 @@ const ExtensionRow = new Lang.Class({ | |||||||
|         this.prefsButton = button; |         this.prefsButton = button; | ||||||
|  |  | ||||||
|         this._switch = new Gtk.Switch({ valign: Gtk.Align.CENTER, |         this._switch = new Gtk.Switch({ valign: Gtk.Align.CENTER, | ||||||
|                                         sensitive: this._canEnable(), |  | ||||||
|                                         state: this._isEnabled() }); |                                         state: this._isEnabled() }); | ||||||
|         this._switch.connect('notify::active', Lang.bind(this, |         this._switch.connect('notify::active', Lang.bind(this, | ||||||
|             function() { |             function() { | ||||||
| @@ -335,13 +333,6 @@ const ExtensionRow = new Lang.Class({ | |||||||
|         hbox.add(this._switch); |         hbox.add(this._switch); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _canEnable: function() { |  | ||||||
|         let extension = ExtensionUtils.extensions[this.uuid]; |  | ||||||
|         let checkVersion = !this._settings.get_boolean('disable-extension-version-validation'); |  | ||||||
|  |  | ||||||
|         return !(checkVersion && ExtensionUtils.isOutOfDate(extension)); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _isEnabled: function() { |     _isEnabled: function() { | ||||||
|         let extensions = this._settings.get_strv('enabled-extensions'); |         let extensions = this._settings.get_strv('enabled-extensions'); | ||||||
|         return extensions.indexOf(this.uuid) != -1; |         return extensions.indexOf(this.uuid) != -1; | ||||||
|   | |||||||
| @@ -1,7 +1,6 @@ | |||||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||||
|  |  | ||||||
| const Clutter = imports.gi.Clutter; | const Clutter = imports.gi.Clutter; | ||||||
| const Gio = imports.gi.Gio; |  | ||||||
| const Lang = imports.lang; | const Lang = imports.lang; | ||||||
| const Signals = imports.signals; | const Signals = imports.signals; | ||||||
| const St = imports.gi.St; | const St = imports.gi.St; | ||||||
| @@ -14,7 +13,7 @@ const ShellEntry = imports.ui.shellEntry; | |||||||
| const Tweener = imports.ui.tweener; | const Tweener = imports.ui.tweener; | ||||||
| const UserWidget = imports.ui.userWidget; | const UserWidget = imports.ui.userWidget; | ||||||
|  |  | ||||||
| const DEFAULT_BUTTON_WELL_ICON_SIZE = 16; | const DEFAULT_BUTTON_WELL_ICON_SIZE = 24; | ||||||
| const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0; | const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0; | ||||||
| const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3; | const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3; | ||||||
|  |  | ||||||
| @@ -127,7 +126,7 @@ const AuthPrompt = new Lang.Class({ | |||||||
|  |  | ||||||
|         this._initButtons(); |         this._initButtons(); | ||||||
|  |  | ||||||
|         let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg'); |         let spinnerIcon = global.datadir + '/theme/process-working.svg'; | ||||||
|         this._spinner = new Animation.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE); |         this._spinner = new Animation.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE); | ||||||
|         this._spinner.actor.opacity = 0; |         this._spinner.actor.opacity = 0; | ||||||
|         this._spinner.actor.show(); |         this._spinner.actor.show(); | ||||||
| @@ -135,12 +134,13 @@ const AuthPrompt = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onDestroy: function() { |     _onDestroy: function() { | ||||||
|         this._userVerifier.destroy(); |         this._userVerifier.clear(); | ||||||
|  |         this._userVerifier.disconnectAll(); | ||||||
|         this._userVerifier = null; |         this._userVerifier = null; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _initButtons: function() { |     _initButtons: function() { | ||||||
|         this.cancelButton = new St.Button({ style_class: 'modal-dialog-button button', |         this.cancelButton = new St.Button({ style_class: 'modal-dialog-button', | ||||||
|                                             button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, |                                             button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, | ||||||
|                                             reactive: true, |                                             reactive: true, | ||||||
|                                             can_focus: true, |                                             can_focus: true, | ||||||
| @@ -162,7 +162,7 @@ const AuthPrompt = new Lang.Class({ | |||||||
|                               y_fill: false, |                               y_fill: false, | ||||||
|                               x_align: St.Align.END, |                               x_align: St.Align.END, | ||||||
|                               y_align: St.Align.MIDDLE }); |                               y_align: St.Align.MIDDLE }); | ||||||
|         this.nextButton = new St.Button({ style_class: 'modal-dialog-button button', |         this.nextButton = new St.Button({ style_class: 'modal-dialog-button', | ||||||
|                                           button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, |                                           button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, | ||||||
|                                           reactive: true, |                                           reactive: true, | ||||||
|                                           can_focus: true, |                                           can_focus: true, | ||||||
| @@ -194,15 +194,17 @@ const AuthPrompt = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onAskQuestion: function(verifier, serviceName, question, passwordChar) { |     _onAskQuestion: function(verifier, serviceName, question, passwordChar) { | ||||||
|         if (this._queryingService) |  | ||||||
|             this.clear(); |  | ||||||
|  |  | ||||||
|         this._queryingService = serviceName; |  | ||||||
|         if (this._preemptiveAnswer) { |         if (this._preemptiveAnswer) { | ||||||
|  |             if (this._queryingService) | ||||||
|                 this._userVerifier.answerQuery(this._queryingService, this._preemptiveAnswer); |                 this._userVerifier.answerQuery(this._queryingService, this._preemptiveAnswer); | ||||||
|             this._preemptiveAnswer = null; |             this._preemptiveAnswer = null; | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if (this._queryingService) | ||||||
|  |             this.clear(); | ||||||
|  |  | ||||||
|  |         this._queryingService = serviceName; | ||||||
|         this.setPasswordChar(passwordChar); |         this.setPasswordChar(passwordChar); | ||||||
|         this.setQuestion(question); |         this.setQuestion(question); | ||||||
|  |  | ||||||
| @@ -258,9 +260,7 @@ const AuthPrompt = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onVerificationComplete: function() { |     _onVerificationComplete: function() { | ||||||
|         this.setActorInDefaultButtonWell(null); |  | ||||||
|         this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED; |         this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED; | ||||||
| 	this.cancelButton.reactive = false; |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onReset: function() { |     _onReset: function() { | ||||||
| @@ -282,12 +282,6 @@ const AuthPrompt = new Lang.Class({ | |||||||
|         if (oldActor) |         if (oldActor) | ||||||
|             Tweener.removeTweens(oldActor); |             Tweener.removeTweens(oldActor); | ||||||
|  |  | ||||||
|         let wasSpinner; |  | ||||||
|         if (oldActor == this._spinner.actor) |  | ||||||
|             wasSpinner = true; |  | ||||||
|         else |  | ||||||
|             wasSpinner = false; |  | ||||||
|  |  | ||||||
|         let isSpinner; |         let isSpinner; | ||||||
|         if (actor == this._spinner.actor) |         if (actor == this._spinner.actor) | ||||||
|             isSpinner = true; |             isSpinner = true; | ||||||
| @@ -297,11 +291,6 @@ const AuthPrompt = new Lang.Class({ | |||||||
|         if (this._defaultButtonWellActor != actor && oldActor) { |         if (this._defaultButtonWellActor != actor && oldActor) { | ||||||
|             if (!animate) { |             if (!animate) { | ||||||
|                 oldActor.opacity = 0; |                 oldActor.opacity = 0; | ||||||
|  |  | ||||||
|                 if (wasSpinner) { |  | ||||||
|                     if (this._spinner) |  | ||||||
|                         this._spinner.stop(); |  | ||||||
|                 } |  | ||||||
|             } else { |             } else { | ||||||
|                 Tweener.addTween(oldActor, |                 Tweener.addTween(oldActor, | ||||||
|                                  { opacity: 0, |                                  { opacity: 0, | ||||||
| @@ -310,7 +299,7 @@ const AuthPrompt = new Lang.Class({ | |||||||
|                                    transition: 'linear', |                                    transition: 'linear', | ||||||
|                                    onCompleteScope: this, |                                    onCompleteScope: this, | ||||||
|                                    onComplete: function() { |                                    onComplete: function() { | ||||||
|                                       if (wasSpinner) { |                                       if (isSpinner) { | ||||||
|                                           if (this._spinner) |                                           if (this._spinner) | ||||||
|                                               this._spinner.stop(); |                                               this._spinner.stop(); | ||||||
|                                       } |                                       } | ||||||
| @@ -413,7 +402,7 @@ const AuthPrompt = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     updateSensitivity: function(sensitive) { |     updateSensitivity: function(sensitive) { | ||||||
|         this._updateNextButtonSensitivity(sensitive && this._entry.text.length > 0); |         this._updateNextButtonSensitivity(sensitive); | ||||||
|         this._entry.reactive = sensitive; |         this._entry.reactive = sensitive; | ||||||
|         this._entry.clutter_text.editable = sensitive; |         this._entry.clutter_text.editable = sensitive; | ||||||
|     }, |     }, | ||||||
| @@ -430,23 +419,19 @@ const AuthPrompt = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     setUser: function(user) { |     setUser: function(user) { | ||||||
|         let oldChild = this._userWell.get_child(); |  | ||||||
|         if (oldChild) |  | ||||||
|             oldChild.destroy(); |  | ||||||
|  |  | ||||||
|         if (user) { |         if (user) { | ||||||
|             let userWidget = new UserWidget.UserWidget(user); |             let userWidget = new UserWidget.UserWidget(user); | ||||||
|             this._userWell.set_child(userWidget.actor); |             this._userWell.set_child(userWidget.actor); | ||||||
|  |         } else { | ||||||
|  |             this._userWell.set_child(null); | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     reset: function() { |     reset: function() { | ||||||
|         let oldStatus = this.verificationStatus; |         let oldStatus = this.verificationStatus; | ||||||
|         this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; |         this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; | ||||||
|         this.cancelButton.reactive = true; |  | ||||||
|         this.nextButton.label = _("Next"); |  | ||||||
|  |  | ||||||
|         if (this._userVerifier) |         if (oldStatus == AuthPromptStatus.VERIFYING) | ||||||
|             this._userVerifier.cancel(); |             this._userVerifier.cancel(); | ||||||
|  |  | ||||||
|         this._queryingService = null; |         this._queryingService = null; | ||||||
| @@ -501,7 +486,6 @@ const AuthPrompt = new Lang.Class({ | |||||||
|  |  | ||||||
|     finish: function(onComplete) { |     finish: function(onComplete) { | ||||||
|         if (!this._userVerifier.hasPendingMessages) { |         if (!this._userVerifier.hasPendingMessages) { | ||||||
|             this._userVerifier.clear(); |  | ||||||
|             onComplete(); |             onComplete(); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| @@ -509,15 +493,11 @@ const AuthPrompt = new Lang.Class({ | |||||||
|         let signalId = this._userVerifier.connect('no-more-messages', |         let signalId = this._userVerifier.connect('no-more-messages', | ||||||
|                                                   Lang.bind(this, function() { |                                                   Lang.bind(this, function() { | ||||||
|                                                       this._userVerifier.disconnect(signalId); |                                                       this._userVerifier.disconnect(signalId); | ||||||
|                                                       this._userVerifier.clear(); |  | ||||||
|                                                       onComplete(); |                                                       onComplete(); | ||||||
|                                                   })); |                                                   })); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     cancel: function() { |     cancel: function() { | ||||||
|         if (this.verificationStatus == AuthPromptStatus.VERIFICATION_SUCCEEDED) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         this.reset(); |         this.reset(); | ||||||
|         this.emit('cancelled'); |         this.emit('cancelled'); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -16,34 +16,6 @@ | |||||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. |  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * In order for transformation animations to look good, they need to be |  | ||||||
|  * incremental and have some order to them (e.g., fade out hidden items, |  | ||||||
|  * then shrink to close the void left over). Chaining animations in this way can |  | ||||||
|  * be error-prone and wordy using just Tweener callbacks. |  | ||||||
|  * |  | ||||||
|  * The classes in this file help with this: |  | ||||||
|  * |  | ||||||
|  * - Task.  encapsulates schedulable work to be run in a specific scope. |  | ||||||
|  * |  | ||||||
|  * - ConsecutiveBatch.  runs a series of tasks in order and completes |  | ||||||
|  *                      when the last in the series finishes. |  | ||||||
|  * |  | ||||||
|  * - ConcurrentBatch.  runs a set of tasks at the same time and completes |  | ||||||
|  *                     when the last to finish completes. |  | ||||||
|  * |  | ||||||
|  * - Hold.  prevents a batch from completing the pending task until |  | ||||||
|  *          the hold is released. |  | ||||||
|  * |  | ||||||
|  * The tasks associated with a batch are specified in a list at batch |  | ||||||
|  * construction time as either task objects or plain functions. |  | ||||||
|  * Batches are task objects, themselves, so they can be nested. |  | ||||||
|  * |  | ||||||
|  * These classes aren't specific to GDM, but were found to be unintuitive and so |  | ||||||
|  * are not used elsewhere. These APIs may ultimately get dropped entirely and |  | ||||||
|  * replaced by something else. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| const Lang = imports.lang; | const Lang = imports.lang; | ||||||
| const Signals = imports.signals; | const Signals = imports.signals; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,12 +22,10 @@ const Clutter = imports.gi.Clutter; | |||||||
| const Gdm = imports.gi.Gdm; | const Gdm = imports.gi.Gdm; | ||||||
| const Gio = imports.gi.Gio; | const Gio = imports.gi.Gio; | ||||||
| const GLib = imports.gi.GLib; | const GLib = imports.gi.GLib; | ||||||
| const GObject = imports.gi.GObject; |  | ||||||
| const Gtk = imports.gi.Gtk; | const Gtk = imports.gi.Gtk; | ||||||
| const Lang = imports.lang; | const Lang = imports.lang; | ||||||
| const Mainloop = imports.mainloop; | const Mainloop = imports.mainloop; | ||||||
| const Meta = imports.gi.Meta; | const Meta = imports.gi.Meta; | ||||||
| const Pango = imports.gi.Pango; |  | ||||||
| const Shell = imports.gi.Shell; | const Shell = imports.gi.Shell; | ||||||
| const Signals = imports.signals; | const Signals = imports.signals; | ||||||
| const St = imports.gi.St; | const St = imports.gi.St; | ||||||
| @@ -49,7 +47,6 @@ const _FADE_ANIMATION_TIME = 0.25; | |||||||
| const _SCROLL_ANIMATION_TIME = 0.5; | const _SCROLL_ANIMATION_TIME = 0.5; | ||||||
| const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0; | const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0; | ||||||
| const _LOGO_ICON_HEIGHT = 48; | const _LOGO_ICON_HEIGHT = 48; | ||||||
| const _MAX_BOTTOM_MENU_ITEMS = 5; |  | ||||||
|  |  | ||||||
| const UserListItem = new Lang.Class({ | const UserListItem = new Lang.Class({ | ||||||
|     Name: 'UserListItem', |     Name: 'UserListItem', | ||||||
| @@ -67,15 +64,10 @@ const UserListItem = new Lang.Class({ | |||||||
|                                      reactive: true, |                                      reactive: true, | ||||||
|                                      x_align: St.Align.START, |                                      x_align: St.Align.START, | ||||||
|                                      x_fill: true }); |                                      x_fill: true }); | ||||||
|         this.actor.connect('destroy', |  | ||||||
|                            Lang.bind(this, this._onDestroy)); |  | ||||||
|  |  | ||||||
|         this._userWidget = new UserWidget.UserWidget(this.user); |         this._userWidget = new UserWidget.UserWidget(this.user); | ||||||
|         layout.add(this._userWidget.actor); |         layout.add(this._userWidget.actor); | ||||||
|  |  | ||||||
|         this._userWidget.actor.bind_property('label-actor', this.actor, 'label-actor', |  | ||||||
|                                              GObject.BindingFlags.SYNC_CREATE); |  | ||||||
|  |  | ||||||
|         this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator', |         this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator', | ||||||
|                                                  scale_x: 0 }); |                                                  scale_x: 0 }); | ||||||
|         layout.add(this._timedLoginIndicator); |         layout.add(this._timedLoginIndicator); | ||||||
| @@ -95,10 +87,6 @@ const UserListItem = new Lang.Class({ | |||||||
|             this.actor.remove_style_pseudo_class('logged-in'); |             this.actor.remove_style_pseudo_class('logged-in'); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onDestroy: function() { |  | ||||||
|         this.user.disconnect(this._userChangedId); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _onClicked: function() { |     _onClicked: function() { | ||||||
|         this.emit('activate'); |         this.emit('activate'); | ||||||
|     }, |     }, | ||||||
| @@ -212,10 +200,6 @@ const UserList = new Lang.Class({ | |||||||
|         return item; |         return item; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     containsUser: function(user) { |  | ||||||
|         return this._items[user.get_user_name()] != null; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     addUser: function(user) { |     addUser: function(user) { | ||||||
|         if (!user.is_loaded) |         if (!user.is_loaded) | ||||||
|             return; |             return; | ||||||
| @@ -288,16 +272,7 @@ const SessionMenuButton = new Lang.Class({ | |||||||
|  |  | ||||||
|         this.actor = new St.Bin({ child: this._button }); |         this.actor = new St.Bin({ child: this._button }); | ||||||
|  |  | ||||||
|         let side = St.Side.TOP; |         this._menu = new PopupMenu.PopupMenu(this._button, 0, St.Side.TOP); | ||||||
|         let align = 0; |  | ||||||
|         if (Gdm.get_session_ids().length > _MAX_BOTTOM_MENU_ITEMS) { |  | ||||||
|             if (this.actor.text_direction == Clutter.TextDirection.RTL) |  | ||||||
|                 side = St.Side.RIGHT; |  | ||||||
|             else |  | ||||||
|                 side = St.Side.LEFT; |  | ||||||
|             align = 0.5; |  | ||||||
|         } |  | ||||||
|         this._menu = new PopupMenu.PopupMenu(this._button, align, side); |  | ||||||
|         Main.uiGroup.add_actor(this._menu.actor); |         Main.uiGroup.add_actor(this._menu.actor); | ||||||
|         this._menu.actor.hide(); |         this._menu.actor.hide(); | ||||||
|  |  | ||||||
| @@ -383,19 +358,31 @@ const LoginDialog = new Lang.Class({ | |||||||
|     Name: 'LoginDialog', |     Name: 'LoginDialog', | ||||||
|  |  | ||||||
|     _init: function(parentActor) { |     _init: function(parentActor) { | ||||||
|         this.actor = new Shell.GenericContainer({ style_class: 'login-dialog', |         this.actor = new St.Widget({ accessible_role: Atk.Role.WINDOW, | ||||||
|  |                                      layout_manager: new Clutter.BinLayout(), | ||||||
|  |                                      style_class: 'login-dialog', | ||||||
|                                      visible: false }); |                                      visible: false }); | ||||||
|         this.actor.get_accessible().set_role(Atk.Role.WINDOW); |  | ||||||
|  |  | ||||||
|         this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true })); |         this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true })); | ||||||
|         this.actor.connect('allocate', Lang.bind(this, this._onAllocate)); |  | ||||||
|         this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); |         this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); | ||||||
|         parentActor.add_child(this.actor); |         parentActor.add_child(this.actor); | ||||||
|  |  | ||||||
|         this._userManager = AccountsService.UserManager.get_default() |         this._userManager = AccountsService.UserManager.get_default() | ||||||
|         this._gdmClient = new Gdm.Client(); |         let gdmClient = new Gdm.Client(); | ||||||
|  |  | ||||||
|         this._settings = new Gio.Settings({ schema_id: GdmUtil.LOGIN_SCREEN_SCHEMA }); |         if (GLib.getenv('GDM_GREETER_TEST') != '1') { | ||||||
|  |             this._greeter = gdmClient.get_greeter_sync(null); | ||||||
|  |  | ||||||
|  |             this._greeter.connect('default-session-name-changed', | ||||||
|  |                                   Lang.bind(this, this._onDefaultSessionChanged)); | ||||||
|  |  | ||||||
|  |             this._greeter.connect('session-opened', | ||||||
|  |                                   Lang.bind(this, this._onSessionOpened)); | ||||||
|  |             this._greeter.connect('timed-login-requested', | ||||||
|  |                                   Lang.bind(this, this._onTimedLoginRequested)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA }); | ||||||
|  |  | ||||||
|         this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY, |         this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY, | ||||||
|                                Lang.bind(this, this._updateBanner)); |                                Lang.bind(this, this._updateBanner)); | ||||||
| @@ -407,23 +394,30 @@ const LoginDialog = new Lang.Class({ | |||||||
|                                Lang.bind(this, this._updateLogo)); |                                Lang.bind(this, this._updateLogo)); | ||||||
|  |  | ||||||
|         this._textureCache = St.TextureCache.get_default(); |         this._textureCache = St.TextureCache.get_default(); | ||||||
|         this._updateLogoTextureId = this._textureCache.connect('texture-file-changed', |         this._textureCache.connect('texture-file-changed', | ||||||
|                                    Lang.bind(this, this._updateLogoTexture)); |                                    Lang.bind(this, this._updateLogoTexture)); | ||||||
|  |  | ||||||
|         this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box', |         this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box', | ||||||
|                                                     x_align: Clutter.ActorAlign.CENTER, |                                                     x_align: Clutter.ActorAlign.CENTER, | ||||||
|                                                     y_align: Clutter.ActorAlign.CENTER, |                                                     y_align: Clutter.ActorAlign.CENTER, | ||||||
|  |                                                     x_expand: true, | ||||||
|  |                                                     y_expand: true, | ||||||
|                                                     vertical: true, |                                                     vertical: true, | ||||||
|                                                     visible: false }); |                                                     visible: false }); | ||||||
|         this.actor.add_child(this._userSelectionBox); |         this.actor.add_child(this._userSelectionBox); | ||||||
|  |  | ||||||
|  |         this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', | ||||||
|  |                                            text: '' }); | ||||||
|  |         this._userSelectionBox.add(this._bannerLabel); | ||||||
|  |         this._updateBanner(); | ||||||
|  |  | ||||||
|         this._userList = new UserList(); |         this._userList = new UserList(); | ||||||
|         this._userSelectionBox.add(this._userList.actor, |         this._userSelectionBox.add(this._userList.actor, | ||||||
|                                    { expand: true, |                                    { expand: true, | ||||||
|                                      x_fill: true, |                                      x_fill: true, | ||||||
|                                      y_fill: true }); |                                      y_fill: true }); | ||||||
|  |  | ||||||
|         this._authPrompt = new AuthPrompt.AuthPrompt(this._gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN); |         this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN); | ||||||
|         this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted)); |         this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted)); | ||||||
|         this._authPrompt.connect('reset', Lang.bind(this, this._onReset)); |         this._authPrompt.connect('reset', Lang.bind(this, this._onReset)); | ||||||
|         this._authPrompt.hide(); |         this._authPrompt.hide(); | ||||||
| @@ -451,25 +445,11 @@ const LoginDialog = new Lang.Class({ | |||||||
|                                      x_align: St.Align.START, |                                      x_align: St.Align.START, | ||||||
|                                      x_fill: true }); |                                      x_fill: true }); | ||||||
|  |  | ||||||
|         this._bannerView = new St.ScrollView({ style_class: 'login-dialog-banner-view', |  | ||||||
|                                                opacity: 0, |  | ||||||
|                                                vscrollbar_policy: Gtk.PolicyType.AUTOMATIC, |  | ||||||
|                                                hscrollbar_policy: Gtk.PolicyType.NEVER }); |  | ||||||
|         this.actor.add_child(this._bannerView); |  | ||||||
|  |  | ||||||
|         let bannerBox = new St.BoxLayout({ vertical: true }); |  | ||||||
|  |  | ||||||
|         this._bannerView.add_actor(bannerBox); |  | ||||||
|         this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', |  | ||||||
|                                            text: '' }); |  | ||||||
|         this._bannerLabel.clutter_text.line_wrap = true; |  | ||||||
|         this._bannerLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; |  | ||||||
|         bannerBox.add_child(this._bannerLabel); |  | ||||||
|         this._updateBanner(); |  | ||||||
|  |  | ||||||
|         this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin', |         this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin', | ||||||
|                                         x_align: Clutter.ActorAlign.CENTER, |                                         x_align: Clutter.ActorAlign.CENTER, | ||||||
|                                         y_align: Clutter.ActorAlign.END }); |                                         y_align: Clutter.ActorAlign.END, | ||||||
|  |                                         x_expand: true, | ||||||
|  |                                         y_expand: true }); | ||||||
|         this.actor.add_child(this._logoBin); |         this.actor.add_child(this._logoBin); | ||||||
|         this._updateLogo(); |         this._updateLogo(); | ||||||
|  |  | ||||||
| @@ -491,203 +471,15 @@ const LoginDialog = new Lang.Class({ | |||||||
|         this._disableUserList = undefined; |         this._disableUserList = undefined; | ||||||
|         this._userListLoaded = false; |         this._userListLoaded = false; | ||||||
|  |  | ||||||
|         this._realmManager = new Realmd.Manager(); |  | ||||||
|         this._realmSignalId = this._realmManager.connect('login-format-changed', |  | ||||||
|                                                          Lang.bind(this, this._showRealmLoginHint)); |  | ||||||
|  |  | ||||||
|         LoginManager.getLoginManager().getCurrentSessionProxy(Lang.bind(this, this._gotGreeterSessionProxy)); |         LoginManager.getLoginManager().getCurrentSessionProxy(Lang.bind(this, this._gotGreeterSessionProxy)); | ||||||
|  |  | ||||||
|         // If the user list is enabled, it should take key focus; make sure the |         // If the user list is enabled, it should take key focus; make sure the | ||||||
|         // screen shield is initialized first to prevent it from stealing the |         // screen shield is initialized first to prevent it from stealing the | ||||||
|         // focus later |         // focus later | ||||||
|         this._startupCompleteId = Main.layoutManager.connect('startup-complete', |         Main.layoutManager.connect('startup-complete', | ||||||
|                                    Lang.bind(this, this._updateDisableUserList)); |                                    Lang.bind(this, this._updateDisableUserList)); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _getBannerAllocation: function (dialogBox) { |  | ||||||
|         let actorBox = new Clutter.ActorBox(); |  | ||||||
|  |  | ||||||
|         let [minWidth, minHeight, natWidth, natHeight] = this._bannerView.get_preferred_size(); |  | ||||||
|         let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2; |  | ||||||
|  |  | ||||||
|         actorBox.x1 = Math.floor(centerX - natWidth / 2); |  | ||||||
|         actorBox.y1 = dialogBox.y1 + Main.layoutManager.panelBox.height; |  | ||||||
|         actorBox.x2 = actorBox.x1 + natWidth; |  | ||||||
|         actorBox.y2 = actorBox.y1 + natHeight; |  | ||||||
|  |  | ||||||
|         return actorBox; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _getLogoBinAllocation: function (dialogBox) { |  | ||||||
|         let actorBox = new Clutter.ActorBox(); |  | ||||||
|  |  | ||||||
|         let [minWidth, minHeight, natWidth, natHeight] = this._logoBin.get_preferred_size(); |  | ||||||
|         let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2; |  | ||||||
|  |  | ||||||
|         actorBox.x1 = Math.floor(centerX - natWidth / 2); |  | ||||||
|         actorBox.y1 = dialogBox.y2 - natHeight; |  | ||||||
|         actorBox.x2 = actorBox.x1 + natWidth; |  | ||||||
|         actorBox.y2 = actorBox.y1 + natHeight; |  | ||||||
|  |  | ||||||
|         return actorBox; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _getCenterActorAllocation: function (dialogBox, actor) { |  | ||||||
|         let actorBox = new Clutter.ActorBox(); |  | ||||||
|  |  | ||||||
|         let [minWidth, minHeight, natWidth, natHeight] = actor.get_preferred_size(); |  | ||||||
|         let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2; |  | ||||||
|         let centerY = dialogBox.y1 + (dialogBox.y2 - dialogBox.y1) / 2; |  | ||||||
|  |  | ||||||
|         natWidth = Math.min(natWidth, dialogBox.x2 - dialogBox.x1); |  | ||||||
|         natHeight = Math.min(natHeight, dialogBox.y2 - dialogBox.y1); |  | ||||||
|  |  | ||||||
|         actorBox.x1 = Math.floor(centerX - natWidth / 2); |  | ||||||
|         actorBox.y1 = Math.floor(centerY - natHeight / 2); |  | ||||||
|         actorBox.x2 = actorBox.x1 + natWidth; |  | ||||||
|         actorBox.y2 = actorBox.y1 + natHeight; |  | ||||||
|  |  | ||||||
|         return actorBox; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _onAllocate: function (actor, dialogBox, flags) { |  | ||||||
|         let dialogWidth = dialogBox.x2 - dialogBox.x1; |  | ||||||
|         let dialogHeight = dialogBox.y2 - dialogBox.y1; |  | ||||||
|  |  | ||||||
|         // First find out what space the children require |  | ||||||
|         let bannerAllocation = null; |  | ||||||
|         let bannerHeight = 0; |  | ||||||
|         let bannerWidth = 0; |  | ||||||
|         if (this._bannerView.visible) { |  | ||||||
|             bannerAllocation = this._getBannerAllocation(dialogBox, this._bannerView); |  | ||||||
|             bannerHeight = bannerAllocation.y2 - bannerAllocation.y1; |  | ||||||
|             bannerWidth = bannerAllocation.x2 - bannerAllocation.x1; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         let authPromptAllocation = null; |  | ||||||
|         let authPromptHeight = 0; |  | ||||||
|         let authPromptWidth = 0; |  | ||||||
|         if (this._authPrompt.actor.visible) { |  | ||||||
|             authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt.actor); |  | ||||||
|             authPromptHeight = authPromptAllocation.y2 - authPromptAllocation.y1; |  | ||||||
|             authPromptWidth = authPromptAllocation.x2 - authPromptAllocation.x1; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         let userSelectionAllocation = null; |  | ||||||
|         let userSelectionHeight = 0; |  | ||||||
|         if (this._userSelectionBox.visible) { |  | ||||||
|             userSelectionAllocation = this._getCenterActorAllocation(dialogBox, this._userSelectionBox); |  | ||||||
|             userSelectionHeight = userSelectionAllocation.y2 - userSelectionAllocation.y1; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         let logoAllocation = null; |  | ||||||
|         let logoHeight = 0; |  | ||||||
|         if (this._logoBin.visible) { |  | ||||||
|             logoAllocation = this._getLogoBinAllocation(dialogBox); |  | ||||||
|             logoHeight = logoAllocation.y2 - logoAllocation.y1; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // Then figure out if we're overly constrained and need to |  | ||||||
|         // try a different layout, or if we have what extra space we |  | ||||||
|         // can hand out |  | ||||||
|         if (bannerAllocation) { |  | ||||||
|             let bannerSpace; |  | ||||||
|  |  | ||||||
|             if (authPromptAllocation) |  | ||||||
|                 bannerSpace = authPromptAllocation.y1 - bannerAllocation.y1; |  | ||||||
|             else |  | ||||||
|                 bannerSpace = 0; |  | ||||||
|  |  | ||||||
|             let leftOverYSpace = bannerSpace - bannerHeight; |  | ||||||
|  |  | ||||||
|             if (leftOverYSpace > 0) { |  | ||||||
|                  // First figure out how much left over space is up top |  | ||||||
|                  let leftOverTopSpace = leftOverYSpace / 2; |  | ||||||
|  |  | ||||||
|                  // Then, shift the banner into the middle of that extra space |  | ||||||
|                  let yShift = Math.floor(leftOverTopSpace / 2); |  | ||||||
|  |  | ||||||
|                  bannerAllocation.y1 += yShift; |  | ||||||
|                  bannerAllocation.y2 += yShift; |  | ||||||
|             } else { |  | ||||||
|                  // Then figure out how much space there would be if we switched to a |  | ||||||
|                  // wide layout with banner on one side and authprompt on the other. |  | ||||||
|                  let leftOverXSpace = dialogWidth - authPromptWidth; |  | ||||||
|  |  | ||||||
|                  // In a wide view, half of the available space goes to the banner, |  | ||||||
|                  // and the other half goes to the margins. |  | ||||||
|                  let wideBannerWidth = leftOverXSpace / 2; |  | ||||||
|                  let wideSpacing  = leftOverXSpace - wideBannerWidth; |  | ||||||
|  |  | ||||||
|                  // If we do go with a wide layout, we need there to be at least enough |  | ||||||
|                  // space for the banner and the auth prompt to be the same width, |  | ||||||
|                  // so it doesn't look unbalanced. |  | ||||||
|                  if (authPromptWidth > 0 && wideBannerWidth > authPromptWidth) { |  | ||||||
|                      let centerX = dialogBox.x1 + dialogWidth / 2; |  | ||||||
|                      let centerY = dialogBox.y1 + dialogHeight / 2; |  | ||||||
|  |  | ||||||
|                      // A small portion of the spacing goes down the center of the |  | ||||||
|                      // screen to help delimit the two columns of the wide view |  | ||||||
|                      let centerGap = wideSpacing / 8; |  | ||||||
|  |  | ||||||
|                      // place the banner along the left edge of the center margin |  | ||||||
|                      bannerAllocation.x2 = Math.floor(centerX - centerGap / 2); |  | ||||||
|                      bannerAllocation.x1 = Math.floor(bannerAllocation.x2 - wideBannerWidth); |  | ||||||
|  |  | ||||||
|                      // figure out how tall it would like to be and try to accomodate |  | ||||||
|                      // but don't let it get too close to the logo |  | ||||||
|                      let [wideMinHeight, wideBannerHeight] = this._bannerView.get_preferred_height(wideBannerWidth); |  | ||||||
|  |  | ||||||
|                      let maxWideHeight = dialogHeight - 3 * logoHeight; |  | ||||||
|                      wideBannerHeight = Math.min(maxWideHeight, wideBannerHeight); |  | ||||||
|                      bannerAllocation.y1 = Math.floor(centerY - wideBannerHeight / 2); |  | ||||||
|                      bannerAllocation.y2 = bannerAllocation.y1 + wideBannerHeight; |  | ||||||
|  |  | ||||||
|                      // place the auth prompt along the right edge of the center margin |  | ||||||
|                      authPromptAllocation.x1 = Math.floor(centerX + centerGap / 2); |  | ||||||
|                      authPromptAllocation.x2 = authPromptAllocation.x1 + authPromptWidth; |  | ||||||
|                  } else { |  | ||||||
|                      // If we aren't going to do a wide view, then we need to limit |  | ||||||
|                      // the height of the banner so it will present scrollbars |  | ||||||
|  |  | ||||||
|                      // First figure out how much space there is without the banner |  | ||||||
|                      leftOverYSpace += bannerHeight; |  | ||||||
|  |  | ||||||
|                      // Then figure out how much of that space is up top |  | ||||||
|                      let availableTopSpace = Math.floor(leftOverYSpace / 2); |  | ||||||
|  |  | ||||||
|                      // Then give all of that space to the banner |  | ||||||
|                      bannerAllocation.y2 = bannerAllocation.y1 + availableTopSpace; |  | ||||||
|                  } |  | ||||||
|             } |  | ||||||
|         } else if (userSelectionAllocation) { |  | ||||||
|             // Grow the user list to fill the space |  | ||||||
|             let leftOverYSpace = dialogHeight - userSelectionHeight - logoHeight; |  | ||||||
|  |  | ||||||
|             if (leftOverYSpace > 0) { |  | ||||||
|                 let topExpansion = Math.floor(leftOverYSpace / 2); |  | ||||||
|                 let bottomExpansion = topExpansion; |  | ||||||
|  |  | ||||||
|                 userSelectionAllocation.y1 -= topExpansion; |  | ||||||
|                 userSelectionAllocation.y2 += bottomExpansion; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // Finally hand out the allocations |  | ||||||
|         if (bannerAllocation) { |  | ||||||
|             this._bannerView.allocate(bannerAllocation, flags); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (authPromptAllocation) |  | ||||||
|             this._authPrompt.actor.allocate(authPromptAllocation, flags); |  | ||||||
|  |  | ||||||
|         if (userSelectionAllocation) |  | ||||||
|             this._userSelectionBox.allocate(userSelectionAllocation, flags); |  | ||||||
|  |  | ||||||
|         if (logoAllocation) |  | ||||||
|             this._logoBin.allocate(logoAllocation, flags); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _ensureUserListLoaded: function() { |     _ensureUserListLoaded: function() { | ||||||
|         if (!this._userManager.is_loaded) { |         if (!this._userManager.is_loaded) { | ||||||
|             this._userManagerLoadedId = this._userManager.connect('notify::is-loaded', |             this._userManagerLoadedId = this._userManager.connect('notify::is-loaded', | ||||||
| @@ -740,28 +532,14 @@ const LoginDialog = new Lang.Class({ | |||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _fadeInBannerView: function() { |     _updateLogoTexture: function(cache, uri) { | ||||||
|         this._bannerView.show(); |         if (this._logoFileUri != uri) | ||||||
|         Tweener.addTween(this._bannerView, |  | ||||||
|                          { opacity: 255, |  | ||||||
|                            time: _FADE_ANIMATION_TIME, |  | ||||||
|                            transition: 'easeOutQuad' }); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _hideBannerView: function() { |  | ||||||
|         Tweener.removeTweens(this._bannerView); |  | ||||||
|         this._bannerView.opacity = 0; |  | ||||||
|         this._bannerView.hide(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _updateLogoTexture: function(cache, file) { |  | ||||||
|         if (this._logoFile && !this._logoFile.equal(file)) |  | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         this._logoBin.destroy_all_children(); |         this._logoBin.destroy_all_children(); | ||||||
|         if (this._logoFile) { |         if (this._logoFileUri) { | ||||||
|             let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; |             let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; | ||||||
|             this._logoBin.add_child(this._textureCache.load_file_async(this._logoFile, |             this._logoBin.add_child(this._textureCache.load_uri_async(this._logoFileUri, | ||||||
|                                                                       -1, _LOGO_ICON_HEIGHT, |                                                                       -1, _LOGO_ICON_HEIGHT, | ||||||
|                                                                       scaleFactor)); |                                                                       scaleFactor)); | ||||||
|         } |         } | ||||||
| @@ -770,8 +548,8 @@ const LoginDialog = new Lang.Class({ | |||||||
|     _updateLogo: function() { |     _updateLogo: function() { | ||||||
|         let path = this._settings.get_string(GdmUtil.LOGO_KEY); |         let path = this._settings.get_string(GdmUtil.LOGO_KEY); | ||||||
|  |  | ||||||
|         this._logoFile = path ? Gio.file_new_for_path(path) : null; |         this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null; | ||||||
|         this._updateLogoTexture(this._textureCache, this._logoFile); |         this._updateLogoTexture(this._textureCache, this._logoFileUri); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onPrompted: function() { |     _onPrompted: function() { | ||||||
| @@ -782,24 +560,7 @@ const LoginDialog = new Lang.Class({ | |||||||
|         this._showPrompt(); |         this._showPrompt(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _resetGreeterProxy: function() { |  | ||||||
|         if (GLib.getenv('GDM_GREETER_TEST') != '1') { |  | ||||||
|             if (this._greeter) { |  | ||||||
|                 this._greeter.run_dispose(); |  | ||||||
|             } |  | ||||||
|             this._greeter = this._gdmClient.get_greeter_sync(null); |  | ||||||
|  |  | ||||||
|             this._defaultSessionChangedId = this._greeter.connect('default-session-name-changed', |  | ||||||
|                                                                   Lang.bind(this, this._onDefaultSessionChanged)); |  | ||||||
|             this._sessionOpenedId = this._greeter.connect('session-opened', |  | ||||||
|                                                           Lang.bind(this, this._onSessionOpened)); |  | ||||||
|             this._timedLoginRequestedId = this._greeter.connect('timed-login-requested', |  | ||||||
|                                                                 Lang.bind(this, this._onTimedLoginRequested)); |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _onReset: function(authPrompt, beginRequest) { |     _onReset: function(authPrompt, beginRequest) { | ||||||
|         this._resetGreeterProxy(); |  | ||||||
|         this._sessionMenuButton.updateSensitivity(true); |         this._sessionMenuButton.updateSensitivity(true); | ||||||
|  |  | ||||||
|         this._user = null; |         this._user = null; | ||||||
| @@ -838,7 +599,6 @@ const LoginDialog = new Lang.Class({ | |||||||
|                          { opacity: 255, |                          { opacity: 255, | ||||||
|                            time: _FADE_ANIMATION_TIME, |                            time: _FADE_ANIMATION_TIME, | ||||||
|                            transition: 'easeOutQuad' }); |                            transition: 'easeOutQuad' }); | ||||||
|         this._fadeInBannerView(); |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _showRealmLoginHint: function(realmManager, hint) { |     _showRealmLoginHint: function(realmManager, hint) { | ||||||
| @@ -858,14 +618,14 @@ const LoginDialog = new Lang.Class({ | |||||||
|         this._authPrompt.setPasswordChar(''); |         this._authPrompt.setPasswordChar(''); | ||||||
|         this._authPrompt.setQuestion(_("Username: ")); |         this._authPrompt.setQuestion(_("Username: ")); | ||||||
|  |  | ||||||
|         this._showRealmLoginHint(this._realmManager.loginFormat); |         let realmManager = new Realmd.Manager(); | ||||||
|  |         let realmSignalId = realmManager.connect('login-format-changed', | ||||||
|  |                                                  Lang.bind(this, this._showRealmLoginHint)); | ||||||
|  |         this._showRealmLoginHint(realmManager.loginFormat); | ||||||
|  |  | ||||||
|         if (this._nextSignalId) |         let nextSignalId = this._authPrompt.connect('next', | ||||||
|             this._authPrompt.disconnect(this._nextSignalId); |  | ||||||
|         this._nextSignalId = this._authPrompt.connect('next', |  | ||||||
|                                                     Lang.bind(this, function() { |                                                     Lang.bind(this, function() { | ||||||
|                                                           this._authPrompt.disconnect(this._nextSignalId); |                                                         this._authPrompt.disconnect(nextSignalId); | ||||||
|                                                           this._nextSignalId = 0; |  | ||||||
|                                                         this._authPrompt.updateSensitivity(false); |                                                         this._authPrompt.updateSensitivity(false); | ||||||
|                                                         let answer = this._authPrompt.getAnswer(); |                                                         let answer = this._authPrompt.getAnswer(); | ||||||
|                                                         this._user = this._userManager.get_user(answer); |                                                         this._user = this._userManager.get_user(answer); | ||||||
| @@ -873,15 +633,16 @@ const LoginDialog = new Lang.Class({ | |||||||
|                                                         this._authPrompt.startSpinning(); |                                                         this._authPrompt.startSpinning(); | ||||||
|                                                         this._authPrompt.begin({ userName: answer }); |                                                         this._authPrompt.begin({ userName: answer }); | ||||||
|                                                         this._updateCancelButton(); |                                                         this._updateCancelButton(); | ||||||
|  |  | ||||||
|  |                                                         realmManager.disconnect(realmSignalId) | ||||||
|  |                                                         realmManager.release(); | ||||||
|                                                     })); |                                                     })); | ||||||
|         this._updateCancelButton(); |         this._updateCancelButton(); | ||||||
|  |  | ||||||
|         this._authPrompt.updateSensitivity(true); |  | ||||||
|         this._showPrompt(); |         this._showPrompt(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _loginScreenSessionActivated: function() { |     _loginScreenSessionActivated: function() { | ||||||
|         if (this.actor.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING) |         if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFICATION_SUCCEEDED) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         Tweener.addTween(this.actor, |         Tweener.addTween(this.actor, | ||||||
| @@ -898,15 +659,12 @@ const LoginDialog = new Lang.Class({ | |||||||
|                            }, |                            }, | ||||||
|                            onUpdateScope: this, |                            onUpdateScope: this, | ||||||
|                            onComplete: function() { |                            onComplete: function() { | ||||||
|                                if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.NOT_VERIFYING) |  | ||||||
|                                this._authPrompt.reset(); |                                this._authPrompt.reset(); | ||||||
|                            }, |                            }, | ||||||
|                            onCompleteScope: this }); |                            onCompleteScope: this }); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _gotGreeterSessionProxy: function(proxy) { |     _gotGreeterSessionProxy: function(proxy) { | ||||||
|         this._greeterSessionProxy = proxy; |  | ||||||
|         this._greeterSessionProxyChangedId = |  | ||||||
|         proxy.connect('g-properties-changed', Lang.bind(this, function() { |         proxy.connect('g-properties-changed', Lang.bind(this, function() { | ||||||
|             if (proxy.Active) |             if (proxy.Active) | ||||||
|                 this._loginScreenSessionActivated(); |                 this._loginScreenSessionActivated(); | ||||||
| @@ -928,7 +686,11 @@ const LoginDialog = new Lang.Class({ | |||||||
|                            }, |                            }, | ||||||
|                            onUpdateScope: this, |                            onUpdateScope: this, | ||||||
|                            onComplete: function() { |                            onComplete: function() { | ||||||
|  |                                let id = Mainloop.idle_add(Lang.bind(this, function() { | ||||||
|                                    this._greeter.call_start_session_when_ready_sync(serviceName, true, null); |                                    this._greeter.call_start_session_when_ready_sync(serviceName, true, null); | ||||||
|  |                                    return GLib.SOURCE_REMOVE; | ||||||
|  |                                })); | ||||||
|  |                                GLib.Source.set_name_by_id(id, '[gnome-shell] this._greeter.call_start_session_when_ready_sync'); | ||||||
|                            }, |                            }, | ||||||
|                            onCompleteScope: this }); |                            onCompleteScope: this }); | ||||||
|     }, |     }, | ||||||
| @@ -1089,7 +851,6 @@ const LoginDialog = new Lang.Class({ | |||||||
|     _showUserList: function() { |     _showUserList: function() { | ||||||
|         this._ensureUserListLoaded(); |         this._ensureUserListLoaded(); | ||||||
|         this._authPrompt.hide(); |         this._authPrompt.hide(); | ||||||
|         this._hideBannerView(); |  | ||||||
|         this._sessionMenuButton.close(); |         this._sessionMenuButton.close(); | ||||||
|         this._setUserListExpanded(true); |         this._setUserListExpanded(true); | ||||||
|         this._notListedButton.show(); |         this._notListedButton.show(); | ||||||
| @@ -1108,11 +869,18 @@ const LoginDialog = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onUserListActivated: function(activatedItem) { |     _onUserListActivated: function(activatedItem) { | ||||||
|  |         let tasks = [function() { | ||||||
|  |                          return GdmUtil.cloneAndFadeOutActor(this._userSelectionBox); | ||||||
|  |                      }, | ||||||
|  |                      function() { | ||||||
|  |                          this._setUserListExpanded(false); | ||||||
|  |                      }]; | ||||||
|  |  | ||||||
|         this._user = activatedItem.user; |         this._user = activatedItem.user; | ||||||
|  |  | ||||||
|         this._updateCancelButton(); |         this._updateCancelButton(); | ||||||
|  |  | ||||||
|         let batch = new Batch.ConcurrentBatch(this, [GdmUtil.cloneAndFadeOutActor(this._userSelectionBox), |         let batch = new Batch.ConcurrentBatch(this, [new Batch.ConsecutiveBatch(this, tasks), | ||||||
|                                                      this._beginVerificationForItem(activatedItem)]); |                                                      this._beginVerificationForItem(activatedItem)]); | ||||||
|         batch.run(); |         batch.run(); | ||||||
|     }, |     }, | ||||||
| @@ -1122,40 +890,6 @@ const LoginDialog = new Lang.Class({ | |||||||
|             this._userManager.disconnect(this._userManagerLoadedId); |             this._userManager.disconnect(this._userManagerLoadedId); | ||||||
|             this._userManagerLoadedId = 0; |             this._userManagerLoadedId = 0; | ||||||
|         } |         } | ||||||
|         if (this._userAddedId) { |  | ||||||
|             this._userManager.disconnect(this._userAddedId); |  | ||||||
|             this._userAddedId = 0; |  | ||||||
|         } |  | ||||||
|         if (this._userRemovedId) { |  | ||||||
|             this._userManager.disconnect(this._userRemovedId); |  | ||||||
|             this._userRemovedId = 0; |  | ||||||
|         } |  | ||||||
|         if (this._userChangedId) { |  | ||||||
|             this._userManager.disconnect(this._userChangedId); |  | ||||||
|             this._userChangedId = 0; |  | ||||||
|         } |  | ||||||
|         this._textureCache.disconnect(this._updateLogoTextureId); |  | ||||||
|         Main.layoutManager.disconnect(this._startupCompleteId); |  | ||||||
|         if (this._settings) { |  | ||||||
|             this._settings.run_dispose(); |  | ||||||
|             this._settings = null; |  | ||||||
|         } |  | ||||||
|         if (this._greeter) { |  | ||||||
|             this._greeter.disconnect(this._defaultSessionChangedId); |  | ||||||
|             this._greeter.disconnect(this._sessionOpenedId); |  | ||||||
|             this._greeter.disconnect(this._timedLoginRequestedId); |  | ||||||
|             this._greeter = null; |  | ||||||
|         } |  | ||||||
|         if (this._greeterSessionProxy) { |  | ||||||
|             this._greeterSessionProxy.disconnect(this._greeterSessionProxyChangedId); |  | ||||||
|             this._greeterSessionProxy = null; |  | ||||||
|         } |  | ||||||
|         if (this._realmManager) { |  | ||||||
|             this._realmManager.disconnect(this._realmSignalId); |  | ||||||
|             this._realmSignalId = 0; |  | ||||||
|             this._realmManager.release(); |  | ||||||
|             this._realmManager = null; |  | ||||||
|         } |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _loadUserList: function() { |     _loadUserList: function() { | ||||||
| @@ -1170,24 +904,16 @@ const LoginDialog = new Lang.Class({ | |||||||
|             this._userList.addUser(users[i]); |             this._userList.addUser(users[i]); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         this._userAddedId = this._userManager.connect('user-added', |         this._userManager.connect('user-added', | ||||||
|                                   Lang.bind(this, function(userManager, user) { |                                   Lang.bind(this, function(userManager, user) { | ||||||
|                                       this._userList.addUser(user); |                                       this._userList.addUser(user); | ||||||
|                                   })); |                                   })); | ||||||
|  |  | ||||||
|         this._userRemovedId = this._userManager.connect('user-removed', |         this._userManager.connect('user-removed', | ||||||
|                                   Lang.bind(this, function(userManager, user) { |                                   Lang.bind(this, function(userManager, user) { | ||||||
|                                       this._userList.removeUser(user); |                                       this._userList.removeUser(user); | ||||||
|                                   })); |                                   })); | ||||||
|  |  | ||||||
|         this._userChangedId = this._userManager.connect('user-changed', |  | ||||||
|                                                         Lang.bind(this, function(userManager, user) { |  | ||||||
|                                                             if (this._userList.containsUser(user) && user.locked) |  | ||||||
|                                                                 this._userList.removeUser(user); |  | ||||||
|                                                             else if (!this._userList.containsUser(user) && !user.locked) |  | ||||||
|                                                                 this._userList.addUser(user); |  | ||||||
|                                                         })); |  | ||||||
|  |  | ||||||
|         return GLib.SOURCE_REMOVE; |         return GLib.SOURCE_REMOVE; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
| @@ -1200,8 +926,6 @@ const LoginDialog = new Lang.Class({ | |||||||
|         this.actor.show(); |         this.actor.show(); | ||||||
|         this.actor.opacity = 0; |         this.actor.opacity = 0; | ||||||
|  |  | ||||||
|         Main.pushModal(this.actor, { actionMode: Shell.ActionMode.LOGIN_SCREEN }); |  | ||||||
|  |  | ||||||
|         Tweener.addTween(this.actor, |         Tweener.addTween(this.actor, | ||||||
|                          { opacity: 255, |                          { opacity: 255, | ||||||
|                            time: 1, |                            time: 1, | ||||||
| @@ -1211,8 +935,7 @@ const LoginDialog = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     close: function() { |     close: function() { | ||||||
|         Main.popModal(this.actor); |         Main.ctrlAltTabManager.removeGroup(this.dialogLayout); | ||||||
|         Main.ctrlAltTabManager.removeGroup(this.actor); |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     cancel: function() { |     cancel: function() { | ||||||
|   | |||||||
| @@ -35,8 +35,8 @@ const ALLOWED_FAILURES_KEY = 'allowed-failures'; | |||||||
| const LOGO_KEY = 'logo'; | const LOGO_KEY = 'logo'; | ||||||
| const DISABLE_USER_LIST_KEY = 'disable-user-list'; | const DISABLE_USER_LIST_KEY = 'disable-user-list'; | ||||||
|  |  | ||||||
| // Give user 48ms to read each character of a PAM message | // Give user 16ms to read each character of a PAM message | ||||||
| const USER_READ_TIME = 48 | const USER_READ_TIME = 16 | ||||||
|  |  | ||||||
| const MessageType = { | const MessageType = { | ||||||
|     NONE: 0, |     NONE: 0, | ||||||
| @@ -128,7 +128,7 @@ const ShellUserVerifier = new Lang.Class({ | |||||||
|  |  | ||||||
|         this._client = client; |         this._client = client; | ||||||
|  |  | ||||||
|         this._settings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA }); |         this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA }); | ||||||
|         this._settings.connect('changed', |         this._settings.connect('changed', | ||||||
|                                Lang.bind(this, this._updateDefaultService)); |                                Lang.bind(this, this._updateDefaultService)); | ||||||
|         this._updateDefaultService(); |         this._updateDefaultService(); | ||||||
| @@ -142,9 +142,9 @@ const ShellUserVerifier = new Lang.Class({ | |||||||
|         // after a user has been picked. |         // after a user has been picked. | ||||||
|         this._checkForSmartcard(); |         this._checkForSmartcard(); | ||||||
|  |  | ||||||
|         this._smartcardInsertedId = this._smartcardManager.connect('smartcard-inserted', |         this._smartcardManager.connect('smartcard-inserted', | ||||||
|                                        Lang.bind(this, this._checkForSmartcard)); |                                        Lang.bind(this, this._checkForSmartcard)); | ||||||
|         this._smartcardRemovedId = this._smartcardManager.connect('smartcard-removed', |         this._smartcardManager.connect('smartcard-removed', | ||||||
|                                        Lang.bind(this, this._checkForSmartcard)); |                                        Lang.bind(this, this._checkForSmartcard)); | ||||||
|  |  | ||||||
|         this._messageQueue = []; |         this._messageQueue = []; | ||||||
| @@ -159,7 +159,7 @@ const ShellUserVerifier = new Lang.Class({ | |||||||
|         if (this._oVirtCredentialsManager.hasToken()) |         if (this._oVirtCredentialsManager.hasToken()) | ||||||
|             this._oVirtUserAuthenticated(this._oVirtCredentialsManager.getToken()); |             this._oVirtUserAuthenticated(this._oVirtCredentialsManager.getToken()); | ||||||
|  |  | ||||||
|         this._oVirtUserAuthenticatedId = this._oVirtCredentialsManager.connect('user-authenticated', |         this._oVirtCredentialsManager.connect('user-authenticated', | ||||||
|                                               Lang.bind(this, this._oVirtUserAuthenticated)); |                                               Lang.bind(this, this._oVirtUserAuthenticated)); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
| @@ -191,37 +191,20 @@ const ShellUserVerifier = new Lang.Class({ | |||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _clearUserVerifier: function() { |  | ||||||
|         if (this._userVerifier) { |  | ||||||
|             this._userVerifier.run_dispose(); |  | ||||||
|             this._userVerifier = null; |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     clear: function() { |     clear: function() { | ||||||
|         if (this._cancellable) { |         if (this._cancellable) { | ||||||
|             this._cancellable.cancel(); |             this._cancellable.cancel(); | ||||||
|             this._cancellable = null; |             this._cancellable = null; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         this._clearUserVerifier(); |         if (this._userVerifier) { | ||||||
|  |             this._userVerifier.run_dispose(); | ||||||
|  |             this._userVerifier = null; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         this._clearMessageQueue(); |         this._clearMessageQueue(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     destroy: function() { |  | ||||||
|         this.clear(); |  | ||||||
|  |  | ||||||
|         this._settings.run_dispose(); |  | ||||||
|         this._settings = null; |  | ||||||
|  |  | ||||||
|         this._smartcardManager.disconnect(this._smartcardInsertedId); |  | ||||||
|         this._smartcardManager.disconnect(this._smartcardRemovedId); |  | ||||||
|         this._smartcardManager = null; |  | ||||||
|  |  | ||||||
|         this._oVirtCredentialsManager.disconnect(this._oVirtUserAuthenticatedId); |  | ||||||
|         this._oVirtCredentialsManager = null; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     answerQuery: function(serviceName, answer) { |     answerQuery: function(serviceName, answer) { | ||||||
|         if (!this.hasPendingMessages) { |         if (!this.hasPendingMessages) { | ||||||
|             this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null); |             this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null); | ||||||
| @@ -300,10 +283,9 @@ const ShellUserVerifier = new Lang.Class({ | |||||||
|  |  | ||||||
|         this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, this._cancellable, Lang.bind(this, |         this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, this._cancellable, Lang.bind(this, | ||||||
|             function(device, error) { |             function(device, error) { | ||||||
|                 if (!error && device) { |                 if (!error && device) | ||||||
|                     this._haveFingerprintReader = true; |                     this._haveFingerprintReader = true; | ||||||
|                     this._updateDefaultService(); |                     this._updateDefaultService(); | ||||||
|                 } |  | ||||||
|             })); |             })); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
| @@ -344,7 +326,6 @@ const ShellUserVerifier = new Lang.Class({ | |||||||
|  |  | ||||||
|     _reauthenticationChannelOpened: function(client, result) { |     _reauthenticationChannelOpened: function(client, result) { | ||||||
|         try { |         try { | ||||||
|             this._clearUserVerifier(); |  | ||||||
|             this._userVerifier = client.open_reauthentication_channel_finish(result); |             this._userVerifier = client.open_reauthentication_channel_finish(result); | ||||||
|         } catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) { |         } catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) { | ||||||
|             return; |             return; | ||||||
| @@ -368,7 +349,6 @@ const ShellUserVerifier = new Lang.Class({ | |||||||
|  |  | ||||||
|     _userVerifierGot: function(client, result) { |     _userVerifierGot: function(client, result) { | ||||||
|         try { |         try { | ||||||
|             this._clearUserVerifier(); |  | ||||||
|             this._userVerifier = client.get_user_verifier_finish(result); |             this._userVerifier = client.get_user_verifier_finish(result); | ||||||
|         } catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) { |         } catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) { | ||||||
|             return; |             return; | ||||||
| @@ -410,7 +390,7 @@ const ShellUserVerifier = new Lang.Class({ | |||||||
|     _updateDefaultService: function() { |     _updateDefaultService: function() { | ||||||
|         if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY)) |         if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY)) | ||||||
|             this._defaultService = PASSWORD_SERVICE_NAME; |             this._defaultService = PASSWORD_SERVICE_NAME; | ||||||
|         else if (this._settings.get_boolean(SMARTCARD_AUTHENTICATION_KEY)) |         else if (this.smartcardDetected) | ||||||
|             this._defaultService = SMARTCARD_SERVICE_NAME; |             this._defaultService = SMARTCARD_SERVICE_NAME; | ||||||
|         else if (this._haveFingerprintReader) |         else if (this._haveFingerprintReader) | ||||||
|             this._defaultService = FINGERPRINT_SERVICE_NAME; |             this._defaultService = FINGERPRINT_SERVICE_NAME; | ||||||
|   | |||||||
| @@ -16,9 +16,7 @@ | |||||||
|     <file>misc/fileUtils.js</file> |     <file>misc/fileUtils.js</file> | ||||||
|     <file>misc/gnomeSession.js</file> |     <file>misc/gnomeSession.js</file> | ||||||
|     <file>misc/history.js</file> |     <file>misc/history.js</file> | ||||||
|     <file>misc/ibusManager.js</file> |  | ||||||
|     <file>misc/jsParse.js</file> |     <file>misc/jsParse.js</file> | ||||||
|     <file>misc/keyboardManager.js</file> |  | ||||||
|     <file>misc/loginManager.js</file> |     <file>misc/loginManager.js</file> | ||||||
|     <file>misc/modemManager.js</file> |     <file>misc/modemManager.js</file> | ||||||
|     <file>misc/objectManager.js</file> |     <file>misc/objectManager.js</file> | ||||||
| @@ -27,9 +25,6 @@ | |||||||
|     <file>misc/util.js</file> |     <file>misc/util.js</file> | ||||||
|  |  | ||||||
|     <file>perf/core.js</file> |     <file>perf/core.js</file> | ||||||
|     <file>perf/hwtest.js</file> |  | ||||||
|  |  | ||||||
|     <file>portalHelper/main.js</file> |  | ||||||
|  |  | ||||||
|     <file>ui/altTab.js</file> |     <file>ui/altTab.js</file> | ||||||
|     <file>ui/animation.js</file> |     <file>ui/animation.js</file> | ||||||
| @@ -44,7 +39,6 @@ | |||||||
|     <file>ui/dash.js</file> |     <file>ui/dash.js</file> | ||||||
|     <file>ui/dateMenu.js</file> |     <file>ui/dateMenu.js</file> | ||||||
|     <file>ui/dnd.js</file> |     <file>ui/dnd.js</file> | ||||||
|     <file>ui/edgeDragAction.js</file> |  | ||||||
|     <file>ui/endSessionDialog.js</file> |     <file>ui/endSessionDialog.js</file> | ||||||
|     <file>ui/environment.js</file> |     <file>ui/environment.js</file> | ||||||
|     <file>ui/extensionDownloader.js</file> |     <file>ui/extensionDownloader.js</file> | ||||||
| @@ -57,7 +51,6 @@ | |||||||
|     <file>ui/layout.js</file> |     <file>ui/layout.js</file> | ||||||
|     <file>ui/lightbox.js</file> |     <file>ui/lightbox.js</file> | ||||||
|     <file>ui/lookingGlass.js</file> |     <file>ui/lookingGlass.js</file> | ||||||
|     <file>ui/legacyTray.js</file> |  | ||||||
|     <file>ui/magnifier.js</file> |     <file>ui/magnifier.js</file> | ||||||
|     <file>ui/magnifierDBus.js</file> |     <file>ui/magnifierDBus.js</file> | ||||||
|     <file>ui/main.js</file> |     <file>ui/main.js</file> | ||||||
| @@ -65,7 +58,6 @@ | |||||||
|     <file>ui/modalDialog.js</file> |     <file>ui/modalDialog.js</file> | ||||||
|     <file>ui/notificationDaemon.js</file> |     <file>ui/notificationDaemon.js</file> | ||||||
|     <file>ui/osdWindow.js</file> |     <file>ui/osdWindow.js</file> | ||||||
|     <file>ui/osdMonitorLabeler.js</file> |  | ||||||
|     <file>ui/overview.js</file> |     <file>ui/overview.js</file> | ||||||
|     <file>ui/overviewControls.js</file> |     <file>ui/overviewControls.js</file> | ||||||
|     <file>ui/panel.js</file> |     <file>ui/panel.js</file> | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ function getCurrentExtension() { | |||||||
|     let path = match[1]; |     let path = match[1]; | ||||||
|     let file = Gio.File.new_for_path(path); |     let file = Gio.File.new_for_path(path); | ||||||
|  |  | ||||||
|     // Walk up the directory tree, looking for an extension with |     // Walk up the directory tree, looking for an extesion with | ||||||
|     // the same UUID as a directory name. |     // the same UUID as a directory name. | ||||||
|     while (file != null) { |     while (file != null) { | ||||||
|         let extension = extensions[file.get_basename()]; |         let extension = extensions[file.get_basename()]; | ||||||
|   | |||||||
| @@ -1,234 +0,0 @@ | |||||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- |  | ||||||
|  |  | ||||||
| const Gio = imports.gi.Gio; |  | ||||||
| const GLib = imports.gi.GLib; |  | ||||||
| const Lang = imports.lang; |  | ||||||
| const Mainloop = imports.mainloop; |  | ||||||
| const Signals = imports.signals; |  | ||||||
|  |  | ||||||
| try { |  | ||||||
|     var IBus = imports.gi.IBus; |  | ||||||
|     _checkIBusVersion(1, 5, 2); |  | ||||||
|     const IBusCandidatePopup = imports.ui.ibusCandidatePopup; |  | ||||||
| } catch (e) { |  | ||||||
|     var IBus = null; |  | ||||||
|     log(e); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| let _ibusManager = null; |  | ||||||
|  |  | ||||||
| function _checkIBusVersion(requiredMajor, requiredMinor, requiredMicro) { |  | ||||||
|     if ((IBus.MAJOR_VERSION > requiredMajor) || |  | ||||||
|         (IBus.MAJOR_VERSION == requiredMajor && IBus.MINOR_VERSION > requiredMinor) || |  | ||||||
|         (IBus.MAJOR_VERSION == requiredMajor && IBus.MINOR_VERSION == requiredMinor && |  | ||||||
|          IBus.MICRO_VERSION >= requiredMicro)) |  | ||||||
|         return; |  | ||||||
|  |  | ||||||
|     throw "Found IBus version %d.%d.%d but required is %d.%d.%d". |  | ||||||
|         format(IBus.MAJOR_VERSION, IBus.MINOR_VERSION, IBus.MINOR_VERSION, |  | ||||||
|                requiredMajor, requiredMinor, requiredMicro); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function getIBusManager() { |  | ||||||
|     if (_ibusManager == null) |  | ||||||
|         _ibusManager = new IBusManager(); |  | ||||||
|     return _ibusManager; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const IBusManager = new Lang.Class({ |  | ||||||
|     Name: 'IBusManager', |  | ||||||
|  |  | ||||||
|     // This is the longest we'll keep the keyboard frozen until an input |  | ||||||
|     // source is active. |  | ||||||
|     _MAX_INPUT_SOURCE_ACTIVATION_TIME: 4000, // ms |  | ||||||
|     _PRELOAD_ENGINES_DELAY_TIME: 30, // sec |  | ||||||
|  |  | ||||||
|     _init: function() { |  | ||||||
|         if (!IBus) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         IBus.init(); |  | ||||||
|  |  | ||||||
|         this._candidatePopup = new IBusCandidatePopup.CandidatePopup(); |  | ||||||
|  |  | ||||||
|         this._panelService = null; |  | ||||||
|         this._engines = {}; |  | ||||||
|         this._ready = false; |  | ||||||
|         this._registerPropertiesId = 0; |  | ||||||
|         this._currentEngineName = null; |  | ||||||
|         this._preloadEnginesId = 0; |  | ||||||
|  |  | ||||||
|         this._ibus = IBus.Bus.new_async(); |  | ||||||
|         this._ibus.connect('connected', Lang.bind(this, this._onConnected)); |  | ||||||
|         this._ibus.connect('disconnected', Lang.bind(this, this._clear)); |  | ||||||
|         // Need to set this to get 'global-engine-changed' emitions |  | ||||||
|         this._ibus.set_watch_ibus_signal(true); |  | ||||||
|         this._ibus.connect('global-engine-changed', Lang.bind(this, this._engineChanged)); |  | ||||||
|  |  | ||||||
|         this._spawn(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _spawn: function() { |  | ||||||
|         try { |  | ||||||
|             Gio.Subprocess.new(['ibus-daemon', '--xim', '--panel', 'disable'], |  | ||||||
|                                Gio.SubprocessFlags.NONE); |  | ||||||
|         } catch(e) { |  | ||||||
|             log('Failed to launch ibus-daemon: ' + e.message); |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _clear: function() { |  | ||||||
|         if (this._panelService) |  | ||||||
|             this._panelService.destroy(); |  | ||||||
|  |  | ||||||
|         this._panelService = null; |  | ||||||
|         this._candidatePopup.setPanelService(null); |  | ||||||
|         this._engines = {}; |  | ||||||
|         this._ready = false; |  | ||||||
|         this._registerPropertiesId = 0; |  | ||||||
|         this._currentEngineName = null; |  | ||||||
|  |  | ||||||
|         this.emit('ready', false); |  | ||||||
|  |  | ||||||
|         this._spawn(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _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, |  | ||||||
|                                       Lang.bind(this, this._initPanelService)); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _initEngines: function(ibus, result) { |  | ||||||
|         let enginesList = this._ibus.list_engines_async_finish(result); |  | ||||||
|         if (enginesList) { |  | ||||||
|             for (let i = 0; i < enginesList.length; ++i) { |  | ||||||
|                 let name = enginesList[i].get_name(); |  | ||||||
|                 this._engines[name] = enginesList[i]; |  | ||||||
|             } |  | ||||||
|             this._updateReadiness(); |  | ||||||
|         } else { |  | ||||||
|             this._clear(); |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _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', Lang.bind(this, this._updateProperty)); |  | ||||||
|             try { |  | ||||||
|                 // IBus versions older than 1.5.10 have a bug which |  | ||||||
|                 // causes spurious set-content-type emissions when |  | ||||||
|                 // switching input focus that temporarily lose purpose |  | ||||||
|                 // and hints defeating its intended semantics and |  | ||||||
|                 // confusing users. We thus don't use it in that case. |  | ||||||
|                 _checkIBusVersion(1, 5, 10); |  | ||||||
|                 this._panelService.connect('set-content-type', Lang.bind(this, this._setContentType)); |  | ||||||
|             } catch (e) { |  | ||||||
|             } |  | ||||||
|             // If an engine is already active we need to get its properties |  | ||||||
|             this._ibus.get_global_engine_async(-1, null, Lang.bind(this, function(i, result) { |  | ||||||
|                 let engine; |  | ||||||
|                 try { |  | ||||||
|                     engine = this._ibus.get_global_engine_async_finish(result); |  | ||||||
|                     if (!engine) |  | ||||||
|                         return; |  | ||||||
|                 } catch(e) { |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|                 this._engineChanged(this._ibus, engine.get_name()); |  | ||||||
|             })); |  | ||||||
|             this._updateReadiness(); |  | ||||||
|         } else { |  | ||||||
|             this._clear(); |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _updateReadiness: function() { |  | ||||||
|         this._ready = (Object.keys(this._engines).length > 0 && |  | ||||||
|                        this._panelService != null); |  | ||||||
|         this.emit('ready', this._ready); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _engineChanged: function(bus, engineName) { |  | ||||||
|         if (!this._ready) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         this._currentEngineName = engineName; |  | ||||||
|  |  | ||||||
|         if (this._registerPropertiesId != 0) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         this._registerPropertiesId = |  | ||||||
|             this._panelService.connect('register-properties', Lang.bind(this, function(p, props) { |  | ||||||
|                 if (!props.get(0)) |  | ||||||
|                     return; |  | ||||||
|  |  | ||||||
|                 this._panelService.disconnect(this._registerPropertiesId); |  | ||||||
|                 this._registerPropertiesId = 0; |  | ||||||
|  |  | ||||||
|                 this.emit('properties-registered', this._currentEngineName, props); |  | ||||||
|             })); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _updateProperty: function(panel, prop) { |  | ||||||
|         this.emit('property-updated', this._currentEngineName, prop); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _setContentType: function(panel, purpose, hints) { |  | ||||||
|         this.emit('set-content-type', purpose, hints); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     activateProperty: function(key, state) { |  | ||||||
|         this._panelService.property_activate(key, state); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     getEngineDesc: function(id) { |  | ||||||
|         if (!IBus || !this._ready) |  | ||||||
|             return null; |  | ||||||
|  |  | ||||||
|         return this._engines[id]; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     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. |  | ||||||
|         if (!IBus || !this._ready) { |  | ||||||
|             if (callback) |  | ||||||
|                 callback(); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this._ibus.set_global_engine_async(id, this._MAX_INPUT_SOURCE_ACTIVATION_TIME, |  | ||||||
|                                            null, callback); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     preloadEngines: function(ids) { |  | ||||||
|         if (!IBus || !this._ibus || ids.length == 0) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         if (this._preloadEnginesId != 0) { |  | ||||||
|             Mainloop.source_remove(this._preloadEnginesId); |  | ||||||
|             this._preloadEnginesId = 0; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this._preloadEnginesId = |  | ||||||
|             Mainloop.timeout_add_seconds(this._PRELOAD_ENGINES_DELAY_TIME, |  | ||||||
|                                          Lang.bind(this, function() { |  | ||||||
|                                              this._ibus.preload_engines_async( |  | ||||||
|                                                  ids, |  | ||||||
|                                                  -1, |  | ||||||
|                                                  null, |  | ||||||
|                                                  null); |  | ||||||
|                                              this._preloadEnginesId = 0; |  | ||||||
|                                              return GLib.SOURCE_REMOVE; |  | ||||||
|                                          })); |  | ||||||
|     }, |  | ||||||
| }); |  | ||||||
| Signals.addSignalMethods(IBusManager.prototype); |  | ||||||
| @@ -1,153 +0,0 @@ | |||||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- |  | ||||||
|  |  | ||||||
| const GLib = imports.gi.GLib; |  | ||||||
| const GnomeDesktop = imports.gi.GnomeDesktop; |  | ||||||
| const Lang = imports.lang; |  | ||||||
| const Meta = imports.gi.Meta; |  | ||||||
|  |  | ||||||
| const Main = imports.ui.main; |  | ||||||
|  |  | ||||||
| const DEFAULT_LOCALE = 'en_US'; |  | ||||||
| const DEFAULT_LAYOUT = 'us'; |  | ||||||
| const DEFAULT_VARIANT = ''; |  | ||||||
|  |  | ||||||
| let _xkbInfo = null; |  | ||||||
|  |  | ||||||
| function getXkbInfo() { |  | ||||||
|     if (_xkbInfo == null) |  | ||||||
|         _xkbInfo = new GnomeDesktop.XkbInfo(); |  | ||||||
|     return _xkbInfo; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| let _keyboardManager = null; |  | ||||||
|  |  | ||||||
| function getKeyboardManager() { |  | ||||||
|     if (_keyboardManager == null) |  | ||||||
|         _keyboardManager = new KeyboardManager(); |  | ||||||
|     return _keyboardManager; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function releaseKeyboard() { |  | ||||||
|     if (Main.modalCount > 0) |  | ||||||
|         global.display.unfreeze_keyboard(global.get_current_time()); |  | ||||||
|     else |  | ||||||
|         global.display.ungrab_keyboard(global.get_current_time()); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function holdKeyboard() { |  | ||||||
|     global.display.freeze_keyboard(global.get_current_time()); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const KeyboardManager = new Lang.Class({ |  | ||||||
|     Name: 'KeyboardManager', |  | ||||||
|  |  | ||||||
|     // The XKB protocol doesn't allow for more that 4 layouts in a |  | ||||||
|     // keymap. Wayland doesn't impose this limit and libxkbcommon can |  | ||||||
|     // handle up to 32 layouts but since we need to support X clients |  | ||||||
|     // even as a Wayland compositor, we can't bump this. |  | ||||||
|     MAX_LAYOUTS_PER_GROUP: 4, |  | ||||||
|  |  | ||||||
|     _init: function() { |  | ||||||
|         this._xkbInfo = getXkbInfo(); |  | ||||||
|         this._current = null; |  | ||||||
|         this._localeLayoutInfo = this._getLocaleLayout(); |  | ||||||
|         this._layoutInfos = {}; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _applyLayoutGroup: function(group) { |  | ||||||
|         let options = this._buildOptionsString(); |  | ||||||
|         let [layouts, variants] = this._buildGroupStrings(group); |  | ||||||
|         Meta.get_backend().set_keymap(layouts, variants, options); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _applyLayoutGroupIndex: function(idx) { |  | ||||||
|         Meta.get_backend().lock_layout_group(idx); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     apply: function(id) { |  | ||||||
|         let info = this._layoutInfos[id]; |  | ||||||
|         if (!info) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         if (this._current && this._current.group == info.group) { |  | ||||||
|             if (this._current.groupIndex != info.groupIndex) |  | ||||||
|                 this._applyLayoutGroupIndex(info.groupIndex); |  | ||||||
|         } else { |  | ||||||
|             this._applyLayoutGroup(info.group); |  | ||||||
|             this._applyLayoutGroupIndex(info.groupIndex); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this._current = info; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     reapply: function() { |  | ||||||
|         if (!this._current) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         this._applyLayoutGroup(this._current.group); |  | ||||||
|         this._applyLayoutGroupIndex(this._current.groupIndex); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     setUserLayouts: function(ids) { |  | ||||||
|         this._current = null; |  | ||||||
|         this._layoutInfos = {}; |  | ||||||
|  |  | ||||||
|         for (let i = 0; i < ids.length; ++i) { |  | ||||||
|             let [found, , , _layout, _variant] = this._xkbInfo.get_layout_info(ids[i]); |  | ||||||
|             if (found) |  | ||||||
|                 this._layoutInfos[ids[i]] = { id: ids[i], layout: _layout, variant: _variant }; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         let i = 0; |  | ||||||
|         let group = []; |  | ||||||
|         for (let id in this._layoutInfos) { |  | ||||||
|             // We need to leave one slot on each group free so that we |  | ||||||
|             // can add a layout containing the symbols for the |  | ||||||
|             // language used in UI strings to ensure that toolkits can |  | ||||||
|             // handle mnemonics like Alt+Ф even if the user is |  | ||||||
|             // actually typing in a different layout. |  | ||||||
|             let groupIndex = i % (this.MAX_LAYOUTS_PER_GROUP - 1); |  | ||||||
|             if (groupIndex == 0) |  | ||||||
|                 group = []; |  | ||||||
|  |  | ||||||
|             let info = this._layoutInfos[id]; |  | ||||||
|             group[groupIndex] = info; |  | ||||||
|             info.group = group; |  | ||||||
|             info.groupIndex = groupIndex; |  | ||||||
|  |  | ||||||
|             i += 1; |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _getLocaleLayout: function() { |  | ||||||
|         let locale = GLib.get_language_names()[0]; |  | ||||||
|         if (locale.indexOf('_') == -1) |  | ||||||
|             locale = DEFAULT_LOCALE; |  | ||||||
|  |  | ||||||
|         let [found, , id] = GnomeDesktop.get_input_source_from_locale(locale); |  | ||||||
|         if (!found) |  | ||||||
|             [, , id] = GnomeDesktop.get_input_source_from_locale(DEFAULT_LOCALE); |  | ||||||
|  |  | ||||||
|         let [found, , , _layout, _variant] = this._xkbInfo.get_layout_info(id); |  | ||||||
|         if (found) |  | ||||||
|             return { layout: _layout, variant: _variant }; |  | ||||||
|         else |  | ||||||
|             return { layout: DEFAULT_LAYOUT, variant: DEFAULT_VARIANT }; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _buildGroupStrings: function(_group) { |  | ||||||
|         let group = _group.concat(this._localeLayoutInfo); |  | ||||||
|         let layouts = group.map(function(g) { return g.layout; }).join(','); |  | ||||||
|         let variants = group.map(function(g) { return g.variant; }).join(','); |  | ||||||
|         return [layouts, variants]; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     setKeyboardOptions: function(options) { |  | ||||||
|         this._xkbOptions = options; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _buildOptionsString: function() { |  | ||||||
|         let options = this._xkbOptions.join(','); |  | ||||||
|         return options; |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
| @@ -134,7 +134,7 @@ const LoginManagerSystemd = new Lang.Class({ | |||||||
|             if (error) |             if (error) | ||||||
|                 asyncCallback(false); |                 asyncCallback(false); | ||||||
|             else |             else | ||||||
|                 asyncCallback(result[0] != 'no' && result[0] != 'na'); |                 asyncCallback(result[0] != 'no'); | ||||||
|         }); |         }); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										103
									
								
								js/misc/util.js
									
									
									
									
									
								
							
							
						
						| @@ -4,12 +4,10 @@ const Clutter = imports.gi.Clutter; | |||||||
| const Gio = imports.gi.Gio; | const Gio = imports.gi.Gio; | ||||||
| const GLib = imports.gi.GLib; | const GLib = imports.gi.GLib; | ||||||
| const Lang = imports.lang; | const Lang = imports.lang; | ||||||
| const Shell = imports.gi.Shell; |  | ||||||
| const St = imports.gi.St; | const St = imports.gi.St; | ||||||
|  |  | ||||||
| const Main = imports.ui.main; | const Main = imports.ui.main; | ||||||
| const Tweener = imports.ui.tweener; | const Tweener = imports.ui.tweener; | ||||||
| const Params = imports.misc.params; |  | ||||||
|  |  | ||||||
| const SCROLL_TIME = 0.1; | const SCROLL_TIME = 0.1; | ||||||
|  |  | ||||||
| @@ -40,8 +38,6 @@ const _urlRegexp = new RegExp( | |||||||
|         ')' + |         ')' + | ||||||
|     ')', 'gi'); |     ')', 'gi'); | ||||||
|  |  | ||||||
| let _desktopSettings = null; |  | ||||||
|  |  | ||||||
| // findUrls: | // findUrls: | ||||||
| // @str: string to find URLs in | // @str: string to find URLs in | ||||||
| // | // | ||||||
| @@ -161,105 +157,6 @@ function _handleSpawnError(command, err) { | |||||||
|     Main.notifyError(title, err.message); |     Main.notifyError(title, err.message); | ||||||
| } | } | ||||||
|  |  | ||||||
| function formatTime(time, params) { |  | ||||||
|     let date; |  | ||||||
|     // HACK: The built-in Date type sucks at timezones, which we need for the |  | ||||||
|     //       world clock; it's often more convenient though, so allow either |  | ||||||
|     //       Date or GLib.DateTime as parameter |  | ||||||
|     if (time instanceof Date) |  | ||||||
|         date = GLib.DateTime.new_from_unix_local(time.getTime() / 1000); |  | ||||||
|     else |  | ||||||
|         date = time; |  | ||||||
|  |  | ||||||
|     let now = GLib.DateTime.new_now_local(); |  | ||||||
|  |  | ||||||
|     let daysAgo = now.difference(date) / (24 * 60 * 60 * 1000 * 1000); |  | ||||||
|  |  | ||||||
|     let format; |  | ||||||
|  |  | ||||||
|     if (_desktopSettings == null) |  | ||||||
|         _desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' }); |  | ||||||
|     let clockFormat = _desktopSettings.get_string('clock-format'); |  | ||||||
|     let hasAmPm = date.format('%p') != ''; |  | ||||||
|  |  | ||||||
|     params = Params.parse(params, { timeOnly: false }); |  | ||||||
|  |  | ||||||
|     if (clockFormat == '24h' || !hasAmPm) { |  | ||||||
|         // Show only the time if date is on today |  | ||||||
|         if (daysAgo < 1 || params.timeOnly) |  | ||||||
|             /* Translators: Time in 24h format */ |  | ||||||
|             format = N_("%H\u2236%M"); |  | ||||||
|         // Show the word "Yesterday" and time if date is on yesterday |  | ||||||
|         else if (daysAgo <2) |  | ||||||
|             /* Translators: this is the word "Yesterday" followed by a |  | ||||||
|              time string in 24h format. i.e. "Yesterday, 14:30" */ |  | ||||||
|             // xgettext:no-c-format |  | ||||||
|             format = N_("Yesterday, %H\u2236%M"); |  | ||||||
|         // Show a week day and time if date is in the last week |  | ||||||
|         else if (daysAgo < 7) |  | ||||||
|             /* Translators: this is the week day name followed by a time |  | ||||||
|              string in 24h format. i.e. "Monday, 14:30" */ |  | ||||||
|             // xgettext:no-c-format |  | ||||||
|             format = N_("%A, %H\u2236%M"); |  | ||||||
|         else if (date.get_year() == now.get_year()) |  | ||||||
|             /* Translators: this is the month name and day number |  | ||||||
|              followed by a time string in 24h format. |  | ||||||
|              i.e. "May 25, 14:30" */ |  | ||||||
|             // xgettext:no-c-format |  | ||||||
|             format = N_("%B %d, %H\u2236%M"); |  | ||||||
|         else |  | ||||||
|             /* Translators: this is the month name, day number, year |  | ||||||
|              number followed by a time string in 24h format. |  | ||||||
|              i.e. "May 25 2012, 14:30" */ |  | ||||||
|             // xgettext:no-c-format |  | ||||||
|             format = N_("%B %d %Y, %H\u2236%M"); |  | ||||||
|     } else { |  | ||||||
|         // Show only the time if date is on today |  | ||||||
|         if (daysAgo < 1 || params.timeOnly) |  | ||||||
|             /* Translators: Time in 12h format */ |  | ||||||
|             format = N_("%l\u2236%M %p"); |  | ||||||
|         // Show the word "Yesterday" and time if date is on yesterday |  | ||||||
|         else if (daysAgo <2) |  | ||||||
|             /* Translators: this is the word "Yesterday" followed by a |  | ||||||
|              time string in 12h format. i.e. "Yesterday, 2:30 pm" */ |  | ||||||
|             // xgettext:no-c-format |  | ||||||
|             format = N_("Yesterday, %l\u2236%M %p"); |  | ||||||
|         // Show a week day and time if date is in the last week |  | ||||||
|         else if (daysAgo < 7) |  | ||||||
|             /* Translators: this is the week day name followed by a time |  | ||||||
|              string in 12h format. i.e. "Monday, 2:30 pm" */ |  | ||||||
|             // xgettext:no-c-format |  | ||||||
|             format = N_("%A, %l\u2236%M %p"); |  | ||||||
|         else if (date.get_year() == now.get_year()) |  | ||||||
|             /* Translators: this is the month name and day number |  | ||||||
|              followed by a time string in 12h format. |  | ||||||
|              i.e. "May 25, 2:30 pm" */ |  | ||||||
|             // xgettext:no-c-format |  | ||||||
|             format = N_("%B %d, %l\u2236%M %p"); |  | ||||||
|         else |  | ||||||
|             /* Translators: this is the month name, day number, year |  | ||||||
|              number followed by a time string in 12h format. |  | ||||||
|              i.e. "May 25 2012, 2:30 pm"*/ |  | ||||||
|             // xgettext:no-c-format |  | ||||||
|             format = N_("%B %d %Y, %l\u2236%M %p"); |  | ||||||
|     } |  | ||||||
|     return date.format(Shell.util_translate_time_string(format)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function createTimeLabel(date, params) { |  | ||||||
|     if (_desktopSettings == null) |  | ||||||
|         _desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' }); |  | ||||||
|  |  | ||||||
|     let label = new St.Label({ text: formatTime(date, params) }); |  | ||||||
|     let id = _desktopSettings.connect('changed::clock-format', function() { |  | ||||||
|         label.text = formatTime(date, params); |  | ||||||
|     }); |  | ||||||
|     label.connect('destroy', function() { |  | ||||||
|         _desktopSettings.disconnect(id); |  | ||||||
|     }); |  | ||||||
|     return label; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // lowerBound: | // lowerBound: | ||||||
| // @array: an array or array-like object, already sorted | // @array: an array or array-like object, already sorted | ||||||
| //         according to @cmp | //         according to @cmp | ||||||
|   | |||||||
| @@ -72,9 +72,6 @@ function run() { | |||||||
|     Scripting.defineScriptEvent("applicationsShowStart", "Starting to switch to applications view"); |     Scripting.defineScriptEvent("applicationsShowStart", "Starting to switch to applications view"); | ||||||
|     Scripting.defineScriptEvent("applicationsShowDone", "Done switching to applications view"); |     Scripting.defineScriptEvent("applicationsShowDone", "Done switching to applications view"); | ||||||
|  |  | ||||||
|     // Enable recording of timestamps for different points in the frame cycle |  | ||||||
|     global.frame_timestamps = true; |  | ||||||
|  |  | ||||||
|     Main.overview.connect('shown', function() { |     Main.overview.connect('shown', function() { | ||||||
|                               Scripting.scriptEvent('overviewShowDone'); |                               Scripting.scriptEvent('overviewShowDone'); | ||||||
|                           }); |                           }); | ||||||
| @@ -90,10 +87,7 @@ function run() { | |||||||
|             yield Scripting.destroyTestWindows(); |             yield Scripting.destroyTestWindows(); | ||||||
|  |  | ||||||
|             for (let k = 0; k < config.count; k++) |             for (let k = 0; k < config.count; k++) | ||||||
|                 yield Scripting.createTestWindow({ width: config.width, |                 yield Scripting.createTestWindow(config.width, config.height, config.alpha, config.maximized); | ||||||
|                                                    height: config.height, |  | ||||||
|                                                    alpha: config.alpha, |  | ||||||
|                                                    maximized: config.maximized }); |  | ||||||
|  |  | ||||||
|             yield Scripting.waitTestWindows(); |             yield Scripting.waitTestWindows(); | ||||||
|             yield Scripting.sleep(1000); |             yield Scripting.sleep(1000); | ||||||
|   | |||||||
| @@ -1,308 +0,0 @@ | |||||||
| const Clutter = imports.gi.Clutter; |  | ||||||
| const Gio = imports.gi.Gio; |  | ||||||
| const Gtk = imports.gi.Gtk; |  | ||||||
| const Meta = imports.gi.Meta; |  | ||||||
| const Main = imports.ui.main; |  | ||||||
| const Scripting = imports.ui.scripting; |  | ||||||
| const Shell = imports.gi.Shell; |  | ||||||
|  |  | ||||||
| let METRICS = { |  | ||||||
|     timeToDesktop: |  | ||||||
|     { description: "Time from starting graphical.target to desktop showing", |  | ||||||
|       units: "us" }, |  | ||||||
|  |  | ||||||
|     overviewShowTime: |  | ||||||
|     { description: "Time to switch to overview view, first time", |  | ||||||
|       units: "us" }, |  | ||||||
|  |  | ||||||
|     applicationsShowTime: |  | ||||||
|     { description: "Time to switch to applications view, first time", |  | ||||||
|       units: "us" }, |  | ||||||
|  |  | ||||||
|     mainViewRedrawTime: |  | ||||||
|     { description: "Time to redraw the main view, full screen", |  | ||||||
|       units: "us" }, |  | ||||||
|  |  | ||||||
|     overviewRedrawTime: |  | ||||||
|     { description: "Time to redraw the overview, full screen, 5 windows", |  | ||||||
|       units: "us" }, |  | ||||||
|  |  | ||||||
|     applicationRedrawTime: |  | ||||||
|     { description: "Time to redraw frame with a maximized application update", |  | ||||||
|       units: "us" }, |  | ||||||
|  |  | ||||||
|     geditStartTime: |  | ||||||
|     { description: "Time from gedit launch to window drawn", |  | ||||||
|       units: "us" }, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function waitAndDraw(milliseconds) { |  | ||||||
|     let cb; |  | ||||||
|  |  | ||||||
|     let timeline = new Clutter.Timeline({ duration: milliseconds }); |  | ||||||
|     timeline.start(); |  | ||||||
|  |  | ||||||
|     timeline.connect('new-frame', |  | ||||||
|         function(timeline, frame) { |  | ||||||
|             global.stage.queue_redraw(); |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|     timeline.connect('completed', |  | ||||||
|         function() { |  | ||||||
|             timeline.stop(); |  | ||||||
|             if (cb) |  | ||||||
|                 cb(); |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|     return function(callback) { |  | ||||||
|         cb = callback; |  | ||||||
|     }; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function waitSignal(object, signal) { |  | ||||||
|     let cb; |  | ||||||
|  |  | ||||||
|     let id = object.connect(signal, function() { |  | ||||||
|         object.disconnect(id); |  | ||||||
|         if (cb) |  | ||||||
|             cb(); |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     return function(callback) { |  | ||||||
|         cb = callback; |  | ||||||
|     }; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function extractBootTimestamp() { |  | ||||||
|     let sp = Gio.Subprocess.new(['journalctl', '-b', |  | ||||||
|                                  'MESSAGE_ID=7d4958e842da4a758f6c1cdc7b36dcc5', |  | ||||||
|                                  'UNIT=graphical.target', |  | ||||||
|                                  '-o', |  | ||||||
|                                  'json'], |  | ||||||
|                                 Gio.SubprocessFlags.STDOUT_PIPE); |  | ||||||
|     let result = null; |  | ||||||
|  |  | ||||||
|     let datastream = Gio.DataInputStream.new(sp.get_stdout_pipe()); |  | ||||||
|     while (true) { |  | ||||||
|         let [line, length] = datastream.read_line_utf8(null); |  | ||||||
|         if (line === null) |  | ||||||
|             break; |  | ||||||
|  |  | ||||||
|         let fields = JSON.parse(line); |  | ||||||
|         result = Number(fields['__MONOTONIC_TIMESTAMP']); |  | ||||||
|     } |  | ||||||
|     datastream.close(null); |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function run() { |  | ||||||
|     Scripting.defineScriptEvent("desktopShown", "Finished initial animation"); |  | ||||||
|     Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview"); |  | ||||||
|     Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing"); |  | ||||||
|     Scripting.defineScriptEvent("applicationsShowStart", "Starting to switch to applications view"); |  | ||||||
|     Scripting.defineScriptEvent("applicationsShowDone", "Done switching to applications view"); |  | ||||||
|     Scripting.defineScriptEvent("mainViewDrawStart", "Drawing main view"); |  | ||||||
|     Scripting.defineScriptEvent("mainViewDrawDone", "Ending timing main view drawing"); |  | ||||||
|     Scripting.defineScriptEvent("overviewDrawStart", "Drawing overview"); |  | ||||||
|     Scripting.defineScriptEvent("overviewDrawDone", "Ending timing overview drawing"); |  | ||||||
|     Scripting.defineScriptEvent("redrawTestStart", "Drawing application window"); |  | ||||||
|     Scripting.defineScriptEvent("redrawTestDone", "Ending timing application window drawing"); |  | ||||||
|     Scripting.defineScriptEvent("collectTimings", "Accumulate frame timings from redraw tests"); |  | ||||||
|     Scripting.defineScriptEvent("geditLaunch", "gedit application launch"); |  | ||||||
|     Scripting.defineScriptEvent("geditFirstFrame", "first frame of gedit window drawn"); |  | ||||||
|  |  | ||||||
|     yield Scripting.waitLeisure(); |  | ||||||
|     Scripting.scriptEvent('desktopShown'); |  | ||||||
|  |  | ||||||
|     Gtk.Settings.get_default().gtk_enable_animations = false; |  | ||||||
|  |  | ||||||
|     Scripting.scriptEvent('overviewShowStart'); |  | ||||||
|     Main.overview.show(); |  | ||||||
|     yield Scripting.waitLeisure(); |  | ||||||
|     Scripting.scriptEvent('overviewShowDone'); |  | ||||||
|  |  | ||||||
|     yield Scripting.sleep(1000); |  | ||||||
|  |  | ||||||
|     Scripting.scriptEvent('applicationsShowStart'); |  | ||||||
|     Main.overview._dash.showAppsButton.checked = true; |  | ||||||
|  |  | ||||||
|     yield Scripting.waitLeisure(); |  | ||||||
|     Scripting.scriptEvent('applicationsShowDone'); |  | ||||||
|  |  | ||||||
|     yield Scripting.sleep(1000); |  | ||||||
|  |  | ||||||
|     Main.overview.hide(); |  | ||||||
|     yield Scripting.waitLeisure(); |  | ||||||
|  |  | ||||||
|     //////////////////////////////////////// |  | ||||||
|     // Tests of redraw speed |  | ||||||
|     //////////////////////////////////////// |  | ||||||
|  |  | ||||||
|     global.frame_timestamps = true; |  | ||||||
|     global.frame_finish_timestamp = true; |  | ||||||
|  |  | ||||||
|     for (let k = 0; k < 5; k++) |  | ||||||
|         yield Scripting.createTestWindow(640, 480, |  | ||||||
|                                          { maximized: true }); |  | ||||||
|     yield Scripting.waitTestWindows(); |  | ||||||
|  |  | ||||||
|     yield Scripting.sleep(1000); |  | ||||||
|  |  | ||||||
|     Scripting.scriptEvent('mainViewDrawStart'); |  | ||||||
|     yield waitAndDraw(1000); |  | ||||||
|     Scripting.scriptEvent('mainViewDrawDone'); |  | ||||||
|  |  | ||||||
|     Main.overview.show(); |  | ||||||
|     Scripting.waitLeisure(); |  | ||||||
|  |  | ||||||
|     yield Scripting.sleep(1500); |  | ||||||
|  |  | ||||||
|     Scripting.scriptEvent('overviewDrawStart'); |  | ||||||
|     yield waitAndDraw(1000); |  | ||||||
|     Scripting.scriptEvent('overviewDrawDone'); |  | ||||||
|  |  | ||||||
|     yield Scripting.destroyTestWindows(); |  | ||||||
|     Main.overview.hide(); |  | ||||||
|  |  | ||||||
|     yield Scripting.createTestWindow(640, 480, |  | ||||||
|                                      { maximized: true, |  | ||||||
|                                        redraws: true}); |  | ||||||
|     yield Scripting.waitTestWindows(); |  | ||||||
|  |  | ||||||
|     yield Scripting.sleep(1000); |  | ||||||
|  |  | ||||||
|     Scripting.scriptEvent('redrawTestStart'); |  | ||||||
|     yield Scripting.sleep(1000); |  | ||||||
|     Scripting.scriptEvent('redrawTestDone'); |  | ||||||
|  |  | ||||||
|     yield Scripting.sleep(1000); |  | ||||||
|     Scripting.scriptEvent('collectTimings'); |  | ||||||
|  |  | ||||||
|     yield Scripting.destroyTestWindows(); |  | ||||||
|  |  | ||||||
|     global.frame_timestamps = false; |  | ||||||
|     global.frame_finish_timestamp = false; |  | ||||||
|  |  | ||||||
|     yield Scripting.sleep(1000); |  | ||||||
|  |  | ||||||
|     //////////////////////////////////////// |  | ||||||
|  |  | ||||||
|     let appSys = Shell.AppSystem.get_default(); |  | ||||||
|     let app = appSys.lookup_app('org.gnome.gedit.desktop'); |  | ||||||
|  |  | ||||||
|     Scripting.scriptEvent('geditLaunch'); |  | ||||||
|     app.activate(); |  | ||||||
|  |  | ||||||
|     let windows = app.get_windows(); |  | ||||||
|     if (windows.length > 0) |  | ||||||
|         throw new Error('gedit was already running'); |  | ||||||
|  |  | ||||||
|     while (windows.length == 0) { |  | ||||||
|         yield waitSignal(global.display, 'window-created'); |  | ||||||
|         windows = app.get_windows(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     let actor = windows[0].get_compositor_private(); |  | ||||||
|     yield waitSignal(actor, 'first-frame'); |  | ||||||
|     Scripting.scriptEvent('geditFirstFrame'); |  | ||||||
|  |  | ||||||
|     yield Scripting.sleep(1000); |  | ||||||
|  |  | ||||||
|     windows[0].delete(global.get_current_time()); |  | ||||||
|  |  | ||||||
|     yield Scripting.sleep(1000); |  | ||||||
|  |  | ||||||
|     Gtk.Settings.get_default().gtk_enable_animations = true; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| let overviewShowStart; |  | ||||||
| let applicationsShowStart; |  | ||||||
| let stagePaintStart; |  | ||||||
| let redrawTiming; |  | ||||||
| let redrawTimes = {}; |  | ||||||
| let geditLaunchTime; |  | ||||||
|  |  | ||||||
| function script_desktopShown(time) { |  | ||||||
|     let bootTimestamp = extractBootTimestamp(); |  | ||||||
|     METRICS.timeToDesktop.value = time - bootTimestamp; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function script_overviewShowStart(time) { |  | ||||||
|     overviewShowStart = time; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function script_overviewShowDone(time) { |  | ||||||
|     METRICS.overviewShowTime.value = time - overviewShowStart; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function script_applicationsShowStart(time) { |  | ||||||
|     applicationsShowStart = time; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function script_applicationsShowDone(time) { |  | ||||||
|     METRICS.applicationsShowTime.value = time - applicationsShowStart; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function script_mainViewDrawStart(time) { |  | ||||||
|     redrawTiming = 'mainView'; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function script_mainViewDrawDone(time) { |  | ||||||
|     redrawTiming = null; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function script_overviewDrawStart(time) { |  | ||||||
|     redrawTiming = 'overview'; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function script_overviewDrawDone(time) { |  | ||||||
|     redrawTiming = null; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function script_redrawTestStart(time) { |  | ||||||
|     redrawTiming = 'application'; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function script_redrawTestDone(time) { |  | ||||||
|     redrawTiming = null; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function script_collectTimings(time) { |  | ||||||
|     for (let timing in redrawTimes) { |  | ||||||
|         let times = redrawTimes[timing]; |  | ||||||
|         times.sort(function(a, b) { return a - b }); |  | ||||||
|  |  | ||||||
|         let len = times.length; |  | ||||||
|         let median; |  | ||||||
|  |  | ||||||
|         if (len == 0) |  | ||||||
|             median = -1; |  | ||||||
|         else if (len % 2 == 1) |  | ||||||
|             median = times[(len - 1)/ 2]; |  | ||||||
|         else |  | ||||||
|             median = Math.round((times[len / 2 - 1] + times[len / 2]) / 2); |  | ||||||
|  |  | ||||||
|         METRICS[timing + 'RedrawTime'].value = median; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function script_geditLaunch(time) { |  | ||||||
|     geditLaunchTime = time; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function script_geditFirstFrame(time) { |  | ||||||
|     METRICS.geditStartTime.value = time - geditLaunchTime; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function clutter_stagePaintStart(time) { |  | ||||||
|     stagePaintStart = time; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function clutter_paintCompletedTimestamp(time) { |  | ||||||
|     if (redrawTiming != null && stagePaintStart != null) { |  | ||||||
|         if (!(redrawTiming in redrawTimes)) |  | ||||||
|             redrawTimes[redrawTiming] = []; |  | ||||||
|         redrawTimes[redrawTiming].push(time - stagePaintStart); |  | ||||||
|     } |  | ||||||
|     stagePaintStart = null; |  | ||||||
| } |  | ||||||
| @@ -1,247 +0,0 @@ | |||||||
| const Format = imports.format; |  | ||||||
| const Gettext = imports.gettext; |  | ||||||
| const GLib = imports.gi.GLib; |  | ||||||
| const GObject = imports.gi.GObject; |  | ||||||
| const Gio = imports.gi.Gio; |  | ||||||
| const Gtk = imports.gi.Gtk; |  | ||||||
| const Lang = imports.lang; |  | ||||||
| const Pango = imports.gi.Pango; |  | ||||||
| const Soup = imports.gi.Soup; |  | ||||||
| const WebKit = imports.gi.WebKit2; |  | ||||||
|  |  | ||||||
| const _ = Gettext.gettext; |  | ||||||
|  |  | ||||||
| const Config = imports.misc.config; |  | ||||||
|  |  | ||||||
| const PortalHelperResult = { |  | ||||||
|     CANCELLED: 0, |  | ||||||
|     COMPLETED: 1, |  | ||||||
|     RECHECK: 2 |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| const INACTIVITY_TIMEOUT = 30000; //ms |  | ||||||
| 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 PortalWindow = new Lang.Class({ |  | ||||||
|     Name: 'PortalWindow', |  | ||||||
|     Extends: Gtk.ApplicationWindow, |  | ||||||
|  |  | ||||||
|     _init: function(application, url, timestamp, doneCallback) { |  | ||||||
|         this.parent({ application: application }); |  | ||||||
|  |  | ||||||
|         if (!url) { |  | ||||||
|             url = 'http://www.gnome.org'; |  | ||||||
|             this._originalUrlWasGnome = true; |  | ||||||
|         } else { |  | ||||||
|             this._originalUrlWasGnome = false; |  | ||||||
|         } |  | ||||||
|         this._uri = new Soup.URI(url); |  | ||||||
|         this._everSeenRedirect = false; |  | ||||||
|         this._originalUrl = url; |  | ||||||
|         this._doneCallback = doneCallback; |  | ||||||
|         this._lastRecheck = 0; |  | ||||||
|         this._recheckAtExit = false; |  | ||||||
|  |  | ||||||
|         this._webView = new WebKit.WebView(); |  | ||||||
|         this._webView.connect('decide-policy', Lang.bind(this, this._onDecidePolicy)); |  | ||||||
|         this._webView.load_uri(url); |  | ||||||
|         this._webView.connect('notify::title', Lang.bind(this, this._syncTitle)); |  | ||||||
|         this._syncTitle(); |  | ||||||
|  |  | ||||||
|         this.add(this._webView); |  | ||||||
|         this._webView.show(); |  | ||||||
|         this.maximize(); |  | ||||||
|         this.present_with_time(timestamp); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _syncTitle: function() { |  | ||||||
|         let title = this._webView.title; |  | ||||||
|  |  | ||||||
|         if (title) { |  | ||||||
|             this.title = title; |  | ||||||
|         } else { |  | ||||||
|             /* TRANSLATORS: this is the title of the wifi captive portal login |  | ||||||
|              * window, until we know the title of the actual login page */ |  | ||||||
|             this.title = _("Web Authentication Redirect"); |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     refresh: function() { |  | ||||||
|         this._everSeenRedirect = false; |  | ||||||
|         this._webView.load_uri(this._originalUrl); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     vfunc_delete_event: function(event) { |  | ||||||
|         if (this._recheckAtExit) |  | ||||||
|             this._doneCallback(PortalHelperResult.RECHECK); |  | ||||||
|         else |  | ||||||
|             this._doneCallback(PortalHelperResult.CANCELLED); |  | ||||||
|         return false; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _onDecidePolicy: function(view, decision, type) { |  | ||||||
|         if (type == WebKit.PolicyDecisionType.NEW_WINDOW_ACTION) { |  | ||||||
|             decision.ignore(); |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (type != WebKit.PolicyDecisionType.NAVIGATION_ACTION) |  | ||||||
|             return false; |  | ||||||
|  |  | ||||||
|         let request = decision.get_request(); |  | ||||||
|         let uri = new Soup.URI(request.get_uri()); |  | ||||||
|  |  | ||||||
|         if (!uri.host_equal(this._uri) && this._originalUrlWasGnome) { |  | ||||||
|             if (uri.get_host() == 'www.gnome.org' && this._everSeenRedirect) { |  | ||||||
|                 // Yay, we got to gnome! |  | ||||||
|                 decision.ignore(); |  | ||||||
|                 this._doneCallback(PortalHelperResult.COMPLETED); |  | ||||||
|                 return true; |  | ||||||
|             } else if (uri.get_host() != 'www.gnome.org') { |  | ||||||
|                 this._everSeenRedirect = true; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // We *may* have finished here, but we don't know for |  | ||||||
|         // sure. Tell gnome-shell to run another connectivity check |  | ||||||
|         // (but ratelimit the checks, we don't want to spam |  | ||||||
|         // nmcheck.gnome.org for portals that have 10 or more internal |  | ||||||
|         // redirects - and unfortunately they exist) |  | ||||||
|         // If we hit the rate limit, we also queue a recheck |  | ||||||
|         // when the window is closed, just in case we miss the |  | ||||||
|         // final check and don't realize we're connected |  | ||||||
|         // This should not be a problem in the cancelled logic, |  | ||||||
|         // because if the user doesn't want to start the login, |  | ||||||
|         // we should not see any redirect at all, outside this._uri |  | ||||||
|  |  | ||||||
|         let now = GLib.get_monotonic_time(); |  | ||||||
|         let shouldRecheck = (now - this._lastRecheck) > |  | ||||||
|             CONNECTIVITY_RECHECK_RATELIMIT_TIMEOUT; |  | ||||||
|  |  | ||||||
|         if (shouldRecheck) { |  | ||||||
|             this._lastRecheck = now; |  | ||||||
|             this._recheckAtExit = false; |  | ||||||
|             this._doneCallback(PortalHelperResult.RECHECK); |  | ||||||
|         } else { |  | ||||||
|             this._recheckAtExit = true; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // Update the URI, in case of chained redirects, so we still |  | ||||||
|         // think we're doing the login until gnome-shell kills us |  | ||||||
|         this._uri = uri; |  | ||||||
|  |  | ||||||
|         decision.use(); |  | ||||||
|         return true; |  | ||||||
|     }, |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| const WebPortalHelper = new Lang.Class({ |  | ||||||
|     Name: 'WebPortalHelper', |  | ||||||
|     Extends: Gtk.Application, |  | ||||||
|  |  | ||||||
|     _init: function() { |  | ||||||
|         this.parent({ application_id: 'org.gnome.Shell.PortalHelper', |  | ||||||
|                       flags: Gio.ApplicationFlags.IS_SERVICE, |  | ||||||
|                       inactivity_timeout: 30000 }); |  | ||||||
|  |  | ||||||
|         this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(HelperDBusInterface, this); |  | ||||||
|         this._queue = []; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     vfunc_dbus_register: function(connection, path) { |  | ||||||
|         this._dbusImpl.export(connection, path); |  | ||||||
|         this.parent(connection, path); |  | ||||||
|         return true; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     vfunc_dbus_unregister: function(connection, path) { |  | ||||||
|         this._dbusImpl.unexport_from_connection(connection); |  | ||||||
|         this.parent(connection, path); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     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: function(connection, url, timestamp) { |  | ||||||
|         this._queue.push({ connection: connection, url: url, timestamp: timestamp }); |  | ||||||
|  |  | ||||||
|         this._processQueue(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     Close: function(connection) { |  | ||||||
|         for (let i = 0; i < this._queue.length; i++) { |  | ||||||
|             let obj = this._queue[i]; |  | ||||||
|  |  | ||||||
|             if (obj.connection == connection) { |  | ||||||
|                 if (obj.window) |  | ||||||
|                     obj.window.destroy(); |  | ||||||
|                 this._queue.splice(i, 1); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this._processQueue(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     Refresh: function(connection) { |  | ||||||
|         for (let i = 0; i < this._queue.length; i++) { |  | ||||||
|             let obj = this._queue[i]; |  | ||||||
|  |  | ||||||
|             if (obj.connection == connection) { |  | ||||||
|                 if (obj.window) |  | ||||||
|                     obj.window.refresh(); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _processQueue: function() { |  | ||||||
|         if (this._queue.length == 0) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         let top = this._queue[0]; |  | ||||||
|         if (top.window != null) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         top.window = new PortalWindow(this, top.uri, top.timestamp, Lang.bind(this, function(result) { |  | ||||||
|             this._dbusImpl.emit_signal('Done', new GLib.Variant('(ou)', [top.connection, result])); |  | ||||||
|         })); |  | ||||||
|     }, |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| function initEnvironment() { |  | ||||||
|     String.prototype.format = Format.format; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function main(argv) { |  | ||||||
|     initEnvironment(); |  | ||||||
|  |  | ||||||
|     Gettext.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR); |  | ||||||
|     Gettext.textdomain(Config.GETTEXT_PACKAGE); |  | ||||||
|  |  | ||||||
|     let app = new WebPortalHelper(); |  | ||||||
|     return app.run(argv); |  | ||||||
| } |  | ||||||
| @@ -58,14 +58,6 @@ const AppSwitcherPopup = new Lang.Class({ | |||||||
|         this._currentWindow = -1; |         this._currentWindow = -1; | ||||||
|  |  | ||||||
|         this.thumbnailsVisible = false; |         this.thumbnailsVisible = false; | ||||||
|  |  | ||||||
|         let apps = Shell.AppSystem.get_default().get_running (); |  | ||||||
|  |  | ||||||
|         if (apps.length == 0) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         this._switcherList = new AppSwitcher(apps, this); |  | ||||||
|         this._items = this._switcherList.icons; |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _allocate: function (actor, box, flags) { |     _allocate: function (actor, box, flags) { | ||||||
| @@ -81,6 +73,7 @@ const AppSwitcherPopup = new Lang.Class({ | |||||||
|             let leftPadding = this.actor.get_theme_node().get_padding(St.Side.LEFT); |             let leftPadding = this.actor.get_theme_node().get_padding(St.Side.LEFT); | ||||||
|             let rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT); |             let rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT); | ||||||
|             let bottomPadding = this.actor.get_theme_node().get_padding(St.Side.BOTTOM); |             let bottomPadding = this.actor.get_theme_node().get_padding(St.Side.BOTTOM); | ||||||
|  |             let vPadding = this.actor.get_theme_node().get_vertical_padding(); | ||||||
|             let hPadding = leftPadding + rightPadding; |             let hPadding = leftPadding + rightPadding; | ||||||
|  |  | ||||||
|             let icon = this._items[this._selectedIndex].actor; |             let icon = this._items[this._selectedIndex].actor; | ||||||
| @@ -106,6 +99,20 @@ const AppSwitcherPopup = new Lang.Class({ | |||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|  |     _createSwitcher: function() { | ||||||
|  |         let apps = Shell.AppSystem.get_default().get_running (); | ||||||
|  |  | ||||||
|  |         if (apps.length == 0) | ||||||
|  |             return false; | ||||||
|  |  | ||||||
|  |         this._switcherList = new AppSwitcher(apps, this); | ||||||
|  |         this._items = this._switcherList.icons; | ||||||
|  |         if (this._items.length == 0) | ||||||
|  |             return false; | ||||||
|  |  | ||||||
|  |         return true; | ||||||
|  |     }, | ||||||
|  |  | ||||||
|     _initialSelection: function(backward, binding) { |     _initialSelection: function(backward, binding) { | ||||||
|         if (binding == 'switch-group') { |         if (binding == 'switch-group') { | ||||||
|             if (backward) { |             if (backward) { | ||||||
| @@ -144,13 +151,13 @@ const AppSwitcherPopup = new Lang.Class({ | |||||||
|                                  this._items[this._selectedIndex].cachedWindows.length); |                                  this._items[this._selectedIndex].cachedWindows.length); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _keyPressHandler: function(keysym, action) { |     _keyPressHandler: function(keysym, backwards, action) { | ||||||
|         if (action == Meta.KeyBindingAction.SWITCH_GROUP) { |         if (action == Meta.KeyBindingAction.SWITCH_GROUP) { | ||||||
|             this._select(this._selectedIndex, this._nextWindow()); |             this._select(this._selectedIndex, backwards ? this._previousWindow() : this._nextWindow()); | ||||||
|         } else if (action == Meta.KeyBindingAction.SWITCH_GROUP_BACKWARD) { |         } else if (action == Meta.KeyBindingAction.SWITCH_GROUP_BACKWARD) { | ||||||
|             this._select(this._selectedIndex, this._previousWindow()); |             this._select(this._selectedIndex, this._previousWindow()); | ||||||
|         } else if (action == Meta.KeyBindingAction.SWITCH_APPLICATIONS) { |         } else if (action == Meta.KeyBindingAction.SWITCH_APPLICATIONS) { | ||||||
|             this._select(this._next()); |             this._select(backwards ? this._previous() : this._next()); | ||||||
|         } else if (action == Meta.KeyBindingAction.SWITCH_APPLICATIONS_BACKWARD) { |         } else if (action == Meta.KeyBindingAction.SWITCH_APPLICATIONS_BACKWARD) { | ||||||
|             this._select(this._previous()); |             this._select(this._previous()); | ||||||
|         } else if (this._thumbnailsFocused) { |         } else if (this._thumbnailsFocused) { | ||||||
| @@ -358,18 +365,9 @@ const WindowSwitcherPopup = new Lang.Class({ | |||||||
|     Name: 'WindowSwitcherPopup', |     Name: 'WindowSwitcherPopup', | ||||||
|     Extends: SwitcherPopup.SwitcherPopup, |     Extends: SwitcherPopup.SwitcherPopup, | ||||||
|  |  | ||||||
|     _init: function() { |     _init: function(items) { | ||||||
|         this.parent(); |         this.parent(items); | ||||||
|         this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' }); |         this._settings = new Gio.Settings({ schema: 'org.gnome.shell.window-switcher' }); | ||||||
|  |  | ||||||
|         let windows = this._getWindowList(); |  | ||||||
|  |  | ||||||
|         if (windows.length == 0) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         let mode = this._settings.get_enum('app-icon-mode'); |  | ||||||
|         this._switcherList = new WindowList(windows, mode); |  | ||||||
|         this._items = this._switcherList.icons; |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _getWindowList: function() { |     _getWindowList: function() { | ||||||
| @@ -377,9 +375,34 @@ const WindowSwitcherPopup = new Lang.Class({ | |||||||
|         return global.display.get_tab_list(Meta.TabList.NORMAL, workspace); |         return global.display.get_tab_list(Meta.TabList.NORMAL, workspace); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _keyPressHandler: function(keysym, action) { |     _createSwitcher: function() { | ||||||
|  |         let windows = this._getWindowList(); | ||||||
|  |  | ||||||
|  |         if (windows.length == 0) | ||||||
|  |             return false; | ||||||
|  |  | ||||||
|  |         let mode = this._settings.get_enum('app-icon-mode'); | ||||||
|  |         this._switcherList = new WindowList(windows, mode); | ||||||
|  |         this._items = this._switcherList.icons; | ||||||
|  |  | ||||||
|  |         if (this._items.length == 0) | ||||||
|  |             return false; | ||||||
|  |  | ||||||
|  |         return true; | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _initialSelection: function(backward, binding) { | ||||||
|  |         if (binding == 'switch-windows-backward' || backward) | ||||||
|  |             this._select(this._items.length - 1); | ||||||
|  |         else if (this._items.length == 1) | ||||||
|  |             this._select(0); | ||||||
|  |         else | ||||||
|  |             this._select(1); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _keyPressHandler: function(keysym, backwards, action) { | ||||||
|         if (action == Meta.KeyBindingAction.SWITCH_WINDOWS) { |         if (action == Meta.KeyBindingAction.SWITCH_WINDOWS) { | ||||||
|             this._select(this._next()); |             this._select(backwards ? this._previous() : this._next()); | ||||||
|         } else if (action == Meta.KeyBindingAction.SWITCH_WINDOWS_BACKWARD) { |         } else if (action == Meta.KeyBindingAction.SWITCH_WINDOWS_BACKWARD) { | ||||||
|             this._select(this._previous()); |             this._select(this._previous()); | ||||||
|         } else { |         } else { | ||||||
| @@ -433,7 +456,7 @@ const AppSwitcher = new Lang.Class({ | |||||||
|         this._arrows = []; |         this._arrows = []; | ||||||
|  |  | ||||||
|         let windowTracker = Shell.WindowTracker.get_default(); |         let windowTracker = Shell.WindowTracker.get_default(); | ||||||
|         let settings = new Gio.Settings({ schema_id: 'org.gnome.shell.app-switcher' }); |         let settings = new Gio.Settings({ schema: 'org.gnome.shell.app-switcher' }); | ||||||
|         let workspace = settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() |         let workspace = settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() | ||||||
|                                                                        : null; |                                                                        : null; | ||||||
|         let allWindows = global.display.get_tab_list(Meta.TabList.NORMAL, workspace); |         let allWindows = global.display.get_tab_list(Meta.TabList.NORMAL, workspace); | ||||||
| @@ -448,6 +471,8 @@ const AppSwitcher = new Lang.Class({ | |||||||
|             }); |             }); | ||||||
|             if (appIcon.cachedWindows.length > 0) |             if (appIcon.cachedWindows.length > 0) | ||||||
|                 this._addIcon(appIcon); |                 this._addIcon(appIcon); | ||||||
|  |             else if (workspace == null) | ||||||
|  |                 throw new Error('%s appears to be running, but doesn\'t have any windows'.format(appIcon.app.get_name())); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         this._curApp = -1; |         this._curApp = -1; | ||||||
| @@ -685,17 +710,15 @@ const WindowIcon = new Lang.Class({ | |||||||
|  |  | ||||||
|         this._icon.destroy_all_children(); |         this._icon.destroy_all_children(); | ||||||
|  |  | ||||||
|         let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; |  | ||||||
|  |  | ||||||
|         switch (mode) { |         switch (mode) { | ||||||
|             case AppIconMode.THUMBNAIL_ONLY: |             case AppIconMode.THUMBNAIL_ONLY: | ||||||
|                 size = WINDOW_PREVIEW_SIZE; |                 size = WINDOW_PREVIEW_SIZE; | ||||||
|                 this._icon.add_actor(_createWindowClone(mutterWindow, size * scaleFactor)); |                 this._icon.add_actor(_createWindowClone(mutterWindow, WINDOW_PREVIEW_SIZE)); | ||||||
|                 break; |                 break; | ||||||
|  |  | ||||||
|             case AppIconMode.BOTH: |             case AppIconMode.BOTH: | ||||||
|                 size = WINDOW_PREVIEW_SIZE; |                 size = WINDOW_PREVIEW_SIZE; | ||||||
|                 this._icon.add_actor(_createWindowClone(mutterWindow, size * scaleFactor)); |                 this._icon.add_actor(_createWindowClone(mutterWindow, WINDOW_PREVIEW_SIZE)); | ||||||
|  |  | ||||||
|                 if (this.app) |                 if (this.app) | ||||||
|                     this._icon.add_actor(this._createAppIcon(this.app, |                     this._icon.add_actor(this._createAppIcon(this.app, | ||||||
| @@ -707,7 +730,7 @@ const WindowIcon = new Lang.Class({ | |||||||
|                 this._icon.add_actor(this._createAppIcon(this.app, size)); |                 this._icon.add_actor(this._createAppIcon(this.app, size)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         this._icon.set_size(size * scaleFactor, size * scaleFactor); |         this._icon.set_size(size, size); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _createAppIcon: function(app, size) { |     _createAppIcon: function(app, size) { | ||||||
|   | |||||||
| @@ -7,12 +7,12 @@ const St = imports.gi.St; | |||||||
| const Signals = imports.signals; | const Signals = imports.signals; | ||||||
| const Atk = imports.gi.Atk; | const Atk = imports.gi.Atk; | ||||||
|  |  | ||||||
| const ANIMATED_ICON_UPDATE_TIMEOUT = 16; | const ANIMATED_ICON_UPDATE_TIMEOUT = 100; | ||||||
|  |  | ||||||
| const Animation = new Lang.Class({ | const Animation = new Lang.Class({ | ||||||
|     Name: 'Animation', |     Name: 'Animation', | ||||||
|  |  | ||||||
|     _init: function(file, width, height, speed) { |     _init: function(filename, width, height, speed) { | ||||||
|         this.actor = new St.Bin(); |         this.actor = new St.Bin(); | ||||||
|         this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); |         this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); | ||||||
|         this._speed = speed; |         this._speed = speed; | ||||||
| @@ -23,7 +23,7 @@ const Animation = new Lang.Class({ | |||||||
|         this._frame = 0; |         this._frame = 0; | ||||||
|  |  | ||||||
|         let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; |         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._animations = St.TextureCache.get_default().load_sliced_image (filename, width, height, scaleFactor, | ||||||
|                                                                             Lang.bind(this, this._animationsLoaded)); |                                                                             Lang.bind(this, this._animationsLoaded)); | ||||||
|         this.actor.set_child(this._animations); |         this.actor.set_child(this._animations); | ||||||
|     }, |     }, | ||||||
| @@ -33,7 +33,7 @@ const Animation = new Lang.Class({ | |||||||
|             if (this._frame == 0) |             if (this._frame == 0) | ||||||
|                 this._showFrame(0); |                 this._showFrame(0); | ||||||
|  |  | ||||||
|             this._timeoutId = GLib.timeout_add(GLib.PRIORITY_LOW, this._speed, Lang.bind(this, this._update)); |             this._timeoutId = Mainloop.timeout_add(this._speed, Lang.bind(this, this._update)); | ||||||
|             GLib.Source.set_name_by_id(this._timeoutId, '[gnome-shell] this._update'); |             GLib.Source.set_name_by_id(this._timeoutId, '[gnome-shell] this._update'); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -82,7 +82,7 @@ const AnimatedIcon = new Lang.Class({ | |||||||
|     Name: 'AnimatedIcon', |     Name: 'AnimatedIcon', | ||||||
|     Extends: Animation, |     Extends: Animation, | ||||||
|  |  | ||||||
|     _init: function(file, size) { |     _init: function(filename, size) { | ||||||
|         this.parent(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT); |         this.parent(filename, size, size, ANIMATED_ICON_UPDATE_TIMEOUT); | ||||||
|     } |     } | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -16,7 +16,6 @@ const Atk = imports.gi.Atk; | |||||||
| const AppFavorites = imports.ui.appFavorites; | const AppFavorites = imports.ui.appFavorites; | ||||||
| const BoxPointer = imports.ui.boxpointer; | const BoxPointer = imports.ui.boxpointer; | ||||||
| const DND = imports.ui.dnd; | const DND = imports.ui.dnd; | ||||||
| const GrabHelper = imports.ui.grabHelper; |  | ||||||
| const IconGrid = imports.ui.iconGrid; | const IconGrid = imports.ui.iconGrid; | ||||||
| const Main = imports.ui.main; | const Main = imports.ui.main; | ||||||
| const Overview = imports.ui.overview; | const Overview = imports.ui.overview; | ||||||
| @@ -34,9 +33,7 @@ const MIN_COLUMNS = 4; | |||||||
| const MIN_ROWS = 4; | const MIN_ROWS = 4; | ||||||
|  |  | ||||||
| const INACTIVE_GRID_OPACITY = 77; | const INACTIVE_GRID_OPACITY = 77; | ||||||
| // This time needs to be less than IconGrid.EXTRA_SPACE_ANIMATION_TIME | const INACTIVE_GRID_OPACITY_ANIMATION_TIME = 0.40; | ||||||
| // to not clash with other animations |  | ||||||
| const INACTIVE_GRID_OPACITY_ANIMATION_TIME = 0.24; |  | ||||||
| const FOLDER_SUBICON_FRACTION = .4; | const FOLDER_SUBICON_FRACTION = .4; | ||||||
|  |  | ||||||
| const MIN_FREQUENT_APPS_COUNT = 3; | const MIN_FREQUENT_APPS_COUNT = 3; | ||||||
| @@ -45,16 +42,6 @@ const INDICATORS_BASE_TIME = 0.25; | |||||||
| const INDICATORS_ANIMATION_DELAY = 0.125; | const INDICATORS_ANIMATION_DELAY = 0.125; | ||||||
| const INDICATORS_ANIMATION_MAX_TIME = 0.75; | const INDICATORS_ANIMATION_MAX_TIME = 0.75; | ||||||
|  |  | ||||||
| // Follow iconGrid animations approach and divide by 2 to animate out to |  | ||||||
| // not annoy the user when the user wants to quit appDisplay. |  | ||||||
| // Also, make sure we don't exceed iconGrid animation total time or |  | ||||||
| // views switch time. |  | ||||||
| const INDICATORS_BASE_TIME_OUT = 0.125; |  | ||||||
| const INDICATORS_ANIMATION_DELAY_OUT = 0.0625; |  | ||||||
| const INDICATORS_ANIMATION_MAX_TIME_OUT = |  | ||||||
|     Math.min (VIEWS_SWITCH_TIME, |  | ||||||
|               IconGrid.ANIMATION_TIME_OUT + IconGrid.ANIMATION_MAX_DELAY_OUT_FOR_ITEM); |  | ||||||
|  |  | ||||||
| const PAGE_SWITCH_TIME = 0.3; | const PAGE_SWITCH_TIME = 0.3; | ||||||
|  |  | ||||||
| const VIEWS_SWITCH_TIME = 0.4; | const VIEWS_SWITCH_TIME = 0.4; | ||||||
| @@ -189,98 +176,26 @@ const BaseAppView = new Lang.Class({ | |||||||
|                 this.selectApp(id); |                 this.selectApp(id); | ||||||
|             })); |             })); | ||||||
|         } |         } | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _doSpringAnimation: function(animationDirection) { |  | ||||||
|         this._grid.actor.opacity = 255; |  | ||||||
|         this._grid.animateSpring(animationDirection, |  | ||||||
|                                  Main.overview.getShowAppsButton()); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     animate: function(animationDirection, onComplete) { |  | ||||||
|         if (animationDirection == IconGrid.AnimationDirection.IN) { |  | ||||||
|             let toAnimate = this._grid.actor.connect('notify::allocation', Lang.bind(this, |  | ||||||
|                 function() { |  | ||||||
|                     this._grid.actor.disconnect(toAnimate); |  | ||||||
|                     // We need to hide the grid temporary to not flash it |  | ||||||
|                     // for a frame |  | ||||||
|                     this._grid.actor.opacity = 0; |  | ||||||
|                     Meta.later_add(Meta.LaterType.BEFORE_REDRAW, |  | ||||||
|                                    Lang.bind(this, function() { |  | ||||||
|                                        this._doSpringAnimation(animationDirection) |  | ||||||
|                                   })); |  | ||||||
|                 })); |  | ||||||
|         } else { |  | ||||||
|             this._doSpringAnimation(animationDirection); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (onComplete) { |  | ||||||
|             let animationDoneId = this._grid.connect('animation-done', Lang.bind(this, |  | ||||||
|                 function () { |  | ||||||
|                     this._grid.disconnect(animationDoneId); |  | ||||||
|                     onComplete(); |  | ||||||
|             })); |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     animateSwitch: function(animationDirection) { |  | ||||||
|         Tweener.removeTweens(this.actor); |  | ||||||
|         Tweener.removeTweens(this._grid.actor); |  | ||||||
|  |  | ||||||
|         let params = { time: VIEWS_SWITCH_TIME, |  | ||||||
|                        transition: 'easeOutQuad' }; |  | ||||||
|         if (animationDirection == IconGrid.AnimationDirection.IN) { |  | ||||||
|             this.actor.show(); |  | ||||||
|             params.opacity = 255; |  | ||||||
|             params.delay = VIEWS_SWITCH_ANIMATION_DELAY; |  | ||||||
|         } else { |  | ||||||
|             params.opacity = 0; |  | ||||||
|             params.delay = 0; |  | ||||||
|             params.onComplete = Lang.bind(this, function() { this.actor.hide() }); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         Tweener.addTween(this._grid.actor, params); |  | ||||||
|     } |     } | ||||||
| }); | }); | ||||||
| Signals.addSignalMethods(BaseAppView.prototype); | Signals.addSignalMethods(BaseAppView.prototype); | ||||||
|  |  | ||||||
| const PageIndicatorsActor = new Lang.Class({ |  | ||||||
|     Name:'PageIndicatorsActor', |  | ||||||
|     Extends: St.BoxLayout, |  | ||||||
|  |  | ||||||
|     _init: function() { |  | ||||||
|         this.parent({ style_class: 'page-indicators', |  | ||||||
|                       vertical: true, |  | ||||||
|                       x_expand: true, y_expand: true, |  | ||||||
|                       x_align: Clutter.ActorAlign.END, |  | ||||||
|                       y_align: Clutter.ActorAlign.CENTER, |  | ||||||
|                       reactive: true, |  | ||||||
|                       clip_to_allocation: true }); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     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 St.BoxLayout, but we only request 0 |  | ||||||
|         // as minimum height, since it's not that important if some indicators |  | ||||||
|         // are not shown |  | ||||||
|         let [, natHeight] = this.parent(forWidth); |  | ||||||
|         return [0, natHeight]; |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| const PageIndicators = new Lang.Class({ | const PageIndicators = new Lang.Class({ | ||||||
|     Name:'PageIndicators', |     Name:'PageIndicators', | ||||||
|  |  | ||||||
|     _init: function() { |     _init: function() { | ||||||
|         this.actor = new PageIndicatorsActor(); |         this.actor = new St.BoxLayout({ style_class: 'page-indicators', | ||||||
|  |                                         vertical: true, | ||||||
|  |                                         x_expand: true, y_expand: true, | ||||||
|  |                                         x_align: Clutter.ActorAlign.END, | ||||||
|  |                                         y_align: Clutter.ActorAlign.CENTER, | ||||||
|  |                                         reactive: true }); | ||||||
|         this._nPages = 0; |         this._nPages = 0; | ||||||
|         this._currentPage = undefined; |         this._currentPage = undefined; | ||||||
|  |  | ||||||
|         this.actor.connect('notify::mapped', |         this.actor.connect('notify::mapped', | ||||||
|                            Lang.bind(this, function() { |                            Lang.bind(this, this._animateIndicators)); | ||||||
|                                this.animateIndicators(IconGrid.AnimationDirection.IN); |  | ||||||
|                            }) |  | ||||||
|                           ); |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     setNPages: function(nPages) { |     setNPages: function(nPages) { | ||||||
| @@ -321,7 +236,7 @@ const PageIndicators = new Lang.Class({ | |||||||
|             children[i].set_checked(i == this._currentPage); |             children[i].set_checked(i == this._currentPage); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     animateIndicators: function(animationDirection) { |     _animateIndicators: function() { | ||||||
|         if (!this.actor.mapped) |         if (!this.actor.mapped) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
| @@ -329,32 +244,24 @@ const PageIndicators = new Lang.Class({ | |||||||
|         if (children.length == 0) |         if (children.length == 0) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         for (let i = 0; i < this._nPages; i++) |  | ||||||
|             Tweener.removeTweens(children[i]); |  | ||||||
|  |  | ||||||
|         let offset; |         let offset; | ||||||
|         if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) |         if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) | ||||||
|             offset = -children[0].width; |             offset = -children[0].width; | ||||||
|         else |         else | ||||||
|             offset = children[0].width; |             offset = children[0].width; | ||||||
|  |  | ||||||
|         let isAnimationIn = animationDirection == IconGrid.AnimationDirection.IN; |         let delay = INDICATORS_ANIMATION_DELAY; | ||||||
|         let delay = isAnimationIn ? INDICATORS_ANIMATION_DELAY : |         let totalAnimationTime = INDICATORS_BASE_TIME + INDICATORS_ANIMATION_DELAY * this._nPages; | ||||||
|                                     INDICATORS_ANIMATION_DELAY_OUT; |         if (totalAnimationTime > INDICATORS_ANIMATION_MAX_TIME) | ||||||
|         let baseTime = isAnimationIn ? INDICATORS_BASE_TIME : INDICATORS_BASE_TIME_OUT; |             delay -= (totalAnimationTime - INDICATORS_ANIMATION_MAX_TIME) / this._nPages; | ||||||
|         let totalAnimationTime = baseTime + delay * this._nPages; |  | ||||||
|         let maxTime = isAnimationIn ? INDICATORS_ANIMATION_MAX_TIME : |  | ||||||
|                                       INDICATORS_ANIMATION_MAX_TIME_OUT; |  | ||||||
|         if (totalAnimationTime > maxTime) |  | ||||||
|             delay -= (totalAnimationTime - maxTime) / this._nPages; |  | ||||||
|  |  | ||||||
|         for (let i = 0; i < this._nPages; i++) { |         for (let i = 0; i < this._nPages; i++) { | ||||||
|             children[i].translation_x = isAnimationIn ? offset : 0; |             children[i].translation_x = offset; | ||||||
|             Tweener.addTween(children[i], |             Tweener.addTween(children[i], | ||||||
|                              { translation_x: isAnimationIn ? 0 : offset, |                              { translation_x: 0, | ||||||
|                                time: baseTime + delay * i, |                                time: INDICATORS_BASE_TIME + delay * i, | ||||||
|                                transition: 'easeInOutQuad', |                                transition: 'easeInOutQuad', | ||||||
|                                delay: isAnimationIn ? VIEWS_SWITCH_ANIMATION_DELAY : 0 |                                delay: VIEWS_SWITCH_ANIMATION_DELAY | ||||||
|                              }); |                              }); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -379,7 +286,9 @@ const AllView = new Lang.Class({ | |||||||
|         this.actor.add_actor(this._scrollView); |         this.actor.add_actor(this._scrollView); | ||||||
|  |  | ||||||
|         this._scrollView.set_policy(Gtk.PolicyType.NEVER, |         this._scrollView.set_policy(Gtk.PolicyType.NEVER, | ||||||
|                                     Gtk.PolicyType.EXTERNAL); |                                     Gtk.PolicyType.AUTOMATIC); | ||||||
|  |         // we are only using ScrollView for the fade effect, hide scrollbars | ||||||
|  |         this._scrollView.vscroll.hide(); | ||||||
|         this._adjustment = this._scrollView.vscroll.adjustment; |         this._adjustment = this._scrollView.vscroll.adjustment; | ||||||
|  |  | ||||||
|         this._pageIndicators = new PageIndicators(); |         this._pageIndicators = new PageIndicators(); | ||||||
| @@ -395,7 +304,7 @@ const AllView = new Lang.Class({ | |||||||
|         this._stack = new St.Widget({ layout_manager: new Clutter.BinLayout() }); |         this._stack = new St.Widget({ layout_manager: new Clutter.BinLayout() }); | ||||||
|         let box = new St.BoxLayout({ vertical: true }); |         let box = new St.BoxLayout({ vertical: true }); | ||||||
|  |  | ||||||
|         this._grid.currentPage = 0; |         this._currentPage = 0; | ||||||
|         this._stack.add_actor(this._grid.actor); |         this._stack.add_actor(this._grid.actor); | ||||||
|         this._eventBlocker = new St.Widget({ x_expand: true, y_expand: true }); |         this._eventBlocker = new St.Widget({ x_expand: true, y_expand: true }); | ||||||
|         this._stack.add_actor(this._eventBlocker); |         this._stack.add_actor(this._eventBlocker); | ||||||
| @@ -461,7 +370,7 @@ const AllView = new Lang.Class({ | |||||||
|         Shell.AppSystem.get_default().connect('installed-changed', Lang.bind(this, function() { |         Shell.AppSystem.get_default().connect('installed-changed', Lang.bind(this, function() { | ||||||
|             Main.queueDeferredWork(this._redisplayWorkId); |             Main.queueDeferredWork(this._redisplayWorkId); | ||||||
|         })); |         })); | ||||||
|         this._folderSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.app-folders' }); |         this._folderSettings = new Gio.Settings({ schema: 'org.gnome.desktop.app-folders' }); | ||||||
|         this._folderSettings.connect('changed::folder-children', Lang.bind(this, function() { |         this._folderSettings.connect('changed::folder-children', Lang.bind(this, function() { | ||||||
|             Main.queueDeferredWork(this._redisplayWorkId); |             Main.queueDeferredWork(this._redisplayWorkId); | ||||||
|         })); |         })); | ||||||
| @@ -500,11 +409,6 @@ const AllView = new Lang.Class({ | |||||||
|  |  | ||||||
|     _loadApps: function() { |     _loadApps: function() { | ||||||
|         let apps = Gio.AppInfo.get_all().filter(function(appInfo) { |         let apps = Gio.AppInfo.get_all().filter(function(appInfo) { | ||||||
|             try { |  | ||||||
|                 let id = appInfo.get_id(); // catch invalid file encodings |  | ||||||
|             } catch(e) { |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
|             return appInfo.should_show(); |             return appInfo.should_show(); | ||||||
|         }).map(function(app) { |         }).map(function(app) { | ||||||
|             return app.get_id(); |             return app.get_id(); | ||||||
| @@ -522,19 +426,9 @@ const AllView = new Lang.Class({ | |||||||
|             this.folderIcons.push(icon); |             this.folderIcons.push(icon); | ||||||
|         })); |         })); | ||||||
|  |  | ||||||
|         // Allow dragging of the icon only if the Dash would accept a drop to |  | ||||||
|         // change favorite-apps. There are no other possible drop targets from |  | ||||||
|         // the app picker, so there's no other need for a drag to start, |  | ||||||
|         // at least on single-monitor setups. |  | ||||||
|         // This also disables drag-to-launch on multi-monitor setups, |  | ||||||
|         // but we hope that is not used much. |  | ||||||
|         let favoritesWritable = global.settings.is_writable('favorite-apps'); |  | ||||||
|  |  | ||||||
|         apps.forEach(Lang.bind(this, function(appId) { |         apps.forEach(Lang.bind(this, function(appId) { | ||||||
|             let app = appSys.lookup_app(appId); |             let app = appSys.lookup_app(appId); | ||||||
|  |             let icon = new AppIcon(app); | ||||||
|             let icon = new AppIcon(app, |  | ||||||
|                                    { isDraggable: favoritesWritable }); |  | ||||||
|             this.addItem(icon); |             this.addItem(icon); | ||||||
|         })); |         })); | ||||||
|  |  | ||||||
| @@ -542,59 +436,14 @@ const AllView = new Lang.Class({ | |||||||
|         this._refilterApps(); |         this._refilterApps(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     // Overriden from BaseAppView |  | ||||||
|     animate: function (animationDirection, onComplete) { |  | ||||||
|         this._scrollView.reactive = false; |  | ||||||
|         let completionFunc = Lang.bind(this, function() { |  | ||||||
|             this._scrollView.reactive = true; |  | ||||||
|             if (onComplete) |  | ||||||
|                 onComplete(); |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         if (animationDirection == IconGrid.AnimationDirection.OUT && |  | ||||||
|             this._displayingPopup && this._currentPopup) { |  | ||||||
|             this._currentPopup.popdown(); |  | ||||||
|             let spaceClosedId = this._grid.connect('space-closed', Lang.bind(this, |  | ||||||
|                 function() { |  | ||||||
|                     this._grid.disconnect(spaceClosedId); |  | ||||||
|                     // Given that we can't call this.parent() inside the |  | ||||||
|                     // signal handler, call again animate which will |  | ||||||
|                     // call the parent given that popup is already |  | ||||||
|                     // closed. |  | ||||||
|                     this.animate(animationDirection, completionFunc); |  | ||||||
|                 })); |  | ||||||
|         } else { |  | ||||||
|             this.parent(animationDirection, completionFunc); |  | ||||||
|             if (animationDirection == IconGrid.AnimationDirection.OUT) |  | ||||||
|                 this._pageIndicators.animateIndicators(animationDirection); |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     animateSwitch: function(animationDirection) { |  | ||||||
|         this.parent(animationDirection); |  | ||||||
|  |  | ||||||
|         if (this._currentPopup && this._displayingPopup && |  | ||||||
|             animationDirection == IconGrid.AnimationDirection.OUT) |  | ||||||
|             Tweener.addTween(this._currentPopup.actor, |  | ||||||
|                              { time: VIEWS_SWITCH_TIME, |  | ||||||
|                                transition: 'easeOutQuad', |  | ||||||
|                                opacity: 0, |  | ||||||
|                                onComplete: function() { |  | ||||||
|                                   this.opacity = 255; |  | ||||||
|                                } }); |  | ||||||
|  |  | ||||||
|         if (animationDirection == IconGrid.AnimationDirection.OUT) |  | ||||||
|             this._pageIndicators.animateIndicators(animationDirection); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     getCurrentPageY: function() { |     getCurrentPageY: function() { | ||||||
|         return this._grid.getPageY(this._grid.currentPage); |         return this._grid.getPageY(this._currentPage); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     goToPage: function(pageNumber) { |     goToPage: function(pageNumber) { | ||||||
|         pageNumber = clamp(pageNumber, 0, this._grid.nPages() - 1); |         pageNumber = clamp(pageNumber, 0, this._grid.nPages() - 1); | ||||||
|  |  | ||||||
|         if (this._grid.currentPage == pageNumber && this._displayingPopup && this._currentPopup) |         if (this._currentPage == pageNumber && this._displayingPopup && this._currentPopup) | ||||||
|             return; |             return; | ||||||
|         if (this._displayingPopup && this._currentPopup) |         if (this._displayingPopup && this._currentPopup) | ||||||
|             this._currentPopup.popdown(); |             this._currentPopup.popdown(); | ||||||
| @@ -614,7 +463,7 @@ const AllView = new Lang.Class({ | |||||||
|         let time; |         let time; | ||||||
|         // Only take the velocity into account on page changes, otherwise |         // Only take the velocity into account on page changes, otherwise | ||||||
|         // return smoothly to the current page using the default velocity |         // return smoothly to the current page using the default velocity | ||||||
|         if (this._grid.currentPage != pageNumber) { |         if (this._currentPage != pageNumber) { | ||||||
|             let minVelocity = totalHeight / (PAGE_SWITCH_TIME * 1000); |             let minVelocity = totalHeight / (PAGE_SWITCH_TIME * 1000); | ||||||
|             velocity = Math.max(minVelocity, velocity); |             velocity = Math.max(minVelocity, velocity); | ||||||
|             time = (diffToPage / velocity) / 1000; |             time = (diffToPage / velocity) / 1000; | ||||||
| @@ -625,9 +474,9 @@ const AllView = new Lang.Class({ | |||||||
|         // longer than PAGE_SWITCH_TIME |         // longer than PAGE_SWITCH_TIME | ||||||
|         time = Math.min(time, PAGE_SWITCH_TIME); |         time = Math.min(time, PAGE_SWITCH_TIME); | ||||||
|  |  | ||||||
|         this._grid.currentPage = pageNumber; |         this._currentPage = pageNumber; | ||||||
|         Tweener.addTween(this._adjustment, |         Tweener.addTween(this._adjustment, | ||||||
|                          { value: this._grid.getPageY(this._grid.currentPage), |                          { value: this._grid.getPageY(this._currentPage), | ||||||
|                            time: time, |                            time: time, | ||||||
|                            transition: 'easeOutQuad' }); |                            transition: 'easeOutQuad' }); | ||||||
|         this._pageIndicators.setCurrentPage(pageNumber); |         this._pageIndicators.setCurrentPage(pageNumber); | ||||||
| @@ -651,14 +500,14 @@ const AllView = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onScroll: function(actor, event) { |     _onScroll: function(actor, event) { | ||||||
|         if (this._displayingPopup || !this._scrollView.reactive) |         if (this._displayingPopup) | ||||||
|             return Clutter.EVENT_STOP; |             return Clutter.EVENT_STOP; | ||||||
|  |  | ||||||
|         let direction = event.get_scroll_direction(); |         let direction = event.get_scroll_direction(); | ||||||
|         if (direction == Clutter.ScrollDirection.UP) |         if (direction == Clutter.ScrollDirection.UP) | ||||||
|             this.goToPage(this._grid.currentPage - 1); |             this.goToPage(this._currentPage - 1); | ||||||
|         else if (direction == Clutter.ScrollDirection.DOWN) |         else if (direction == Clutter.ScrollDirection.DOWN) | ||||||
|             this.goToPage(this._grid.currentPage + 1); |             this.goToPage(this._currentPage + 1); | ||||||
|  |  | ||||||
|         return Clutter.EVENT_STOP; |         return Clutter.EVENT_STOP; | ||||||
|     }, |     }, | ||||||
| @@ -698,10 +547,10 @@ const AllView = new Lang.Class({ | |||||||
|             return Clutter.EVENT_STOP; |             return Clutter.EVENT_STOP; | ||||||
|  |  | ||||||
|         if (event.get_key_symbol() == Clutter.Page_Up) { |         if (event.get_key_symbol() == Clutter.Page_Up) { | ||||||
|             this.goToPage(this._grid.currentPage - 1); |             this.goToPage(this._currentPage - 1); | ||||||
|             return Clutter.EVENT_STOP; |             return Clutter.EVENT_STOP; | ||||||
|         } else if (event.get_key_symbol() == Clutter.Page_Down) { |         } else if (event.get_key_symbol() == Clutter.Page_Down) { | ||||||
|             this.goToPage(this._grid.currentPage + 1); |             this.goToPage(this._currentPage + 1); | ||||||
|             return Clutter.EVENT_STOP; |             return Clutter.EVENT_STOP; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -758,12 +607,10 @@ const AllView = new Lang.Class({ | |||||||
|         let fadeOffset = Math.min(this._grid.topPadding, |         let fadeOffset = Math.min(this._grid.topPadding, | ||||||
|                                   this._grid.bottomPadding); |                                   this._grid.bottomPadding); | ||||||
|         this._scrollView.update_fade_effect(fadeOffset, 0); |         this._scrollView.update_fade_effect(fadeOffset, 0); | ||||||
|         if (fadeOffset > 0) |  | ||||||
|         this._scrollView.get_effect('fade').fade_edges = true; |         this._scrollView.get_effect('fade').fade_edges = true; | ||||||
|  |  | ||||||
|         if (this._availWidth != availWidth || this._availHeight != availHeight || oldNPages != this._grid.nPages()) { |         if (this._availWidth != availWidth || this._availHeight != availHeight || oldNPages != this._grid.nPages()) { | ||||||
|             this._adjustment.value = 0; |             this._adjustment.value = 0; | ||||||
|             this._grid.currentPage = 0; |  | ||||||
|             Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, |             Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, | ||||||
|                 function() { |                 function() { | ||||||
|                     this._pageIndicators.setNPages(this._grid.nPages()); |                     this._pageIndicators.setNPages(this._grid.nPages()); | ||||||
| @@ -786,7 +633,6 @@ const FrequentView = new Lang.Class({ | |||||||
|  |  | ||||||
|     _init: function() { |     _init: function() { | ||||||
|         this.parent(null, { fillParent: true }); |         this.parent(null, { fillParent: true }); | ||||||
|  |  | ||||||
|         this.actor = new St.Widget({ style_class: 'frequent-apps', |         this.actor = new St.Widget({ style_class: 'frequent-apps', | ||||||
|                                      layout_manager: new Clutter.BinLayout(), |                                      layout_manager: new Clutter.BinLayout(), | ||||||
|                                      x_expand: true, y_expand: true }); |                                      x_expand: true, y_expand: true }); | ||||||
| @@ -823,19 +669,10 @@ const FrequentView = new Lang.Class({ | |||||||
|         if(!hasUsefulData) |         if(!hasUsefulData) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         // Allow dragging of the icon only if the Dash would accept a drop to |  | ||||||
|         // change favorite-apps. There are no other possible drop targets from |  | ||||||
|         // the app picker, so there's no other need for a drag to start, |  | ||||||
|         // at least on single-monitor setups. |  | ||||||
|         // This also disables drag-to-launch on multi-monitor setups, |  | ||||||
|         // but we hope that is not used much. |  | ||||||
|         let favoritesWritable = global.settings.is_writable('favorite-apps'); |  | ||||||
|  |  | ||||||
|         for (let i = 0; i < mostUsed.length; i++) { |         for (let i = 0; i < mostUsed.length; i++) { | ||||||
|             if (!mostUsed[i].get_app_info().should_show()) |             if (!mostUsed[i].get_app_info().should_show()) | ||||||
|                 continue; |                 continue; | ||||||
|             let appIcon = new AppIcon(mostUsed[i], |             let appIcon = new AppIcon(mostUsed[i]); | ||||||
|                                       { isDraggable: favoritesWritable }); |  | ||||||
|             this._grid.addItem(appIcon, -1); |             this._grid.addItem(appIcon, -1); | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
| @@ -903,7 +740,7 @@ const AppDisplay = new Lang.Class({ | |||||||
|     Name: 'AppDisplay', |     Name: 'AppDisplay', | ||||||
|  |  | ||||||
|     _init: function() { |     _init: function() { | ||||||
|         this._privacySettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.privacy' }); |         this._privacySettings = new Gio.Settings({ schema: 'org.gnome.desktop.privacy' }); | ||||||
|         this._privacySettings.connect('changed::remember-app-usage', |         this._privacySettings.connect('changed::remember-app-usage', | ||||||
|                                       Lang.bind(this, this._updateFrequentVisibility)); |                                       Lang.bind(this, this._updateFrequentVisibility)); | ||||||
|  |  | ||||||
| @@ -912,14 +749,14 @@ const AppDisplay = new Lang.Class({ | |||||||
|         let view, button; |         let view, button; | ||||||
|         view = new FrequentView(); |         view = new FrequentView(); | ||||||
|         button = new St.Button({ label: _("Frequent"), |         button = new St.Button({ label: _("Frequent"), | ||||||
|                                  style_class: 'app-view-control button', |                                  style_class: 'app-view-control', | ||||||
|                                  can_focus: true, |                                  can_focus: true, | ||||||
|                                  x_expand: true }); |                                  x_expand: true }); | ||||||
|         this._views[Views.FREQUENT] = { 'view': view, 'control': button }; |         this._views[Views.FREQUENT] = { 'view': view, 'control': button }; | ||||||
|  |  | ||||||
|         view = new AllView(); |         view = new AllView(); | ||||||
|         button = new St.Button({ label: _("All"), |         button = new St.Button({ label: _("All"), | ||||||
|                                  style_class: 'app-view-control button', |                                  style_class: 'app-view-control', | ||||||
|                                  can_focus: true, |                                  can_focus: true, | ||||||
|                                  x_expand: true }); |                                  x_expand: true }); | ||||||
|         this._views[Views.ALL] = { 'view': view, 'control': button }; |         this._views[Views.ALL] = { 'view': view, 'control': button }; | ||||||
| @@ -935,19 +772,6 @@ const AppDisplay = new Lang.Class({ | |||||||
|         let layout = new ControlsBoxLayout({ homogeneous: true }); |         let layout = new ControlsBoxLayout({ homogeneous: true }); | ||||||
|         this._controls = new St.Widget({ style_class: 'app-view-controls', |         this._controls = new St.Widget({ style_class: 'app-view-controls', | ||||||
|                                          layout_manager: layout }); |                                          layout_manager: layout }); | ||||||
|         this._controls.connect('notify::mapped', Lang.bind(this, |  | ||||||
|             function() { |  | ||||||
|                 // controls are faded either with their parent or |  | ||||||
|                 // explicitly in animate(); we can't know how they'll be |  | ||||||
|                 // shown next, so make sure to restore their opacity |  | ||||||
|                 // when they are hidden |  | ||||||
|                 if (this._controls.mapped) |  | ||||||
|                   return; |  | ||||||
|  |  | ||||||
|                 Tweener.removeTweens(this._controls); |  | ||||||
|                 this._controls.opacity = 255; |  | ||||||
|             })); |  | ||||||
|  |  | ||||||
|         layout.hookup_style(this._controls); |         layout.hookup_style(this._controls); | ||||||
|         this.actor.add_actor(new St.Bin({ child: this._controls })); |         this.actor.add_actor(new St.Bin({ child: this._controls })); | ||||||
|  |  | ||||||
| @@ -971,39 +795,23 @@ const AppDisplay = new Lang.Class({ | |||||||
|         this._updateFrequentVisibility(); |         this._updateFrequentVisibility(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     animate: function(animationDirection, onComplete) { |  | ||||||
|         let currentView = this._views[global.settings.get_uint('app-picker-view')].view; |  | ||||||
|  |  | ||||||
|         // Animate controls opacity using iconGrid animation time, since |  | ||||||
|         // it will be the time the AllView or FrequentView takes to show |  | ||||||
|         // it entirely. |  | ||||||
|         let finalOpacity; |  | ||||||
|         if (animationDirection == IconGrid.AnimationDirection.IN) { |  | ||||||
|             this._controls.opacity = 0; |  | ||||||
|             finalOpacity = 255; |  | ||||||
|         } else { |  | ||||||
|             finalOpacity = 0 |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         Tweener.addTween(this._controls, |  | ||||||
|                          { time: IconGrid.ANIMATION_TIME_IN, |  | ||||||
|                            transition: 'easeInOutQuad', |  | ||||||
|                            opacity: finalOpacity, |  | ||||||
|                           }); |  | ||||||
|  |  | ||||||
|         currentView.animate(animationDirection, onComplete); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _showView: function(activeIndex) { |     _showView: function(activeIndex) { | ||||||
|         for (let i = 0; i < this._views.length; i++) { |         for (let i = 0; i < this._views.length; i++) { | ||||||
|  |             let actor = this._views[i].view.actor; | ||||||
|  |  | ||||||
|  |             let params = { time: VIEWS_SWITCH_TIME, | ||||||
|  |                            opacity: (i == activeIndex) ? 255 : 0, | ||||||
|  |                            delay: (i == activeIndex) ? VIEWS_SWITCH_ANIMATION_DELAY : 0 }; | ||||||
|  |             if (i == activeIndex) | ||||||
|  |                 actor.visible = true; | ||||||
|  |             else | ||||||
|  |                 params.onComplete = function() { actor.hide(); }; | ||||||
|  |             Tweener.addTween(actor, params); | ||||||
|  |  | ||||||
|             if (i == activeIndex) |             if (i == activeIndex) | ||||||
|                 this._views[i].control.add_style_pseudo_class('checked'); |                 this._views[i].control.add_style_pseudo_class('checked'); | ||||||
|             else |             else | ||||||
|                 this._views[i].control.remove_style_pseudo_class('checked'); |                 this._views[i].control.remove_style_pseudo_class('checked'); | ||||||
|  |  | ||||||
|             let animationDirection = i == activeIndex ? IconGrid.AnimationDirection.IN : |  | ||||||
|                                                         IconGrid.AnimationDirection.OUT; |  | ||||||
|             this._views[i].view.animateSwitch(animationDirection); |  | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
| @@ -1066,7 +874,7 @@ const AppSearchProvider = new Lang.Class({ | |||||||
|  |  | ||||||
|     getInitialResultSet: function(terms, callback, cancellable) { |     getInitialResultSet: function(terms, callback, cancellable) { | ||||||
|         let query = terms.join(' '); |         let query = terms.join(' '); | ||||||
|         let groups = Shell.AppSystem.search(query); |         let groups = Gio.DesktopAppInfo.search(query); | ||||||
|         let usage = Shell.AppUsage.get_default(); |         let usage = Shell.AppUsage.get_default(); | ||||||
|         let results = []; |         let results = []; | ||||||
|         groups.forEach(function(group) { |         groups.forEach(function(group) { | ||||||
| @@ -1085,6 +893,26 @@ const AppSearchProvider = new Lang.Class({ | |||||||
|         this.getInitialResultSet(terms, callback, cancellable); |         this.getInitialResultSet(terms, callback, cancellable); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|  |     activateResult: function(result) { | ||||||
|  |         let app = this._appSys.lookup_app(result); | ||||||
|  |         let event = Clutter.get_current_event(); | ||||||
|  |         let modifiers = event ? event.get_state() : 0; | ||||||
|  |         let openNewWindow = modifiers & Clutter.ModifierType.CONTROL_MASK; | ||||||
|  |  | ||||||
|  |         if (openNewWindow) | ||||||
|  |             app.open_new_window(-1); | ||||||
|  |         else | ||||||
|  |             app.activate(); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     dragActivateResult: function(id, params) { | ||||||
|  |         params = Params.parse(params, { workspace: -1, | ||||||
|  |                                         timestamp: 0 }); | ||||||
|  |  | ||||||
|  |         let app = this._appSys.lookup_app(id); | ||||||
|  |         app.open_new_window(workspace); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|     createResultObject: function (resultMeta) { |     createResultObject: function (resultMeta) { | ||||||
|         let app = this._appSys.lookup_app(resultMeta['id']); |         let app = this._appSys.lookup_app(resultMeta['id']); | ||||||
|         return new AppIcon(app); |         return new AppIcon(app); | ||||||
| @@ -1116,20 +944,14 @@ const FolderView = new Lang.Class({ | |||||||
|         Util.ensureActorVisibleInScrollView(this.actor, actor); |         Util.ensureActorVisibleInScrollView(this.actor, actor); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     // Overriden from BaseAppView |  | ||||||
|     animate: function(animationDirection) { |  | ||||||
|         this._grid.animatePulse(animationDirection); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     createFolderIcon: function(size) { |     createFolderIcon: function(size) { | ||||||
|         let layout = new Clutter.GridLayout(); |         let layout = new Clutter.TableLayout(); | ||||||
|         let icon = new St.Widget({ layout_manager: layout, |         let icon = new St.Widget({ layout_manager: layout, | ||||||
|                                    style_class: 'app-folder-icon' }); |                                    style_class: 'app-folder-icon' }); | ||||||
|         layout.hookup_style(icon); |         layout.hookup_style(icon); | ||||||
|         let subSize = Math.floor(FOLDER_SUBICON_FRACTION * size); |         let subSize = Math.floor(FOLDER_SUBICON_FRACTION * size); | ||||||
|  |  | ||||||
|         let numItems = this._allItems.length; |         let numItems = this._allItems.length; | ||||||
|         let rtl = icon.get_text_direction() == Clutter.TextDirection.RTL; |  | ||||||
|         for (let i = 0; i < 4; i++) { |         for (let i = 0; i < 4; i++) { | ||||||
|             let bin; |             let bin; | ||||||
|             if (i < numItems) { |             if (i < numItems) { | ||||||
| @@ -1138,7 +960,7 @@ const FolderView = new Lang.Class({ | |||||||
|             } else { |             } else { | ||||||
|                 bin = new St.Bin({ width: subSize, height: subSize }); |                 bin = new St.Bin({ width: subSize, height: subSize }); | ||||||
|             } |             } | ||||||
|             layout.attach(bin, rtl ? (i + 1) % 2 : i % 2, Math.floor(i / 2), 1, 1); |             layout.pack(bin, i % 2, Math.floor(i / 2)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return icon; |         return icon; | ||||||
| @@ -1295,13 +1117,9 @@ const FolderIcon = new Lang.Class({ | |||||||
|             if (!_listsIntersect(folderCategories, appCategories)) |             if (!_listsIntersect(folderCategories, appCategories)) | ||||||
|                 return; |                 return; | ||||||
|  |  | ||||||
|             try { |             addAppId(appInfo.get_id()); | ||||||
|                 addAppId(appInfo.get_id()); // catch invalid file encodings |  | ||||||
|             } catch(e) { |  | ||||||
|             } |  | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         this.actor.visible = this.view.getAllItems().length > 0; |  | ||||||
|         this.view.loadGrid(); |         this.view.loadGrid(); | ||||||
|         this.emit('apps-changed'); |         this.emit('apps-changed'); | ||||||
|     }, |     }, | ||||||
| @@ -1431,53 +1249,18 @@ const AppFolderPopup = new Lang.Class({ | |||||||
|             function() { |             function() { | ||||||
|                 this.actor.destroy(); |                 this.actor.destroy(); | ||||||
|             })); |             })); | ||||||
|         this._grabHelper = new GrabHelper.GrabHelper(this.actor); |  | ||||||
|         this._grabHelper.addActor(Main.layoutManager.overviewGroup); |  | ||||||
|         this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPress)); |         this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPress)); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onKeyPress: function(actor, event) { |     _onKeyPress: function(actor, event) { | ||||||
|         if (global.stage.get_key_focus() != actor) |         if (!this._isOpen) | ||||||
|             return Clutter.EVENT_PROPAGATE; |             return Clutter.EVENT_PROPAGATE; | ||||||
|  |  | ||||||
|         // Since we need to only grab focus on one item child when the user |         if (event.get_key_symbol() != Clutter.KEY_Escape) | ||||||
|         // actually press a key we don't use navigate_focus when opening |  | ||||||
|         // the popup. |  | ||||||
|         // Instead of that, grab the focus on the AppFolderPopup actor |  | ||||||
|         // and actually moves the focus to a child only when the user |  | ||||||
|         // actually press a key. |  | ||||||
|         // It should work with just grab_key_focus on the AppFolderPopup |  | ||||||
|         // actor, but since the arrow keys are not wrapping_around the focus |  | ||||||
|         // is not grabbed by a child when the widget that has the current focus |  | ||||||
|         // is the same that is requesting focus, so to make it works with arrow |  | ||||||
|         // keys we need to connect to the key-press-event and navigate_focus |  | ||||||
|         // when that happens using TAB_FORWARD or TAB_BACKWARD instead of arrow |  | ||||||
|         // keys |  | ||||||
|  |  | ||||||
|         // Use TAB_FORWARD for down key and right key |  | ||||||
|         // and TAB_BACKWARD for up key and left key on ltr |  | ||||||
|         // languages |  | ||||||
|         let direction; |  | ||||||
|         let isLtr = Clutter.get_default_text_direction() == Clutter.TextDirection.LTR; |  | ||||||
|         switch (event.get_key_symbol()) { |  | ||||||
|             case Clutter.Down: |  | ||||||
|                 direction = Gtk.DirectionType.TAB_FORWARD; |  | ||||||
|                 break; |  | ||||||
|             case Clutter.Right: |  | ||||||
|                 direction = isLtr ? Gtk.DirectionType.TAB_FORWARD : |  | ||||||
|                                     Gtk.DirectionType.TAB_BACKWARD; |  | ||||||
|                 break; |  | ||||||
|             case Clutter.Up: |  | ||||||
|                 direction = Gtk.DirectionType.TAB_BACKWARD; |  | ||||||
|                 break; |  | ||||||
|             case Clutter.Left: |  | ||||||
|                 direction = isLtr ? Gtk.DirectionType.TAB_BACKWARD : |  | ||||||
|                                     Gtk.DirectionType.TAB_FORWARD; |  | ||||||
|                 break; |  | ||||||
|             default: |  | ||||||
|             return Clutter.EVENT_PROPAGATE; |             return Clutter.EVENT_PROPAGATE; | ||||||
|         } |  | ||||||
|         return actor.navigate_focus(null, direction, false); |         this.popdown(); | ||||||
|  |         return Clutter.EVENT_STOP; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     toggle: function() { |     toggle: function() { | ||||||
| @@ -1491,27 +1274,15 @@ const AppFolderPopup = new Lang.Class({ | |||||||
|         if (this._isOpen) |         if (this._isOpen) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         this._isOpen = this._grabHelper.grab({ actor: this.actor, |  | ||||||
|                                                onUngrab: Lang.bind(this, this.popdown) }); |  | ||||||
|  |  | ||||||
|         if (!this._isOpen) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         this.actor.show(); |         this.actor.show(); | ||||||
|  |  | ||||||
|         this._boxPointer.setArrowActor(this._source.actor); |         this._boxPointer.setArrowActor(this._source.actor); | ||||||
|         // We need to hide the icons of the view until the boxpointer animation |  | ||||||
|         // is completed so we can animate the icons after as we like without |  | ||||||
|         // showing them while boxpointer is animating. |  | ||||||
|         this._view.actor.opacity = 0; |  | ||||||
|         this._boxPointer.show(BoxPointer.PopupAnimation.FADE | |         this._boxPointer.show(BoxPointer.PopupAnimation.FADE | | ||||||
|                               BoxPointer.PopupAnimation.SLIDE, |                               BoxPointer.PopupAnimation.SLIDE); | ||||||
|                               Lang.bind(this, |  | ||||||
|             function() { |  | ||||||
|                 this._view.actor.opacity = 255; |  | ||||||
|                 this._view.animate(IconGrid.AnimationDirection.IN); |  | ||||||
|             })); |  | ||||||
|  |  | ||||||
|  |         this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); | ||||||
|  |  | ||||||
|  |         this._isOpen = true; | ||||||
|         this.emit('open-state-changed', true); |         this.emit('open-state-changed', true); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
| @@ -1519,8 +1290,6 @@ const AppFolderPopup = new Lang.Class({ | |||||||
|         if (!this._isOpen) |         if (!this._isOpen) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         this._grabHelper.ungrab({ actor: this.actor }); |  | ||||||
|  |  | ||||||
|         this._boxPointer.hide(BoxPointer.PopupAnimation.FADE | |         this._boxPointer.hide(BoxPointer.PopupAnimation.FADE | | ||||||
|                               BoxPointer.PopupAnimation.SLIDE); |                               BoxPointer.PopupAnimation.SLIDE); | ||||||
|         this._isOpen = false; |         this._isOpen = false; | ||||||
| @@ -1559,46 +1328,25 @@ const AppIcon = new Lang.Class({ | |||||||
|                                      can_focus: true, |                                      can_focus: true, | ||||||
|                                      x_fill: true, |                                      x_fill: true, | ||||||
|                                      y_fill: true }); |                                      y_fill: true }); | ||||||
|  |  | ||||||
|         this._dot = new St.Widget({ style_class: 'app-well-app-running-dot', |  | ||||||
|                                     layout_manager: new Clutter.BinLayout(), |  | ||||||
|                                     x_expand: true, y_expand: true, |  | ||||||
|                                     x_align: Clutter.ActorAlign.CENTER, |  | ||||||
|                                     y_align: Clutter.ActorAlign.END }); |  | ||||||
|  |  | ||||||
|         this._iconContainer = new St.Widget({ layout_manager: new Clutter.BinLayout(), |  | ||||||
|                                               x_expand: true, y_expand: true }); |  | ||||||
|  |  | ||||||
|         this.actor.set_child(this._iconContainer); |  | ||||||
|         this._iconContainer.add_child(this._dot); |  | ||||||
|  |  | ||||||
|         this.actor._delegate = this; |         this.actor._delegate = this; | ||||||
|  |  | ||||||
|         if (!iconParams) |         if (!iconParams) | ||||||
|             iconParams = {}; |             iconParams = {}; | ||||||
|  |  | ||||||
|         // Get the isDraggable property without passing it on to the BaseIcon: |  | ||||||
|         let appIconParams = Params.parse(iconParams, { isDraggable: true }, true); |  | ||||||
|         let isDraggable = appIconParams['isDraggable']; |  | ||||||
|         delete iconParams['isDraggable']; |  | ||||||
|  |  | ||||||
|         iconParams['createIcon'] = Lang.bind(this, this._createIcon); |         iconParams['createIcon'] = Lang.bind(this, this._createIcon); | ||||||
|         iconParams['setSizeManually'] = true; |         iconParams['setSizeManually'] = true; | ||||||
|         this.icon = new IconGrid.BaseIcon(app.get_name(), iconParams); |         this.icon = new IconGrid.BaseIcon(app.get_name(), iconParams); | ||||||
|         this._iconContainer.add_child(this.icon.actor); |         this.actor.set_child(this.icon.actor); | ||||||
|  |  | ||||||
|         this.actor.label_actor = this.icon.label; |         this.actor.label_actor = this.icon.label; | ||||||
|  |  | ||||||
|         this.actor.connect('leave-event', Lang.bind(this, this._onLeaveEvent)); |  | ||||||
|         this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress)); |         this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress)); | ||||||
|         this.actor.connect('touch-event', Lang.bind(this, this._onTouchEvent)); |  | ||||||
|         this.actor.connect('clicked', Lang.bind(this, this._onClicked)); |         this.actor.connect('clicked', Lang.bind(this, this._onClicked)); | ||||||
|         this.actor.connect('popup-menu', Lang.bind(this, this._onKeyboardPopupMenu)); |         this.actor.connect('popup-menu', Lang.bind(this, this._onKeyboardPopupMenu)); | ||||||
|  |  | ||||||
|         this._menu = null; |         this._menu = null; | ||||||
|         this._menuManager = new PopupMenu.PopupMenuManager(this); |         this._menuManager = new PopupMenu.PopupMenuManager(this); | ||||||
|  |  | ||||||
|         if (isDraggable) { |  | ||||||
|         this._draggable = DND.makeDraggable(this.actor); |         this._draggable = DND.makeDraggable(this.actor); | ||||||
|         this._draggable.connect('drag-begin', Lang.bind(this, |         this._draggable.connect('drag-begin', Lang.bind(this, | ||||||
|             function () { |             function () { | ||||||
| @@ -1613,16 +1361,14 @@ const AppIcon = new Lang.Class({ | |||||||
|             function () { |             function () { | ||||||
|                Main.overview.endItemDrag(this); |                Main.overview.endItemDrag(this); | ||||||
|             })); |             })); | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); |         this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); | ||||||
|  |  | ||||||
|         this._menuTimeoutId = 0; |         this._menuTimeoutId = 0; | ||||||
|         this._stateChangedId = this.app.connect('notify::state', Lang.bind(this, |         this._stateChangedId = this.app.connect('notify::state', | ||||||
|             function () { |                                                 Lang.bind(this, | ||||||
|                 this._updateRunningStyle(); |                                                           this._onStateChanged)); | ||||||
|             })); |         this._onStateChanged(); | ||||||
|         this._updateRunningStyle(); |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onDestroy: function() { |     _onDestroy: function() { | ||||||
| @@ -1643,14 +1389,16 @@ const AppIcon = new Lang.Class({ | |||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _updateRunningStyle: function() { |     _onStateChanged: function() { | ||||||
|         if (this.app.state != Shell.AppState.STOPPED) |         if (this.app.state != Shell.AppState.STOPPED) | ||||||
|             this._dot.show(); |             this.actor.add_style_class_name('running'); | ||||||
|         else |         else | ||||||
|             this._dot.hide(); |             this.actor.remove_style_class_name('running'); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _setPopupTimeout: function() { |     _onButtonPress: function(actor, event) { | ||||||
|  |         let button = event.get_button(); | ||||||
|  |         if (button == 1) { | ||||||
|             this._removeMenuTimeout(); |             this._removeMenuTimeout(); | ||||||
|             this._menuTimeoutId = Mainloop.timeout_add(MENU_POPUP_TIMEOUT, |             this._menuTimeoutId = Mainloop.timeout_add(MENU_POPUP_TIMEOUT, | ||||||
|                 Lang.bind(this, function() { |                 Lang.bind(this, function() { | ||||||
| @@ -1659,17 +1407,6 @@ const AppIcon = new Lang.Class({ | |||||||
|                     return GLib.SOURCE_REMOVE; |                     return GLib.SOURCE_REMOVE; | ||||||
|                 })); |                 })); | ||||||
|             GLib.Source.set_name_by_id(this._menuTimeoutId, '[gnome-shell] this.popupMenu'); |             GLib.Source.set_name_by_id(this._menuTimeoutId, '[gnome-shell] this.popupMenu'); | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _onLeaveEvent: function(actor, event) { |  | ||||||
|         this.actor.fake_release(); |  | ||||||
|         this._removeMenuTimeout(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _onButtonPress: function(actor, event) { |  | ||||||
|         let button = event.get_button(); |  | ||||||
|         if (button == 1) { |  | ||||||
|             this._setPopupTimeout(); |  | ||||||
|         } else if (button == 3) { |         } else if (button == 3) { | ||||||
|             this.popupMenu(); |             this.popupMenu(); | ||||||
|             return Clutter.EVENT_STOP; |             return Clutter.EVENT_STOP; | ||||||
| @@ -1677,16 +1414,16 @@ const AppIcon = new Lang.Class({ | |||||||
|         return Clutter.EVENT_PROPAGATE; |         return Clutter.EVENT_PROPAGATE; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onTouchEvent: function (actor, event) { |  | ||||||
|         if (event.type() == Clutter.EventType.TOUCH_BEGIN) |  | ||||||
|             this._setPopupTimeout(); |  | ||||||
|  |  | ||||||
|         return Clutter.EVENT_PROPAGATE; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _onClicked: function(actor, button) { |     _onClicked: function(actor, button) { | ||||||
|         this._removeMenuTimeout(); |         this._removeMenuTimeout(); | ||||||
|         this.activate(button); |  | ||||||
|  |         if (button == 1) { | ||||||
|  |             this._onActivate(Clutter.get_current_event()); | ||||||
|  |         } else if (button == 2) { | ||||||
|  |             this.app.open_new_window(-1); | ||||||
|  |             Main.overview.hide(); | ||||||
|  |         } | ||||||
|  |         return false; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onKeyboardPopupMenu: function() { |     _onKeyboardPopupMenu: function() { | ||||||
| @@ -1701,8 +1438,6 @@ const AppIcon = new Lang.Class({ | |||||||
|     popupMenu: function() { |     popupMenu: function() { | ||||||
|         this._removeMenuTimeout(); |         this._removeMenuTimeout(); | ||||||
|         this.actor.fake_release(); |         this.actor.fake_release(); | ||||||
|  |  | ||||||
|         if (this._draggable) |  | ||||||
|         this._draggable.fakeRelease(); |         this._draggable.fakeRelease(); | ||||||
|  |  | ||||||
|         if (!this._menu) { |         if (!this._menu) { | ||||||
| @@ -1714,10 +1449,7 @@ const AppIcon = new Lang.Class({ | |||||||
|                 if (!isPoppedUp) |                 if (!isPoppedUp) | ||||||
|                     this._onMenuPoppedDown(); |                     this._onMenuPoppedDown(); | ||||||
|             })); |             })); | ||||||
|             let id = Main.overview.connect('hiding', Lang.bind(this, function () { this._menu.close(); })); |             Main.overview.connect('hiding', Lang.bind(this, function () { this._menu.close(); })); | ||||||
|             this.actor.connect('destroy', function() { |  | ||||||
|                 Main.overview.disconnect(id); |  | ||||||
|             }); |  | ||||||
|  |  | ||||||
|             this._menuManager.addMenu(this._menu); |             this._menuManager.addMenu(this._menu); | ||||||
|         } |         } | ||||||
| @@ -1745,29 +1477,19 @@ const AppIcon = new Lang.Class({ | |||||||
|         this.emit('menu-state-changed', false); |         this.emit('menu-state-changed', false); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     activate: function (button) { |     _onActivate: function (event) { | ||||||
|         let event = Clutter.get_current_event(); |         let modifiers = event.get_state(); | ||||||
|         let modifiers = event ? event.get_state() : 0; |  | ||||||
|         let openNewWindow = this.app.can_open_new_window () && |  | ||||||
|                             modifiers & Clutter.ModifierType.CONTROL_MASK && |  | ||||||
|                             this.app.state == Shell.AppState.RUNNING || |  | ||||||
|                             button && button == 2; |  | ||||||
|  |  | ||||||
|         if (this.app.state == Shell.AppState.STOPPED || openNewWindow) |         if (modifiers & Clutter.ModifierType.CONTROL_MASK | ||||||
|             this.animateLaunch(); |             && this.app.state == Shell.AppState.RUNNING) { | ||||||
|  |  | ||||||
|         if (openNewWindow) |  | ||||||
|             this.app.open_new_window(-1); |             this.app.open_new_window(-1); | ||||||
|         else |         } else { | ||||||
|             this.app.activate(); |             this.app.activate(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         Main.overview.hide(); |         Main.overview.hide(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     animateLaunch: function() { |  | ||||||
|         this.icon.animateZoomOut(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     shellWorkspaceLaunch : function(params) { |     shellWorkspaceLaunch : function(params) { | ||||||
|         params = Params.parse(params, { workspace: -1, |         params = Params.parse(params, { workspace: -1, | ||||||
|                                         timestamp: 0 }); |                                         timestamp: 0 }); | ||||||
| @@ -1846,21 +1568,15 @@ const AppIconMenu = new Lang.Class({ | |||||||
|         if (!this._source.app.is_window_backed()) { |         if (!this._source.app.is_window_backed()) { | ||||||
|             this._appendSeparator(); |             this._appendSeparator(); | ||||||
|  |  | ||||||
|             let appInfo = this._source.app.get_app_info(); |  | ||||||
|             let actions = appInfo.list_actions(); |  | ||||||
|             if (this._source.app.can_open_new_window() && |  | ||||||
|                 actions.indexOf('new-window') == -1) { |  | ||||||
|             this._newWindowMenuItem = this._appendMenuItem(_("New Window")); |             this._newWindowMenuItem = this._appendMenuItem(_("New Window")); | ||||||
|             this._newWindowMenuItem.connect('activate', Lang.bind(this, function() { |             this._newWindowMenuItem.connect('activate', Lang.bind(this, function() { | ||||||
|                     if (this._source.app.state == Shell.AppState.STOPPED) |  | ||||||
|                         this._source.animateLaunch(); |  | ||||||
|  |  | ||||||
|                 this._source.app.open_new_window(-1); |                 this._source.app.open_new_window(-1); | ||||||
|                 this.emit('activate-window', null); |                 this.emit('activate-window', null); | ||||||
|             })); |             })); | ||||||
|             this._appendSeparator(); |             this._appendSeparator(); | ||||||
|             } |  | ||||||
|  |  | ||||||
|  |             let appInfo = this._source.app.get_app_info(); | ||||||
|  |             let actions = appInfo.list_actions(); | ||||||
|             for (let i = 0; i < actions.length; i++) { |             for (let i = 0; i < actions.length; i++) { | ||||||
|                 let action = actions[i]; |                 let action = actions[i]; | ||||||
|                 let item = this._appendMenuItem(appInfo.get_action_name(action)); |                 let item = this._appendMenuItem(appInfo.get_action_name(action)); | ||||||
| @@ -1869,10 +1585,6 @@ const AppIconMenu = new Lang.Class({ | |||||||
|                     this.emit('activate-window', null); |                     this.emit('activate-window', null); | ||||||
|                 })); |                 })); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             let canFavorite = global.settings.is_writable('favorite-apps'); |  | ||||||
|  |  | ||||||
|             if (canFavorite) { |  | ||||||
|             this._appendSeparator(); |             this._appendSeparator(); | ||||||
|  |  | ||||||
|             let isFavorite = AppFavorites.getAppFavorites().isFavorite(this._source.app.get_id()); |             let isFavorite = AppFavorites.getAppFavorites().isFavorite(this._source.app.get_id()); | ||||||
| @@ -1890,7 +1602,6 @@ const AppIconMenu = new Lang.Class({ | |||||||
|                     favs.addFavorite(this._source.app.get_id()); |                     favs.addFavorite(this._source.app.get_id()); | ||||||
|                 })); |                 })); | ||||||
|             } |             } | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (Shell.AppSystem.get_default().lookup_app('org.gnome.Software.desktop')) { |             if (Shell.AppSystem.get_default().lookup_app('org.gnome.Software.desktop')) { | ||||||
|                 this._appendSeparator(); |                 this._appendSeparator(); | ||||||
|   | |||||||
| @@ -6,37 +6,6 @@ const Signals = imports.signals; | |||||||
|  |  | ||||||
| const Main = imports.ui.main; | const Main = imports.ui.main; | ||||||
|  |  | ||||||
| const RENAMED_DESKTOP_IDS = { |  | ||||||
|     'baobab.desktop': 'org.gnome.baobab.desktop', |  | ||||||
|     'cheese.desktop': 'org.gnome.Cheese.desktop', |  | ||||||
|     'dconf-editor.desktop': 'ca.desrt.dconf-editor.desktop', |  | ||||||
|     'file-roller.desktop': 'org.gnome.FileRoller.desktop', |  | ||||||
|     'gcalctool.desktop': 'gnome-calculator.desktop', |  | ||||||
|     'gedit.desktop': 'org.gnome.gedit.desktop', |  | ||||||
|     'glchess.desktop': 'gnome-chess.desktop', |  | ||||||
|     'glines.desktop': 'five-or-more.desktop', |  | ||||||
|     'gnect.desktop': 'four-in-a-row.desktop', |  | ||||||
|     'gnibbles.desktop': 'gnome-nibbles.desktop', |  | ||||||
|     'gnobots2.desktop': 'gnome-robots.desktop', |  | ||||||
|     'gnome-boxes.desktop': 'org.gnome.Boxes.desktop', |  | ||||||
|     'gnome-clocks.desktop': 'org.gnome.clocks.desktop', |  | ||||||
|     'gnome-contacts.desktop': 'org.gnome.Contacts.desktop', |  | ||||||
|     'gnome-documents.desktop': 'org.gnome.Documents.desktop', |  | ||||||
|     'gnome-font-viewer.desktop': 'org.gnome.font-viewer.desktop', |  | ||||||
|     'gnome-photos.desktop': 'org.gnome.Photos.desktop', |  | ||||||
|     'gnome-screenshot.desktop': 'org.gnome.Screenshot.desktop', |  | ||||||
|     'gnome-software.desktop': 'org.gnome.Software.desktop', |  | ||||||
|     'gnome-terminal.desktop': 'org.gnome.Terminal.desktop', |  | ||||||
|     'gnome-weather.desktop': 'org.gnome.Weather.Application.desktop', |  | ||||||
|     'gnomine.desktop': 'gnome-mines.desktop', |  | ||||||
|     'gnotravex.desktop': 'gnome-tetravex.desktop', |  | ||||||
|     'gnotski.desktop': 'gnome-klotski.desktop', |  | ||||||
|     'gtali.desktop': 'tali.desktop', |  | ||||||
|     'nautilus.desktop': 'org.gnome.Nautilus.desktop', |  | ||||||
|     'polari.desktop': 'org.gnome.Polari.desktop', |  | ||||||
|     'totem.desktop': 'org.gnome.Totem.desktop', |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| const AppFavorites = new Lang.Class({ | const AppFavorites = new Lang.Class({ | ||||||
|     Name: 'AppFavorites', |     Name: 'AppFavorites', | ||||||
|  |  | ||||||
| @@ -55,21 +24,6 @@ const AppFavorites = new Lang.Class({ | |||||||
|  |  | ||||||
|     reload: function() { |     reload: function() { | ||||||
|         let ids = global.settings.get_strv(this.FAVORITE_APPS_KEY); |         let ids = global.settings.get_strv(this.FAVORITE_APPS_KEY); | ||||||
|  |  | ||||||
|         // Map old desktop file names to the current ones |  | ||||||
|         let updated = false; |  | ||||||
|         ids = ids.map(function (id) { |  | ||||||
|             let newId = RENAMED_DESKTOP_IDS[id]; |  | ||||||
|             if (newId !== undefined) { |  | ||||||
|                 updated = true; |  | ||||||
|                 return newId; |  | ||||||
|             } |  | ||||||
|             return id; |  | ||||||
|         }); |  | ||||||
|         // ... and write back the updated desktop file names |  | ||||||
|         if (updated) |  | ||||||
|             global.settings.set_strv(this.FAVORITE_APPS_KEY, ids); |  | ||||||
|  |  | ||||||
|         let appSys = Shell.AppSystem.get_default(); |         let appSys = Shell.AppSystem.get_default(); | ||||||
|         let apps = ids.map(function (id) { |         let apps = ids.map(function (id) { | ||||||
|                 return appSys.lookup_app(id); |                 return appSys.lookup_app(id); | ||||||
|   | |||||||
| @@ -16,10 +16,9 @@ const BackgroundMenu = new Lang.Class({ | |||||||
|     _init: function(layoutManager) { |     _init: function(layoutManager) { | ||||||
|         this.parent(layoutManager.dummyCursor, 0, St.Side.TOP); |         this.parent(layoutManager.dummyCursor, 0, St.Side.TOP); | ||||||
|  |  | ||||||
|         this.addSettingsAction(_("Change Background…"), 'gnome-background-panel.desktop'); |  | ||||||
|         this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); |  | ||||||
|         this.addSettingsAction(_("Display Settings"), 'gnome-display-panel.desktop'); |  | ||||||
|         this.addSettingsAction(_("Settings"), 'gnome-control-center.desktop'); |         this.addSettingsAction(_("Settings"), 'gnome-control-center.desktop'); | ||||||
|  |         this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); | ||||||
|  |         this.addSettingsAction(_("Change Background…"), 'gnome-background-panel.desktop'); | ||||||
|  |  | ||||||
|         this.actor.add_style_class_name('background-menu'); |         this.actor.add_style_class_name('background-menu'); | ||||||
|  |  | ||||||
| @@ -34,7 +33,8 @@ function addBackgroundMenu(actor, layoutManager) { | |||||||
|     actor._backgroundManager = new PopupMenu.PopupMenuManager({ actor: actor }); |     actor._backgroundManager = new PopupMenu.PopupMenuManager({ actor: actor }); | ||||||
|     actor._backgroundManager.addMenu(actor._backgroundMenu); |     actor._backgroundManager.addMenu(actor._backgroundMenu); | ||||||
|  |  | ||||||
|     function openMenu(x, y) { |     function openMenu() { | ||||||
|  |         let [x, y] = global.get_pointer(); | ||||||
|         Main.layoutManager.setDummyCursorGeometry(x, y, 0, 0); |         Main.layoutManager.setDummyCursorGeometry(x, y, 0, 0); | ||||||
|         actor._backgroundMenu.open(BoxPointer.PopupAnimation.NONE); |         actor._backgroundMenu.open(BoxPointer.PopupAnimation.NONE); | ||||||
|     } |     } | ||||||
| @@ -42,32 +42,22 @@ function addBackgroundMenu(actor, layoutManager) { | |||||||
|     let clickAction = new Clutter.ClickAction(); |     let clickAction = new Clutter.ClickAction(); | ||||||
|     clickAction.connect('long-press', function(action, actor, state) { |     clickAction.connect('long-press', function(action, actor, state) { | ||||||
|         if (state == Clutter.LongPressState.QUERY) |         if (state == Clutter.LongPressState.QUERY) | ||||||
|             return ((action.get_button() == 0 || |             return action.get_button() == 1 && !actor._backgroundMenu.isOpen; | ||||||
|                      action.get_button() == 1) && |  | ||||||
|                     !actor._backgroundMenu.isOpen); |  | ||||||
|         if (state == Clutter.LongPressState.ACTIVATE) { |         if (state == Clutter.LongPressState.ACTIVATE) { | ||||||
|             let [x, y] = action.get_coords(); |             openMenu(); | ||||||
|             openMenu(x, y); |  | ||||||
|             actor._backgroundManager.ignoreRelease(); |             actor._backgroundManager.ignoreRelease(); | ||||||
|         } |         } | ||||||
|         return true; |         return true; | ||||||
|     }); |     }); | ||||||
|     clickAction.connect('clicked', function(action) { |     clickAction.connect('clicked', function(action) { | ||||||
|         if (action.get_button() == 3) { |         if (action.get_button() == 3) | ||||||
|             let [x, y] = action.get_coords(); |             openMenu(); | ||||||
|             openMenu(x, y); |  | ||||||
|         } |  | ||||||
|     }); |     }); | ||||||
|     actor.add_action(clickAction); |     actor.add_action(clickAction); | ||||||
|  |  | ||||||
|     let grabOpBeginId = global.display.connect('grab-op-begin', function () { |  | ||||||
|         clickAction.release(); |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     actor.connect('destroy', function() { |     actor.connect('destroy', function() { | ||||||
|         actor._backgroundMenu.destroy(); |         actor._backgroundMenu.destroy(); | ||||||
|         actor._backgroundMenu = null; |         actor._backgroundMenu = null; | ||||||
|         actor._backgroundManager = null; |         actor._backgroundManager = null; | ||||||
|         global.display.disconnect(grabOpBeginId); |  | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										1489
									
								
								js/ui/calendar.js
									
									
									
									
									
								
							
							
						
						| @@ -23,7 +23,7 @@ const AutomountManager = new Lang.Class({ | |||||||
|     Name: 'AutomountManager', |     Name: 'AutomountManager', | ||||||
|  |  | ||||||
|     _init: function() { |     _init: function() { | ||||||
|         this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA }); |         this._settings = new Gio.Settings({ schema: SETTINGS_SCHEMA }); | ||||||
|         this._volumeQueue = []; |         this._volumeQueue = []; | ||||||
|         this._session = new GnomeSession.SessionManager(); |         this._session = new GnomeSession.SessionManager(); | ||||||
|         this._session.connectSignal('InhibitorAdded', |         this._session.connectSignal('InhibitorAdded', | ||||||
|   | |||||||
| @@ -24,11 +24,11 @@ const AutorunSetting = { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| // misc utils | // misc utils | ||||||
| function shouldAutorunMount(mount) { | function shouldAutorunMount(mount, forTransient) { | ||||||
|     let root = mount.get_root(); |     let root = mount.get_root(); | ||||||
|     let volume = mount.get_volume(); |     let volume = mount.get_volume(); | ||||||
|  |  | ||||||
|     if (!volume || !volume.allowAutorun) |     if (!volume || (!volume.allowAutorun && forTransient)) | ||||||
|         return false; |         return false; | ||||||
|  |  | ||||||
|     if (root.is_native() && isMountRootHidden(root)) |     if (root.is_native() && isMountRootHidden(root)) | ||||||
| @@ -96,7 +96,7 @@ const ContentTypeDiscoverer = new Lang.Class({ | |||||||
|  |  | ||||||
|     _init: function(callback) { |     _init: function(callback) { | ||||||
|         this._callback = callback; |         this._callback = callback; | ||||||
|         this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA }); |         this._settings = new Gio.Settings({ schema: SETTINGS_SCHEMA }); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     guessContentTypes: function(mount) { |     guessContentTypes: function(mount) { | ||||||
| @@ -167,10 +167,12 @@ const AutorunManager = new Lang.Class({ | |||||||
|         this._session = new GnomeSession.SessionManager(); |         this._session = new GnomeSession.SessionManager(); | ||||||
|         this._volumeMonitor = Gio.VolumeMonitor.get(); |         this._volumeMonitor = Gio.VolumeMonitor.get(); | ||||||
|  |  | ||||||
|         this._dispatcher = new AutorunDispatcher(this); |         this._transDispatcher = new AutorunTransientDispatcher(this); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     enable: function() { |     enable: function() { | ||||||
|  |         this._scanMounts(); | ||||||
|  |  | ||||||
|         this._mountAddedId = this._volumeMonitor.connect('mount-added', Lang.bind(this, this._onMountAdded)); |         this._mountAddedId = this._volumeMonitor.connect('mount-added', Lang.bind(this, this._onMountAdded)); | ||||||
|         this._mountRemovedId = this._volumeMonitor.connect('mount-removed', Lang.bind(this, this._onMountRemoved)); |         this._mountRemovedId = this._volumeMonitor.connect('mount-removed', Lang.bind(this, this._onMountRemoved)); | ||||||
|     }, |     }, | ||||||
| @@ -180,30 +182,101 @@ const AutorunManager = new Lang.Class({ | |||||||
|         this._volumeMonitor.disconnect(this._mountRemovedId); |         this._volumeMonitor.disconnect(this._mountRemovedId); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|  |     _processMount: function(mount, hotplug) { | ||||||
|  |         let discoverer = new ContentTypeDiscoverer(Lang.bind(this, function(mount, apps, contentTypes) { | ||||||
|  |             if (hotplug) | ||||||
|  |                 this._transDispatcher.addMount(mount, apps, contentTypes); | ||||||
|  |         })); | ||||||
|  |         discoverer.guessContentTypes(mount); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _scanMounts: function() { | ||||||
|  |         let mounts = this._volumeMonitor.get_mounts(); | ||||||
|  |         mounts.forEach(Lang.bind(this, function(mount) { | ||||||
|  |             this._processMount(mount, false); | ||||||
|  |         })); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|     _onMountAdded: function(monitor, mount) { |     _onMountAdded: function(monitor, mount) { | ||||||
|         // don't do anything if our session is not the currently |         // don't do anything if our session is not the currently | ||||||
|         // active one |         // active one | ||||||
|         if (!this._session.SessionIsActive) |         if (!this._session.SessionIsActive) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         let discoverer = new ContentTypeDiscoverer(Lang.bind(this, function(mount, apps, contentTypes) { |         this._processMount(mount, true); | ||||||
|             this._dispatcher.addMount(mount, apps, contentTypes); |  | ||||||
|         })); |  | ||||||
|         discoverer.guessContentTypes(mount); |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onMountRemoved: function(monitor, mount) { |     _onMountRemoved: function(monitor, mount) { | ||||||
|         this._dispatcher.removeMount(mount); |         this._transDispatcher.removeMount(mount); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     ejectMount: function(mount) { | ||||||
|  |         let mountOp = new ShellMountOperation.ShellMountOperation(mount); | ||||||
|  |  | ||||||
|  |         // first, see if we have a drive | ||||||
|  |         let drive = mount.get_drive(); | ||||||
|  |         let volume = mount.get_volume(); | ||||||
|  |  | ||||||
|  |         if (drive && | ||||||
|  |             drive.get_start_stop_type() == Gio.DriveStartStopType.SHUTDOWN && | ||||||
|  |             drive.can_stop()) { | ||||||
|  |             drive.stop(0, mountOp.mountOp, null, | ||||||
|  |                        Lang.bind(this, this._onStop)); | ||||||
|  |         } else { | ||||||
|  |             if (mount.can_eject()) { | ||||||
|  |                 mount.eject_with_operation(0, mountOp.mountOp, null, | ||||||
|  |                                            Lang.bind(this, this._onEject)); | ||||||
|  |             } else if (volume && volume.can_eject()) { | ||||||
|  |                 volume.eject_with_operation(0, mountOp.mountOp, null, | ||||||
|  |                                             Lang.bind(this, this._onEject)); | ||||||
|  |             } else if (drive && drive.can_eject()) { | ||||||
|  |                 drive.eject_with_operation(0, mountOp.mountOp, null, | ||||||
|  |                                            Lang.bind(this, this._onEject)); | ||||||
|  |             } else if (mount.can_unmount()) { | ||||||
|  |                 mount.unmount_with_operation(0, mountOp.mountOp, null, | ||||||
|  |                                              Lang.bind(this, this._onUnmount)); | ||||||
|             } |             } | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _onUnmount: function(mount, res) { | ||||||
|  |         try { | ||||||
|  |             mount.unmount_with_operation_finish(res); | ||||||
|  |         } catch (e) { | ||||||
|  |             if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED)) | ||||||
|  |                 log('Unable to eject the mount ' + mount.get_name()  | ||||||
|  |                     + ': ' + e.toString()); | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _onEject: function(source, res) { | ||||||
|  |         try { | ||||||
|  |             source.eject_with_operation_finish(res); | ||||||
|  |         } catch (e) { | ||||||
|  |             if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED)) | ||||||
|  |                 log('Unable to eject the drive ' + source.get_name() | ||||||
|  |                     + ': ' + e.toString()); | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _onStop: function(drive, res) { | ||||||
|  |         try { | ||||||
|  |             drive.stop_finish(res); | ||||||
|  |         } catch (e) { | ||||||
|  |             if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED)) | ||||||
|  |                 log('Unable to stop the drive ' + drive.get_name()  | ||||||
|  |                     + ': ' + e.toString()); | ||||||
|  |         } | ||||||
|  |     }, | ||||||
| }); | }); | ||||||
|  |  | ||||||
| const AutorunDispatcher = new Lang.Class({ | const AutorunTransientDispatcher = new Lang.Class({ | ||||||
|     Name: 'AutorunDispatcher', |     Name: 'AutorunTransientDispatcher', | ||||||
|  |  | ||||||
|     _init: function(manager) { |     _init: function(manager) { | ||||||
|         this._manager = manager; |         this._manager = manager; | ||||||
|         this._sources = []; |         this._sources = []; | ||||||
|         this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA }); |         this._settings = new Gio.Settings({ schema: SETTINGS_SCHEMA }); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _getAutorunSettingForType: function(contentType) { |     _getAutorunSettingForType: function(contentType) { | ||||||
| @@ -244,7 +317,7 @@ const AutorunDispatcher = new Lang.Class({ | |||||||
|             return; |             return; | ||||||
|       |       | ||||||
|         // add a new source |         // add a new source | ||||||
|         this._sources.push(new AutorunSource(this._manager, mount, apps)); |         this._sources.push(new AutorunTransientSource(this._manager, mount, apps)); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     addMount: function(mount, apps, contentTypes) { |     addMount: function(mount, apps, contentTypes) { | ||||||
| @@ -253,7 +326,7 @@ const AutorunDispatcher = new Lang.Class({ | |||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         // if the mount doesn't want to be autorun, return |         // if the mount doesn't want to be autorun, return | ||||||
|         if (!shouldAutorunMount(mount)) |         if (!shouldAutorunMount(mount, true)) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         let setting = this._getAutorunSettingForType(contentTypes[0]); |         let setting = this._getAutorunSettingForType(contentTypes[0]); | ||||||
| @@ -293,8 +366,8 @@ const AutorunDispatcher = new Lang.Class({ | |||||||
|     } |     } | ||||||
| }); | }); | ||||||
|  |  | ||||||
| const AutorunSource = new Lang.Class({ | const AutorunTransientSource = new Lang.Class({ | ||||||
|     Name: 'AutorunSource', |     Name: 'AutorunTransientSource', | ||||||
|     Extends: MessageTray.Source, |     Extends: MessageTray.Source, | ||||||
|  |  | ||||||
|     _init: function(manager, mount, apps) { |     _init: function(manager, mount, apps) { | ||||||
| @@ -304,7 +377,7 @@ const AutorunSource = new Lang.Class({ | |||||||
|  |  | ||||||
|         this.parent(mount.get_name()); |         this.parent(mount.get_name()); | ||||||
|  |  | ||||||
|         this._notification = new AutorunNotification(this._manager, this); |         this._notification = new AutorunTransientNotification(this._manager, this); | ||||||
|  |  | ||||||
|         // add ourselves as a source, and popup the notification |         // add ourselves as a source, and popup the notification | ||||||
|         Main.messageTray.add(this); |         Main.messageTray.add(this); | ||||||
| @@ -313,35 +386,38 @@ const AutorunSource = new Lang.Class({ | |||||||
|  |  | ||||||
|     getIcon: function() { |     getIcon: function() { | ||||||
|         return this.mount.get_icon(); |         return this.mount.get_icon(); | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _createPolicy: function() { |  | ||||||
|         return new MessageTray.NotificationApplicationPolicy('org.gnome.Nautilus'); |  | ||||||
|     } |     } | ||||||
| }); | }); | ||||||
|  |  | ||||||
| const AutorunNotification = new Lang.Class({ | const AutorunTransientNotification = new Lang.Class({ | ||||||
|     Name: 'AutorunNotification', |     Name: 'AutorunTransientNotification', | ||||||
|     Extends: MessageTray.Notification, |     Extends: MessageTray.Notification, | ||||||
|  |  | ||||||
|     _init: function(manager, source) { |     _init: function(manager, source) { | ||||||
|         this.parent(source, source.title); |         this.parent(source, source.title); | ||||||
|  |  | ||||||
|         this._manager = manager; |         this._manager = manager; | ||||||
|  |         this._box = new St.BoxLayout({ style_class: 'hotplug-transient-box', | ||||||
|  |                                        vertical: true }); | ||||||
|  |         this._bodyBin.child = this._box; | ||||||
|  |  | ||||||
|         this._mount = source.mount; |         this._mount = source.mount; | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     createBanner: function() { |         source.apps.forEach(Lang.bind(this, function (app) { | ||||||
|         let banner = new MessageTray.NotificationBanner(this); |  | ||||||
|  |  | ||||||
|         this.source.apps.forEach(Lang.bind(this, function (app) { |  | ||||||
|             let actor = this._buttonForApp(app); |             let actor = this._buttonForApp(app); | ||||||
|  |  | ||||||
|             if (actor) |             if (actor) | ||||||
|                 banner.addButton(actor); |                 this._box.add(actor, { x_fill: true, | ||||||
|  |                                        x_align: St.Align.START }); | ||||||
|         })); |         })); | ||||||
|  |  | ||||||
|         return banner; |         this._box.add(this._buttonForEject(), { x_fill: true, | ||||||
|  |                                                 x_align: St.Align.START }); | ||||||
|  |  | ||||||
|  |         // set the notification to transient and urgent, so that it | ||||||
|  |         // expands out | ||||||
|  |         this.setTransient(true); | ||||||
|  |         this.setUrgency(MessageTray.Urgency.CRITICAL); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _buttonForApp: function(app) { |     _buttonForApp: function(app) { | ||||||
| @@ -359,9 +435,8 @@ const AutorunNotification = new Lang.Class({ | |||||||
|         let button = new St.Button({ child: box, |         let button = new St.Button({ child: box, | ||||||
|                                      x_fill: true, |                                      x_fill: true, | ||||||
|                                      x_align: St.Align.START, |                                      x_align: St.Align.START, | ||||||
|                                      x_expand: true, |  | ||||||
|                                      button_mask: St.ButtonMask.ONE, |                                      button_mask: St.ButtonMask.ONE, | ||||||
|                                      style_class: 'hotplug-notification-item button' }); |                                      style_class: 'hotplug-notification-item' }); | ||||||
|  |  | ||||||
|         button.connect('clicked', Lang.bind(this, function() { |         button.connect('clicked', Lang.bind(this, function() { | ||||||
|             startAppForMount(app, this._mount); |             startAppForMount(app, this._mount); | ||||||
| @@ -371,11 +446,29 @@ const AutorunNotification = new Lang.Class({ | |||||||
|         return button; |         return button; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     activate: function() { |     _buttonForEject: function() { | ||||||
|         this.parent(); |         let box = new St.BoxLayout(); | ||||||
|  |         let icon = new St.Icon({ icon_name: 'media-eject-symbolic', | ||||||
|  |                                  style_class: 'hotplug-notification-item-icon' }); | ||||||
|  |         box.add(icon); | ||||||
|  |  | ||||||
|         let app = Gio.app_info_get_default_for_type('inode/directory', false); |         let label = new St.Bin({ y_align: St.Align.MIDDLE, | ||||||
|         startAppForMount(app, this._mount); |                                  child: new St.Label | ||||||
|  |                                  ({ text: _("Eject") }) | ||||||
|  |                                }); | ||||||
|  |         box.add(label); | ||||||
|  |  | ||||||
|  |         let button = new St.Button({ child: box, | ||||||
|  |                                      x_fill: true, | ||||||
|  |                                      x_align: St.Align.START, | ||||||
|  |                                      button_mask: St.ButtonMask.ONE, | ||||||
|  |                                      style_class: 'hotplug-notification-item' }); | ||||||
|  |  | ||||||
|  |         button.connect('clicked', Lang.bind(this, function() { | ||||||
|  |             this._manager.ejectMount(this._mount); | ||||||
|  |         })); | ||||||
|  |  | ||||||
|  |         return button; | ||||||
|     } |     } | ||||||
| }); | }); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,15 +9,9 @@ const Gio = imports.gi.Gio; | |||||||
| const GObject = imports.gi.GObject; | const GObject = imports.gi.GObject; | ||||||
| const Gcr = imports.gi.Gcr; | const Gcr = imports.gi.Gcr; | ||||||
|  |  | ||||||
| const Animation = imports.ui.animation; |  | ||||||
| const ModalDialog = imports.ui.modalDialog; | const ModalDialog = imports.ui.modalDialog; | ||||||
| const ShellEntry = imports.ui.shellEntry; | const ShellEntry = imports.ui.shellEntry; | ||||||
| const CheckBox = imports.ui.checkBox; | const CheckBox = imports.ui.checkBox; | ||||||
| const Tweener = imports.ui.tweener; |  | ||||||
|  |  | ||||||
| const WORK_SPINNER_ICON_SIZE = 16; |  | ||||||
| const WORK_SPINNER_ANIMATION_DELAY = 1.0; |  | ||||||
| const WORK_SPINNER_ANIMATION_TIME = 0.3; |  | ||||||
|  |  | ||||||
| const KeyringDialog = new Lang.Class({ | const KeyringDialog = new Lang.Class({ | ||||||
|     Name: 'KeyringDialog', |     Name: 'KeyringDialog', | ||||||
| @@ -47,7 +41,7 @@ const KeyringDialog = new Lang.Class({ | |||||||
|         mainContentBox.add(this._messageBox, |         mainContentBox.add(this._messageBox, | ||||||
|                            { y_align: St.Align.START, expand: true, x_fill: true, y_fill: true }); |                            { y_align: St.Align.START, expand: true, x_fill: true, y_fill: true }); | ||||||
|  |  | ||||||
|         let subject = new St.Label({ style_class: 'prompt-dialog-headline headline' }); |         let subject = new St.Label({ style_class: 'prompt-dialog-headline' }); | ||||||
|         this.prompt.bind_property('message', subject, 'text', GObject.BindingFlags.SYNC_CREATE); |         this.prompt.bind_property('message', subject, 'text', GObject.BindingFlags.SYNC_CREATE); | ||||||
|  |  | ||||||
|         this._messageBox.add(subject, |         this._messageBox.add(subject, | ||||||
| @@ -64,107 +58,66 @@ const KeyringDialog = new Lang.Class({ | |||||||
|                             { y_fill:  true, |                             { y_fill:  true, | ||||||
|                               y_align: St.Align.START }); |                               y_align: St.Align.START }); | ||||||
|  |  | ||||||
|         this._workSpinner = null; |  | ||||||
|         this._controlTable = null; |         this._controlTable = null; | ||||||
|  |  | ||||||
|  |  | ||||||
|         this._cancelButton = this.addButton({ label: '', |         this._cancelButton = this.addButton({ label: '', | ||||||
|                                               action: Lang.bind(this, this._onCancelButton), |                                               action: Lang.bind(this, this._onCancelButton), | ||||||
|                                               key: Clutter.Escape }); |                                               key: Clutter.Escape }, | ||||||
|  |                                             { expand: true, x_fill: false, x_align: St.Align.START }); | ||||||
|  |         this.placeSpinner({ expand: false, | ||||||
|  |                             x_fill: false, | ||||||
|  |                             y_fill: false, | ||||||
|  |                             x_align: St.Align.END, | ||||||
|  |                             y_align: St.Align.MIDDLE }); | ||||||
|         this._continueButton = this.addButton({ label: '', |         this._continueButton = this.addButton({ label: '', | ||||||
|                                                 action: Lang.bind(this, this._onContinueButton), |                                                 action: Lang.bind(this, this._onContinueButton), | ||||||
|                                                 default: true }); |                                                 default: true }, | ||||||
|  |                                               { expand: false, x_fill: false, x_align: St.Align.END }); | ||||||
|  |  | ||||||
|         this.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE); |         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); |         this.prompt.bind_property('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _setWorking: function(working) { |  | ||||||
|         if (!this._workSpinner) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         Tweener.removeTweens(this._workSpinner.actor); |  | ||||||
|         if (working) { |  | ||||||
|             this._workSpinner.play(); |  | ||||||
|             Tweener.addTween(this._workSpinner.actor, |  | ||||||
|                              { opacity: 255, |  | ||||||
|                                delay: WORK_SPINNER_ANIMATION_DELAY, |  | ||||||
|                                time: WORK_SPINNER_ANIMATION_TIME, |  | ||||||
|                                transition: 'linear' |  | ||||||
|                              }); |  | ||||||
|         } else { |  | ||||||
|             Tweener.addTween(this._workSpinner.actor, |  | ||||||
|                              { opacity: 0, |  | ||||||
|                                time: WORK_SPINNER_ANIMATION_TIME, |  | ||||||
|                                transition: 'linear', |  | ||||||
|                                onCompleteScope: this, |  | ||||||
|                                onComplete: function() { |  | ||||||
|                                    if (this._workSpinner) |  | ||||||
|                                        this._workSpinner.stop(); |  | ||||||
|                                } |  | ||||||
|                              }); |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _buildControlTable: function() { |     _buildControlTable: function() { | ||||||
|         let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL }); |         let layout = new Clutter.TableLayout(); | ||||||
|         let table = new St.Widget({ style_class: 'keyring-dialog-control-table', |         let table = new St.Widget({ style_class: 'keyring-dialog-control-table', | ||||||
|                                     layout_manager: layout }); |                                     layout_manager: layout }); | ||||||
|         layout.hookup_style(table); |         layout.hookup_style(table); | ||||||
|         let rtl = table.get_text_direction() == Clutter.TextDirection.RTL; |  | ||||||
|         let row = 0; |         let row = 0; | ||||||
|  |  | ||||||
|         if (this.prompt.password_visible) { |         if (this.prompt.password_visible) { | ||||||
|             let label = new St.Label({ style_class: 'prompt-dialog-password-label', |             let label = new St.Label({ style_class: 'prompt-dialog-password-label' }); | ||||||
|                                        x_align: Clutter.ActorAlign.START, |  | ||||||
|                                        y_align: Clutter.ActorAlign.CENTER }); |  | ||||||
|             label.set_text(_("Password:")); |             label.set_text(_("Password:")); | ||||||
|             label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; |             label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; | ||||||
|  |             layout.pack(label, 0, row); | ||||||
|  |             layout.child_set(label, { x_expand: false, y_fill: false, | ||||||
|  |                                       x_align: Clutter.TableAlignment.START }); | ||||||
|             this._passwordEntry = new St.Entry({ style_class: 'prompt-dialog-password-entry', |             this._passwordEntry = new St.Entry({ style_class: 'prompt-dialog-password-entry', | ||||||
|                                                  text: '', |                                                  text: '', | ||||||
|                                                  can_focus: true, |                                                  can_focus: true }); | ||||||
|                                                  x_expand: true }); |  | ||||||
|             this._passwordEntry.clutter_text.set_password_char('\u25cf'); // ● U+25CF BLACK CIRCLE |             this._passwordEntry.clutter_text.set_password_char('\u25cf'); // ● U+25CF BLACK CIRCLE | ||||||
|             ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true }); |             ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true }); | ||||||
|             this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onPasswordActivate)); |             this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onPasswordActivate)); | ||||||
|  |             layout.pack(this._passwordEntry, 1, row); | ||||||
|             let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg'); |  | ||||||
|             this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE); |  | ||||||
|             this._workSpinner.actor.opacity = 0; |  | ||||||
|  |  | ||||||
|             if (rtl) { |  | ||||||
|                 layout.attach(this._workSpinner.actor, 0, row, 1, 1); |  | ||||||
|                 layout.attach(this._passwordEntry, 1, row, 1, 1); |  | ||||||
|                 layout.attach(label, 2, row, 1, 1); |  | ||||||
|             } else { |  | ||||||
|                 layout.attach(label, 0, row, 1, 1); |  | ||||||
|                 layout.attach(this._passwordEntry, 1, row, 1, 1); |  | ||||||
|                 layout.attach(this._workSpinner.actor, 2, row, 1, 1); |  | ||||||
|             } |  | ||||||
|             row++; |             row++; | ||||||
|         } else { |         } else { | ||||||
|             this._workSpinner = null; |  | ||||||
|             this._passwordEntry = null; |             this._passwordEntry = null; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (this.prompt.confirm_visible) { |         if (this.prompt.confirm_visible) { | ||||||
|             var label = new St.Label(({ style_class: 'prompt-dialog-password-label', |             var label = new St.Label(({ style_class: 'prompt-dialog-password-label' })); | ||||||
|                                         x_align: Clutter.ActorAlign.START, |  | ||||||
|                                         y_align: Clutter.ActorAlign.CENTER })); |  | ||||||
|             label.set_text(_("Type again:")); |             label.set_text(_("Type again:")); | ||||||
|  |             layout.pack(label, 0, row); | ||||||
|  |             layout.child_set(label, { x_expand: false, y_fill: false, | ||||||
|  |                                       x_align: Clutter.TableAlignment.START }); | ||||||
|             this._confirmEntry = new St.Entry({ style_class: 'prompt-dialog-password-entry', |             this._confirmEntry = new St.Entry({ style_class: 'prompt-dialog-password-entry', | ||||||
|                                                 text: '', |                                                 text: '', | ||||||
|                                                 can_focus: true, |                                                 can_focus: true }); | ||||||
|                                                 x_expand: true }); |  | ||||||
|             this._confirmEntry.clutter_text.set_password_char('\u25cf'); // ● U+25CF BLACK CIRCLE |             this._confirmEntry.clutter_text.set_password_char('\u25cf'); // ● U+25CF BLACK CIRCLE | ||||||
|             ShellEntry.addContextMenu(this._confirmEntry, { isPassword: true }); |             ShellEntry.addContextMenu(this._confirmEntry, { isPassword: true }); | ||||||
|             this._confirmEntry.clutter_text.connect('activate', Lang.bind(this, this._onConfirmActivate)); |             this._confirmEntry.clutter_text.connect('activate', Lang.bind(this, this._onConfirmActivate)); | ||||||
|             if (rtl) { |             layout.pack(this._confirmEntry, 1, row); | ||||||
|                 layout.attach(this._confirmEntry, 0, row, 1, 1); |  | ||||||
|                 layout.attach(label, 1, row, 1, 1); |  | ||||||
|             } else { |  | ||||||
|                 layout.attach(label, 0, row, 1, 1); |  | ||||||
|                 layout.attach(this._confirmEntry, 1, row, 1, 1); |  | ||||||
|             } |  | ||||||
|             row++; |             row++; | ||||||
|         } else { |         } else { | ||||||
|             this._confirmEntry = null; |             this._confirmEntry = null; | ||||||
| @@ -177,15 +130,15 @@ const KeyringDialog = new Lang.Class({ | |||||||
|             let choice = new CheckBox.CheckBox(); |             let choice = new CheckBox.CheckBox(); | ||||||
|             this.prompt.bind_property('choice-label', choice.getLabelActor(), 'text', GObject.BindingFlags.SYNC_CREATE); |             this.prompt.bind_property('choice-label', choice.getLabelActor(), 'text', GObject.BindingFlags.SYNC_CREATE); | ||||||
|             this.prompt.bind_property('choice-chosen', choice.actor, 'checked', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL); |             this.prompt.bind_property('choice-chosen', choice.actor, 'checked', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL); | ||||||
|             layout.attach(choice.actor, rtl ? 0 : 1, row, 1, 1); |             layout.pack(choice.actor, 1, row); | ||||||
|             row++; |             row++; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         let warning = new St.Label({ style_class: 'prompt-dialog-error-label', |         let warning = new St.Label({ style_class: 'prompt-dialog-error-label' }); | ||||||
|                                      x_align: Clutter.ActorAlign.START }); |  | ||||||
|         warning.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; |         warning.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; | ||||||
|         warning.clutter_text.line_wrap = true; |         warning.clutter_text.line_wrap = true; | ||||||
|         layout.attach(warning, rtl ? 0 : 1, row, 1, 1); |         layout.pack(warning, 1, row); | ||||||
|  |         layout.child_set(warning, { x_fill: false, x_align: Clutter.TableAlignment.START }); | ||||||
|         this.prompt.bind_property('warning-visible', warning, 'visible', GObject.BindingFlags.SYNC_CREATE); |         this.prompt.bind_property('warning-visible', warning, 'visible', GObject.BindingFlags.SYNC_CREATE); | ||||||
|         this.prompt.bind_property('warning', warning, 'text', GObject.BindingFlags.SYNC_CREATE); |         this.prompt.bind_property('warning', warning, 'text', GObject.BindingFlags.SYNC_CREATE); | ||||||
|  |  | ||||||
| @@ -211,7 +164,7 @@ const KeyringDialog = new Lang.Class({ | |||||||
|  |  | ||||||
|         this._continueButton.can_focus = sensitive; |         this._continueButton.can_focus = sensitive; | ||||||
|         this._continueButton.reactive = sensitive; |         this._continueButton.reactive = sensitive; | ||||||
|         this._setWorking(!sensitive); |         this.setWorking(!sensitive); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _ensureOpen: function() { |     _ensureOpen: function() { | ||||||
|   | |||||||
| @@ -12,8 +12,6 @@ const Shell = imports.gi.Shell; | |||||||
| const St = imports.gi.St; | const St = imports.gi.St; | ||||||
|  |  | ||||||
| const Config = imports.misc.config; | const Config = imports.misc.config; | ||||||
| const Main = imports.ui.main; |  | ||||||
| const MessageTray = imports.ui.messageTray; |  | ||||||
| const ModalDialog = imports.ui.modalDialog; | const ModalDialog = imports.ui.modalDialog; | ||||||
| const PopupMenu = imports.ui.popupMenu; | const PopupMenu = imports.ui.popupMenu; | ||||||
| const ShellEntry = imports.ui.shellEntry; | const ShellEntry = imports.ui.shellEntry; | ||||||
| @@ -56,7 +54,7 @@ const NetworkSecretDialog = new Lang.Class({ | |||||||
|         mainContentBox.add(messageBox, |         mainContentBox.add(messageBox, | ||||||
|                            { y_align: St.Align.START }); |                            { y_align: St.Align.START }); | ||||||
|  |  | ||||||
|         let subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline headline', |         let subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline', | ||||||
|                                             text: this._content.title }); |                                             text: this._content.title }); | ||||||
|         messageBox.add(subjectLabel, |         messageBox.add(subjectLabel, | ||||||
|                        { y_fill:  false, |                        { y_fill:  false, | ||||||
| @@ -74,28 +72,24 @@ const NetworkSecretDialog = new Lang.Class({ | |||||||
|                              expand: true }); |                              expand: true }); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL }); |         let layout = new Clutter.TableLayout(); | ||||||
|         let secretTable = new St.Widget({ style_class: 'network-dialog-secret-table', |         let secretTable = new St.Widget({ style_class: 'network-dialog-secret-table', | ||||||
|                                           layout_manager: layout }); |                                           layout_manager: layout }); | ||||||
|         layout.hookup_style(secretTable); |         layout.hookup_style(secretTable); | ||||||
|  |  | ||||||
|         let rtl = secretTable.get_text_direction() == Clutter.TextDirection.RTL; |  | ||||||
|         let initialFocusSet = false; |         let initialFocusSet = false; | ||||||
|         let pos = 0; |         let pos = 0; | ||||||
|         for (let i = 0; i < this._content.secrets.length; i++) { |         for (let i = 0; i < this._content.secrets.length; i++) { | ||||||
|             let secret = this._content.secrets[i]; |             let secret = this._content.secrets[i]; | ||||||
|             let label = new St.Label({ style_class: 'prompt-dialog-password-label', |             let label = new St.Label({ style_class: 'prompt-dialog-password-label', | ||||||
|                                        text: secret.label, |                                        text: secret.label }); | ||||||
|                                        x_align: Clutter.ActorAlign.START, |  | ||||||
|                                        y_align: Clutter.ActorAlign.CENTER }); |  | ||||||
|             label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; |             label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; | ||||||
|  |  | ||||||
|             let reactive = secret.key != null; |             let reactive = secret.key != null; | ||||||
|  |  | ||||||
|             secret.entry = new St.Entry({ style_class: 'prompt-dialog-password-entry', |             secret.entry = new St.Entry({ style_class: 'prompt-dialog-password-entry', | ||||||
|                                           text: secret.value, can_focus: reactive, |                                           text: secret.value, can_focus: reactive, | ||||||
|                                           reactive: reactive, |                                           reactive: reactive }); | ||||||
|                                           x_expand: true }); |  | ||||||
|             ShellEntry.addContextMenu(secret.entry, |             ShellEntry.addContextMenu(secret.entry, | ||||||
|                                       { isPassword: secret.password }); |                                       { isPassword: secret.password }); | ||||||
|  |  | ||||||
| @@ -122,13 +116,10 @@ const NetworkSecretDialog = new Lang.Class({ | |||||||
|             } else |             } else | ||||||
|                 secret.valid = true; |                 secret.valid = true; | ||||||
|  |  | ||||||
|             if (rtl) { |             layout.pack(label, 0, pos); | ||||||
|                 layout.attach(secret.entry, 0, pos, 1, 1); |             layout.child_set(label, { x_expand: false, y_fill: false, | ||||||
|                 layout.attach(label, 1, pos, 1, 1); |                                       x_align: Clutter.TableAlignment.START }); | ||||||
|             } else { |             layout.pack(secret.entry, 1, pos); | ||||||
|                 layout.attach(label, 0, pos, 1, 1); |  | ||||||
|                 layout.attach(secret.entry, 1, pos, 1, 1); |  | ||||||
|             } |  | ||||||
|             pos++; |             pos++; | ||||||
|  |  | ||||||
|             if (secret.password) |             if (secret.password) | ||||||
| @@ -340,7 +331,6 @@ const NetworkSecretDialog = new Lang.Class({ | |||||||
|                 content.message = _("PIN code is needed for the mobile broadband device"); |                 content.message = _("PIN code is needed for the mobile broadband device"); | ||||||
|                 content.secrets.push({ label: _("PIN: "), key: 'pin', |                 content.secrets.push({ label: _("PIN: "), key: 'pin', | ||||||
|                                        value: gsmSetting.pin || '', password: true }); |                                        value: gsmSetting.pin || '', password: true }); | ||||||
|                 break; |  | ||||||
|             } |             } | ||||||
|             // fall through |             // fall through | ||||||
|         case 'cdma': |         case 'cdma': | ||||||
| @@ -383,12 +373,6 @@ const VPNRequestHandler = new Lang.Class({ | |||||||
|             argv.push('-i'); |             argv.push('-i'); | ||||||
|         if (flags & NMClient.SecretAgentGetSecretsFlags.REQUEST_NEW) |         if (flags & NMClient.SecretAgentGetSecretsFlags.REQUEST_NEW) | ||||||
|             argv.push('-r'); |             argv.push('-r'); | ||||||
|         if (authHelper.supportsHints) { |  | ||||||
|             for (let i = 0; i < hints.length; i++) { |  | ||||||
|                 argv.push('-t'); |  | ||||||
|                 argv.push(hints[i]); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this._newStylePlugin = authHelper.externalUIMode; |         this._newStylePlugin = authHelper.externalUIMode; | ||||||
|  |  | ||||||
| @@ -607,13 +591,10 @@ const NetworkAgent = new Lang.Class({ | |||||||
|     Name: 'NetworkAgent', |     Name: 'NetworkAgent', | ||||||
|  |  | ||||||
|     _init: function() { |     _init: function() { | ||||||
|         this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent', |         this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent' }); | ||||||
|                                                 capabilities: NMClient.SecretAgentCapabilities.VPN_HINTS |  | ||||||
|                                               }); |  | ||||||
|  |  | ||||||
|         this._dialogs = { }; |         this._dialogs = { }; | ||||||
|         this._vpnRequests = { }; |         this._vpnRequests = { }; | ||||||
|         this._notifications = { }; |  | ||||||
|  |  | ||||||
|         this._native.connect('new-request', Lang.bind(this, this._newRequest)); |         this._native.connect('new-request', Lang.bind(this, this._newRequest)); | ||||||
|         this._native.connect('cancel-request', Lang.bind(this, this._cancelRequest)); |         this._native.connect('cancel-request', Lang.bind(this, this._cancelRequest)); | ||||||
| @@ -636,92 +617,21 @@ const NetworkAgent = new Lang.Class({ | |||||||
|             this._vpnRequests[requestId].cancel(true); |             this._vpnRequests[requestId].cancel(true); | ||||||
|         this._vpnRequests = { }; |         this._vpnRequests = { }; | ||||||
|  |  | ||||||
|         for (requestId in this._notifications) |  | ||||||
|             this._notifications[requestId].destroy(); |  | ||||||
|         this._notifications = { }; |  | ||||||
|  |  | ||||||
|         this._enabled = false; |         this._enabled = false; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _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'); |  | ||||||
|  |  | ||||||
|         let title, body; |  | ||||||
|  |  | ||||||
|         let connectionSetting = connection.get_setting_connection(); |  | ||||||
|         let connectionType = connectionSetting.get_connection_type(); |  | ||||||
|         switch (connectionType) { |  | ||||||
|         case '802-11-wireless': |  | ||||||
|             let wirelessSetting = connection.get_setting_wireless(); |  | ||||||
|             let ssid = NetworkManager.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; |  | ||||||
|         case '802-3-ethernet': |  | ||||||
|             title = _("Wired 802.1X authentication"); |  | ||||||
|             body = _("A password is required to connect to “%s”.".format(connection.get_id())); |  | ||||||
|             break; |  | ||||||
|         case 'pppoe': |  | ||||||
|             title = _("DSL authentication"); |  | ||||||
|             body = _("A password is required to connect to “%s”.".format(connection.get_id())); |  | ||||||
|             break; |  | ||||||
|         case 'gsm': |  | ||||||
|             if (hints.indexOf('pin') != -1) { |  | ||||||
|                 let gsmSetting = connection.get_setting_gsm(); |  | ||||||
|                 title = _("PIN code required"); |  | ||||||
|                 message = _("PIN code is needed for the mobile broadband device"); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|             // fall through |  | ||||||
|         case 'cdma': |  | ||||||
|         case 'bluetooth': |  | ||||||
|             title = _("Mobile broadband network password"); |  | ||||||
|             message = _("A password is required to connect to “%s”.").format(connectionSetting.get_id()); |  | ||||||
|             break; |  | ||||||
|         default: |  | ||||||
|             log('Invalid connection type: ' + connectionType); |  | ||||||
|             this._native.respond(requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         let notification = new MessageTray.Notification(source, title, body); |  | ||||||
|  |  | ||||||
|         notification.connect('activated', Lang.bind(this, function() { |  | ||||||
|             notification.answered = true; |  | ||||||
|             this._handleRequest(requestId, connection, settingName, hints, flags); |  | ||||||
|         })); |  | ||||||
|  |  | ||||||
|         this._notifications[requestId] = notification; |  | ||||||
|         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:  function(agent, requestId, connection, settingName, hints, flags) { |     _newRequest:  function(agent, requestId, connection, settingName, hints, flags) { | ||||||
|         if (!this._enabled) { |         if (!this._enabled) { | ||||||
|             agent.respond(requestId, Shell.NetworkAgentResponse.USER_CANCELED); |             agent.respond(requestId, Shell.NetworkAgentResponse.USER_CANCELED); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!(flags & NMClient.SecretAgentGetSecretsFlags.USER_REQUESTED)) |  | ||||||
|             this._showNotification(requestId, connection, settingName, hints, flags); |  | ||||||
|         else |  | ||||||
|             this._handleRequest(requestId, connection, settingName, hints, flags); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _handleRequest: function(requestId, connection, settingName, hints, flags) { |  | ||||||
|         if (settingName == 'vpn') { |         if (settingName == 'vpn') { | ||||||
|             this._vpnRequest(requestId, connection, hints, flags); |             this._vpnRequest(requestId, connection, hints, flags); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         let dialog = new NetworkSecretDialog(this._native, requestId, connection, settingName, hints); |         let dialog = new NetworkSecretDialog(agent, requestId, connection, settingName, hints); | ||||||
|         dialog.connect('destroy', Lang.bind(this, function() { |         dialog.connect('destroy', Lang.bind(this, function() { | ||||||
|             delete this._dialogs[requestId]; |             delete this._dialogs[requestId]; | ||||||
|         })); |         })); | ||||||
| @@ -781,23 +691,16 @@ const NetworkAgent = new Lang.Class({ | |||||||
|                     let service = keyfile.get_string('VPN Connection', 'service'); |                     let service = keyfile.get_string('VPN Connection', 'service'); | ||||||
|                     let binary = keyfile.get_string('GNOME', 'auth-dialog'); |                     let binary = keyfile.get_string('GNOME', 'auth-dialog'); | ||||||
|                     let externalUIMode = false; |                     let externalUIMode = false; | ||||||
|                     let hints = false; |  | ||||||
|  |  | ||||||
|                     try { |                     try { | ||||||
|                         externalUIMode = keyfile.get_boolean('GNOME', 'supports-external-ui-mode'); |                         externalUIMode = keyfile.get_boolean('GNOME', 'supports-external-ui-mode'); | ||||||
|                     } catch(e) { } // ignore errors if key does not exist |                     } 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; |                     let path = binary; | ||||||
|                     if (!GLib.path_is_absolute(path)) { |                     if (!GLib.path_is_absolute(path)) { | ||||||
|                         path = GLib.build_filenamev([Config.LIBEXECDIR, path]); |                         path = GLib.build_filenamev([Config.LIBEXECDIR, path]); | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                     if (GLib.file_test(path, GLib.FileTest.IS_EXECUTABLE)) |                     if (GLib.file_test(path, GLib.FileTest.IS_EXECUTABLE)) | ||||||
|                         this._vpnBinaries[service] = { fileName: path, externalUIMode: externalUIMode, supportsHints: hints }; |                         this._vpnBinaries[service] = { fileName: path, externalUIMode: externalUIMode }; | ||||||
|                     else |                     else | ||||||
|                         throw new Error('VPN plugin at %s is not executable'.format(path)); |                         throw new Error('VPN plugin at %s is not executable'.format(path)); | ||||||
|                 } catch(e) { |                 } catch(e) { | ||||||
|   | |||||||
| @@ -13,19 +13,13 @@ const Mainloop = imports.mainloop; | |||||||
| const Polkit = imports.gi.Polkit; | const Polkit = imports.gi.Polkit; | ||||||
| const PolkitAgent = imports.gi.PolkitAgent; | const PolkitAgent = imports.gi.PolkitAgent; | ||||||
|  |  | ||||||
| const Animation = imports.ui.animation; |  | ||||||
| const Components = imports.ui.components; | const Components = imports.ui.components; | ||||||
| const ModalDialog = imports.ui.modalDialog; | const ModalDialog = imports.ui.modalDialog; | ||||||
| const ShellEntry = imports.ui.shellEntry; | const ShellEntry = imports.ui.shellEntry; | ||||||
| const UserWidget = imports.ui.userWidget; | const UserWidget = imports.ui.userWidget; | ||||||
| const Tweener = imports.ui.tweener; |  | ||||||
|  |  | ||||||
| const DIALOG_ICON_SIZE = 48; | const DIALOG_ICON_SIZE = 48; | ||||||
|  |  | ||||||
| const WORK_SPINNER_ICON_SIZE = 16; |  | ||||||
| const WORK_SPINNER_ANIMATION_DELAY = 1.0; |  | ||||||
| const WORK_SPINNER_ANIMATION_TIME = 0.3; |  | ||||||
|  |  | ||||||
| const AuthenticationDialog = new Lang.Class({ | const AuthenticationDialog = new Lang.Class({ | ||||||
|     Name: 'AuthenticationDialog', |     Name: 'AuthenticationDialog', | ||||||
|     Extends: ModalDialog.ModalDialog, |     Extends: ModalDialog.ModalDialog, | ||||||
| @@ -56,7 +50,7 @@ const AuthenticationDialog = new Lang.Class({ | |||||||
|         mainContentBox.add(messageBox, |         mainContentBox.add(messageBox, | ||||||
|                            { expand: true, y_align: St.Align.START }); |                            { expand: true, y_align: St.Align.START }); | ||||||
|  |  | ||||||
|         this._subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline headline', |         this._subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline', | ||||||
|                                             text: _("Authentication Required") }); |                                             text: _("Authentication Required") }); | ||||||
|  |  | ||||||
|         messageBox.add(this._subjectLabel, |         messageBox.add(this._subjectLabel, | ||||||
| @@ -142,13 +136,6 @@ const AuthenticationDialog = new Lang.Class({ | |||||||
|         this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivate)); |         this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivate)); | ||||||
|         this._passwordBox.add(this._passwordEntry, |         this._passwordBox.add(this._passwordEntry, | ||||||
|                               { expand: true }); |                               { expand: true }); | ||||||
|  |  | ||||||
|         let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg'); |  | ||||||
|         this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE); |  | ||||||
|         this._workSpinner.actor.opacity = 0; |  | ||||||
|  |  | ||||||
|         this._passwordBox.add(this._workSpinner.actor); |  | ||||||
|  |  | ||||||
|         this.setInitialKeyFocus(this._passwordEntry); |         this.setInitialKeyFocus(this._passwordEntry); | ||||||
|         this._passwordBox.hide(); |         this._passwordBox.hide(); | ||||||
|  |  | ||||||
| @@ -178,10 +165,17 @@ const AuthenticationDialog = new Lang.Class({ | |||||||
|  |  | ||||||
|         this._cancelButton = this.addButton({ label: _("Cancel"), |         this._cancelButton = this.addButton({ label: _("Cancel"), | ||||||
|                                               action: Lang.bind(this, this.cancel), |                                               action: Lang.bind(this, this.cancel), | ||||||
|                                               key: Clutter.Escape }); |                                               key: Clutter.Escape }, | ||||||
|  |                                             { expand: true, x_fill: false, x_align: St.Align.START }); | ||||||
|  |         this.placeSpinner({ expand: false, | ||||||
|  |                             x_fill: false, | ||||||
|  |                             y_fill: false, | ||||||
|  |                             x_align: St.Align.END, | ||||||
|  |                             y_align: St.Align.MIDDLE }); | ||||||
|         this._okButton = this.addButton({ label:  _("Authenticate"), |         this._okButton = this.addButton({ label:  _("Authenticate"), | ||||||
|                                           action: Lang.bind(this, this._onAuthenticateButtonPressed), |                                           action: Lang.bind(this, this._onAuthenticateButtonPressed), | ||||||
|                                           default: true }); |                                           default: true }, | ||||||
|  |                                         { expand: false, x_fill: false, x_align: St.Align.END }); | ||||||
|  |  | ||||||
|         this._doneEmitted = false; |         this._doneEmitted = false; | ||||||
|  |  | ||||||
| @@ -189,30 +183,6 @@ const AuthenticationDialog = new Lang.Class({ | |||||||
|         this._cookie = cookie; |         this._cookie = cookie; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _setWorking: function(working) { |  | ||||||
|         Tweener.removeTweens(this._workSpinner.actor); |  | ||||||
|         if (working) { |  | ||||||
|             this._workSpinner.play(); |  | ||||||
|             Tweener.addTween(this._workSpinner.actor, |  | ||||||
|                              { opacity: 255, |  | ||||||
|                                delay: WORK_SPINNER_ANIMATION_DELAY, |  | ||||||
|                                time: WORK_SPINNER_ANIMATION_TIME, |  | ||||||
|                                transition: 'linear' |  | ||||||
|                              }); |  | ||||||
|         } else { |  | ||||||
|             Tweener.addTween(this._workSpinner.actor, |  | ||||||
|                              { opacity: 0, |  | ||||||
|                                time: WORK_SPINNER_ANIMATION_TIME, |  | ||||||
|                                transition: 'linear', |  | ||||||
|                                onCompleteScope: this, |  | ||||||
|                                onComplete: function() { |  | ||||||
|                                    if (this._workSpinner) |  | ||||||
|                                        this._workSpinner.stop(); |  | ||||||
|                                } |  | ||||||
|                              }); |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     performAuthentication: function() { |     performAuthentication: function() { | ||||||
|         this.destroySession(); |         this.destroySession(); | ||||||
|         this._session = new PolkitAgent.Session({ identity: this._identityToAuth, |         this._session = new PolkitAgent.Session({ identity: this._identityToAuth, | ||||||
| @@ -259,7 +229,7 @@ const AuthenticationDialog = new Lang.Class({ | |||||||
|  |  | ||||||
|         this._okButton.can_focus = sensitive; |         this._okButton.can_focus = sensitive; | ||||||
|         this._okButton.reactive = sensitive; |         this._okButton.reactive = sensitive; | ||||||
|         this._setWorking(!sensitive); |         this.setWorking(!sensitive); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onEntryActivate: function() { |     _onEntryActivate: function() { | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ | |||||||
| const Clutter = imports.gi.Clutter; | const Clutter = imports.gi.Clutter; | ||||||
| const Gio = imports.gi.Gio; | const Gio = imports.gi.Gio; | ||||||
| const GLib = imports.gi.GLib; | const GLib = imports.gi.GLib; | ||||||
| const Gtk = imports.gi.Gtk; |  | ||||||
| const Lang = imports.lang; | const Lang = imports.lang; | ||||||
| const Mainloop = imports.mainloop; | const Mainloop = imports.mainloop; | ||||||
| const Shell = imports.gi.Shell; | const Shell = imports.gi.Shell; | ||||||
| @@ -12,13 +11,11 @@ const St = imports.gi.St; | |||||||
| const Tpl = imports.gi.TelepathyLogger; | const Tpl = imports.gi.TelepathyLogger; | ||||||
| const Tp = imports.gi.TelepathyGLib; | const Tp = imports.gi.TelepathyGLib; | ||||||
|  |  | ||||||
| const Calendar = imports.ui.calendar; |  | ||||||
| const History = imports.misc.history; | const History = imports.misc.history; | ||||||
| const Main = imports.ui.main; | const Main = imports.ui.main; | ||||||
| const MessageTray = imports.ui.messageTray; | const MessageTray = imports.ui.messageTray; | ||||||
| const Params = imports.misc.params; | const Params = imports.misc.params; | ||||||
| const PopupMenu = imports.ui.popupMenu; | const PopupMenu = imports.ui.popupMenu; | ||||||
| const Util = imports.misc.util; |  | ||||||
|  |  | ||||||
| // See Notification.appendMessage | // See Notification.appendMessage | ||||||
| const SCROLLBACK_IMMEDIATE_TIME = 3 * 60; // 3 minutes | const SCROLLBACK_IMMEDIATE_TIME = 3 * 60; // 3 minutes | ||||||
| @@ -32,15 +29,13 @@ const SCROLLBACK_HISTORY_LINES = 10; | |||||||
| // See Notification._onEntryChanged | // See Notification._onEntryChanged | ||||||
| const COMPOSING_STOP_TIMEOUT = 5; | const COMPOSING_STOP_TIMEOUT = 5; | ||||||
|  |  | ||||||
| const CHAT_EXPAND_LINES = 12; | const CLOCK_FORMAT_KEY = 'clock-format'; | ||||||
|  |  | ||||||
| const NotificationDirection = { | const NotificationDirection = { | ||||||
|     SENT: 'chat-sent', |     SENT: 'chat-sent', | ||||||
|     RECEIVED: 'chat-received' |     RECEIVED: 'chat-received' | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const N_ = function(s) { return s; }; |  | ||||||
|  |  | ||||||
| function makeMessageFromTpMessage(tpMessage, direction) { | function makeMessageFromTpMessage(tpMessage, direction) { | ||||||
|     let [text, flags] = tpMessage.to_text(); |     let [text, flags] = tpMessage.to_text(); | ||||||
|  |  | ||||||
| @@ -121,7 +116,7 @@ const TelepathyClient = new Lang.Class({ | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!this._accountManager.is_prepared(Tp.AccountManager.get_feature_quark_core())) |         if (!this._accountManager.is_prepared(Tp.AccountManager.get_feature_quark_core())) | ||||||
|             this._accountManager.prepare_async(null, null); |             this._accountManager.prepare_async(null, Lang.bind(this, this._accountManagerPrepared)); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     disable: function() { |     disable: function() { | ||||||
| @@ -158,6 +153,14 @@ const TelepathyClient = new Lang.Class({ | |||||||
|         this._chatSources[channel.get_object_path()] = source; |         this._chatSources[channel.get_object_path()] = source; | ||||||
|         source.connect('destroy', Lang.bind(this, |         source.connect('destroy', Lang.bind(this, | ||||||
|                        function() { |                        function() { | ||||||
|  |                            if (this._tpClient.is_handling_channel(channel)) { | ||||||
|  |                                // The chat box has been destroyed so it can't | ||||||
|  |                                // handle the channel any more. | ||||||
|  |                                channel.close_async(function(src, result) { | ||||||
|  |                                    channel.close_finish(result); | ||||||
|  |                                }); | ||||||
|  |                            } | ||||||
|  |  | ||||||
|                            delete this._chatSources[channel.get_object_path()]; |                            delete this._chatSources[channel.get_object_path()]; | ||||||
|                        })); |                        })); | ||||||
|     }, |     }, | ||||||
| @@ -223,29 +226,29 @@ const TelepathyClient = new Lang.Class({ | |||||||
|     _approveTextChannel: function(account, conn, channel, dispatchOp, context) { |     _approveTextChannel: function(account, conn, channel, dispatchOp, context) { | ||||||
|         let [targetHandle, targetHandleType] = channel.get_handle(); |         let [targetHandle, targetHandleType] = channel.get_handle(); | ||||||
|  |  | ||||||
|         if (targetHandleType != Tp.HandleType.CONTACT) { |         if (targetHandleType == Tp.HandleType.CONTACT) { | ||||||
|             context.fail(new Tp.Error({ code: Tp.Error.INVALID_ARGUMENT, |  | ||||||
|                                         message: 'Unsupported handle type' })); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|             // Approve private text channels right away as we are going to handle it |             // Approve private text channels right away as we are going to handle it | ||||||
|         dispatchOp.claim_with_async(this._tpClient, Lang.bind(this, function(dispatchOp, result) { |             dispatchOp.claim_with_async(this._tpClient, | ||||||
|  |                                         Lang.bind(this, function(dispatchOp, result) { | ||||||
|                 try { |                 try { | ||||||
|                     dispatchOp.claim_with_finish(result); |                     dispatchOp.claim_with_finish(result); | ||||||
|                     this._handlingChannels(account, conn, [channel], false); |                     this._handlingChannels(account, conn, [channel], false); | ||||||
|                 } catch (err) { |                 } catch (err) { | ||||||
|                 log('Failed to Claim channel: ' + err); |                     throw new Error('Failed to Claim channel: ' + err); | ||||||
|             } |                 }})); | ||||||
|         })); |  | ||||||
|  |  | ||||||
|             context.accept(); |             context.accept(); | ||||||
|  |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _delegatedChannelsCb: function(client, channels) { |     _delegatedChannelsCb: function(client, channels) { | ||||||
|         // Nothing to do as we don't make a distinction between observed and |         // Nothing to do as we don't make a distinction between observed and | ||||||
|         // handled channels. |         // handled channels. | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|  |     _accountManagerPrepared: function(am, result) { | ||||||
|  |         am.prepare_finish(result); | ||||||
|  |     }, | ||||||
| }); | }); | ||||||
|  |  | ||||||
| const ChatSource = new Lang.Class({ | const ChatSource = new Lang.Class({ | ||||||
| @@ -266,8 +269,15 @@ const ChatSource = new Lang.Class({ | |||||||
|         this._channel = channel; |         this._channel = channel; | ||||||
|         this._closedId = this._channel.connect('invalidated', Lang.bind(this, this._channelClosed)); |         this._closedId = this._channel.connect('invalidated', Lang.bind(this, this._channelClosed)); | ||||||
|  |  | ||||||
|  |         this._notification = new ChatNotification(this); | ||||||
|  |         this._notification.connect('clicked', Lang.bind(this, this.open)); | ||||||
|  |         this._notification.setUrgency(MessageTray.Urgency.HIGH); | ||||||
|         this._notifyTimeoutId = 0; |         this._notifyTimeoutId = 0; | ||||||
|  |  | ||||||
|  |         // We ack messages when the user expands the new notification or views the summary | ||||||
|  |         // notification, in which case the notification is also expanded. | ||||||
|  |         this._notification.connect('expanded', Lang.bind(this, this._ackMessages)); | ||||||
|  |  | ||||||
|         this._presence = contact.get_presence_type(); |         this._presence = contact.get_presence_type(); | ||||||
|  |  | ||||||
|         this._sentId = this._channel.connect('message-sent', Lang.bind(this, this._messageSent)); |         this._sentId = this._channel.connect('message-sent', Lang.bind(this, this._messageSent)); | ||||||
| @@ -280,48 +290,31 @@ const ChatSource = new Lang.Class({ | |||||||
|  |  | ||||||
|         // Add ourselves as a source. |         // Add ourselves as a source. | ||||||
|         Main.messageTray.add(this); |         Main.messageTray.add(this); | ||||||
|  |         this.pushNotification(this._notification); | ||||||
|  |  | ||||||
|         this._getLogMessages(); |         this._getLogMessages(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _ensureNotification: function() { |     buildRightClickMenu: function() { | ||||||
|         if (this._notification) |         let item; | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         this._notification = new ChatNotification(this); |         let rightClickMenu = this.parent(); | ||||||
|         this._notification.connect('activated', Lang.bind(this, this.open)); |         item = new PopupMenu.PopupMenuItem(''); | ||||||
|         this._notification.connect('updated', Lang.bind(this, |         item.actor.connect('notify::mapped', Lang.bind(this, function() { | ||||||
|             function() { |             item.label.set_text(this.isMuted ? _("Unmute") : _("Mute")); | ||||||
|                 if (this._banner && this._banner.expanded) |  | ||||||
|                     this._ackMessages(); |  | ||||||
|         })); |         })); | ||||||
|         this._notification.connect('destroy', Lang.bind(this, |         item.connect('activate', Lang.bind(this, function() { | ||||||
|             function() { |             this.setMuted(!this.isMuted); | ||||||
|                 this._notification = null; |             this.emit('done-displaying-content', false); | ||||||
|         })); |         })); | ||||||
|         this.pushNotification(this._notification); |         rightClickMenu.add(item.actor); | ||||||
|  |         return rightClickMenu; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _createPolicy: function() { |     _createPolicy: function() { | ||||||
|         if (this._account.protocol_name == 'irc') |  | ||||||
|             return new MessageTray.NotificationApplicationPolicy('org.gnome.Polari'); |  | ||||||
|         return new MessageTray.NotificationApplicationPolicy('empathy'); |         return new MessageTray.NotificationApplicationPolicy('empathy'); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     createBanner: function() { |  | ||||||
|         this._banner = new ChatNotificationBanner(this._notification); |  | ||||||
|  |  | ||||||
|         // We ack messages when the user expands the new notification |  | ||||||
|         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: function() { |     _updateAlias: function() { | ||||||
|         let oldAlias = this.title; |         let oldAlias = this.title; | ||||||
|         let newAlias = this._contact.get_alias(); |         let newAlias = this._contact.get_alias(); | ||||||
| @@ -330,7 +323,6 @@ const ChatSource = new Lang.Class({ | |||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         this.setTitle(newAlias); |         this.setTitle(newAlias); | ||||||
|         if (this._notification) |  | ||||||
|         this._notification.appendAliasChange(oldAlias, newAlias); |         this._notification.appendAliasChange(oldAlias, newAlias); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
| @@ -374,28 +366,15 @@ const ChatSource = new Lang.Class({ | |||||||
|  |  | ||||||
|     _updateAvatarIcon: function() { |     _updateAvatarIcon: function() { | ||||||
|         this.iconUpdated(); |         this.iconUpdated(); | ||||||
|         if (this._notifiction) |         this._notification.update(this._notification.title); | ||||||
|             this._notification.update(this._notification.title, |  | ||||||
|                                       this._notification.bannerBodyText, |  | ||||||
|                                       { gicon: this.getIcon() }); |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     open: function() { |     open: function() { | ||||||
|         Main.overview.hide(); |  | ||||||
|         Main.panel.closeCalendar(); |  | ||||||
|  |  | ||||||
|         if (this._client.is_handling_channel(this._channel)) { |         if (this._client.is_handling_channel(this._channel)) { | ||||||
|             // We are handling the channel, try to pass it to Empathy or Polari |             // We are handling the channel, try to pass it to Empathy | ||||||
|             // (depending on the channel type) |             this._client.delegate_channels_async([this._channel], | ||||||
|             // We don't check if either app is availble - mission control will |                                                  global.get_current_time(), | ||||||
|             // fallback to something else if activation fails |                                                  'org.freedesktop.Telepathy.Client.Empathy.Chat', null); | ||||||
|  |  | ||||||
|             let target; |  | ||||||
|             if (this._channel.connection.protocol_name == 'irc') |  | ||||||
|                 target = 'org.freedesktop.Telepathy.Client.Polari'; |  | ||||||
|             else |  | ||||||
|                 target = 'org.freedesktop.Telepathy.Client.Empathy.Chat'; |  | ||||||
|             this._client.delegate_channels_async([this._channel], global.get_current_time(), target, null); |  | ||||||
|         } else { |         } else { | ||||||
|             // We are not the handler, just ask to present the channel |             // We are not the handler, just ask to present the channel | ||||||
|             let dbus = Tp.DBusDaemon.dup(); |             let dbus = Tp.DBusDaemon.dup(); | ||||||
| @@ -418,7 +397,6 @@ const ChatSource = new Lang.Class({ | |||||||
|         let [success, events] = logManager.get_filtered_events_finish(result); |         let [success, events] = logManager.get_filtered_events_finish(result); | ||||||
|  |  | ||||||
|         let logMessages = events.map(makeMessageFromTplEvent); |         let logMessages = events.map(makeMessageFromTplEvent); | ||||||
|         this._ensureNotification(); |  | ||||||
|  |  | ||||||
|         let pendingTpMessages = this._channel.get_pending_messages(); |         let pendingTpMessages = this._channel.get_pending_messages(); | ||||||
|         let pendingMessages = []; |         let pendingMessages = []; | ||||||
| @@ -468,18 +446,6 @@ const ChatSource = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     destroy: function(reason) { |     destroy: function(reason) { | ||||||
|         if (this._client.is_handling_channel(this._channel)) { |  | ||||||
|             // The chat box has been destroyed so it can't |  | ||||||
|             // handle the channel any more. |  | ||||||
|             this._channel.close_async(function(channel, result) { |  | ||||||
|                 channel.close_finish(result); |  | ||||||
|             }); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // Keep source alive while the channel is open |  | ||||||
|         if (reason != MessageTray.NotificationDestroyedReason.SOURCE_CLOSED) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         if (this._destroyed) |         if (this._destroyed) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
| @@ -493,6 +459,9 @@ const ChatSource = new Lang.Class({ | |||||||
|         this._contact.disconnect(this._notifyAvatarId); |         this._contact.disconnect(this._notifyAvatarId); | ||||||
|         this._contact.disconnect(this._presenceChangedId); |         this._contact.disconnect(this._presenceChangedId); | ||||||
|  |  | ||||||
|  |         if (this._timestampTimeoutId) | ||||||
|  |             Mainloop.source_remove(this._timestampTimeoutId); | ||||||
|  |  | ||||||
|         this.parent(reason); |         this.parent(reason); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
| @@ -505,6 +474,10 @@ const ChatSource = new Lang.Class({ | |||||||
|         return this._pendingMessages.length; |         return this._pendingMessages.length; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|  |     get indicatorCount() { | ||||||
|  |         return this.count; | ||||||
|  |     }, | ||||||
|  |  | ||||||
|     get unseenCount() { |     get unseenCount() { | ||||||
|         return this.count; |         return this.count; | ||||||
|     }, |     }, | ||||||
| @@ -517,7 +490,6 @@ const ChatSource = new Lang.Class({ | |||||||
|         if (message.get_message_type() == Tp.ChannelTextMessageType.DELIVERY_REPORT) |         if (message.get_message_type() == Tp.ChannelTextMessageType.DELIVERY_REPORT) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         this._ensureNotification(); |  | ||||||
|         this._pendingMessages.push(message); |         this._pendingMessages.push(message); | ||||||
|         this.countUpdated(); |         this.countUpdated(); | ||||||
|  |  | ||||||
| @@ -545,7 +517,6 @@ const ChatSource = new Lang.Class({ | |||||||
|     // This is called for both messages we send from |     // This is called for both messages we send from | ||||||
|     // our client and other clients as well. |     // our client and other clients as well. | ||||||
|     _messageSent: function(channel, message, flags, token) { |     _messageSent: function(channel, message, flags, token) { | ||||||
|         this._ensureNotification(); |  | ||||||
|         message = makeMessageFromTpMessage(message, NotificationDirection.SENT); |         message = makeMessageFromTpMessage(message, NotificationDirection.SENT); | ||||||
|         this._notification.appendMessage(message); |         this._notification.appendMessage(message); | ||||||
|     }, |     }, | ||||||
| @@ -583,10 +554,14 @@ const ChatSource = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _presenceChanged: function (contact, presence, status, message) { |     _presenceChanged: function (contact, presence, status, message) { | ||||||
|         if (this._notification) |         let msg, title; | ||||||
|             this._notification.update(this._notification.title, |  | ||||||
|                                       this._notification.bannerBodyText, |         title = GLib.markup_escape_text(this.title, -1); | ||||||
|                                       { secondaryGIcon: this.getSecondaryIcon() }); |  | ||||||
|  |         this._notification.update(this._notification.title, null, { secondaryGIcon: this.getSecondaryIcon() }); | ||||||
|  |  | ||||||
|  |         if (message) | ||||||
|  |             msg += ' <i>(' + GLib.markup_escape_text(message, -1) + ')</i>'; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _pendingRemoved: function(channel, message) { |     _pendingRemoved: function(channel, message) { | ||||||
| @@ -596,10 +571,6 @@ const ChatSource = new Lang.Class({ | |||||||
|             this._pendingMessages.splice(idx, 1); |             this._pendingMessages.splice(idx, 1); | ||||||
|             this.countUpdated(); |             this.countUpdated(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (this._pendingMessages.length == 0 && |  | ||||||
|             this._banner && !this._banner.expanded) |  | ||||||
|             this._banner.hide(); |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _ackMessages: function() { |     _ackMessages: function() { | ||||||
| @@ -614,20 +585,43 @@ const ChatNotification = new Lang.Class({ | |||||||
|     Extends: MessageTray.Notification, |     Extends: MessageTray.Notification, | ||||||
|  |  | ||||||
|     _init: function(source) { |     _init: function(source) { | ||||||
|         this.parent(source, source.title, null, |         this.parent(source, source.title, null, { secondaryGIcon: source.getSecondaryIcon() }); | ||||||
|                     { secondaryGIcon: source.getSecondaryIcon() }); |  | ||||||
|         this.setUrgency(MessageTray.Urgency.HIGH); |  | ||||||
|         this.setResident(true); |  | ||||||
|  |  | ||||||
|         this.messages = []; |         this._responseEntry = new St.Entry({ style_class: 'chat-response', | ||||||
|         this._timestampTimeoutId = 0; |                                              can_focus: true }); | ||||||
|     }, |         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); | ||||||
|  |  | ||||||
|     destroy: function(reason) { |         this._responseEntry.clutter_text.connect('key-focus-in', Lang.bind(this, function() { | ||||||
|         if (this._timestampTimeoutId) |             this.focused = true; | ||||||
|             Mainloop.source_remove(this._timestampTimeoutId); |         })); | ||||||
|  |         this._responseEntry.clutter_text.connect('key-focus-out', Lang.bind(this, function() { | ||||||
|  |             this.focused = false; | ||||||
|  |             this.emit('unfocused'); | ||||||
|  |         })); | ||||||
|  |  | ||||||
|  |         this._lastGroup = null; | ||||||
|  |  | ||||||
|  |         this._bodyBox = new St.BoxLayout({ style_class: 'chat-notification-body-box' }); | ||||||
|  |         this._bodyBin.child = this._bodyBox; | ||||||
|  |  | ||||||
|  |         // Keep track of the bottom position for the current adjustment and | ||||||
|  |         // force a scroll to the bottom if things change while we were at the | ||||||
|  |         // bottom | ||||||
|  |         this._oldMaxScrollValue = this._bodyScrollArea.vscroll.adjustment.value; | ||||||
|  |         this._bodyScrollArea.add_style_class_name('chat-notification-scrollview'); | ||||||
|  |         this._bodyScrollArea.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 }); | ||||||
|  |  | ||||||
|  |         this._history = []; | ||||||
|         this._timestampTimeoutId = 0; |         this._timestampTimeoutId = 0; | ||||||
|         this.parent(reason); |         this._composingTimeoutId = 0; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -653,8 +647,9 @@ const ChatNotification = new Lang.Class({ | |||||||
|             styles.push('chat-action'); |             styles.push('chat-action'); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (message.direction == NotificationDirection.RECEIVED) |         if (message.direction == NotificationDirection.RECEIVED) { | ||||||
|             this.update(this.source.title, messageBody, { bannerMarkup: true }); |             this.update(this.source.title, messageBody, { bannerMarkup: true }); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         let group = (message.direction == NotificationDirection.RECEIVED ? |         let group = (message.direction == NotificationDirection.RECEIVED ? | ||||||
|                      'received' : 'sent'); |                      'received' : 'sent'); | ||||||
| @@ -667,10 +662,10 @@ const ChatNotification = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _filterMessages: function() { |     _filterMessages: function() { | ||||||
|         if (this.messages.length < 1) |         if (this._history.length < 1) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         let lastMessageTime = this.messages[0].timestamp; |         let lastMessageTime = this._history[0].time; | ||||||
|         let currentTime = (Date.now() / 1000); |         let currentTime = (Date.now() / 1000); | ||||||
|  |  | ||||||
|         // Keep the scrollback from growing too long. If the most |         // Keep the scrollback from growing too long. If the most | ||||||
| @@ -682,12 +677,19 @@ const ChatNotification = new Lang.Class({ | |||||||
|         let maxLength = (lastMessageTime < currentTime - SCROLLBACK_RECENT_TIME) ? |         let maxLength = (lastMessageTime < currentTime - SCROLLBACK_RECENT_TIME) ? | ||||||
|             SCROLLBACK_IDLE_LENGTH : SCROLLBACK_RECENT_LENGTH; |             SCROLLBACK_IDLE_LENGTH : SCROLLBACK_RECENT_LENGTH; | ||||||
|  |  | ||||||
|         let filteredHistory = this.messages.filter(function(item) { return item.realMessage }); |         let filteredHistory = this._history.filter(function(item) { return item.realMessage }); | ||||||
|         if (filteredHistory.length > maxLength) { |         if (filteredHistory.length > maxLength) { | ||||||
|             let lastMessageToKeep = filteredHistory[maxLength]; |             let lastMessageToKeep = filteredHistory[maxLength]; | ||||||
|             let expired = this.messages.splice(this.messages.indexOf(lastMessageToKeep)); |             let expired = this._history.splice(this._history.indexOf(lastMessageToKeep)); | ||||||
|             for (let i = 0; i < expired.length; i++) |             for (let i = 0; i < expired.length; i++) | ||||||
|                 this.emit('message-removed', expired[i]); |                 expired[i].actor.destroy(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         let groups = this._bodyBox.get_children(); | ||||||
|  |         for (let i = 0; i < groups.length; i++) { | ||||||
|  |             let group = groups[i]; | ||||||
|  |             if (group.get_n_children() == 0) | ||||||
|  |                 group.destroy(); | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
| @@ -700,6 +702,7 @@ const ChatNotification = new Lang.Class({ | |||||||
|      *  styles: Style class names for the message to have. |      *  styles: Style class names for the message to have. | ||||||
|      *  timestamp: The timestamp of the message. |      *  timestamp: The timestamp of the message. | ||||||
|      *  noTimestamp: suppress timestamp signal? |      *  noTimestamp: suppress timestamp signal? | ||||||
|  |      *  childProps: props to add the actor with. | ||||||
|      */ |      */ | ||||||
|     _append: function(props) { |     _append: function(props) { | ||||||
|         let currentTime = (Date.now() / 1000); |         let currentTime = (Date.now() / 1000); | ||||||
| @@ -707,23 +710,39 @@ const ChatNotification = new Lang.Class({ | |||||||
|                                       group: null, |                                       group: null, | ||||||
|                                       styles: [], |                                       styles: [], | ||||||
|                                       timestamp: currentTime, |                                       timestamp: currentTime, | ||||||
|                                       noTimestamp: false }); |                                       noTimestamp: false, | ||||||
|  |                                       childProps: null }); | ||||||
|  |  | ||||||
|         // Reset the old message timeout |         // Reset the old message timeout | ||||||
|         if (this._timestampTimeoutId) |         if (this._timestampTimeoutId) | ||||||
|             Mainloop.source_remove(this._timestampTimeoutId); |             Mainloop.source_remove(this._timestampTimeoutId); | ||||||
|         this._timestampTimeoutId = 0; |  | ||||||
|  |  | ||||||
|         let message = { realMessage: props.group != 'meta', |         let highlighter = new MessageTray.URLHighlighter(); | ||||||
|                         showTimestamp: false }; |         highlighter.actor.clutter_text.line_wrap = true; | ||||||
|         Lang.copyProperties(props, message); |         highlighter.setMarkup(props.body, true); | ||||||
|         delete message.noTimestamp; |  | ||||||
|  |  | ||||||
|         this.messages.unshift(message); |         let body = highlighter.actor; | ||||||
|         this.emit('message-added', message); |  | ||||||
|  |         let styles = props.styles; | ||||||
|  |         for (let i = 0; i < styles.length; i++) | ||||||
|  |             body.add_style_class_name(styles[i]); | ||||||
|  |  | ||||||
|  |         let group = props.group; | ||||||
|  |         if (group != this._lastGroup) { | ||||||
|  |             this._lastGroup = group; | ||||||
|  |             let emptyLine = new St.Label({ style_class: 'chat-empty-line' }); | ||||||
|  |             this._bodyBox.add_child(emptyLine); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         this._lastMessageBox = new St.BoxLayout({ vertical: false }); | ||||||
|  |         this._lastMessageBox.add(body, props.childProps); | ||||||
|  |         this._bodyBox.add_child(this._lastMessageBox); | ||||||
|  |  | ||||||
|  |         let timestamp = props.timestamp; | ||||||
|  |         this._history.unshift({ actor: body, time: timestamp, | ||||||
|  |                                 realMessage: group != 'meta' }); | ||||||
|  |  | ||||||
|         if (!props.noTimestamp) { |         if (!props.noTimestamp) { | ||||||
|             let timestamp = props.timestamp; |  | ||||||
|             if (timestamp < currentTime - SCROLLBACK_IMMEDIATE_TIME) { |             if (timestamp < currentTime - SCROLLBACK_IMMEDIATE_TIME) { | ||||||
|                 this.appendTimestamp(); |                 this.appendTimestamp(); | ||||||
|             } else { |             } else { | ||||||
| @@ -739,11 +758,101 @@ const ChatNotification = new Lang.Class({ | |||||||
|         this._filterMessages(); |         this._filterMessages(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|  |     _formatTimestamp: function(date) { | ||||||
|  |         let now = new Date(); | ||||||
|  |  | ||||||
|  |         var daysAgo = (now.getTime() - date.getTime()) / (24 * 60 * 60 * 1000); | ||||||
|  |  | ||||||
|  |         let format; | ||||||
|  |  | ||||||
|  |         let desktopSettings = new Gio.Settings({ schema: 'org.gnome.desktop.interface' }); | ||||||
|  |         let clockFormat = desktopSettings.get_string(CLOCK_FORMAT_KEY); | ||||||
|  |         let hasAmPm = date.toLocaleFormat('%p') != ''; | ||||||
|  |  | ||||||
|  |         if (clockFormat == '24h' || !hasAmPm) { | ||||||
|  |             // Show only the time if date is on today | ||||||
|  |             if(daysAgo < 1){ | ||||||
|  |                 /* Translators: Time in 24h format */ | ||||||
|  |                 format = _("%H\u2236%M"); | ||||||
|  |             } | ||||||
|  |             // Show the word "Yesterday" and time if date is on yesterday | ||||||
|  |             else if(daysAgo <2){ | ||||||
|  |                 /* Translators: this is the word "Yesterday" followed by a | ||||||
|  |                  time string in 24h format. i.e. "Yesterday, 14:30" */ | ||||||
|  |                 // xgettext:no-c-format | ||||||
|  |                 format = _("Yesterday, %H\u2236%M"); | ||||||
|  |             } | ||||||
|  |             // Show a week day and time if date is in the last week | ||||||
|  |             else if (daysAgo < 7) { | ||||||
|  |                 /* Translators: this is the week day name followed by a time | ||||||
|  |                  string in 24h format. i.e. "Monday, 14:30" */ | ||||||
|  |                 // xgettext:no-c-format | ||||||
|  |                 format = _("%A, %H\u2236%M"); | ||||||
|  |  | ||||||
|  |             } else if (date.getYear() == now.getYear()) { | ||||||
|  |                 /* Translators: this is the month name and day number | ||||||
|  |                  followed by a time string in 24h format. | ||||||
|  |                  i.e. "May 25, 14:30" */ | ||||||
|  |                 // xgettext:no-c-format | ||||||
|  |                 format = _("%B %d, %H\u2236%M"); | ||||||
|  |             } else { | ||||||
|  |                 /* Translators: this is the month name, day number, year | ||||||
|  |                  number followed by a time string in 24h format. | ||||||
|  |                  i.e. "May 25 2012, 14:30" */ | ||||||
|  |                 // xgettext:no-c-format | ||||||
|  |                 format = _("%B %d %Y, %H\u2236%M"); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             // Show only the time if date is on today | ||||||
|  |             if(daysAgo < 1){ | ||||||
|  |                 /* Translators: Time in 24h format */ | ||||||
|  |                 format = _("%l\u2236%M %p"); | ||||||
|  |             } | ||||||
|  |             // Show the word "Yesterday" and time if date is on yesterday | ||||||
|  |             else if(daysAgo <2){ | ||||||
|  |                 /* Translators: this is the word "Yesterday" followed by a | ||||||
|  |                  time string in 12h format. i.e. "Yesterday, 2:30 pm" */ | ||||||
|  |                 // xgettext:no-c-format | ||||||
|  |                 format = _("Yesterday, %l\u2236%M %p"); | ||||||
|  |             } | ||||||
|  |             // Show a week day and time if date is in the last week | ||||||
|  |             else if (daysAgo < 7) { | ||||||
|  |                 /* Translators: this is the week day name followed by a time | ||||||
|  |                  string in 12h format. i.e. "Monday, 2:30 pm" */ | ||||||
|  |                 // xgettext:no-c-format | ||||||
|  |                 format = _("%A, %l\u2236%M %p"); | ||||||
|  |  | ||||||
|  |             } else if (date.getYear() == now.getYear()) { | ||||||
|  |                 /* Translators: this is the month name and day number | ||||||
|  |                  followed by a time string in 12h format. | ||||||
|  |                  i.e. "May 25, 2:30 pm" */ | ||||||
|  |                 // xgettext:no-c-format | ||||||
|  |                 format = _("%B %d, %l\u2236%M %p"); | ||||||
|  |             } else { | ||||||
|  |                 /* Translators: this is the month name, day number, year | ||||||
|  |                  number followed by a time string in 12h format. | ||||||
|  |                  i.e. "May 25 2012, 2:30 pm"*/ | ||||||
|  |                 // xgettext:no-c-format | ||||||
|  |                 format = _("%B %d %Y, %l\u2236%M %p"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return date.toLocaleFormat(format); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|     appendTimestamp: function() { |     appendTimestamp: function() { | ||||||
|         this._timestampTimeoutId = 0; |         this._timestampTimeoutId = 0; | ||||||
|  |  | ||||||
|         this.messages[0].showTimestamp = true; |         let lastMessageTime = this._history[0].time; | ||||||
|         this.emit('timestamp-changed', this.messages[0]); |         let lastMessageDate = new Date(lastMessageTime * 1000); | ||||||
|  |  | ||||||
|  |         let timeLabel = new St.Label({ text: this._formatTimestamp(lastMessageDate), | ||||||
|  |                                        style_class: 'chat-meta-message', | ||||||
|  |                                        x_expand: true, | ||||||
|  |                                        y_expand: true, | ||||||
|  |                                        x_align: Clutter.ActorAlign.END, | ||||||
|  |                                        y_align: Clutter.ActorAlign.END }); | ||||||
|  |  | ||||||
|  |         this._lastMessageBox.add_actor(timeLabel); | ||||||
|  |  | ||||||
|         this._filterMessages(); |         this._filterMessages(); | ||||||
|  |  | ||||||
| @@ -758,154 +867,13 @@ const ChatNotification = new Lang.Class({ | |||||||
|            IM name. */ |            IM name. */ | ||||||
|         let message = '<i>' + _("%s is now known as %s").format(oldAlias, newAlias) + '</i>'; |         let message = '<i>' + _("%s is now known as %s").format(oldAlias, newAlias) + '</i>'; | ||||||
|  |  | ||||||
|         this._append({ body: message, |         let label = this._append({ body: message, | ||||||
|                                    group: 'meta', |                                    group: 'meta', | ||||||
|                                    styles: ['chat-meta-message'] }); |                                    styles: ['chat-meta-message'] }); | ||||||
|  |  | ||||||
|  |         this.update(newAlias); | ||||||
|  |  | ||||||
|         this._filterMessages(); |         this._filterMessages(); | ||||||
|     } |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| const ChatLineBox = new Lang.Class({ |  | ||||||
|     Name: 'ChatLineBox', |  | ||||||
|     Extends: St.BoxLayout, |  | ||||||
|  |  | ||||||
|     vfunc_get_preferred_height: function(forWidth) { |  | ||||||
|         let [, natHeight] = this.parent(forWidth); |  | ||||||
|         return [natHeight, natHeight]; |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| const ChatNotificationBanner = new Lang.Class({ |  | ||||||
|     Name: 'ChatNotificationBanner', |  | ||||||
|     Extends: MessageTray.NotificationBanner, |  | ||||||
|  |  | ||||||
|     _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', 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', Lang.bind(this, function() { |  | ||||||
|             this.focused = true; |  | ||||||
|         })); |  | ||||||
|         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, |  | ||||||
|                                                hscrollbar_policy: Gtk.PolicyType.NEVER, |  | ||||||
|                                                visible: this.expanded }); |  | ||||||
|         this._contentArea = new St.BoxLayout({ style_class: 'chat-body', |  | ||||||
|                                                vertical: true }); |  | ||||||
|         this._scrollArea.add_actor(this._contentArea); |  | ||||||
|  |  | ||||||
|         this.setExpandedBody(this._scrollArea); |  | ||||||
|         this.setExpandedLines(CHAT_EXPAND_LINES); |  | ||||||
|  |  | ||||||
|         this._lastGroup = null; |  | ||||||
|  |  | ||||||
|         // Keep track of the bottom position for the current adjustment and |  | ||||||
|         // 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', 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 }); |  | ||||||
|  |  | ||||||
|         this._composingTimeoutId = 0; |  | ||||||
|  |  | ||||||
|         this._messageActors = new Map(); |  | ||||||
|  |  | ||||||
|         this._messageAddedId = this.notification.connect('message-added', |  | ||||||
|             Lang.bind(this, function(n, message) { |  | ||||||
|                 this._addMessage(message); |  | ||||||
|             })); |  | ||||||
|         this._messageRemovedId = this.notification.connect('message-removed', |  | ||||||
|             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', |  | ||||||
|             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: function() { |  | ||||||
|         this.parent(); |  | ||||||
|         this.notification.disconnect(this._messageAddedId); |  | ||||||
|         this.notification.disconnect(this._messageRemovedId); |  | ||||||
|         this.notification.disconnect(this._timestampChangedId); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     scrollTo: function(side) { |  | ||||||
|         let adjustment = this._scrollArea.vscroll.adjustment; |  | ||||||
|         if (side == St.Side.TOP) |  | ||||||
|             adjustment.value = adjustment.lower; |  | ||||||
|         else if (side == St.Side.BOTTOM) |  | ||||||
|             adjustment.value = adjustment.upper; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     hide: function() { |  | ||||||
|         this.emit('done-displaying'); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _addMessage: function(message) { |  | ||||||
|         let highlighter = new Calendar.URLHighlighter(message.body, true, true); |  | ||||||
|         let body = highlighter.actor; |  | ||||||
|  |  | ||||||
|         let styles = message.styles; |  | ||||||
|         for (let i = 0; i < styles.length; i++) |  | ||||||
|             body.add_style_class_name(styles[i]); |  | ||||||
|  |  | ||||||
|         let group = message.group; |  | ||||||
|         if (group != this._lastGroup) { |  | ||||||
|             this._lastGroup = group; |  | ||||||
|             body.add_style_class_name('chat-new-group'); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         let lineBox = new ChatLineBox(); |  | ||||||
|         lineBox.add(body); |  | ||||||
|         this._contentArea.add_actor(lineBox); |  | ||||||
|         this._messageActors.set(message, lineBox); |  | ||||||
|  |  | ||||||
|         this._updateTimestamp(message); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _updateTimestamp: function(message) { |  | ||||||
|         let actor = this._messageActors.get(message); |  | ||||||
|         if (!actor) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         while (actor.get_n_children() > 1) |  | ||||||
|             actor.get_child_at_index(1).destroy(); |  | ||||||
|  |  | ||||||
|         if (message.showTimestamp) { |  | ||||||
|             let lastMessageTime = message.timestamp; |  | ||||||
|             let lastMessageDate = new Date(lastMessageTime * 1000); |  | ||||||
|  |  | ||||||
|             let timeLabel = Util.createTimeLabel(lastMessageDate); |  | ||||||
|             timeLabel.style_class = 'chat-meta-message'; |  | ||||||
|             timeLabel.x_expand = timeLabel.y_expand = true; |  | ||||||
|             timeLabel.x_align = timeLabel.y_align = Clutter.ActorAlign.END; |  | ||||||
|  |  | ||||||
|             actor.add_actor(timeLabel); |  | ||||||
|         } |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onEntryActivated: function() { |     _onEntryActivated: function() { | ||||||
| @@ -918,13 +886,13 @@ const ChatNotificationBanner = new Lang.Class({ | |||||||
|         // Telepathy sends out the Sent signal for us. |         // Telepathy sends out the Sent signal for us. | ||||||
|         // see Source._messageSent |         // see Source._messageSent | ||||||
|         this._responseEntry.set_text(''); |         this._responseEntry.set_text(''); | ||||||
|         this.notification.source.respond(text); |         this.source.respond(text); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _composingStopTimeout: function() { |     _composingStopTimeout: function() { | ||||||
|         this._composingTimeoutId = 0; |         this._composingTimeoutId = 0; | ||||||
|  |  | ||||||
|         this.notification.source.setChatState(Tp.ChannelChatState.PAUSED); |         this.source.setChatState(Tp.ChannelChatState.PAUSED); | ||||||
|  |  | ||||||
|         return GLib.SOURCE_REMOVE; |         return GLib.SOURCE_REMOVE; | ||||||
|     }, |     }, | ||||||
| @@ -944,14 +912,14 @@ const ChatNotificationBanner = new Lang.Class({ | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (text != '') { |         if (text != '') { | ||||||
|             this.notification.source.setChatState(Tp.ChannelChatState.COMPOSING); |             this.source.setChatState(Tp.ChannelChatState.COMPOSING); | ||||||
|  |  | ||||||
|             this._composingTimeoutId = Mainloop.timeout_add_seconds( |             this._composingTimeoutId = Mainloop.timeout_add_seconds( | ||||||
|                 COMPOSING_STOP_TIMEOUT, |                 COMPOSING_STOP_TIMEOUT, | ||||||
|                 Lang.bind(this, this._composingStopTimeout)); |                 Lang.bind(this, this._composingStopTimeout)); | ||||||
|             GLib.Source.set_name_by_id(this._composingTimeoutId, '[gnome-shell] this._composingStopTimeout'); |             GLib.Source.set_name_by_id(this._composingTimeoutId, '[gnome-shell] this._composingStopTimeout'); | ||||||
|         } else { |         } else { | ||||||
|             this.notification.source.setChatState(Tp.ChannelChatState.ACTIVE); |             this.source.setChatState(Tp.ChannelChatState.ACTIVE); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ const CtrlAltTabManager = new Lang.Class({ | |||||||
|     _init: function() { |     _init: function() { | ||||||
|         this._items = []; |         this._items = []; | ||||||
|         this.addGroup(global.window_group, _("Windows"), |         this.addGroup(global.window_group, _("Windows"), | ||||||
|                       'focus-windows-symbolic', { sortGroup: SortGroup.TOP, |                       'emblem-documents-symbolic', { sortGroup: SortGroup.TOP, | ||||||
|                                                      focusCallback: Lang.bind(this, this._focusWindows) }); |                                                      focusCallback: Lang.bind(this, this._focusWindows) }); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
| @@ -100,7 +100,7 @@ const CtrlAltTabManager = new Lang.Class({ | |||||||
|                     if (app) |                     if (app) | ||||||
|                         icon = app.create_icon_texture(POPUP_APPICON_SIZE); |                         icon = app.create_icon_texture(POPUP_APPICON_SIZE); | ||||||
|                     else |                     else | ||||||
|                         icon = textureCache.bind_cairo_surface_property(windows[i], 'icon'); |                         icon = textureCache.bind_pixbuf_property(windows[i], 'icon'); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 items.push({ name: windows[i].title, |                 items.push({ name: windows[i].title, | ||||||
| @@ -140,17 +140,27 @@ const CtrlAltTabPopup = new Lang.Class({ | |||||||
|     Name: 'CtrlAltTabPopup', |     Name: 'CtrlAltTabPopup', | ||||||
|     Extends: SwitcherPopup.SwitcherPopup, |     Extends: SwitcherPopup.SwitcherPopup, | ||||||
|  |  | ||||||
|     _init: function(items) { |     _createSwitcher: function() { | ||||||
|         this.parent(items); |  | ||||||
|  |  | ||||||
|         this._switcherList = new CtrlAltTabSwitcher(this._items); |         this._switcherList = new CtrlAltTabSwitcher(this._items); | ||||||
|  |         return true; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _keyPressHandler: function(keysym, action) { |     _initialSelection: function(backward, binding) { | ||||||
|  |         if (binding == 'switch-panels') { | ||||||
|  |             if (backward) | ||||||
|  |                 this._selectedIndex = this._items.length - 1; | ||||||
|  |         } else if (binding == 'switch-panels-backward') { | ||||||
|  |             if (!backward) | ||||||
|  |                 this._selectedIndex = this._items.length - 1; | ||||||
|  |         } | ||||||
|  |         this._select(this._selectedIndex); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _keyPressHandler: function(keysym, backwards, action) { | ||||||
|         if (action == Meta.KeyBindingAction.SWITCH_PANELS) |         if (action == Meta.KeyBindingAction.SWITCH_PANELS) | ||||||
|             this._select(this._next()); |             this._select(backwards ? this._previous() : this._next()); | ||||||
|         else if (action == Meta.KeyBindingAction.SWITCH_PANELS_BACKWARD) |         else if (action == Meta.KeyBindingAction.SWITCH_PANELS_BACKWARD) | ||||||
|             this._select(this._previous()); |             this._select(backwards ? this._next() : this._previous()); | ||||||
|         else if (keysym == Clutter.Left) |         else if (keysym == Clutter.Left) | ||||||
|             this._select(this._previous()); |             this._select(this._previous()); | ||||||
|         else if (keysym == Clutter.Right) |         else if (keysym == Clutter.Right) | ||||||
|   | |||||||
| @@ -1,7 +1,6 @@ | |||||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||||
|  |  | ||||||
| const Clutter = imports.gi.Clutter; | const Clutter = imports.gi.Clutter; | ||||||
| const Gio = imports.gi.Gio; |  | ||||||
| const GLib = imports.gi.GLib; | const GLib = imports.gi.GLib; | ||||||
| const Signals = imports.signals; | const Signals = imports.signals; | ||||||
| const Lang = imports.lang; | const Lang = imports.lang; | ||||||
| @@ -270,9 +269,6 @@ const ShowAppsIcon = new Lang.Class({ | |||||||
|         if (app == null) |         if (app == null) | ||||||
|             return false; |             return false; | ||||||
|  |  | ||||||
|         if (!global.settings.is_writable('favorite-apps')) |  | ||||||
|             return false; |  | ||||||
|  |  | ||||||
|         let id = app.get_id(); |         let id = app.get_id(); | ||||||
|         let isFavorite = AppFavorites.getAppFavorites().isFavorite(id); |         let isFavorite = AppFavorites.getAppFavorites().isFavorite(id); | ||||||
|         return isFavorite; |         return isFavorite; | ||||||
| @@ -517,13 +513,10 @@ const Dash = new Lang.Class({ | |||||||
|             this._syncLabel(item, appIcon); |             this._syncLabel(item, appIcon); | ||||||
|         })); |         })); | ||||||
|  |  | ||||||
|         let id = Main.overview.connect('hiding', Lang.bind(this, function() { |         Main.overview.connect('hiding', Lang.bind(this, function() { | ||||||
|             this._labelShowing = false; |             this._labelShowing = false; | ||||||
|             item.hideLabel(); |             item.hideLabel(); | ||||||
|         })); |         })); | ||||||
|         item.child.connect('destroy', function() { |  | ||||||
|             Main.overview.disconnect(id); |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         if (appIcon) { |         if (appIcon) { | ||||||
|             appIcon.connect('sync-tooltip', Lang.bind(this, function() { |             appIcon.connect('sync-tooltip', Lang.bind(this, function() { | ||||||
| @@ -536,7 +529,6 @@ const Dash = new Lang.Class({ | |||||||
|         let appIcon = new AppDisplay.AppIcon(app, |         let appIcon = new AppDisplay.AppIcon(app, | ||||||
|                                              { setSizeManually: true, |                                              { setSizeManually: true, | ||||||
|                                                showLabel: false }); |                                                showLabel: false }); | ||||||
|         if (appIcon._draggable) { |  | ||||||
|         appIcon._draggable.connect('drag-begin', |         appIcon._draggable.connect('drag-begin', | ||||||
|                                    Lang.bind(this, function() { |                                    Lang.bind(this, function() { | ||||||
|                                        appIcon.actor.opacity = 50; |                                        appIcon.actor.opacity = 50; | ||||||
| @@ -545,8 +537,6 @@ const Dash = new Lang.Class({ | |||||||
|                                    Lang.bind(this, function() { |                                    Lang.bind(this, function() { | ||||||
|                                        appIcon.actor.opacity = 255; |                                        appIcon.actor.opacity = 255; | ||||||
|                                    })); |                                    })); | ||||||
|         } |  | ||||||
|  |  | ||||||
|         appIcon.connect('menu-state-changed', |         appIcon.connect('menu-state-changed', | ||||||
|                         Lang.bind(this, function(appIcon, opened) { |                         Lang.bind(this, function(appIcon, opened) { | ||||||
|                             this._itemMenuStateChanged(item, opened); |                             this._itemMenuStateChanged(item, opened); | ||||||
| @@ -644,14 +634,15 @@ const Dash = new Lang.Class({ | |||||||
|         let firstIcon = firstButton._delegate.icon; |         let firstIcon = firstButton._delegate.icon; | ||||||
|  |  | ||||||
|         let minHeight, natHeight; |         let minHeight, natHeight; | ||||||
|         let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; |  | ||||||
|  |  | ||||||
|         // Enforce the current icon size during the size request |         // Enforce the current icon size during the size request | ||||||
|         firstIcon.icon.ensure_style(); |         firstIcon.setIconSize(this.iconSize); | ||||||
|         let [currentWidth, currentHeight] = firstIcon.icon.get_size(); |  | ||||||
|         firstIcon.icon.set_size(this.iconSize * scaleFactor, this.iconSize * scaleFactor); |  | ||||||
|         [minHeight, natHeight] = firstButton.get_preferred_height(-1); |         [minHeight, natHeight] = firstButton.get_preferred_height(-1); | ||||||
|         firstIcon.icon.set_size(currentWidth, currentHeight); |  | ||||||
|  |         let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; | ||||||
|  |         let iconSizes = baseIconSizes.map(function(s) { | ||||||
|  |             return s * scaleFactor; | ||||||
|  |         }); | ||||||
|  |  | ||||||
|         // Subtract icon padding and box spacing from the available height |         // Subtract icon padding and box spacing from the available height | ||||||
|         availHeight -= iconChildren.length * (natHeight - this.iconSize * scaleFactor) + |         availHeight -= iconChildren.length * (natHeight - this.iconSize * scaleFactor) + | ||||||
| @@ -659,10 +650,6 @@ const Dash = new Lang.Class({ | |||||||
|  |  | ||||||
|         let availSize = availHeight / iconChildren.length; |         let availSize = availHeight / iconChildren.length; | ||||||
|  |  | ||||||
|         let iconSizes = baseIconSizes.map(function(s) { |  | ||||||
|             return s * scaleFactor; |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         let newIconSize = baseIconSizes[0]; |         let newIconSize = baseIconSizes[0]; | ||||||
|         for (let i = 0; i < iconSizes.length; i++) { |         for (let i = 0; i < iconSizes.length; i++) { | ||||||
|             if (iconSizes[i] < availSize) |             if (iconSizes[i] < availSize) | ||||||
| @@ -863,9 +850,6 @@ const Dash = new Lang.Class({ | |||||||
|         if (app == null || app.is_window_backed()) |         if (app == null || app.is_window_backed()) | ||||||
|             return DND.DragMotionResult.NO_DROP; |             return DND.DragMotionResult.NO_DROP; | ||||||
|  |  | ||||||
|         if (!global.settings.is_writable('favorite-apps')) |  | ||||||
|             return DND.DragMotionResult.NO_DROP; |  | ||||||
|  |  | ||||||
|         let favorites = AppFavorites.getAppFavorites().getFavorites(); |         let favorites = AppFavorites.getAppFavorites().getFavorites(); | ||||||
|         let numFavorites = favorites.length; |         let numFavorites = favorites.length; | ||||||
|  |  | ||||||
| @@ -942,9 +926,6 @@ const Dash = new Lang.Class({ | |||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!global.settings.is_writable('favorite-apps')) |  | ||||||
|             return false; |  | ||||||
|  |  | ||||||
|         let id = app.get_id(); |         let id = app.get_id(); | ||||||
|  |  | ||||||
|         let favorites = AppFavorites.getAppFavorites().getFavoriteMap(); |         let favorites = AppFavorites.getAppFavorites().getFavoriteMap(); | ||||||
|   | |||||||
| @@ -3,9 +3,6 @@ | |||||||
| const GLib = imports.gi.GLib; | const GLib = imports.gi.GLib; | ||||||
| const Gio = imports.gi.Gio; | const Gio = imports.gi.Gio; | ||||||
| const GnomeDesktop = imports.gi.GnomeDesktop; | const GnomeDesktop = imports.gi.GnomeDesktop; | ||||||
| const GObject = imports.gi.GObject; |  | ||||||
| const Gtk = imports.gi.Gtk; |  | ||||||
| const GWeather = imports.gi.GWeather; |  | ||||||
| const Lang = imports.lang; | const Lang = imports.lang; | ||||||
| const Mainloop = imports.mainloop; | const Mainloop = imports.mainloop; | ||||||
| const Cairo = imports.cairo; | const Cairo = imports.cairo; | ||||||
| @@ -21,292 +18,22 @@ const PanelMenu = imports.ui.panelMenu; | |||||||
| const PopupMenu = imports.ui.popupMenu; | const PopupMenu = imports.ui.popupMenu; | ||||||
| const Calendar = imports.ui.calendar; | const Calendar = imports.ui.calendar; | ||||||
|  |  | ||||||
| function _isToday(date) { | function _onVertSepRepaint (area) | ||||||
|     let now = new Date(); | { | ||||||
|     return now.getYear() == date.getYear() && |     let cr = area.get_context(); | ||||||
|            now.getMonth() == date.getMonth() && |     let themeNode = area.get_theme_node(); | ||||||
|            now.getDate() == date.getDate(); |     let [width, height] = area.get_surface_size(); | ||||||
| } |     let stippleColor = themeNode.get_color('-stipple-color'); | ||||||
|  |     let stippleWidth = themeNode.get_length('-stipple-width'); | ||||||
| const TodayButton = new Lang.Class({ |     let x = Math.floor(width/2) + 0.5; | ||||||
|     Name: 'TodayButton', |     cr.moveTo(x, 0); | ||||||
|  |     cr.lineTo(x, height); | ||||||
|     _init: function(calendar) { |     Clutter.cairo_set_source_color(cr, stippleColor); | ||||||
|         // Having the ability to go to the current date if the user is already |     cr.setDash([1, 3], 1); // Hard-code for now | ||||||
|         // on the current date can be confusing. So don't make the button reactive |     cr.setLineWidth(stippleWidth); | ||||||
|         // until the selected date changes. |     cr.stroke(); | ||||||
|         this.actor = new St.Button({ style_class: 'datemenu-today-button', |     cr.$dispose(); | ||||||
|                                      x_align: St.Align.START, | }; | ||||||
|                                      can_focus: true, |  | ||||||
|                                      reactive: 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); |  | ||||||
|  |  | ||||||
|         this._dayLabel = new St.Label({ style_class: 'day-label', |  | ||||||
|                                         x_align: Clutter.ActorAlign.START }); |  | ||||||
|         hbox.add_actor(this._dayLabel); |  | ||||||
|  |  | ||||||
|         this._dateLabel = new St.Label({ style_class: 'date-label' }); |  | ||||||
|         hbox.add_actor(this._dateLabel); |  | ||||||
|  |  | ||||||
|         this._calendar = calendar; |  | ||||||
|         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: function(date) { |  | ||||||
|         this._dayLabel.set_text(date.toLocaleFormat('%A')); |  | ||||||
|  |  | ||||||
|         /* Translators: This is the date format to use when the calendar popup is |  | ||||||
|          * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM"). |  | ||||||
|          */ |  | ||||||
|         let dateFormat = Shell.util_translate_time_string (N_("%B %e %Y")); |  | ||||||
|         this._dateLabel.set_text(date.toLocaleFormat(dateFormat)); |  | ||||||
|  |  | ||||||
|         /* Translators: This is the accessible name of the date button shown |  | ||||||
|          * below the time in the shell; it should combine the weekday and the |  | ||||||
|          * date, e.g. "Tuesday February 17 2015". |  | ||||||
|          */ |  | ||||||
|         let dateFormat = Shell.util_translate_time_string (N_("%A %B %e %Y")); |  | ||||||
|         this.actor.accessible_name = date.toLocaleFormat(dateFormat); |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| const WorldClocksSection = new Lang.Class({ |  | ||||||
|     Name: 'WorldClocksSection', |  | ||||||
|  |  | ||||||
|     _init: function() { |  | ||||||
|         this._clock = new GnomeDesktop.WallClock(); |  | ||||||
|         this._settings = null; |  | ||||||
|         this._clockNotifyId = 0; |  | ||||||
|         this._changedId = 0; |  | ||||||
|  |  | ||||||
|         this._locations = []; |  | ||||||
|  |  | ||||||
|         this.actor = new St.Button({ style_class: 'world-clocks-button', |  | ||||||
|                                      x_fill: true, |  | ||||||
|                                      can_focus: true }); |  | ||||||
|         this.actor.connect('clicked', Lang.bind(this, |  | ||||||
|             function() { |  | ||||||
|                 let app = this._getClockApp(); |  | ||||||
|                 app.activate(); |  | ||||||
|  |  | ||||||
|                 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', |  | ||||||
|                                      layout_manager: layout }); |  | ||||||
|         layout.hookup_style(this._grid); |  | ||||||
|  |  | ||||||
|         this.actor.child = this._grid; |  | ||||||
|  |  | ||||||
|         Shell.AppSystem.get_default().connect('installed-changed', |  | ||||||
|                                               Lang.bind(this, this._sync)); |  | ||||||
|         this._sync(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _getClockApp: function() { |  | ||||||
|         return Shell.AppSystem.get_default().lookup_app('org.gnome.clocks.desktop'); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _sync: function() { |  | ||||||
|         this.actor.visible = (this._getClockApp() != null); |  | ||||||
|  |  | ||||||
|         if (this.actor.visible) { |  | ||||||
|             if (!this._settings) { |  | ||||||
|                 this._settings = new Gio.Settings({ schema_id: 'org.gnome.clocks' }); |  | ||||||
|                 this._changedId = |  | ||||||
|                     this._settings.connect('changed::world-clocks', |  | ||||||
|                                            Lang.bind(this, this._clocksChanged)); |  | ||||||
|                 this._clocksChanged(); |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             if (this._settings) |  | ||||||
|                 this._settings.disconnect(this._changedId); |  | ||||||
|             this._settings = null; |  | ||||||
|             this._changedId = 0; |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _clocksChanged: function() { |  | ||||||
|         this._grid.destroy_all_children(); |  | ||||||
|         this._locations = []; |  | ||||||
|  |  | ||||||
|         let world = GWeather.Location.get_world(); |  | ||||||
|         let clocks = this._settings.get_value('world-clocks').deep_unpack(); |  | ||||||
|         for (let i = 0; i < clocks.length; i++) { |  | ||||||
|             let l = world.deserialize(clocks[i].location); |  | ||||||
|             this._locations.push({ location: l }); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this._locations.sort(function(a, b) { |  | ||||||
|             return a.location.get_timezone().get_offset() - |  | ||||||
|                    b.location.get_timezone().get_offset(); |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         let layout = this._grid.layout_manager; |  | ||||||
|         let title = (this._locations.length == 0) ? _("Add world clocks…") |  | ||||||
|                                                   : _("World Clocks"); |  | ||||||
|         let header = new St.Label({ style_class: 'world-clocks-header', |  | ||||||
|                                     x_align: Clutter.ActorAlign.START, |  | ||||||
|                                     text: title }); |  | ||||||
|         layout.attach(header, 0, 0, 2, 1); |  | ||||||
|         this.actor.label_actor = header; |  | ||||||
|  |  | ||||||
|         for (let i = 0; i < this._locations.length; i++) { |  | ||||||
|             let l = this._locations[i].location; |  | ||||||
|  |  | ||||||
|             let label = new St.Label({ style_class: 'world-clocks-city', |  | ||||||
|                                        text: l.get_city_name(), |  | ||||||
|                                        x_align: Clutter.ActorAlign.START, |  | ||||||
|                                        x_expand: true }); |  | ||||||
|  |  | ||||||
|             let time = new St.Label({ style_class: 'world-clocks-time', |  | ||||||
|                                       x_align: Clutter.ActorAlign.END, |  | ||||||
|                                       x_expand: true }); |  | ||||||
|  |  | ||||||
|             if (this._grid.text_direction == Clutter.TextDirection.RTL) { |  | ||||||
|                 layout.attach(time, 0, i + 1, 1, 1); |  | ||||||
|                 layout.attach(label, 1, i + 1, 1, 1); |  | ||||||
|             } else { |  | ||||||
|                 layout.attach(label, 0, i + 1, 1, 1); |  | ||||||
|                 layout.attach(time, 1, i + 1, 1, 1); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             this._locations[i].actor = time; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (this._grid.get_n_children() > 1) { |  | ||||||
|             if (!this._clockNotifyId) |  | ||||||
|                 this._clockNotifyId = |  | ||||||
|                     this._clock.connect('notify::clock', Lang.bind(this, this._updateLabels)); |  | ||||||
|             this._updateLabels(); |  | ||||||
|         } else { |  | ||||||
|             if (this._clockNotifyId) |  | ||||||
|                 this._clock.disconnect(this._clockNotifyId); |  | ||||||
|             this._clockNotifyId = 0; |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _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()); |  | ||||||
|             let now = GLib.DateTime.new_now(tz); |  | ||||||
|             l.actor.text = Util.formatTime(now, { timeOnly: true }); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| const MessagesIndicator = new Lang.Class({ |  | ||||||
|     Name: 'MessagesIndicator', |  | ||||||
|  |  | ||||||
|     _init: function() { |  | ||||||
|         this.actor = new St.Label({ text: '⚫', visible: false, y_expand: true, |  | ||||||
|                                     y_align: Clutter.ActorAlign.CENTER }); |  | ||||||
|  |  | ||||||
|         this._sources = []; |  | ||||||
|  |  | ||||||
|         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(Lang.bind(this, function(source) { this._onSourceAdded(null, source); })); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _onSourceAdded: function(tray, source) { |  | ||||||
|         source.connect('count-updated', Lang.bind(this, this._updateCount)); |  | ||||||
|         this._sources.push(source); |  | ||||||
|         this._updateCount(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _onSourceRemoved: function(tray, source) { |  | ||||||
|         this._sources.splice(this._sources.indexOf(source), 1); |  | ||||||
|         this._updateCount(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _updateCount: function() { |  | ||||||
|         let count = 0; |  | ||||||
|         this._sources.forEach(Lang.bind(this, |  | ||||||
|             function(source) { |  | ||||||
|                 count += source.unseenCount; |  | ||||||
|             })); |  | ||||||
|         count -= Main.messageTray.queueCount; |  | ||||||
|  |  | ||||||
|         this.actor.visible = (count > 0); |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| const IndicatorPad = new Lang.Class({ |  | ||||||
|     Name: 'IndicatorPad', |  | ||||||
|     Extends: St.Widget, |  | ||||||
|  |  | ||||||
|     _init: function(actor) { |  | ||||||
|         this._source = actor; |  | ||||||
|         this._source.connect('notify::visible', |  | ||||||
|                              Lang.bind(this, this.queue_relayout)); |  | ||||||
|         this.parent(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     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: function(container, forWidth) { |  | ||||||
|         if (this._source.visible) |  | ||||||
|             return this._source.get_preferred_height(forWidth); |  | ||||||
|         return [0, 0]; |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| const FreezableBinLayout = new Lang.Class({ |  | ||||||
|     Name: 'FreezableBinLayout', |  | ||||||
|     Extends: Clutter.BinLayout, |  | ||||||
|  |  | ||||||
|     _init: function() { |  | ||||||
|         this.parent(); |  | ||||||
|  |  | ||||||
|         this._frozen = false; |  | ||||||
|         this._savedWidth = [NaN, NaN]; |  | ||||||
|         this._savedHeight = [NaN, NaN]; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     set frozen(v) { |  | ||||||
|         if (this._frozen == v) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         this._frozen = v; |  | ||||||
|         if (!this._frozen) |  | ||||||
|             this.layout_changed(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     vfunc_get_preferred_width: function(container, forHeight) { |  | ||||||
|         if (!this._frozen || this._savedWidth.some(isNaN)) |  | ||||||
|             this._savedWidth = this.parent(container, forHeight); |  | ||||||
|         return this._savedWidth; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     vfunc_get_preferred_height: function(container, forWidth) { |  | ||||||
|         if (!this._frozen || this._savedHeight.some(isNaN)) |  | ||||||
|             this._savedHeight = this.parent(container, forWidth); |  | ||||||
|         return this._savedHeight; |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| const DateMenuButton = new Lang.Class({ | const DateMenuButton = new Lang.Class({ | ||||||
|     Name: 'DateMenuButton', |     Name: 'DateMenuButton', | ||||||
| @@ -317,87 +44,128 @@ const DateMenuButton = new Lang.Class({ | |||||||
|         let hbox; |         let hbox; | ||||||
|         let vbox; |         let vbox; | ||||||
|  |  | ||||||
|         let menuAlignment = 0.5; |         let menuAlignment = 0.25; | ||||||
|         if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) |         if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) | ||||||
|             menuAlignment = 1.0 - menuAlignment; |             menuAlignment = 1.0 - menuAlignment; | ||||||
|         this.parent(menuAlignment); |         this.parent(menuAlignment); | ||||||
|  |  | ||||||
|         this._clockDisplay = new St.Label({ y_align: Clutter.ActorAlign.CENTER }); |         this._clockDisplay = new St.Label({ y_align: Clutter.ActorAlign.CENTER }); | ||||||
|         this._indicator = new MessagesIndicator(); |  | ||||||
|  |  | ||||||
|         let box = new St.BoxLayout(); |  | ||||||
|         box.add_actor(new IndicatorPad(this._indicator.actor)); |  | ||||||
|         box.add_actor(this._clockDisplay); |  | ||||||
|         box.add_actor(this._indicator.actor); |  | ||||||
|  |  | ||||||
|         this.actor.label_actor = this._clockDisplay; |         this.actor.label_actor = this._clockDisplay; | ||||||
|         this.actor.add_actor(box); |         this.actor.add_actor(this._clockDisplay); | ||||||
|         this.actor.add_style_class_name ('clock-display'); |         this.actor.add_style_class_name ('clock-display'); | ||||||
|  |  | ||||||
|  |  | ||||||
|         let layout = new FreezableBinLayout(); |  | ||||||
|         let bin = new St.Widget({ layout_manager: layout }); |  | ||||||
|         this.menu.box.add_child(bin); |  | ||||||
|  |  | ||||||
|         hbox = new St.BoxLayout({ name: 'calendarArea' }); |         hbox = new St.BoxLayout({ name: 'calendarArea' }); | ||||||
|         bin.add_actor(hbox); |         this.menu.box.add_child(hbox); | ||||||
|  |  | ||||||
|  |         // Fill up the first column | ||||||
|  |  | ||||||
|  |         vbox = new St.BoxLayout({vertical: true}); | ||||||
|  |         hbox.add(vbox); | ||||||
|  |  | ||||||
|  |         // Date | ||||||
|  |         // 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. | ||||||
|  |         this._date = new St.Button({ style_class: 'datemenu-date-label', | ||||||
|  |                                      reactive: false | ||||||
|  |                                    }); | ||||||
|  |         this._date.connect('clicked', | ||||||
|  |                            Lang.bind(this, function() { | ||||||
|  |                                this._calendar.setDate(new Date(), false); | ||||||
|  |                            })); | ||||||
|  |         vbox.add(this._date, { x_fill: false  }); | ||||||
|  |  | ||||||
|  |         this._eventList = new Calendar.EventsList(); | ||||||
|         this._calendar = new Calendar.Calendar(); |         this._calendar = new Calendar.Calendar(); | ||||||
|  |  | ||||||
|         this._calendar.connect('selected-date-changed', |         this._calendar.connect('selected-date-changed', | ||||||
|                                Lang.bind(this, function(calendar, date) { |                                Lang.bind(this, function(calendar, date) { | ||||||
|                                    layout.frozen = !_isToday(date); |                                   // we know this._eventList is defined here, because selected-data-changed | ||||||
|                                    this._messageList.setDate(date); |                                   // only gets emitted when the user clicks a date in the calendar, | ||||||
|                                })); |                                   // and the calender makes those dates unclickable when instantiated with | ||||||
|  |                                   // a null event source | ||||||
|  |                                    this._eventList.setDate(date); | ||||||
|  |  | ||||||
|  |                                    // Make the button reactive only if the selected date is not the current date. | ||||||
|  |                                    this._date.can_focus = this._date.reactive = !this._isToday(date) | ||||||
|  |                                })); | ||||||
|  |         vbox.add(this._calendar.actor); | ||||||
|  |  | ||||||
|  |         let separator = new PopupMenu.PopupSeparatorMenuItem(); | ||||||
|  |         vbox.add(separator.actor, { y_align: St.Align.END, expand: true, y_fill: false }); | ||||||
|  |  | ||||||
|  |         this._openCalendarItem = new PopupMenu.PopupMenuItem(_("Open Calendar")); | ||||||
|  |         this._openCalendarItem.connect('activate', Lang.bind(this, this._onOpenCalendarActivate)); | ||||||
|  |         vbox.add(this._openCalendarItem.actor, {y_align: St.Align.END, expand: true, y_fill: false}); | ||||||
|  |  | ||||||
|  |         this._openClocksItem = new PopupMenu.PopupMenuItem(_("Open Clocks")); | ||||||
|  |         this._openClocksItem.connect('activate', Lang.bind(this, this._onOpenClocksActivate)); | ||||||
|  |         vbox.add(this._openClocksItem.actor, {y_align: St.Align.END, expand: true, y_fill: false}); | ||||||
|  |  | ||||||
|  |         Shell.AppSystem.get_default().connect('installed-changed', | ||||||
|  |                                               Lang.bind(this, this._appInstalledChanged)); | ||||||
|  |  | ||||||
|  |         item = this.menu.addSettingsAction(_("Date & Time Settings"), 'gnome-datetime-panel.desktop'); | ||||||
|  |         if (item) { | ||||||
|  |             item.actor.show_on_set_parent = false; | ||||||
|  |             item.actor.reparent(vbox); | ||||||
|  |             this._dateAndTimeSeparator = separator; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         this._separator = new St.DrawingArea({ style_class: 'calendar-vertical-separator', | ||||||
|  |                                                pseudo_class: 'highlighted' }); | ||||||
|  |         this._separator.connect('repaint', Lang.bind(this, _onVertSepRepaint)); | ||||||
|  |         hbox.add(this._separator); | ||||||
|  |  | ||||||
|  |         // Fill up the second column | ||||||
|  |         hbox.add(this._eventList.actor, { expand: true, y_fill: false, y_align: St.Align.START }); | ||||||
|  |  | ||||||
|         this.menu.connect('open-state-changed', Lang.bind(this, function(menu, isOpen) { |  | ||||||
|         // Whenever the menu is opened, select today |         // Whenever the menu is opened, select today | ||||||
|  |         this.menu.connect('open-state-changed', Lang.bind(this, function(menu, isOpen) { | ||||||
|             if (isOpen) { |             if (isOpen) { | ||||||
|                 let now = new Date(); |                 let now = new Date(); | ||||||
|                 this._calendar.setDate(now); |                 this._calendar.setDate(now); | ||||||
|                 this._date.setDate(now); |  | ||||||
|                 this._messageList.setDate(now); |  | ||||||
|             } |             } | ||||||
|         })); |         })); | ||||||
|  |  | ||||||
|         // Fill up the first column |  | ||||||
|         this._messageList = new Calendar.MessageList(); |  | ||||||
|         hbox.add(this._messageList.actor, { expand: true, y_fill: false, y_align: St.Align.START }); |  | ||||||
|  |  | ||||||
|         // Fill up the second column |  | ||||||
|         vbox = new St.BoxLayout({ style_class: 'datemenu-calendar-column', |  | ||||||
|                                   vertical: true }); |  | ||||||
|         hbox.add(vbox); |  | ||||||
|  |  | ||||||
|         this._date = new TodayButton(this._calendar); |  | ||||||
|         vbox.add_actor(this._date.actor); |  | ||||||
|  |  | ||||||
|         vbox.add(this._calendar.actor); |  | ||||||
|  |  | ||||||
|         this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade', |  | ||||||
|                                                     x_expand: true, x_fill: true, |  | ||||||
|                                                     overlay_scrollbars: true }); |  | ||||||
|         this._displaysSection.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC); |  | ||||||
|         vbox.add_actor(this._displaysSection); |  | ||||||
|  |  | ||||||
|         let displaysBox = new St.BoxLayout({ vertical: true, |  | ||||||
|                                              style_class: 'datemenu-displays-box' }); |  | ||||||
|         this._displaysSection.add_actor(displaysBox); |  | ||||||
|  |  | ||||||
|         this._clocksItem = new WorldClocksSection(); |  | ||||||
|         displaysBox.add(this._clocksItem.actor, { x_fill: true }); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|         // Done with hbox for calendar and event list |         // Done with hbox for calendar and event list | ||||||
|  |  | ||||||
|         this._clock = new GnomeDesktop.WallClock(); |         this._clock = new GnomeDesktop.WallClock(); | ||||||
|         this._clock.bind_property('clock', this._clockDisplay, 'text', GObject.BindingFlags.SYNC_CREATE); |         this._clock.connect('notify::clock', Lang.bind(this, this._updateClockAndDate)); | ||||||
|  |         this._updateClockAndDate(); | ||||||
|  |  | ||||||
|         Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated)); |         Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated)); | ||||||
|         this._sessionUpdated(); |         this._sessionUpdated(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _getEventSource: function() { |     _isToday: function(date) { | ||||||
|         return new Calendar.DBusEventSource(); |         let now = new Date(); | ||||||
|  |         return now.getYear() == date.getYear() && | ||||||
|  |                now.getMonth() == date.getMonth() && | ||||||
|  |                now.getDay() == date.getDay(); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _appInstalledChanged: function() { | ||||||
|  |         this._calendarApp = undefined; | ||||||
|  |         this._updateEventsVisibility(); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _updateEventsVisibility: function() { | ||||||
|  |         let visible = this._eventSource.hasCalendars; | ||||||
|  |         this._openCalendarItem.actor.visible = visible && | ||||||
|  |             (this._getCalendarApp() != null); | ||||||
|  |         this._openClocksItem.actor.visible = visible && | ||||||
|  |             (this._getClockApp() != null); | ||||||
|  |         this._separator.visible = visible; | ||||||
|  |         this._eventList.actor.visible = visible; | ||||||
|  |         if (visible) { | ||||||
|  |             let alignment = 0.25; | ||||||
|  |             if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) | ||||||
|  |                 alignment = 1.0 - alignment; | ||||||
|  |             this.menu._arrowAlignment = alignment; | ||||||
|  |         } else { | ||||||
|  |             this.menu._arrowAlignment = 0.5; | ||||||
|  |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _setEventSource: function(eventSource) { |     _setEventSource: function(eventSource) { | ||||||
| @@ -405,24 +173,68 @@ const DateMenuButton = new Lang.Class({ | |||||||
|             this._eventSource.destroy(); |             this._eventSource.destroy(); | ||||||
|  |  | ||||||
|         this._calendar.setEventSource(eventSource); |         this._calendar.setEventSource(eventSource); | ||||||
|         this._messageList.setEventSource(eventSource); |         this._eventList.setEventSource(eventSource); | ||||||
|  |  | ||||||
|         this._eventSource = eventSource; |         this._eventSource = eventSource; | ||||||
|  |         this._eventSource.connect('notify::has-calendars', Lang.bind(this, function() { | ||||||
|  |             this._updateEventsVisibility(); | ||||||
|  |         })); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _sessionUpdated: function() { |     _sessionUpdated: function() { | ||||||
|         let eventSource; |         let eventSource; | ||||||
|         let showEvents = Main.sessionMode.showCalendarEvents; |         let showEvents = Main.sessionMode.showCalendarEvents; | ||||||
|         if (showEvents) { |         if (showEvents) { | ||||||
|             eventSource = this._getEventSource(); |             eventSource = new Calendar.DBusEventSource(); | ||||||
|         } else { |         } else { | ||||||
|             eventSource = new Calendar.EmptyEventSource(); |             eventSource = new Calendar.EmptyEventSource(); | ||||||
|         } |         } | ||||||
|         this._setEventSource(eventSource); |         this._setEventSource(eventSource); | ||||||
|  |         this._updateEventsVisibility(); | ||||||
|  |  | ||||||
|         // Displays are not actually expected to launch Settings when activated |         // This needs to be handled manually, as the code to | ||||||
|         // but the corresponding app (clocks, weather); however we can consider |         // autohide separators doesn't work across the vbox | ||||||
|         // that display-specific settings, so re-use "allowSettings" here ... |         this._dateAndTimeSeparator.actor.visible = Main.sessionMode.allowSettings; | ||||||
|         this._displaysSection.visible = Main.sessionMode.allowSettings; |     }, | ||||||
|  |  | ||||||
|  |     _updateClockAndDate: function() { | ||||||
|  |         this._clockDisplay.set_text(this._clock.clock); | ||||||
|  |         /* Translators: This is the date format to use when the calendar popup is | ||||||
|  |          * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM"). | ||||||
|  |          */ | ||||||
|  |         let dateFormat = _("%A %B %e, %Y"); | ||||||
|  |         let displayDate = new Date(); | ||||||
|  |         this._date.set_label(displayDate.toLocaleFormat(dateFormat)); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _getCalendarApp: function() { | ||||||
|  |         if (this._calendarApp !== undefined) | ||||||
|  |             return this._calendarApp; | ||||||
|  |  | ||||||
|  |         let apps = Gio.AppInfo.get_recommended_for_type('text/calendar'); | ||||||
|  |         if (apps && (apps.length > 0)) | ||||||
|  |             this._calendarApp = apps[0]; | ||||||
|  |         else | ||||||
|  |             this._calendarApp = null; | ||||||
|  |         return this._calendarApp; | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _getClockApp: function() { | ||||||
|  |         return Shell.AppSystem.get_default().lookup_app('org.gnome.clocks.desktop'); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _onOpenCalendarActivate: function() { | ||||||
|  |         this.menu.close(); | ||||||
|  |  | ||||||
|  |         let app = this._getCalendarApp(); | ||||||
|  |         if (app.get_id() == 'evolution.desktop') | ||||||
|  |             app = Gio.DesktopAppInfo.new('evolution-calendar.desktop'); | ||||||
|  |         app.launch([], global.create_app_launch_context(0, -1)); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _onOpenClocksActivate: function() { | ||||||
|  |         this.menu.close(); | ||||||
|  |         let app = this._getClockApp(); | ||||||
|  |         app.activate(); | ||||||
|     } |     } | ||||||
| }); | }); | ||||||
|   | |||||||
							
								
								
									
										69
									
								
								js/ui/dnd.js
									
									
									
									
									
								
							
							
						
						| @@ -79,12 +79,9 @@ const _Draggable = new Lang.Class({ | |||||||
|                                         dragActorOpacity: undefined }); |                                         dragActorOpacity: undefined }); | ||||||
|  |  | ||||||
|         this.actor = actor; |         this.actor = actor; | ||||||
|         if (!params.manualMode) { |         if (!params.manualMode) | ||||||
|             this.actor.connect('button-press-event', |             this.actor.connect('button-press-event', | ||||||
|                                Lang.bind(this, this._onButtonPress)); |                                Lang.bind(this, this._onButtonPress)); | ||||||
|             this.actor.connect('touch-event', |  | ||||||
|                                Lang.bind(this, this._onTouchEvent)); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.actor.connect('destroy', Lang.bind(this, function() { |         this.actor.connect('destroy', Lang.bind(this, function() { | ||||||
|             this._actorDestroyed = true; |             this._actorDestroyed = true; | ||||||
| @@ -124,50 +121,8 @@ const _Draggable = new Lang.Class({ | |||||||
|         return Clutter.EVENT_PROPAGATE; |         return Clutter.EVENT_PROPAGATE; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _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; |  | ||||||
|  |  | ||||||
|         if (Tweener.getTweenCount(actor)) |  | ||||||
|             return Clutter.EVENT_PROPAGATE; |  | ||||||
|  |  | ||||||
|         this._touchSequence = event.get_event_sequence(); |  | ||||||
|  |  | ||||||
|         this._buttonDown = true; |  | ||||||
|         this._grabActor(); |  | ||||||
|  |  | ||||||
|         let [stageX, stageY] = event.get_coords(); |  | ||||||
|         this._dragStartX = stageX; |  | ||||||
|         this._dragStartY = stageY; |  | ||||||
|  |  | ||||||
|         return Clutter.EVENT_PROPAGATE; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _grabDevice: function(actor) { |  | ||||||
|         let manager = Clutter.DeviceManager.get_default(); |  | ||||||
|         let pointer = manager.get_core_device(Clutter.InputDeviceType.POINTER_DEVICE); |  | ||||||
|  |  | ||||||
|         if (pointer && this._touchSequence) |  | ||||||
|             pointer.sequence_grab(this._touchSequence, actor); |  | ||||||
|         else if (pointer) |  | ||||||
|             pointer.grab (actor); |  | ||||||
|  |  | ||||||
|         this._grabbedDevice = pointer; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _ungrabDevice: function() { |  | ||||||
|         if (this._touchSequence) |  | ||||||
|             this._grabbedDevice.sequence_ungrab (this._touchSequence); |  | ||||||
|         else |  | ||||||
|             this._grabbedDevice.ungrab(); |  | ||||||
|  |  | ||||||
|         this._touchSequence = null; |  | ||||||
|         this._grabbedDevice = null; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _grabActor: function() { |     _grabActor: function() { | ||||||
|         this._grabDevice(this.actor); |         Clutter.grab_pointer(this.actor); | ||||||
|         this._onEventId = this.actor.connect('event', |         this._onEventId = this.actor.connect('event', | ||||||
|                                              Lang.bind(this, this._onEvent)); |                                              Lang.bind(this, this._onEvent)); | ||||||
|     }, |     }, | ||||||
| @@ -176,7 +131,7 @@ const _Draggable = new Lang.Class({ | |||||||
|         if (!this._onEventId) |         if (!this._onEventId) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         this._ungrabDevice(); |         Clutter.ungrab_pointer(); | ||||||
|         this.actor.disconnect(this._onEventId); |         this.actor.disconnect(this._onEventId); | ||||||
|         this._onEventId = null; |         this._onEventId = null; | ||||||
|     }, |     }, | ||||||
| @@ -185,13 +140,13 @@ const _Draggable = new Lang.Class({ | |||||||
|         if (!this._eventsGrabbed) { |         if (!this._eventsGrabbed) { | ||||||
|             this._eventsGrabbed = Main.pushModal(_getEventHandlerActor()); |             this._eventsGrabbed = Main.pushModal(_getEventHandlerActor()); | ||||||
|             if (this._eventsGrabbed) |             if (this._eventsGrabbed) | ||||||
|                 this._grabDevice(_getEventHandlerActor()); |                 Clutter.grab_pointer(_getEventHandlerActor()); | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _ungrabEvents: function() { |     _ungrabEvents: function() { | ||||||
|         if (this._eventsGrabbed) { |         if (this._eventsGrabbed) { | ||||||
|             this._ungrabDevice(); |             Clutter.ungrab_pointer(); | ||||||
|             Main.popModal(_getEventHandlerActor()); |             Main.popModal(_getEventHandlerActor()); | ||||||
|             this._eventsGrabbed = false; |             this._eventsGrabbed = false; | ||||||
|         } |         } | ||||||
| @@ -202,9 +157,7 @@ const _Draggable = new Lang.Class({ | |||||||
|         // didn't start the drag, to drop the draggable in case the drag was in progress, and |         // 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 |         // to complete the drag and ensure that whatever happens to be under the pointer does | ||||||
|         // not get triggered if the drag was cancelled with Esc. |         // not get triggered if the drag was cancelled with Esc. | ||||||
|         if (event.type() == Clutter.EventType.BUTTON_RELEASE || |         if (event.type() == Clutter.EventType.BUTTON_RELEASE) { | ||||||
|             (event.type() == Clutter.EventType.TOUCH_END && |  | ||||||
|              global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) { |  | ||||||
|             this._buttonDown = false; |             this._buttonDown = false; | ||||||
|             if (this._dragInProgress) { |             if (this._dragInProgress) { | ||||||
|                 return this._dragActorDropped(event); |                 return this._dragActorDropped(event); | ||||||
| @@ -219,9 +172,7 @@ const _Draggable = new Lang.Class({ | |||||||
|             } |             } | ||||||
|         // We intercept MOTION event to figure out if the drag has started and to draw |         // We intercept MOTION event to figure out if the drag has started and to draw | ||||||
|         // this._dragActor under the pointer when dragging is in progress |         // this._dragActor under the pointer when dragging is in progress | ||||||
|         } else if (event.type() == Clutter.EventType.MOTION || |         } else if (event.type() == Clutter.EventType.MOTION) { | ||||||
|                    (event.type() == Clutter.EventType.TOUCH_UPDATE && |  | ||||||
|                     global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) { |  | ||||||
|             if (this._dragInProgress) { |             if (this._dragInProgress) { | ||||||
|                 return this._updateDragPosition(event); |                 return this._updateDragPosition(event); | ||||||
|             } else if (this._dragActor == null) { |             } else if (this._dragActor == null) { | ||||||
| @@ -263,7 +214,7 @@ const _Draggable = new Lang.Class({ | |||||||
|      * This function is useful to call if you've specified manualMode |      * This function is useful to call if you've specified manualMode | ||||||
|      * for the draggable. |      * for the draggable. | ||||||
|      */ |      */ | ||||||
|     startDrag: function (stageX, stageY, time, sequence) { |     startDrag: function (stageX, stageY, time) { | ||||||
|         currentDraggable = this; |         currentDraggable = this; | ||||||
|         this._dragInProgress = true; |         this._dragInProgress = true; | ||||||
|  |  | ||||||
| @@ -277,8 +228,6 @@ const _Draggable = new Lang.Class({ | |||||||
|         this.emit('drag-begin', time); |         this.emit('drag-begin', time); | ||||||
|         if (this._onEventId) |         if (this._onEventId) | ||||||
|             this._ungrabActor(); |             this._ungrabActor(); | ||||||
|  |  | ||||||
|         this._touchSequence = sequence; |  | ||||||
|         this._grabEvents(); |         this._grabEvents(); | ||||||
|         global.screen.set_cursor(Meta.Cursor.DND_IN_DRAG); |         global.screen.set_cursor(Meta.Cursor.DND_IN_DRAG); | ||||||
|  |  | ||||||
| @@ -389,7 +338,7 @@ const _Draggable = new Lang.Class({ | |||||||
|         let threshold = Gtk.Settings.get_default().gtk_dnd_drag_threshold; |         let threshold = Gtk.Settings.get_default().gtk_dnd_drag_threshold; | ||||||
|         if ((Math.abs(stageX - this._dragStartX) > threshold || |         if ((Math.abs(stageX - this._dragStartX) > threshold || | ||||||
|              Math.abs(stageY - this._dragStartY) > threshold)) { |              Math.abs(stageY - this._dragStartY) > threshold)) { | ||||||
|             this.startDrag(stageX, stageY, event.get_time(), this._touchSequence); |                 this.startDrag(stageX, stageY, event.get_time()); | ||||||
|                 this._updateDragPosition(event); |                 this._updateDragPosition(event); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,84 +0,0 @@ | |||||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- |  | ||||||
|  |  | ||||||
| const Lang = imports.lang; |  | ||||||
| const Signals = imports.signals; |  | ||||||
| const Meta = imports.gi.Meta; |  | ||||||
| const Clutter = imports.gi.Clutter; |  | ||||||
| const St = imports.gi.St; |  | ||||||
|  |  | ||||||
| const Main = imports.ui.main; |  | ||||||
|  |  | ||||||
| const EDGE_THRESHOLD = 20; |  | ||||||
| const DRAG_DISTANCE = 80; |  | ||||||
|  |  | ||||||
| const EdgeDragAction = new Lang.Class({ |  | ||||||
|     Name: 'EdgeDragAction', |  | ||||||
|     Extends: Clutter.GestureAction, |  | ||||||
|  |  | ||||||
|     _init : function(side, allowedModes) { |  | ||||||
|         this.parent(); |  | ||||||
|         this._side = side; |  | ||||||
|         this._allowedModes = allowedModes; |  | ||||||
|         this.set_n_touch_points(1); |  | ||||||
|  |  | ||||||
|         global.display.connect('grab-op-begin', Lang.bind(this, function() { |  | ||||||
|             this.cancel(); |  | ||||||
|         })); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _getMonitorRect : function (x, y) { |  | ||||||
|         let rect = new Meta.Rectangle({ x: x - 1, y: y - 1, width: 1, height: 1 }); |  | ||||||
|         let monitorIndex = global.screen.get_monitor_index_for_rect(rect); |  | ||||||
|  |  | ||||||
|         return global.screen.get_monitor_geometry(monitorIndex); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     vfunc_gesture_prepare : function(action, actor) { |  | ||||||
|         if (this.get_n_current_points() == 0) |  | ||||||
|             return false; |  | ||||||
|  |  | ||||||
|         if (!(this._allowedModes & Main.actionMode)) |  | ||||||
|             return false; |  | ||||||
|  |  | ||||||
|         let [x, y] = this.get_press_coords(0); |  | ||||||
|         let monitorRect = this._getMonitorRect(x, y); |  | ||||||
|  |  | ||||||
|         return ((this._side == St.Side.LEFT && x < monitorRect.x + EDGE_THRESHOLD) || |  | ||||||
|                 (this._side == St.Side.RIGHT && x > monitorRect.x + monitorRect.width - EDGE_THRESHOLD) || |  | ||||||
|                 (this._side == St.Side.TOP && y < monitorRect.y + EDGE_THRESHOLD) || |  | ||||||
|                 (this._side == St.Side.BOTTOM && y > monitorRect.y + monitorRect.height - EDGE_THRESHOLD)); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     vfunc_gesture_progress : 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); |  | ||||||
|         let offsetY = Math.abs (y - startY); |  | ||||||
|  |  | ||||||
|         if (offsetX < EDGE_THRESHOLD && offsetY < EDGE_THRESHOLD) |  | ||||||
|             return true; |  | ||||||
|  |  | ||||||
|         if ((offsetX > offsetY && |  | ||||||
|              (this._side == St.Side.TOP || this._side == St.Side.BOTTOM)) || |  | ||||||
|             (offsetY > offsetX && |  | ||||||
|              (this._side == St.Side.LEFT || this._side == St.Side.RIGHT))) { |  | ||||||
|             this.cancel(); |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return true; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     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); |  | ||||||
|  |  | ||||||
|         if ((this._side == St.Side.TOP && y > monitorRect.y + DRAG_DISTANCE) || |  | ||||||
|             (this._side == St.Side.BOTTOM && y < monitorRect.y + monitorRect.height - DRAG_DISTANCE) || |  | ||||||
|             (this._side == St.Side.LEFT && x > monitorRect.x + DRAG_DISTANCE) || |  | ||||||
|             (this._side == St.Side.RIGHT && x < monitorRect.x + monitorRect.width - DRAG_DISTANCE)) |  | ||||||
|             this.emit('activated'); |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
| Signals.addSignalMethods(EdgeDragAction.prototype); |  | ||||||
| @@ -38,6 +38,8 @@ const UserWidget = imports.ui.userWidget; | |||||||
|  |  | ||||||
| let _endSessionDialog = null; | let _endSessionDialog = null; | ||||||
|  |  | ||||||
|  | const TRIGGER_OFFLINE_UPDATE = '/usr/libexec/pk-trigger-offline-update'; | ||||||
|  |  | ||||||
| const _ITEM_ICON_SIZE = 48; | const _ITEM_ICON_SIZE = 48; | ||||||
| const _DIALOG_ICON_SIZE = 48; | const _DIALOG_ICON_SIZE = 48; | ||||||
|  |  | ||||||
| @@ -132,18 +134,11 @@ const restartInstallDialogContent = { | |||||||
|     showOtherSessions: true, |     showOtherSessions: true, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const DialogType = { |  | ||||||
|   LOGOUT: 0 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_LOGOUT */, |  | ||||||
|   SHUTDOWN: 1 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_SHUTDOWN */, |  | ||||||
|   RESTART: 2 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_RESTART */, |  | ||||||
|   UPDATE_RESTART: 3 |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| const DialogContent = { | const DialogContent = { | ||||||
|     0 /* DialogType.LOGOUT */: logoutDialogContent, |     0 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_LOGOUT */: logoutDialogContent, | ||||||
|     1 /* DialogType.SHUTDOWN */: shutdownDialogContent, |     1 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_SHUTDOWN */: shutdownDialogContent, | ||||||
|     2 /* DialogType.RESTART */: restartDialogContent, |     2 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_RESTART */: restartDialogContent, | ||||||
|     3 /* DialogType.UPDATE_RESTART */: restartInstallDialogContent |     3: restartInstallDialogContent | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const MAX_USERS_IN_SESSION_DIALOG = 5; | const MAX_USERS_IN_SESSION_DIALOG = 5; | ||||||
| @@ -160,19 +155,6 @@ const LogindSessionIface = '<node> \ | |||||||
|  |  | ||||||
| const LogindSession = Gio.DBusProxy.makeProxyWrapper(LogindSessionIface); | const LogindSession = Gio.DBusProxy.makeProxyWrapper(LogindSessionIface); | ||||||
|  |  | ||||||
| const PkOfflineIface = '<node> \ |  | ||||||
| <interface name="org.freedesktop.PackageKit.Offline"> \ |  | ||||||
|     <property name="UpdatePrepared" type="b" access="read"/> \ |  | ||||||
|     <property name="TriggerAction" type="s" access="read"/> \ |  | ||||||
|     <method name="Trigger"> \ |  | ||||||
|         <arg type="s" name="action" direction="in"/> \ |  | ||||||
|     </method> \ |  | ||||||
|     <method name="Cancel"/> \ |  | ||||||
| </interface> \ |  | ||||||
| </node>'; |  | ||||||
|  |  | ||||||
| const PkOfflineProxy = Gio.DBusProxy.makeProxyWrapper(PkOfflineIface); |  | ||||||
|  |  | ||||||
| const UPowerIface = '<node> \ | const UPowerIface = '<node> \ | ||||||
| <interface name="org.freedesktop.UPower"> \ | <interface name="org.freedesktop.UPower"> \ | ||||||
|     <property name="OnBattery" type="b" access="read"/> \ |     <property name="OnBattery" type="b" access="read"/> \ | ||||||
| @@ -263,14 +245,9 @@ const EndSessionDialog = new Lang.Class({ | |||||||
|         this._loginManager = LoginManager.getLoginManager(); |         this._loginManager = LoginManager.getLoginManager(); | ||||||
|         this._userManager = AccountsService.UserManager.get_default(); |         this._userManager = AccountsService.UserManager.get_default(); | ||||||
|         this._user = this._userManager.get_user(GLib.get_user_name()); |         this._user = this._userManager.get_user(GLib.get_user_name()); | ||||||
|  |         this._updatesFile = Gio.File.new_for_path('/system-update'); | ||||||
|  |         this._preparedUpdateFile = Gio.File.new_for_path('/var/lib/PackageKit/prepared-update'); | ||||||
|  |  | ||||||
|         this._pkOfflineProxy = new PkOfflineProxy(Gio.DBus.system, |  | ||||||
|                                                   'org.freedesktop.PackageKit', |  | ||||||
|                                                   '/org/freedesktop/PackageKit', |  | ||||||
|                                                   Lang.bind(this, function(proxy, error) { |  | ||||||
|                                                       if (error) |  | ||||||
|                                                           log(error.message); |  | ||||||
|                                                   })); |  | ||||||
|         this._powerProxy = new UPowerProxy(Gio.DBus.system, |         this._powerProxy = new UPowerProxy(Gio.DBus.system, | ||||||
|                                            'org.freedesktop.UPower', |                                            'org.freedesktop.UPower', | ||||||
|                                            '/org/freedesktop/UPower', |                                            '/org/freedesktop/UPower', | ||||||
| @@ -522,29 +499,31 @@ const EndSessionDialog = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _triggerOfflineUpdateReboot: function(callback) { |     _triggerOfflineUpdateReboot: function(callback) { | ||||||
|         this._pkOfflineProxy.TriggerRemote('reboot', |         this._pkexecSpawn([TRIGGER_OFFLINE_UPDATE, 'reboot'], callback); | ||||||
|                                            function (result, error) { |  | ||||||
|             if (error) |  | ||||||
|                 log(error.message); |  | ||||||
|  |  | ||||||
|             callback(); |  | ||||||
|         }); |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _triggerOfflineUpdateShutdown: function(callback) { |     _triggerOfflineUpdateShutdown: function(callback) { | ||||||
|         this._pkOfflineProxy.TriggerRemote('power-off', |         this._pkexecSpawn([TRIGGER_OFFLINE_UPDATE, 'power-off'], callback); | ||||||
|                                            function (result, error) { |  | ||||||
|             if (error) |  | ||||||
|                 log(error.message); |  | ||||||
|  |  | ||||||
|             callback(); |  | ||||||
|         }); |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _triggerOfflineUpdateCancel: function(callback) { |     _triggerOfflineUpdateCancel: function(callback) { | ||||||
|         this._pkOfflineProxy.CancelRemote(function (result, error) { |         this._pkexecSpawn([TRIGGER_OFFLINE_UPDATE, '--cancel'], callback); | ||||||
|             if (error) |     }, | ||||||
|                 log(error.message); |  | ||||||
|  |     _pkexecSpawn: function(argv, callback) { | ||||||
|  |         let ret, pid; | ||||||
|  |         try { | ||||||
|  |             [ret, pid] = GLib.spawn_async(null, ['pkexec'].concat(argv), null, | ||||||
|  |                                           GLib.SpawnFlags.DO_NOT_REAP_CHILD | GLib.SpawnFlags.SEARCH_PATH, | ||||||
|  |                                           null); | ||||||
|  |         } catch (e) { | ||||||
|  |             log('Error spawning "pkexec %s": %s'.format(argv.join(' '), e.toString())); | ||||||
|  |             callback(); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function(pid, status) { | ||||||
|  |             GLib.spawn_close_pid(pid); | ||||||
|  |  | ||||||
|             callback(); |             callback(); | ||||||
|         }); |         }); | ||||||
| @@ -698,9 +677,8 @@ const EndSessionDialog = new Lang.Class({ | |||||||
|         this._totalSecondsToStayOpen = totalSecondsToStayOpen; |         this._totalSecondsToStayOpen = totalSecondsToStayOpen; | ||||||
|         this._type = type; |         this._type = type; | ||||||
|  |  | ||||||
|         if (this._type == DialogType.RESTART && |         if (this._type == 2 && this._updatesFile.query_exists(null)) | ||||||
|             this._pkOfflineProxy.TriggerAction == 'reboot') |             this._type = 3; | ||||||
|             this._type = DialogType.UPDATE_RESTART; |  | ||||||
|  |  | ||||||
|         this._applications = []; |         this._applications = []; | ||||||
|         this._applicationList.destroy_all_children(); |         this._applicationList.destroy_all_children(); | ||||||
| @@ -727,19 +705,19 @@ const EndSessionDialog = new Lang.Class({ | |||||||
|         if (dialogContent.showOtherSessions) |         if (dialogContent.showOtherSessions) | ||||||
|             this._loadSessions(); |             this._loadSessions(); | ||||||
|  |  | ||||||
|         let updateAlreadyTriggered = this._pkOfflineProxy.TriggerAction == 'power-off' || this._pkOfflineProxy.TriggerAction == 'reboot'; |         let preparedUpdate = this._preparedUpdateFile.query_exists(null); | ||||||
|         let updatePrepared = this._pkOfflineProxy.UpdatePrepared; |         let updateAlreadyTriggered = this._updatesFile.query_exists(null); | ||||||
|         let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed; |         let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed; | ||||||
|  |  | ||||||
|         _setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText); |         _setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText); | ||||||
|         this._checkBox.actor.visible = (dialogContent.checkBoxText && updatePrepared && updatesAllowed); |         this._checkBox.actor.visible = (dialogContent.checkBoxText && preparedUpdate && updatesAllowed); | ||||||
|         this._checkBox.actor.checked = (updatePrepared && updateAlreadyTriggered); |         this._checkBox.actor.checked = (preparedUpdate && updateAlreadyTriggered); | ||||||
|  |  | ||||||
|         // We show the warning either together with the checkbox, or when |         // We show the warning either together with the checkbox, or when | ||||||
|         // updates have already been triggered, but the user doesn't have |         // updates have already been triggered, but the user doesn't have | ||||||
|         // enough permissions to cancel them. |         // enough permissions to cancel them. | ||||||
|         this._batteryWarning.visible = (dialogContent.showBatteryWarning && |         this._batteryWarning.visible = (dialogContent.showBatteryWarning && | ||||||
|                                         (this._checkBox.actor.visible || updatePrepared && updateAlreadyTriggered && !updatesAllowed)); |                                         (this._checkBox.actor.visible || preparedUpdate && updateAlreadyTriggered && !updatesAllowed)); | ||||||
|  |  | ||||||
|         this._updateButtons(); |         this._updateButtons(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -77,10 +77,10 @@ function init() { | |||||||
|     window._ = Gettext.gettext; |     window._ = Gettext.gettext; | ||||||
|     window.C_ = Gettext.pgettext; |     window.C_ = Gettext.pgettext; | ||||||
|     window.ngettext = Gettext.ngettext; |     window.ngettext = Gettext.ngettext; | ||||||
|     window.N_ = function(s) { return s; }; |  | ||||||
|  |  | ||||||
|     // Miscellaneous monkeypatching |     // Miscellaneous monkeypatching | ||||||
|     _patchContainerClass(St.BoxLayout); |     _patchContainerClass(St.BoxLayout); | ||||||
|  |     _patchContainerClass(St.Table); | ||||||
|  |  | ||||||
|     _patchLayoutClass(Clutter.TableLayout, { row_spacing: 'spacing-rows', |     _patchLayoutClass(Clutter.TableLayout, { row_spacing: 'spacing-rows', | ||||||
|                                              column_spacing: 'spacing-columns' }); |                                              column_spacing: 'spacing-columns' }); | ||||||
|   | |||||||
| @@ -203,16 +203,14 @@ const InstallExtensionDialog = new Lang.Class({ | |||||||
|  |  | ||||||
|         let message = _("Download and install “%s” from extensions.gnome.org?").format(info.name); |         let message = _("Download and install “%s” from extensions.gnome.org?").format(info.name); | ||||||
|  |  | ||||||
|         let box = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout', |         let box = new St.BoxLayout(); | ||||||
|                                      vertical: false }); |  | ||||||
|         this.contentLayout.add(box); |         this.contentLayout.add(box); | ||||||
|  |  | ||||||
|         let gicon = new Gio.FileIcon({ file: Gio.File.new_for_uri(REPOSITORY_URL_BASE + info.icon) }) |         let gicon = new Gio.FileIcon({ file: Gio.File.new_for_uri(REPOSITORY_URL_BASE + info.icon) }) | ||||||
|         let icon = new St.Icon({ gicon: gicon }); |         let icon = new St.Icon({ gicon: gicon }); | ||||||
|         box.add(icon); |         box.add(icon); | ||||||
|  |  | ||||||
|         let label = new St.Label({ style_class: 'prompt-dialog-headline headline', |         let label = new St.Label({ text: message }); | ||||||
|                                    text: message }); |  | ||||||
|         box.add(label); |         box.add(label); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|   | |||||||
| @@ -74,7 +74,7 @@ function disableExtension(uuid) { | |||||||
|  |  | ||||||
|     if (extension.stylesheet) { |     if (extension.stylesheet) { | ||||||
|         let theme = St.ThemeContext.get_for_stage(global.stage).get_theme(); |         let theme = St.ThemeContext.get_for_stage(global.stage).get_theme(); | ||||||
|         theme.unload_stylesheet(extension.stylesheet); |         theme.unload_stylesheet(extension.stylesheet.get_path()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     try { |     try { | ||||||
| @@ -118,7 +118,7 @@ function enableExtension(uuid) { | |||||||
|         let stylesheetFile = extension.dir.get_child(stylesheetNames[i]); |         let stylesheetFile = extension.dir.get_child(stylesheetNames[i]); | ||||||
|         if (stylesheetFile.query_exists(null)) { |         if (stylesheetFile.query_exists(null)) { | ||||||
|             let theme = St.ThemeContext.get_for_stage(global.stage).get_theme(); |             let theme = St.ThemeContext.get_for_stage(global.stage).get_theme(); | ||||||
|             theme.load_stylesheet(stylesheetFile); |             theme.load_stylesheet(stylesheetFile.get_path()); | ||||||
|             extension.stylesheet = stylesheetFile; |             extension.stylesheet = stylesheetFile; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| @@ -271,17 +271,10 @@ function onEnabledExtensionsChanged() { | |||||||
| } | } | ||||||
|  |  | ||||||
| function _onVersionValidationChanged() { | function _onVersionValidationChanged() { | ||||||
|     // we want to reload all extensions, but only enable |  | ||||||
|     // extensions when allowed by the sessionMode, so |  | ||||||
|     // temporarily disable them all |  | ||||||
|     enabledExtensions = []; |  | ||||||
|     for (let uuid in ExtensionUtils.extensions) |  | ||||||
|         reloadExtension(ExtensionUtils.extensions[uuid]); |  | ||||||
|     enabledExtensions = getEnabledExtensions(); |  | ||||||
|  |  | ||||||
|     if (Main.sessionMode.allowExtensions) { |     if (Main.sessionMode.allowExtensions) { | ||||||
|         enabledExtensions.forEach(function(uuid) { |         enabledExtensions.forEach(function(uuid) { | ||||||
|             enableExtension(uuid); |             if (ExtensionUtils.extensions[uuid]) | ||||||
|  |                 reloadExtension(ExtensionUtils.extensions[uuid]); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -334,7 +327,7 @@ function _sessionUpdated() { | |||||||
|     // from allowExtensions in the future |     // from allowExtensions in the future | ||||||
|     if (Main.sessionMode.allowExtensions) { |     if (Main.sessionMode.allowExtensions) { | ||||||
|         if (initted) |         if (initted) | ||||||
|             enabledExtensions = getEnabledExtensions(); |             onEnabledExtensionsChanged(); | ||||||
|         enableAllExtensions(); |         enableAllExtensions(); | ||||||
|     } else { |     } else { | ||||||
|         disableAllExtensions(); |         disableAllExtensions(); | ||||||
|   | |||||||
| @@ -32,9 +32,11 @@ const FocusCaretTracker = new Lang.Class({ | |||||||
|     Name: 'FocusCaretTracker', |     Name: 'FocusCaretTracker', | ||||||
|  |  | ||||||
|     _init: function() { |     _init: function() { | ||||||
|  |         Atspi.init(); | ||||||
|  |         Atspi.set_timeout(250, 250); | ||||||
|  |  | ||||||
|         this._atspiListener = Atspi.EventListener.new(Lang.bind(this, this._onChanged)); |         this._atspiListener = Atspi.EventListener.new(Lang.bind(this, this._onChanged)); | ||||||
|  |  | ||||||
|         this._atspiInited = false; |  | ||||||
|         this._focusListenerRegistered = false; |         this._focusListenerRegistered = false; | ||||||
|         this._caretListenerRegistered = false; |         this._caretListenerRegistered = false; | ||||||
|     }, |     }, | ||||||
| @@ -46,20 +48,12 @@ const FocusCaretTracker = new Lang.Class({ | |||||||
|             this.emit('caret-moved', event); |             this.emit('caret-moved', event); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _initAtspi: function() { |  | ||||||
|         if (!this._atspiInited) { |  | ||||||
|             Atspi.init(); |  | ||||||
|             Atspi.set_timeout(250, 250); |  | ||||||
|             this._atspiInited = true; |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     registerFocusListener: function() { |     registerFocusListener: function() { | ||||||
|         if (this._focusListenerRegistered) |         if (this._focusListenerRegistered) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         this._initAtspi(); |         // Ignore the return value, we get an exception if they fail | ||||||
|  |         // And they should never fail | ||||||
|         this._atspiListener.register(STATECHANGED + ':focused'); |         this._atspiListener.register(STATECHANGED + ':focused'); | ||||||
|         this._atspiListener.register(STATECHANGED + ':selected'); |         this._atspiListener.register(STATECHANGED + ':selected'); | ||||||
|         this._focusListenerRegistered = true; |         this._focusListenerRegistered = true; | ||||||
| @@ -69,8 +63,6 @@ const FocusCaretTracker = new Lang.Class({ | |||||||
|         if (this._caretListenerRegistered) |         if (this._caretListenerRegistered) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         this._initAtspi(); |  | ||||||
|  |  | ||||||
|         this._atspiListener.register(CARETMOVED); |         this._atspiListener.register(CARETMOVED); | ||||||
|         this._caretListenerRegistered = true; |         this._caretListenerRegistered = true; | ||||||
|     }, |     }, | ||||||
|   | |||||||
| @@ -56,7 +56,7 @@ const GrabHelper = new Lang.Class({ | |||||||
|         this._grabStack = []; |         this._grabStack = []; | ||||||
|  |  | ||||||
|         this._actors = []; |         this._actors = []; | ||||||
|         this._ignoreUntilRelease = false; |         this._ignoreRelease = false; | ||||||
|  |  | ||||||
|         this._modalCount = 0; |         this._modalCount = 0; | ||||||
|     }, |     }, | ||||||
| @@ -215,7 +215,7 @@ const GrabHelper = new Lang.Class({ | |||||||
|  |  | ||||||
|         _popGrabHelper(this); |         _popGrabHelper(this); | ||||||
|  |  | ||||||
|         this._ignoreUntilRelease = false; |         this._ignoreRelease = false; | ||||||
|  |  | ||||||
|         Main.popModal(this._owner); |         Main.popModal(this._owner); | ||||||
|         global.sync_pointer(); |         global.sync_pointer(); | ||||||
| @@ -228,7 +228,7 @@ const GrabHelper = new Lang.Class({ | |||||||
|     // like the ComboBoxMenu that go away on press, but need to eat |     // like the ComboBoxMenu that go away on press, but need to eat | ||||||
|     // the next release event. |     // the next release event. | ||||||
|     ignoreRelease: function() { |     ignoreRelease: function() { | ||||||
|         this._ignoreUntilRelease = true; |         this._ignoreRelease = true; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     // ungrab: |     // ungrab: | ||||||
| @@ -283,22 +283,12 @@ const GrabHelper = new Lang.Class({ | |||||||
|             return Clutter.EVENT_STOP; |             return Clutter.EVENT_STOP; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         let motion = type == Clutter.EventType.MOTION; |  | ||||||
|         let press = type == Clutter.EventType.BUTTON_PRESS; |         let press = type == Clutter.EventType.BUTTON_PRESS; | ||||||
|         let release = type == Clutter.EventType.BUTTON_RELEASE; |         let release = type == Clutter.EventType.BUTTON_RELEASE; | ||||||
|         let button = press || release; |         let button = press || release; | ||||||
|  |  | ||||||
|         let touchUpdate = type == Clutter.EventType.TOUCH_UPDATE; |         if (release && this._ignoreRelease) { | ||||||
|         let touchBegin = type == Clutter.EventType.TOUCH_BEGIN; |             this._ignoreRelease = false; | ||||||
|         let touchEnd = type == Clutter.EventType.TOUCH_END; |  | ||||||
|         let touch = touchUpdate || touchBegin || touchEnd; |  | ||||||
|  |  | ||||||
|         if (touch && !global.display.is_pointer_emulating_sequence (event.get_event_sequence())) |  | ||||||
|             return Clutter.EVENT_PROPAGATE; |  | ||||||
|  |  | ||||||
|         if (this._ignoreUntilRelease && (motion || release || touch)) { |  | ||||||
|             if (release || touchEnd) |  | ||||||
|                 this._ignoreUntilRelease = false; |  | ||||||
|             return Clutter.EVENT_STOP; |             return Clutter.EVENT_STOP; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -308,12 +298,11 @@ const GrabHelper = new Lang.Class({ | |||||||
|         if (Main.keyboard.shouldTakeEvent(event)) |         if (Main.keyboard.shouldTakeEvent(event)) | ||||||
|             return Clutter.EVENT_PROPAGATE; |             return Clutter.EVENT_PROPAGATE; | ||||||
|  |  | ||||||
|         if (button || touchBegin) { |         if (button) { | ||||||
|             // If we have a press event, ignore the next |             // If we have a press event, ignore the next event, | ||||||
|             // motion/release events. |             // which should be a release event. | ||||||
|             if (press || touchBegin) |             if (press) | ||||||
|                 this._ignoreUntilRelease = true; |                 this._ignoreRelease = true; | ||||||
|  |  | ||||||
|             let i = this._actorInGrabStack(event.get_source()) + 1; |             let i = this._actorInGrabStack(event.get_source()) + 1; | ||||||
|             this.ungrab({ actor: this._grabStack[i].actor, isUser: true }); |             this.ungrab({ actor: this._grabStack[i].actor, isUser: true }); | ||||||
|             return Clutter.EVENT_STOP; |             return Clutter.EVENT_STOP; | ||||||
|   | |||||||
| @@ -11,9 +11,6 @@ const Main = imports.ui.main; | |||||||
|  |  | ||||||
| const MAX_CANDIDATES_PER_PAGE = 16; | const MAX_CANDIDATES_PER_PAGE = 16; | ||||||
|  |  | ||||||
| const DEFAULT_INDEX_LABELS = [ '1', '2', '3', '4', '5', '6', '7', '8', |  | ||||||
|                                '9', '0', 'a', 'b', 'c', 'd', 'e', 'f' ]; |  | ||||||
|  |  | ||||||
| const CandidateArea = new Lang.Class({ | const CandidateArea = new Lang.Class({ | ||||||
|     Name: 'CandidateArea', |     Name: 'CandidateArea', | ||||||
|  |  | ||||||
| @@ -41,11 +38,11 @@ const CandidateArea = new Lang.Class({ | |||||||
|  |  | ||||||
|         this._buttonBox = new St.BoxLayout({ style_class: 'candidate-page-button-box' }); |         this._buttonBox = new St.BoxLayout({ style_class: 'candidate-page-button-box' }); | ||||||
|  |  | ||||||
|         this._previousButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-previous button' }); |         this._previousButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-previous' }); | ||||||
|         this._previousButton.child = new St.Icon({ style_class: 'candidate-page-button-icon' }); |         this._previousButton.child = new St.Icon({ style_class: 'candidate-page-button-icon' }); | ||||||
|         this._buttonBox.add(this._previousButton, { expand: true }); |         this._buttonBox.add(this._previousButton, { expand: true }); | ||||||
|  |  | ||||||
|         this._nextButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-next button' }); |         this._nextButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-next' }); | ||||||
|         this._nextButton.child = new St.Icon({ style_class: 'candidate-page-button-icon' }); |         this._nextButton.child = new St.Icon({ style_class: 'candidate-page-button-icon' }); | ||||||
|         this._buttonBox.add(this._nextButton, { expand: true }); |         this._buttonBox.add(this._nextButton, { expand: true }); | ||||||
|  |  | ||||||
| @@ -92,7 +89,7 @@ const CandidateArea = new Lang.Class({ | |||||||
|             if (!visible) |             if (!visible) | ||||||
|                 continue; |                 continue; | ||||||
|  |  | ||||||
|             box._indexLabel.text = ((indexes && indexes[i]) ? indexes[i] : DEFAULT_INDEX_LABELS[i]); |             box._indexLabel.text = ((indexes && indexes[i]) ? indexes[i] : '%x'.format(i + 1)); | ||||||
|             box._candidateLabel.text = candidates[i]; |             box._candidateLabel.text = candidates[i]; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,30 +10,12 @@ const St = imports.gi.St; | |||||||
| const Lang = imports.lang; | const Lang = imports.lang; | ||||||
| const Params = imports.misc.params; | const Params = imports.misc.params; | ||||||
| const Tweener = imports.ui.tweener; | const Tweener = imports.ui.tweener; | ||||||
| const Main = imports.ui.main; |  | ||||||
|  |  | ||||||
| const ICON_SIZE = 96; | const ICON_SIZE = 96; | ||||||
| const MIN_ICON_SIZE = 16; | const MIN_ICON_SIZE = 16; | ||||||
|  |  | ||||||
| const EXTRA_SPACE_ANIMATION_TIME = 0.25; | const EXTRA_SPACE_ANIMATION_TIME = 0.25; | ||||||
|  |  | ||||||
| const ANIMATION_TIME_IN = 0.350; |  | ||||||
| const ANIMATION_TIME_OUT = 1/2 * ANIMATION_TIME_IN; |  | ||||||
| const ANIMATION_MAX_DELAY_FOR_ITEM = 2/3 * ANIMATION_TIME_IN; |  | ||||||
| const ANIMATION_BASE_DELAY_FOR_ITEM = 1/4 * ANIMATION_MAX_DELAY_FOR_ITEM; |  | ||||||
| const ANIMATION_MAX_DELAY_OUT_FOR_ITEM = 2/3 * ANIMATION_TIME_OUT; |  | ||||||
| const ANIMATION_FADE_IN_TIME_FOR_ITEM = 1/4 * ANIMATION_TIME_IN; |  | ||||||
|  |  | ||||||
| const ANIMATION_BOUNCE_ICON_SCALE = 1.1; |  | ||||||
|  |  | ||||||
| const AnimationDirection = { |  | ||||||
|     IN: 0, |  | ||||||
|     OUT: 1 |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| const APPICON_ANIMATION_OUT_SCALE = 3; |  | ||||||
| const APPICON_ANIMATION_OUT_TIME = 0.25; |  | ||||||
|  |  | ||||||
| const BaseIcon = new Lang.Class({ | const BaseIcon = new Lang.Class({ | ||||||
|     Name: 'BaseIcon', |     Name: 'BaseIcon', | ||||||
|  |  | ||||||
| @@ -191,55 +173,9 @@ const BaseIcon = new Lang.Class({ | |||||||
|  |  | ||||||
|     _onIconThemeChanged: function() { |     _onIconThemeChanged: function() { | ||||||
|         this._createIconTexture(this.iconSize); |         this._createIconTexture(this.iconSize); | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     animateZoomOut: function() { |  | ||||||
|         // Animate only the child instead of the entire actor, so the |  | ||||||
|         // styles like hover and running are not applied while |  | ||||||
|         // animating. |  | ||||||
|         zoomOutActor(this.actor.child); |  | ||||||
|     } |     } | ||||||
| }); | }); | ||||||
|  |  | ||||||
| function clamp(value, min, max) { |  | ||||||
|     return Math.max(Math.min(value, max), min); |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| function zoomOutActor(actor) { |  | ||||||
|     let actorClone = new Clutter.Clone({ source: actor, |  | ||||||
|                                          reactive: false }); |  | ||||||
|     let [width, height] = actor.get_transformed_size(); |  | ||||||
|     let [x, y] = actor.get_transformed_position(); |  | ||||||
|     actorClone.set_size(width, height); |  | ||||||
|     actorClone.set_position(x, y); |  | ||||||
|     actorClone.opacity = 255; |  | ||||||
|     actorClone.set_pivot_point(0.5, 0.5); |  | ||||||
|  |  | ||||||
|     Main.uiGroup.add_actor(actorClone); |  | ||||||
|  |  | ||||||
|     // Avoid monitor edges to not zoom outside the current monitor |  | ||||||
|     let monitor = Main.layoutManager.findMonitorForActor(actor); |  | ||||||
|     let scaledWidth = width * APPICON_ANIMATION_OUT_SCALE; |  | ||||||
|     let scaledHeight = height * APPICON_ANIMATION_OUT_SCALE; |  | ||||||
|     let scaledX = x - (scaledWidth - width) / 2; |  | ||||||
|     let scaledY = y - (scaledHeight - height) / 2; |  | ||||||
|     let containedX = clamp(scaledX, monitor.x, monitor.x + monitor.width - scaledWidth); |  | ||||||
|     let containedY = clamp(scaledY, monitor.y, monitor.y + monitor.height - scaledHeight); |  | ||||||
|  |  | ||||||
|     Tweener.addTween(actorClone, |  | ||||||
|                      { time: APPICON_ANIMATION_OUT_TIME, |  | ||||||
|                        scale_x: APPICON_ANIMATION_OUT_SCALE, |  | ||||||
|                        scale_y: APPICON_ANIMATION_OUT_SCALE, |  | ||||||
|                        translation_x: containedX - scaledX, |  | ||||||
|                        translation_y: containedY - scaledY, |  | ||||||
|                        opacity: 0, |  | ||||||
|                        transition: 'easeOutQuad', |  | ||||||
|                        onComplete: function() { |  | ||||||
|                            actorClone.destroy(); |  | ||||||
|                        } |  | ||||||
|                     }); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const IconGrid = new Lang.Class({ | const IconGrid = new Lang.Class({ | ||||||
|     Name: 'IconGrid', |     Name: 'IconGrid', | ||||||
|  |  | ||||||
| @@ -402,202 +338,15 @@ const IconGrid = new Lang.Class({ | |||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Intended to be override by subclasses if they need a different |  | ||||||
|      * set of items to be animated. |  | ||||||
|      */ |  | ||||||
|     _getChildrenToAnimate: function() { |  | ||||||
|         return this._getVisibleChildren(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _animationDone: function() { |  | ||||||
|         this._animating = false; |  | ||||||
|         this.emit('animation-done'); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     animatePulse: function(animationDirection) { |  | ||||||
|         if (animationDirection != AnimationDirection.IN) |  | ||||||
|             throw new Error("Pulse animation only implements 'in' animation direction"); |  | ||||||
|  |  | ||||||
|         if (this._animating) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         this._animating = true; |  | ||||||
|  |  | ||||||
|         let actors = this._getChildrenToAnimate(); |  | ||||||
|         if (actors.length == 0) { |  | ||||||
|             this._animationDone(); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // For few items the animation can be slow, so use a smaller |  | ||||||
|         // delay when there are less than 4 items |  | ||||||
|         // (ANIMATION_BASE_DELAY_FOR_ITEM = 1/4 * |  | ||||||
|         // ANIMATION_MAX_DELAY_FOR_ITEM) |  | ||||||
|         let maxDelay = Math.min(ANIMATION_BASE_DELAY_FOR_ITEM * actors.length, |  | ||||||
|                                 ANIMATION_MAX_DELAY_FOR_ITEM); |  | ||||||
|  |  | ||||||
|         for (let index = 0; index < actors.length; index++) { |  | ||||||
|             let actor = actors[index]; |  | ||||||
|             actor.reactive = false; |  | ||||||
|             actor.set_scale(0, 0); |  | ||||||
|             actor.set_pivot_point(0.5, 0.5); |  | ||||||
|  |  | ||||||
|             let delay = index / actors.length * maxDelay; |  | ||||||
|             let bounceUpTime = ANIMATION_TIME_IN / 4; |  | ||||||
|             let isLastItem = index == actors.length - 1; |  | ||||||
|             Tweener.addTween(actor, |  | ||||||
|                             { time: bounceUpTime, |  | ||||||
|                               transition: 'easeInOutQuad', |  | ||||||
|                               delay: delay, |  | ||||||
|                               scale_x: ANIMATION_BOUNCE_ICON_SCALE, |  | ||||||
|                               scale_y: ANIMATION_BOUNCE_ICON_SCALE, |  | ||||||
|                               onComplete: Lang.bind(this, function() { |  | ||||||
|                                   Tweener.addTween(actor, |  | ||||||
|                                                    { time: ANIMATION_TIME_IN - bounceUpTime, |  | ||||||
|                                                      transition: 'easeInOutQuad', |  | ||||||
|                                                      scale_x: 1, |  | ||||||
|                                                      scale_y: 1, |  | ||||||
|                                                      onComplete: Lang.bind(this, function() { |  | ||||||
|                                                         if (isLastItem) |  | ||||||
|                                                             this._animationDone(); |  | ||||||
|                                                         actor.reactive = true; |  | ||||||
|                                                     }) |  | ||||||
|                                                    }); |  | ||||||
|                               }) |  | ||||||
|                             }); |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     animateSpring: function(animationDirection, sourceActor) { |  | ||||||
|         if (this._animating) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         this._animating = true; |  | ||||||
|  |  | ||||||
|         let actors = this._getChildrenToAnimate(); |  | ||||||
|         if (actors.length == 0) { |  | ||||||
|             this._animationDone(); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         let [sourceX, sourceY] = sourceActor.get_transformed_position(); |  | ||||||
|         let [sourceWidth, sourceHeight] = sourceActor.get_size(); |  | ||||||
|         // Get the center |  | ||||||
|         let [sourceCenterX, sourceCenterY] = [sourceX + sourceWidth / 2, sourceY + sourceHeight / 2]; |  | ||||||
|         // Design decision, 1/2 of the source actor size. |  | ||||||
|         let [sourceScaledWidth, sourceScaledHeight] = [sourceWidth / 2, sourceHeight / 2]; |  | ||||||
|  |  | ||||||
|         actors.forEach(function(actor) { |  | ||||||
|             let [actorX, actorY] = actor._transformedPosition = actor.get_transformed_position(); |  | ||||||
|             let [x, y] = [actorX - sourceX, actorY - sourceY]; |  | ||||||
|             actor._distance = Math.sqrt(x * x + y * y); |  | ||||||
|         }); |  | ||||||
|         let maxDist = actors.reduce(function(prev, cur) { |  | ||||||
|             return Math.max(prev, cur._distance); |  | ||||||
|         }, 0); |  | ||||||
|         let minDist = actors.reduce(function(prev, cur) { |  | ||||||
|             return Math.min(prev, cur._distance); |  | ||||||
|         }, Infinity); |  | ||||||
|         let normalization = maxDist - minDist; |  | ||||||
|  |  | ||||||
|         for (let index = 0; index < actors.length; index++) { |  | ||||||
|             let actor = actors[index]; |  | ||||||
|             actor.opacity = 0; |  | ||||||
|             actor.reactive = false; |  | ||||||
|  |  | ||||||
|             let actorClone = new Clutter.Clone({ source: actor }); |  | ||||||
|             Main.uiGroup.add_actor(actorClone); |  | ||||||
|  |  | ||||||
|             let [width, height,,] = this._getAllocatedChildSizeAndSpacing(actor); |  | ||||||
|             actorClone.set_size(width, height); |  | ||||||
|             let scaleX = sourceScaledWidth / width; |  | ||||||
|             let scaleY = sourceScaledHeight / height; |  | ||||||
|             let [adjustedSourcePositionX, adjustedSourcePositionY] = [sourceCenterX - sourceScaledWidth / 2, sourceCenterY - sourceScaledHeight / 2]; |  | ||||||
|  |  | ||||||
|             let movementParams, fadeParams; |  | ||||||
|             if (animationDirection == AnimationDirection.IN) { |  | ||||||
|                 let isLastItem = actor._distance == minDist; |  | ||||||
|  |  | ||||||
|                 actorClone.opacity = 0; |  | ||||||
|                 actorClone.set_scale(scaleX, scaleY); |  | ||||||
|  |  | ||||||
|                 actorClone.set_position(adjustedSourcePositionX, adjustedSourcePositionY); |  | ||||||
|  |  | ||||||
|                 let delay = (1 - (actor._distance - minDist) / normalization) * ANIMATION_MAX_DELAY_FOR_ITEM; |  | ||||||
|                 let [finalX, finalY]  = actor._transformedPosition; |  | ||||||
|                 movementParams = { time: ANIMATION_TIME_IN, |  | ||||||
|                                    transition: 'easeInOutQuad', |  | ||||||
|                                    delay: delay, |  | ||||||
|                                    x: finalX, |  | ||||||
|                                    y: finalY, |  | ||||||
|                                    scale_x: 1, |  | ||||||
|                                    scale_y: 1, |  | ||||||
|                                    onComplete: Lang.bind(this, function() { |  | ||||||
|                                        if (isLastItem) |  | ||||||
|                                            this._animationDone(); |  | ||||||
|  |  | ||||||
|                                        actor.opacity = 255; |  | ||||||
|                                        actor.reactive = true; |  | ||||||
|                                        actorClone.destroy(); |  | ||||||
|                                    })}; |  | ||||||
|                 fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM, |  | ||||||
|                                transition: 'easeInOutQuad', |  | ||||||
|                                delay: delay, |  | ||||||
|                                opacity: 255 }; |  | ||||||
|             } else { |  | ||||||
|                 let isLastItem = actor._distance == maxDist; |  | ||||||
|  |  | ||||||
|                 let [startX, startY]  = actor._transformedPosition; |  | ||||||
|                 actorClone.set_position(startX, startY); |  | ||||||
|  |  | ||||||
|                 let delay = (actor._distance - minDist) / normalization * ANIMATION_MAX_DELAY_OUT_FOR_ITEM; |  | ||||||
|                 movementParams = { time: ANIMATION_TIME_OUT, |  | ||||||
|                                    transition: 'easeInOutQuad', |  | ||||||
|                                    delay: delay, |  | ||||||
|                                    x: adjustedSourcePositionX, |  | ||||||
|                                    y: adjustedSourcePositionY, |  | ||||||
|                                    scale_x: scaleX, |  | ||||||
|                                    scale_y: scaleY, |  | ||||||
|                                    onComplete: Lang.bind(this, function() { |  | ||||||
|                                        if (isLastItem) { |  | ||||||
|                                            this._animationDone(); |  | ||||||
|                                            this._restoreItemsOpacity(); |  | ||||||
|                                        } |  | ||||||
|                                        actor.reactive = true; |  | ||||||
|                                        actorClone.destroy(); |  | ||||||
|                                    })}; |  | ||||||
|                 fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM, |  | ||||||
|                                transition: 'easeInOutQuad', |  | ||||||
|                                delay: ANIMATION_TIME_OUT + delay - ANIMATION_FADE_IN_TIME_FOR_ITEM, |  | ||||||
|                                opacity: 0 }; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|             Tweener.addTween(actorClone, movementParams); |  | ||||||
|             Tweener.addTween(actorClone, fadeParams); |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _restoreItemsOpacity: function() { |  | ||||||
|         for (let index = 0; index < this._items.length; index++) { |  | ||||||
|             this._items[index].actor.opacity = 255; |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _getAllocatedChildSizeAndSpacing: function(child) { |  | ||||||
|         let [,, natWidth, natHeight] = child.get_preferred_size(); |  | ||||||
|         let width = Math.min(this._getHItemSize(), natWidth); |  | ||||||
|         let xSpacing = Math.max(0, width - natWidth) / 2; |  | ||||||
|         let height = Math.min(this._getVItemSize(), natHeight); |  | ||||||
|         let ySpacing = Math.max(0, height - natHeight) / 2; |  | ||||||
|         return [width, height, xSpacing, ySpacing]; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _calculateChildBox: function(child, x, y, box) { |     _calculateChildBox: function(child, x, y, box) { | ||||||
|  |         let [childMinWidth, childMinHeight, childNaturalWidth, childNaturalHeight] = | ||||||
|  |              child.get_preferred_size(); | ||||||
|  |  | ||||||
|         /* Center the item in its allocation horizontally */ |         /* Center the item in its allocation horizontally */ | ||||||
|         let [width, height, childXSpacing, childYSpacing] = |         let width = Math.min(this._getHItemSize(), childNaturalWidth); | ||||||
|             this._getAllocatedChildSizeAndSpacing(child); |         let childXSpacing = Math.max(0, width - childNaturalWidth) / 2; | ||||||
|  |         let height = Math.min(this._getVItemSize(), childNaturalHeight); | ||||||
|  |         let childYSpacing = Math.max(0, height - childNaturalHeight) / 2; | ||||||
|  |  | ||||||
|         let childBox = new Clutter.ActorBox(); |         let childBox = new Clutter.ActorBox(); | ||||||
|         if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) { |         if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) { | ||||||
| @@ -773,17 +522,21 @@ const IconGrid = new Lang.Class({ | |||||||
|             this._fixedHItemSize = Math.max(this._hItemSize - neededSpacePerItem, MIN_ICON_SIZE); |             this._fixedHItemSize = Math.max(this._hItemSize - neededSpacePerItem, MIN_ICON_SIZE); | ||||||
|             this._fixedVItemSize = Math.max(this._vItemSize - neededSpacePerItem, MIN_ICON_SIZE); |             this._fixedVItemSize = Math.max(this._vItemSize - neededSpacePerItem, MIN_ICON_SIZE); | ||||||
|  |  | ||||||
|  |             if (this._fixedHItemSize < MIN_ICON_SIZE) | ||||||
|  |                 this._fixedHItemSize = MIN_ICON_SIZE; | ||||||
|  |             if (this._fixedVItemSize < MIN_ICON_SIZE) | ||||||
|  |                 this._fixedVItemSize = MIN_ICON_SIZE; | ||||||
|  |  | ||||||
|             this._updateSpacingForSize(availWidth, availHeight); |             this._updateSpacingForSize(availWidth, availHeight); | ||||||
|         } |         } | ||||||
|         Meta.later_add(Meta.LaterType.BEFORE_REDRAW, |         let scale = Math.min(this._fixedHItemSize, this._fixedVItemSize) / Math.max(this._hItemSize, this._vItemSize); | ||||||
|                        Lang.bind(this, this._updateIconSizes)); |         Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() { this._updateChildrenScale(scale); })); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     // Note that this is ICON_SIZE as used by BaseIcon, not elsewhere in IconGrid; it's a bit messed up |     // Note that this is ICON_SIZE as used by BaseIcon, not elsewhere in IconGrid; it's a bit messed up | ||||||
|     _updateIconSizes: function() { |     _updateChildrenScale: function(scale) { | ||||||
|         let scale = Math.min(this._fixedHItemSize, this._fixedVItemSize) / Math.max(this._hItemSize, this._vItemSize); |  | ||||||
|         let newIconSize = Math.floor(ICON_SIZE * scale); |  | ||||||
|         for (let i in this._items) { |         for (let i in this._items) { | ||||||
|  |             let newIconSize = Math.floor(ICON_SIZE * scale); | ||||||
|             this._items[i].icon.setIconSize(newIconSize); |             this._items[i].icon.setIconSize(newIconSize); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -797,7 +550,6 @@ const PaginatedIconGrid = new Lang.Class({ | |||||||
|     _init: function(params) { |     _init: function(params) { | ||||||
|         this.parent(params); |         this.parent(params); | ||||||
|         this._nPages = 0; |         this._nPages = 0; | ||||||
|         this.currentPage = 0; |  | ||||||
|         this._rowsPerPage = 0; |         this._rowsPerPage = 0; | ||||||
|         this._spaceBetweenPages = 0; |         this._spaceBetweenPages = 0; | ||||||
|         this._childrenPerPage = 0; |         this._childrenPerPage = 0; | ||||||
| @@ -861,15 +613,6 @@ const PaginatedIconGrid = new Lang.Class({ | |||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     // Overriden from IconGrid |  | ||||||
|     _getChildrenToAnimate: function() { |  | ||||||
|         let children = this._getVisibleChildren(); |  | ||||||
|         let firstIndex = this._childrenPerPage * this.currentPage; |  | ||||||
|         let lastIndex = firstIndex + this._childrenPerPage; |  | ||||||
|  |  | ||||||
|         return children.slice(firstIndex, lastIndex); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _computePages: function (availWidthPerPage, availHeightPerPage) { |     _computePages: function (availWidthPerPage, availHeightPerPage) { | ||||||
|         let [nColumns, usedWidth] = this._computeLayout(availWidthPerPage); |         let [nColumns, usedWidth] = this._computeLayout(availWidthPerPage); | ||||||
|         let nRows; |         let nRows; | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ const Gdk = imports.gi.Gdk; | |||||||
| const Gio = imports.gi.Gio; | const Gio = imports.gi.Gio; | ||||||
| const GLib = imports.gi.GLib; | const GLib = imports.gi.GLib; | ||||||
| const Lang = imports.lang; | const Lang = imports.lang; | ||||||
| const Meta = imports.gi.Meta; |  | ||||||
| const Shell = imports.gi.Shell; | const Shell = imports.gi.Shell; | ||||||
| const Signals = imports.signals; | const Signals = imports.signals; | ||||||
| const St = imports.gi.St; | const St = imports.gi.St; | ||||||
| @@ -24,9 +23,6 @@ const KEYBOARD_TYPE = 'keyboard-type'; | |||||||
| const A11Y_APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications'; | const A11Y_APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications'; | ||||||
| const SHOW_KEYBOARD = 'screen-keyboard-enabled'; | const SHOW_KEYBOARD = 'screen-keyboard-enabled'; | ||||||
|  |  | ||||||
| const CARIBOU_BUS_NAME = 'org.gnome.Caribou.Daemon'; |  | ||||||
| const CARIBOU_OBJECT_PATH = '/org/gnome/Caribou/Daemon'; |  | ||||||
|  |  | ||||||
| const CaribouKeyboardIface = '<node> \ | const CaribouKeyboardIface = '<node> \ | ||||||
| <interface name="org.gnome.Caribou.Keyboard"> \ | <interface name="org.gnome.Caribou.Keyboard"> \ | ||||||
| <method name="Show"> \ | <method name="Show"> \ | ||||||
| @@ -51,22 +47,13 @@ const CaribouKeyboardIface = '<node> \ | |||||||
| </interface> \ | </interface> \ | ||||||
| </node>'; | </node>'; | ||||||
|  |  | ||||||
| const CaribouDaemonIface = '<node> \ |  | ||||||
| <interface name="org.gnome.Caribou.Daemon"> \ |  | ||||||
| <method name="Run" /> \ |  | ||||||
| <method name="Quit" /> \ |  | ||||||
| </interface> \ |  | ||||||
| </node>'; |  | ||||||
|  |  | ||||||
| const CaribouDaemonProxy = Gio.DBusProxy.makeProxyWrapper(CaribouDaemonIface); |  | ||||||
|  |  | ||||||
| const Key = new Lang.Class({ | const Key = new Lang.Class({ | ||||||
|     Name: 'Key', |     Name: 'Key', | ||||||
|  |  | ||||||
|     _init : function(key) { |     _init : function(key) { | ||||||
|         this._key = key; |         this._key = key; | ||||||
|         this.actor = this._makeKey(key, GLib.markup_escape_text(key.label, -1)); |  | ||||||
|         this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); |         this.actor = this._makeKey(); | ||||||
|  |  | ||||||
|         this._extended_keys = this._key.get_extended_keys(); |         this._extended_keys = this._key.get_extended_keys(); | ||||||
|         this._extended_keyboard = null; |         this._extended_keyboard = null; | ||||||
| @@ -89,55 +76,20 @@ const Key = new Lang.Class({ | |||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onDestroy: function() { |     _makeKey: function () { | ||||||
|         if (this._boxPointer) { |         let label = GLib.markup_escape_text(this._key.label, -1); | ||||||
|             this._boxPointer.actor.destroy(); |  | ||||||
|             this._boxPointer = null; |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _makeKey: function (key, label) { |  | ||||||
|         let button = new St.Button ({ label: label, |         let button = new St.Button ({ label: label, | ||||||
|                                       style_class: 'keyboard-key' }); |                                       style_class: 'keyboard-key' }); | ||||||
|  |  | ||||||
|         button.key_width = this._key.width; |         button.key_width = this._key.width; | ||||||
|         button.connect('button-press-event', Lang.bind(this, |         button.connect('button-press-event', Lang.bind(this, | ||||||
|             function () { |             function () { | ||||||
|                 key.press(); |                 this._key.press(); | ||||||
|                 return Clutter.EVENT_PROPAGATE; |                 return Clutter.EVENT_PROPAGATE; | ||||||
|             })); |             })); | ||||||
|         button.connect('button-release-event', Lang.bind(this, |         button.connect('button-release-event', Lang.bind(this, | ||||||
|             function () { |             function () { | ||||||
|                 key.release(); |                 this._key.release(); | ||||||
|                 return Clutter.EVENT_PROPAGATE; |  | ||||||
|             })); |  | ||||||
|         button.connect('touch-event', Lang.bind(this, |  | ||||||
|             function (actor, event) { |  | ||||||
|                 let device = event.get_device(); |  | ||||||
|                 let sequence = event.get_event_sequence(); |  | ||||||
|  |  | ||||||
|                 // We only handle touch events here on wayland. On X11 |  | ||||||
|                 // we do get emulated pointer events, which already works |  | ||||||
|                 // for single-touch cases. Besides, the X11 passive touch grab |  | ||||||
|                 // set up by Mutter will make us see first the touch events |  | ||||||
|                 // and later the pointer events, so it will look like two |  | ||||||
|                 // unrelated series of events, we want to avoid double handling |  | ||||||
|                 // in these cases. |  | ||||||
|                 if (!Meta.is_wayland_compositor()) |  | ||||||
|                     return Clutter.EVENT_PROPAGATE; |  | ||||||
|  |  | ||||||
|                 if (!this._touchPressed && |  | ||||||
|                     event.type() == Clutter.EventType.TOUCH_BEGIN) { |  | ||||||
|                     device.sequence_grab(sequence, actor); |  | ||||||
|                     this._touchPressed = true; |  | ||||||
|                     key.press(); |  | ||||||
|                 } else if (this._touchPressed && |  | ||||||
|                            event.type() == Clutter.EventType.TOUCH_END && |  | ||||||
|                            device.sequence_get_grabbed_actor(sequence) == actor) { |  | ||||||
|                     device.sequence_ungrab(sequence); |  | ||||||
|                     this._touchPressed = false; |  | ||||||
|                     key.release(); |  | ||||||
|                 } |  | ||||||
|                 return Clutter.EVENT_PROPAGATE; |                 return Clutter.EVENT_PROPAGATE; | ||||||
|             })); |             })); | ||||||
|  |  | ||||||
| @@ -160,9 +112,18 @@ const Key = new Lang.Class({ | |||||||
|         for (let i = 0; i < this._extended_keys.length; ++i) { |         for (let i = 0; i < this._extended_keys.length; ++i) { | ||||||
|             let extended_key = this._extended_keys[i]; |             let extended_key = this._extended_keys[i]; | ||||||
|             let label = this._getUnichar(extended_key); |             let label = this._getUnichar(extended_key); | ||||||
|             let key = this._makeKey(extended_key, label); |             let key = new St.Button({ label: label, style_class: 'keyboard-key' }); | ||||||
|  |  | ||||||
|             key.extended_key = extended_key; |             key.extended_key = extended_key; | ||||||
|  |             key.connect('button-press-event', Lang.bind(this, | ||||||
|  |                 function () { | ||||||
|  |                     extended_key.press(); | ||||||
|  |                     return Clutter.EVENT_PROPAGATE; | ||||||
|  |                 })); | ||||||
|  |             key.connect('button-release-event', Lang.bind(this, | ||||||
|  |                 function () { | ||||||
|  |                     extended_key.release(); | ||||||
|  |                     return Clutter.EVENT_PROPAGATE; | ||||||
|  |                 })); | ||||||
|             this._extended_keyboard.add(key); |             this._extended_keyboard.add(key); | ||||||
|         } |         } | ||||||
|         this._boxPointer.bin.add_actor(this._extended_keyboard); |         this._boxPointer.bin.add_actor(this._extended_keyboard); | ||||||
| @@ -200,28 +161,11 @@ const Keyboard = new Lang.Class({ | |||||||
|  |  | ||||||
|         this._timestamp = global.display.get_current_time_roundtrip(); |         this._timestamp = global.display.get_current_time_roundtrip(); | ||||||
|  |  | ||||||
|         this._keyboardSettings = new Gio.Settings({ schema_id: KEYBOARD_SCHEMA }); |         this._keyboardSettings = new Gio.Settings({ schema: KEYBOARD_SCHEMA }); | ||||||
|         this._keyboardSettings.connect('changed', Lang.bind(this, this._sync)); |         this._keyboardSettings.connect('changed', Lang.bind(this, this._settingsChanged)); | ||||||
|         this._a11yApplicationsSettings = new Gio.Settings({ schema_id: A11Y_APPLICATIONS_SCHEMA }); |         this._a11yApplicationsSettings = new Gio.Settings({ schema: A11Y_APPLICATIONS_SCHEMA }); | ||||||
|         this._a11yApplicationsSettings.connect('changed', Lang.bind(this, this._sync)); |         this._a11yApplicationsSettings.connect('changed', Lang.bind(this, this._settingsChanged)); | ||||||
|         this._daemonProxy = null; |         this._settingsChanged(); | ||||||
|         this._lastDeviceId = null; |  | ||||||
|  |  | ||||||
|         if (Meta.is_wayland_compositor() && |  | ||||||
|             Caribou.DisplayAdapter.set_default) |  | ||||||
|             Caribou.DisplayAdapter.set_default(new ShellWaylandAdapter()); |  | ||||||
|  |  | ||||||
|         Meta.get_backend().connect('last-device-changed', Lang.bind(this, |  | ||||||
|             function (backend, deviceId) { |  | ||||||
|                 let manager = Clutter.DeviceManager.get_default(); |  | ||||||
|                 let device = manager.get_device(deviceId); |  | ||||||
|  |  | ||||||
|                 if (device.get_device_name().indexOf('XTEST') < 0) { |  | ||||||
|                     this._lastDeviceId = deviceId; |  | ||||||
|                     this._sync(); |  | ||||||
|                 } |  | ||||||
|             })); |  | ||||||
|         this._sync(); |  | ||||||
|  |  | ||||||
|         this._showIdleId = 0; |         this._showIdleId = 0; | ||||||
|         this._subkeysBoxPointer = null; |         this._subkeysBoxPointer = null; | ||||||
| @@ -239,22 +183,8 @@ const Keyboard = new Lang.Class({ | |||||||
|         this._redraw(); |         this._redraw(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _lastDeviceIsTouchscreen: function () { |     _settingsChanged: function (settings, key) { | ||||||
|         if (!this._lastDeviceId) |         this._enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD); | ||||||
|             return false; |  | ||||||
|  |  | ||||||
|         let manager = Clutter.DeviceManager.get_default(); |  | ||||||
|         let device = manager.get_device(this._lastDeviceId); |  | ||||||
|  |  | ||||||
|         if (!device) |  | ||||||
|             return false; |  | ||||||
|  |  | ||||||
|         return device.get_device_type() == Clutter.InputDeviceType.TOUCHSCREEN_DEVICE; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _sync: function () { |  | ||||||
|         this._enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD) || |  | ||||||
|                                this._lastDeviceIsTouchscreen(); |  | ||||||
|         if (!this._enableKeyboard && !this._keyboard) |         if (!this._enableKeyboard && !this._keyboard) | ||||||
|             return; |             return; | ||||||
|         if (this._enableKeyboard && this._keyboard && |         if (this._enableKeyboard && this._keyboard && | ||||||
| @@ -284,35 +214,9 @@ const Keyboard = new Lang.Class({ | |||||||
|         this.actor = null; |         this.actor = null; | ||||||
|  |  | ||||||
|         this._destroySource(); |         this._destroySource(); | ||||||
|         if (this._daemonProxy) { |  | ||||||
|             this._daemonProxy.QuitRemote(function (result, error) { |  | ||||||
|                 if (error) { |  | ||||||
|                     log(error.message); |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|             this._daemonProxy = null; |  | ||||||
|         } |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _setupKeyboard: function() { |     _setupKeyboard: function() { | ||||||
|         if (!this._daemonProxy) { |  | ||||||
|             this._daemonProxy = new CaribouDaemonProxy(Gio.DBus.session, CARIBOU_BUS_NAME, |  | ||||||
|                                                        CARIBOU_OBJECT_PATH, |  | ||||||
|                                                        Lang.bind(this, function(proxy, error) { |  | ||||||
|                                                            if (error) { |  | ||||||
|                                                                log(error.message); |  | ||||||
|                                                                return; |  | ||||||
|                                                            } |  | ||||||
|                                                        })); |  | ||||||
|         } |  | ||||||
|         this._daemonProxy.RunRemote(function (result, error) { |  | ||||||
|             if (error) { |  | ||||||
|                 log(error.message); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true }); |         this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true }); | ||||||
|         Main.layoutManager.keyboardBox.add_actor(this.actor); |         Main.layoutManager.keyboardBox.add_actor(this.actor); | ||||||
|         Main.layoutManager.trackChrome(this.actor); |         Main.layoutManager.trackChrome(this.actor); | ||||||
| @@ -651,7 +555,7 @@ const Keyboard = new Lang.Class({ | |||||||
|  |  | ||||||
|     _moveTemporarily: function () { |     _moveTemporarily: function () { | ||||||
|         let currentWindow = global.screen.get_display().focus_window; |         let currentWindow = global.screen.get_display().focus_window; | ||||||
|         let rect = currentWindow.get_frame_rect(); |         let rect = currentWindow.get_outer_rect(); | ||||||
|  |  | ||||||
|         let newX = rect.x; |         let newX = rect.x; | ||||||
|         let newY = 3 * this.actor.height / 2; |         let newY = 3 * this.actor.height / 2; | ||||||
| @@ -752,24 +656,3 @@ const KeyboardSource = new Lang.Class({ | |||||||
|         this._keyboard.show(Main.layoutManager.bottomIndex); |         this._keyboard.show(Main.layoutManager.bottomIndex); | ||||||
|     } |     } | ||||||
| }); | }); | ||||||
|  |  | ||||||
| const ShellWaylandAdapter = new Lang.Class({ |  | ||||||
|     Name: 'ShellWaylandAdapter', |  | ||||||
|     Extends: Caribou.XAdapter, |  | ||||||
|  |  | ||||||
|     vfunc_keyval_press: function(keyval) { |  | ||||||
|         let focus = global.stage.get_key_focus(); |  | ||||||
|         if (focus instanceof Clutter.Text) |  | ||||||
|             Shell.util_text_insert_keyval(focus, keyval); |  | ||||||
|         else |  | ||||||
|             this.parent(keyval); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     vfunc_keyval_release: function(keyval) { |  | ||||||
|         let focus = global.stage.get_key_focus(); |  | ||||||
|         if (focus instanceof Clutter.Text) |  | ||||||
|             return;             // do nothing |  | ||||||
|         else |  | ||||||
|             this.parent(keyval); |  | ||||||
|     }, |  | ||||||
| }); |  | ||||||
|   | |||||||
							
								
								
									
										332
									
								
								js/ui/layout.js
									
									
									
									
									
								
							
							
						
						| @@ -11,7 +11,6 @@ const St = imports.gi.St; | |||||||
|  |  | ||||||
| const Background = imports.ui.background; | const Background = imports.ui.background; | ||||||
| const BackgroundMenu = imports.ui.backgroundMenu; | const BackgroundMenu = imports.ui.backgroundMenu; | ||||||
| const LoginManager = imports.misc.loginManager; |  | ||||||
|  |  | ||||||
| const DND = imports.ui.dnd; | const DND = imports.ui.dnd; | ||||||
| const Main = imports.ui.main; | const Main = imports.ui.main; | ||||||
| @@ -21,6 +20,12 @@ const Tweener = imports.ui.tweener; | |||||||
| const STARTUP_ANIMATION_TIME = 0.5; | const STARTUP_ANIMATION_TIME = 0.5; | ||||||
| const KEYBOARD_ANIMATION_TIME = 0.15; | const KEYBOARD_ANIMATION_TIME = 0.15; | ||||||
| const BACKGROUND_FADE_ANIMATION_TIME = 1.0; | const BACKGROUND_FADE_ANIMATION_TIME = 1.0; | ||||||
|  | const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff); | ||||||
|  |  | ||||||
|  | // The message tray takes this much pressure | ||||||
|  | // in the pressure barrier at once to release it. | ||||||
|  | const MESSAGE_TRAY_PRESSURE_THRESHOLD = 250; // pixels | ||||||
|  | const MESSAGE_TRAY_PRESSURE_TIMEOUT = 1000; // ms | ||||||
|  |  | ||||||
| const HOT_CORNER_PRESSURE_THRESHOLD = 100; // pixels | const HOT_CORNER_PRESSURE_THRESHOLD = 100; // pixels | ||||||
| const HOT_CORNER_PRESSURE_TIMEOUT = 1000; // ms | const HOT_CORNER_PRESSURE_TIMEOUT = 1000; // ms | ||||||
| @@ -46,16 +51,11 @@ const MonitorConstraint = new Lang.Class({ | |||||||
|                  'index': GObject.ParamSpec.int('index', |                  'index': GObject.ParamSpec.int('index', | ||||||
|                                                 'Monitor index', 'Track specific monitor', |                                                 'Monitor index', 'Track specific monitor', | ||||||
|                                                 GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE, |                                                 GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE, | ||||||
|                                                 -1, 64, -1), |                                                 -1, 64, -1)}, | ||||||
|                  'work-area': GObject.ParamSpec.boolean('work-area', |  | ||||||
|                                                         'Work-area', 'Track monitor\'s work-area', |  | ||||||
|                                                         GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE, |  | ||||||
|                                                         false)}, |  | ||||||
|  |  | ||||||
|     _init: function(props) { |     _init: function(props) { | ||||||
|         this._primary = false; |         this._primary = false; | ||||||
|         this._index = -1; |         this._index = -1; | ||||||
|         this._workArea = false; |  | ||||||
|  |  | ||||||
|         this.parent(props); |         this.parent(props); | ||||||
|     }, |     }, | ||||||
| @@ -85,19 +85,6 @@ const MonitorConstraint = new Lang.Class({ | |||||||
|         this.notify('index'); |         this.notify('index'); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     get work_area() { |  | ||||||
|         return this._workArea; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     set work_area(v) { |  | ||||||
|         if (v == this._workArea) |  | ||||||
|             return; |  | ||||||
|         this._workArea = v; |  | ||||||
|         if (this.actor) |  | ||||||
|             this.actor.queue_relayout(); |  | ||||||
|         this.notify('work-area'); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     vfunc_set_actor: function(actor) { |     vfunc_set_actor: function(actor) { | ||||||
|         if (actor) { |         if (actor) { | ||||||
|             if (!this._monitorsChangedId) { |             if (!this._monitorsChangedId) { | ||||||
| @@ -105,21 +92,10 @@ const MonitorConstraint = new Lang.Class({ | |||||||
|                     this.actor.queue_relayout(); |                     this.actor.queue_relayout(); | ||||||
|                 })); |                 })); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (!this._workareasChangedId) { |  | ||||||
|                 this._workareasChangedId = global.screen.connect('workareas-changed', Lang.bind(this, function() { |  | ||||||
|                     if (this._workArea) |  | ||||||
|                         this.actor.queue_relayout(); |  | ||||||
|                 })); |  | ||||||
|             } |  | ||||||
|         } else { |         } else { | ||||||
|             if (this._monitorsChangedId) |             if (this._monitorsChangedId) | ||||||
|                 Main.layoutManager.disconnect(this._monitorsChangedId); |                 Main.layoutManager.disconnect(this._monitorsChangedId); | ||||||
|             this._monitorsChangedId = 0; |             this._monitorsChangedId = 0; | ||||||
|  |  | ||||||
|             if (this._workareasChangedId) |  | ||||||
|                 global.screen.disconnect(this._workareasChangedId); |  | ||||||
|             this._workareasChangedId = 0; |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         this.parent(actor); |         this.parent(actor); | ||||||
| @@ -129,21 +105,15 @@ const MonitorConstraint = new Lang.Class({ | |||||||
|         if (!this._primary && this._index < 0) |         if (!this._primary && this._index < 0) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         let index; |         let monitor; | ||||||
|         if (this._primary) |         if (this._primary) { | ||||||
|             index = Main.layoutManager.primaryIndex; |             monitor = Main.layoutManager.primaryMonitor; | ||||||
|         else |  | ||||||
|             index = Math.min(this._index, Main.layoutManager.monitors.length - 1); |  | ||||||
|  |  | ||||||
|         let rect; |  | ||||||
|         if (this._workArea) { |  | ||||||
|             let ws = global.screen.get_workspace_by_index(0); |  | ||||||
|             rect = ws.get_work_area_for_monitor(index); |  | ||||||
|         } else { |         } else { | ||||||
|             rect = Main.layoutManager.monitors[index]; |             let index = Math.min(this._index, Main.layoutManager.monitors.length - 1); | ||||||
|  |             monitor = Main.layoutManager.monitors[index]; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         actorBox.init_rect(rect.x, rect.y, rect.width, rect.height); |         actorBox.init_rect(monitor.x, monitor.y, monitor.width, monitor.height); | ||||||
|     } |     } | ||||||
| }); | }); | ||||||
|  |  | ||||||
| @@ -166,7 +136,6 @@ const Monitor = new Lang.Class({ | |||||||
| const defaultParams = { | const defaultParams = { | ||||||
|     trackFullscreen: false, |     trackFullscreen: false, | ||||||
|     affectsStruts: false, |     affectsStruts: false, | ||||||
|     affectsInputRegion: true |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const LayoutManager = new Lang.Class({ | const LayoutManager = new Lang.Class({ | ||||||
| @@ -181,6 +150,7 @@ const LayoutManager = new Lang.Class({ | |||||||
|  |  | ||||||
|         this._keyboardIndex = -1; |         this._keyboardIndex = -1; | ||||||
|         this._rightPanelBarrier = null; |         this._rightPanelBarrier = null; | ||||||
|  |         this._trayBarrier = null; | ||||||
|  |  | ||||||
|         this._inOverview = false; |         this._inOverview = false; | ||||||
|         this._updateRegionIdle = 0; |         this._updateRegionIdle = 0; | ||||||
| @@ -190,10 +160,10 @@ const LayoutManager = new Lang.Class({ | |||||||
|         this._isPopupWindowVisible = false; |         this._isPopupWindowVisible = false; | ||||||
|         this._startingUp = true; |         this._startingUp = true; | ||||||
|  |  | ||||||
|         // We don't want to paint the stage background color because either |         // Normally, the stage is always covered so Clutter doesn't need to clear | ||||||
|         // the SystemBackground we create or the MetaBackgroundActor inside |         // it; however it becomes visible during the startup animation | ||||||
|         // global.window_group covers the entirety of the screen. |         // See the comment below for a longer explanation | ||||||
|         global.stage.no_clear_hint = true; |         global.stage.color = DEFAULT_BACKGROUND_COLOR; | ||||||
|  |  | ||||||
|         // Set up stage hierarchy to group all UI actors under one container. |         // Set up stage hierarchy to group all UI actors under one container. | ||||||
|         this.uiGroup = new Shell.GenericContainer({ name: 'uiGroup' }); |         this.uiGroup = new Shell.GenericContainer({ name: 'uiGroup' }); | ||||||
| @@ -237,6 +207,11 @@ const LayoutManager = new Lang.Class({ | |||||||
|         this.panelBox.connect('allocation-changed', |         this.panelBox.connect('allocation-changed', | ||||||
|                               Lang.bind(this, this._panelBoxChanged)); |                               Lang.bind(this, this._panelBoxChanged)); | ||||||
|  |  | ||||||
|  |         this.trayBox = new St.Widget({ name: 'trayBox', | ||||||
|  |                                        layout_manager: new Clutter.BinLayout() });  | ||||||
|  |         this.addChrome(this.trayBox); | ||||||
|  |         this._setupTrayPressure(); | ||||||
|  |  | ||||||
|         this.modalDialogGroup = new St.Widget({ name: 'modalDialogGroup', |         this.modalDialogGroup = new St.Widget({ name: 'modalDialogGroup', | ||||||
|                                                 layout_manager: new Clutter.BinLayout() }); |                                                 layout_manager: new Clutter.BinLayout() }); | ||||||
|         this.uiGroup.add_actor(this.modalDialogGroup); |         this.uiGroup.add_actor(this.modalDialogGroup); | ||||||
| @@ -249,16 +224,12 @@ const LayoutManager = new Lang.Class({ | |||||||
|  |  | ||||||
|         // A dummy actor that tracks the mouse or text cursor, based on the |         // A dummy actor that tracks the mouse or text cursor, based on the | ||||||
|         // position and size set in setDummyCursorGeometry. |         // position and size set in setDummyCursorGeometry. | ||||||
|         this.dummyCursor = new St.Widget({ width: 0, height: 0, visible: false }); |         this.dummyCursor = new St.Widget({ width: 0, height: 0 }); | ||||||
|         this.uiGroup.add_actor(this.dummyCursor); |         this.uiGroup.add_actor(this.dummyCursor); | ||||||
|  |  | ||||||
|         global.stage.remove_actor(global.top_window_group); |         global.stage.remove_actor(global.top_window_group); | ||||||
|         this.uiGroup.add_actor(global.top_window_group); |         this.uiGroup.add_actor(global.top_window_group); | ||||||
|  |  | ||||||
|         let feedbackGroup = Meta.get_feedback_group_for_screen(global.screen); |  | ||||||
|         global.stage.remove_actor(feedbackGroup); |  | ||||||
|         this.uiGroup.add_actor(feedbackGroup); |  | ||||||
|  |  | ||||||
|         this._backgroundGroup = new Meta.BackgroundGroup(); |         this._backgroundGroup = new Meta.BackgroundGroup(); | ||||||
|         global.window_group.add_child(this._backgroundGroup); |         global.window_group.add_child(this._backgroundGroup); | ||||||
|         this._backgroundGroup.lower_bottom(); |         this._backgroundGroup.lower_bottom(); | ||||||
| @@ -274,18 +245,6 @@ const LayoutManager = new Lang.Class({ | |||||||
|         global.screen.connect('in-fullscreen-changed', |         global.screen.connect('in-fullscreen-changed', | ||||||
|                               Lang.bind(this, this._updateFullscreen)); |                               Lang.bind(this, this._updateFullscreen)); | ||||||
|         this._monitorsChanged(); |         this._monitorsChanged(); | ||||||
|  |  | ||||||
|         // NVIDIA drivers don't preserve FBO contents across |  | ||||||
|         // suspend/resume, see |  | ||||||
|         // https://bugzilla.gnome.org/show_bug.cgi?id=739178 |  | ||||||
|         if (Shell.util_need_background_refresh()) { |  | ||||||
|             LoginManager.getLoginManager().connect('prepare-for-sleep', |  | ||||||
|                                                    function(lm, suspending) { |  | ||||||
|                                                        if (suspending) |  | ||||||
|                                                            return; |  | ||||||
|                                                        Meta.Background.refresh_all(); |  | ||||||
|                                                    }); |  | ||||||
|         } |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     // This is called by Main after everything else is constructed |     // This is called by Main after everything else is constructed | ||||||
| @@ -300,6 +259,7 @@ const LayoutManager = new Lang.Class({ | |||||||
|  |  | ||||||
|         this._inOverview = true; |         this._inOverview = true; | ||||||
|         this._updateVisibility(); |         this._updateVisibility(); | ||||||
|  |         this._updateRegions(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     hideOverview: function() { |     hideOverview: function() { | ||||||
| @@ -307,6 +267,7 @@ const LayoutManager = new Lang.Class({ | |||||||
|  |  | ||||||
|         this._inOverview = false; |         this._inOverview = false; | ||||||
|         this._updateVisibility(); |         this._updateVisibility(); | ||||||
|  |         this._queueUpdateRegions(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _sessionUpdated: function() { |     _sessionUpdated: function() { | ||||||
| @@ -400,7 +361,7 @@ const LayoutManager = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _addBackgroundMenu: function(bgManager) { |     _addBackgroundMenu: function(bgManager) { | ||||||
|         BackgroundMenu.addBackgroundMenu(bgManager.backgroundActor, this); |         BackgroundMenu.addBackgroundMenu(bgManager.background.actor, this); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _createBackgroundManager: function(monitorIndex) { |     _createBackgroundManager: function(monitorIndex) { | ||||||
| @@ -417,10 +378,10 @@ const LayoutManager = new Lang.Class({ | |||||||
|     _showSecondaryBackgrounds: function() { |     _showSecondaryBackgrounds: function() { | ||||||
|         for (let i = 0; i < this.monitors.length; i++) { |         for (let i = 0; i < this.monitors.length; i++) { | ||||||
|             if (i != this.primaryIndex) { |             if (i != this.primaryIndex) { | ||||||
|                 let backgroundActor = this._bgManagers[i].backgroundActor; |                 let background = this._bgManagers[i].background; | ||||||
|                 backgroundActor.show(); |                 background.actor.show(); | ||||||
|                 backgroundActor.opacity = 0; |                 background.actor.opacity = 0; | ||||||
|                 Tweener.addTween(backgroundActor, |                 Tweener.addTween(background.actor, | ||||||
|                                  { opacity: 255, |                                  { opacity: 255, | ||||||
|                                    time: BACKGROUND_FADE_ANIMATION_TIME, |                                    time: BACKGROUND_FADE_ANIMATION_TIME, | ||||||
|                                    transition: 'easeOutQuad' }); |                                    transition: 'easeOutQuad' }); | ||||||
| @@ -443,16 +404,10 @@ const LayoutManager = new Lang.Class({ | |||||||
|             this._bgManagers.push(bgManager); |             this._bgManagers.push(bgManager); | ||||||
|  |  | ||||||
|             if (i != this.primaryIndex && this._startingUp) |             if (i != this.primaryIndex && this._startingUp) | ||||||
|                 bgManager.backgroundActor.hide(); |                 bgManager.background.actor.hide(); | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _updateKeyboardBox: function() { |  | ||||||
|         this.keyboardBox.set_position(this.keyboardMonitor.x, |  | ||||||
|                                       this.keyboardMonitor.y + this.keyboardMonitor.height); |  | ||||||
|         this.keyboardBox.set_size(this.keyboardMonitor.width, -1); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _updateBoxes: function() { |     _updateBoxes: function() { | ||||||
|         this.screenShieldGroup.set_position(0, 0); |         this.screenShieldGroup.set_position(0, 0); | ||||||
|         this.screenShieldGroup.set_size(global.screen_width, global.screen_height); |         this.screenShieldGroup.set_size(global.screen_width, global.screen_height); | ||||||
| @@ -460,7 +415,12 @@ const LayoutManager = new Lang.Class({ | |||||||
|         this.panelBox.set_position(this.primaryMonitor.x, this.primaryMonitor.y); |         this.panelBox.set_position(this.primaryMonitor.x, this.primaryMonitor.y); | ||||||
|         this.panelBox.set_size(this.primaryMonitor.width, -1); |         this.panelBox.set_size(this.primaryMonitor.width, -1); | ||||||
|  |  | ||||||
|  |         if (this.keyboardIndex < 0) | ||||||
|             this.keyboardIndex = this.primaryIndex; |             this.keyboardIndex = this.primaryIndex; | ||||||
|  |  | ||||||
|  |         this.trayBox.set_position(this.bottomMonitor.x, | ||||||
|  |                                   this.bottomMonitor.y + this.bottomMonitor.height); | ||||||
|  |         this.trayBox.set_size(this.bottomMonitor.width, -1); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _panelBoxChanged: function() { |     _panelBoxChanged: function() { | ||||||
| @@ -489,9 +449,50 @@ const LayoutManager = new Lang.Class({ | |||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|  |     _setupTrayPressure: function() { | ||||||
|  |         this._trayPressure = new PressureBarrier(MESSAGE_TRAY_PRESSURE_THRESHOLD, | ||||||
|  |                                                  MESSAGE_TRAY_PRESSURE_TIMEOUT, | ||||||
|  |                                                  Shell.KeyBindingMode.NORMAL | | ||||||
|  |                                                  Shell.KeyBindingMode.OVERVIEW); | ||||||
|  |         this._trayPressure.setEventFilter(this._trayBarrierEventFilter); | ||||||
|  |         this._trayPressure.connect('trigger', function(barrier) { | ||||||
|  |             if (Main.layoutManager.bottomMonitor.inFullscreen) | ||||||
|  |                 return; | ||||||
|  |  | ||||||
|  |             Main.messageTray.openTray(); | ||||||
|  |         }); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _updateTrayBarrier: function() { | ||||||
|  |         let monitor = this.bottomMonitor; | ||||||
|  |  | ||||||
|  |         if (this._trayBarrier) { | ||||||
|  |             this._trayPressure.removeBarrier(this._trayBarrier); | ||||||
|  |             this._trayBarrier.destroy(); | ||||||
|  |             this._trayBarrier = null; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         this._trayBarrier = new Meta.Barrier({ display: global.display, | ||||||
|  |                                                x1: monitor.x, x2: monitor.x + monitor.width, | ||||||
|  |                                                y1: monitor.y + monitor.height, y2: monitor.y + monitor.height, | ||||||
|  |                                                directions: Meta.BarrierDirection.NEGATIVE_Y }); | ||||||
|  |         this._trayPressure.addBarrier(this._trayBarrier); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _trayBarrierEventFilter: function(event) { | ||||||
|  |         // Throw out all events where the pointer was grabbed by another | ||||||
|  |         // client, as the client that grabbed the pointer expects to have | ||||||
|  |         // complete control over it | ||||||
|  |         if (event.grabbed && Main.modalCount == 0) | ||||||
|  |             return true; | ||||||
|  |  | ||||||
|  |         return false; | ||||||
|  |     }, | ||||||
|  |  | ||||||
|     _monitorsChanged: function() { |     _monitorsChanged: function() { | ||||||
|         this._updateMonitors(); |         this._updateMonitors(); | ||||||
|         this._updateBoxes(); |         this._updateBoxes(); | ||||||
|  |         this._updateTrayBarrier(); | ||||||
|         this._updateHotCorners(); |         this._updateHotCorners(); | ||||||
|         this._updateBackgrounds(); |         this._updateBackgrounds(); | ||||||
|         this._updateFullscreen(); |         this._updateFullscreen(); | ||||||
| @@ -540,7 +541,9 @@ const LayoutManager = new Lang.Class({ | |||||||
|  |  | ||||||
|     set keyboardIndex(v) { |     set keyboardIndex(v) { | ||||||
|         this._keyboardIndex = v; |         this._keyboardIndex = v; | ||||||
|         this._updateKeyboardBox(); |         this.keyboardBox.set_position(this.keyboardMonitor.x, | ||||||
|  |                                       this.keyboardMonitor.y + this.keyboardMonitor.height); | ||||||
|  |         this.keyboardBox.set_size(this.keyboardMonitor.width, -1); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     get keyboardIndex() { |     get keyboardIndex() { | ||||||
| @@ -580,6 +583,10 @@ const LayoutManager = new Lang.Class({ | |||||||
|     // |     // | ||||||
|     // When starting a normal user session, we want to grow it out of the middle |     // When starting a normal user session, we want to grow it out of the middle | ||||||
|     // of the screen. |     // of the screen. | ||||||
|  |     // | ||||||
|  |     // Usually, we don't want to paint the stage background color because the | ||||||
|  |     // MetaBackgroundActor inside global.window_group covers the entirety of the | ||||||
|  |     // screen. So, we set no_clear_hint at the end of the animation. | ||||||
|  |  | ||||||
|     _prepareStartupAnimation: function() { |     _prepareStartupAnimation: function() { | ||||||
|         // During the initial transition, add a simple actor to block all events, |         // During the initial transition, add a simple actor to block all events, | ||||||
| @@ -590,9 +597,7 @@ const LayoutManager = new Lang.Class({ | |||||||
|                                               reactive: true }); |                                               reactive: true }); | ||||||
|         this.addChrome(this._coverPane); |         this.addChrome(this._coverPane); | ||||||
|  |  | ||||||
|         if (Meta.is_restart()) { |         if (Main.sessionMode.isGreeter) { | ||||||
|             // On restart, we don't do an animation |  | ||||||
|         } else if (Main.sessionMode.isGreeter) { |  | ||||||
|             this.panelBox.translation_y = -this.panelBox.height; |             this.panelBox.translation_y = -this.panelBox.height; | ||||||
|         } else { |         } else { | ||||||
|             this._updateBackgrounds(); |             this._updateBackgrounds(); | ||||||
| @@ -601,6 +606,7 @@ const LayoutManager = new Lang.Class({ | |||||||
|             // the UI group to get the correct allocation for the struts. |             // the UI group to get the correct allocation for the struts. | ||||||
|             this._updateRegions(); |             this._updateRegions(); | ||||||
|  |  | ||||||
|  |             this.trayBox.hide(); | ||||||
|             this.keyboardBox.hide(); |             this.keyboardBox.hide(); | ||||||
|  |  | ||||||
|             let monitor = this.primaryMonitor; |             let monitor = this.primaryMonitor; | ||||||
| @@ -630,9 +636,7 @@ const LayoutManager = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _startupAnimation: function() { |     _startupAnimation: function() { | ||||||
|         if (Meta.is_restart()) |         if (Main.sessionMode.isGreeter) | ||||||
|             this._startupAnimationComplete(); |  | ||||||
|         else if (Main.sessionMode.isGreeter) |  | ||||||
|             this._startupAnimationGreeter(); |             this._startupAnimationGreeter(); | ||||||
|         else |         else | ||||||
|             this._startupAnimationSession(); |             this._startupAnimationSession(); | ||||||
| @@ -659,6 +663,10 @@ const LayoutManager = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _startupAnimationComplete: function() { |     _startupAnimationComplete: function() { | ||||||
|  |         // At this point, the UI group is covering everything, so | ||||||
|  |         // we no longer need to clear the stage | ||||||
|  |         global.stage.no_clear_hint = true; | ||||||
|  |  | ||||||
|         this._coverPane.destroy(); |         this._coverPane.destroy(); | ||||||
|         this._coverPane = null; |         this._coverPane = null; | ||||||
|  |  | ||||||
| @@ -667,6 +675,7 @@ const LayoutManager = new Lang.Class({ | |||||||
|  |  | ||||||
|         this._startingUp = false; |         this._startingUp = false; | ||||||
|  |  | ||||||
|  |         this.trayBox.show(); | ||||||
|         this.keyboardBox.show(); |         this.keyboardBox.show(); | ||||||
|  |  | ||||||
|         if (!Main.sessionMode.isGreeter) { |         if (!Main.sessionMode.isGreeter) { | ||||||
| @@ -739,11 +748,10 @@ const LayoutManager = new Lang.Class({ | |||||||
|     // @actor: an actor to add to the chrome |     // @actor: an actor to add to the chrome | ||||||
|     // @params: (optional) additional params |     // @params: (optional) additional params | ||||||
|     // |     // | ||||||
|     // Adds @actor to the chrome, and (unless %affectsInputRegion in |     // Adds @actor to the chrome, and extends the input region | ||||||
|     // @params is %false) extends the input region to include it. |     // to include it. Changes in @actor's size, position, and | ||||||
|     // Changes in @actor's size, position, and visibility will |     // visibility will automatically result in appropriate changes | ||||||
|     // automatically result in appropriate changes to the input |     // to the input region. | ||||||
|     // region. |  | ||||||
|     // |     // | ||||||
|     // If %affectsStruts in @params is %true (and @actor is along a |     // If %affectsStruts in @params is %true (and @actor is along a | ||||||
|     // screen edge), then @actor's size and position will also affect |     // screen edge), then @actor's size and position will also affect | ||||||
| @@ -837,7 +845,6 @@ const LayoutManager = new Lang.Class({ | |||||||
|         // need to connect to 'destroy' too. |         // need to connect to 'destroy' too. | ||||||
|  |  | ||||||
|         this._trackedActors.push(actorData); |         this._trackedActors.push(actorData); | ||||||
|         this._updateActorVisibility(actorData); |  | ||||||
|         this._queueUpdateRegions(); |         this._queueUpdateRegions(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
| @@ -856,23 +863,25 @@ const LayoutManager = new Lang.Class({ | |||||||
|         this._queueUpdateRegions(); |         this._queueUpdateRegions(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _updateActorVisibility: function(actorData) { |  | ||||||
|         if (!actorData.trackFullscreen) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         let monitor = this.findMonitorForActor(actorData.actor); |  | ||||||
|         actorData.actor.visible = !(global.window_group.visible && |  | ||||||
|                                     monitor && |  | ||||||
|                                     monitor.inFullscreen); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _updateVisibility: function() { |     _updateVisibility: function() { | ||||||
|         let windowsVisible = Main.sessionMode.hasWindows && !this._inOverview; |         let windowsVisible = Main.sessionMode.hasWindows && !this._inOverview; | ||||||
|  |  | ||||||
|         global.window_group.visible = windowsVisible; |         global.window_group.visible = windowsVisible; | ||||||
|         global.top_window_group.visible = windowsVisible; |         global.top_window_group.visible = windowsVisible; | ||||||
|  |  | ||||||
|         this._trackedActors.forEach(Lang.bind(this, this._updateActorVisibility)); |         for (let i = 0; i < this._trackedActors.length; i++) { | ||||||
|  |             let actorData = this._trackedActors[i], visible; | ||||||
|  |             if (!actorData.trackFullscreen) | ||||||
|  |                 continue; | ||||||
|  |  | ||||||
|  |             if (!windowsVisible) | ||||||
|  |                 visible = true; | ||||||
|  |             else if (this.findMonitorForActor(actorData.actor).inFullscreen) | ||||||
|  |                 visible = false; | ||||||
|  |             else | ||||||
|  |                 visible = true; | ||||||
|  |             actorData.actor.visible = visible; | ||||||
|  |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     getWorkAreaForMonitor: function(monitorIndex) { |     getWorkAreaForMonitor: function(monitorIndex) { | ||||||
| @@ -896,6 +905,9 @@ const LayoutManager = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _queueUpdateRegions: function() { |     _queueUpdateRegions: function() { | ||||||
|  |         if (Main.sessionMode.isGreeter) | ||||||
|  |             return; | ||||||
|  |  | ||||||
|         if (this._startingUp) |         if (this._startingUp) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
| @@ -929,22 +941,19 @@ const LayoutManager = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _updateRegions: function() { |     _updateRegions: function() { | ||||||
|  |         let rects = [], struts = [], i; | ||||||
|  |  | ||||||
|         if (this._updateRegionIdle) { |         if (this._updateRegionIdle) { | ||||||
|             Meta.later_remove(this._updateRegionIdle); |             Meta.later_remove(this._updateRegionIdle); | ||||||
|             delete this._updateRegionIdle; |             delete this._updateRegionIdle; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // No need to update when we have a modal. |  | ||||||
|         if (Main.modalCount > 0) |  | ||||||
|             return GLib.SOURCE_REMOVE; |  | ||||||
|  |  | ||||||
|         let rects = [], struts = [], i; |  | ||||||
|         let isPopupMenuVisible = global.top_window_group.get_children().some(isPopupMetaWindow); |         let isPopupMenuVisible = global.top_window_group.get_children().some(isPopupMetaWindow); | ||||||
|         let wantsInputRegion = !isPopupMenuVisible; |         let wantsInputRegion = !isPopupMenuVisible; | ||||||
|  |  | ||||||
|         for (i = 0; i < this._trackedActors.length; i++) { |         for (i = 0; i < this._trackedActors.length; i++) { | ||||||
|             let actorData = this._trackedActors[i]; |             let actorData = this._trackedActors[i]; | ||||||
|             if (!(actorData.affectsInputRegion && wantsInputRegion) && !actorData.affectsStruts) |             if (!wantsInputRegion && !actorData.affectsStruts) | ||||||
|                 continue; |                 continue; | ||||||
|  |  | ||||||
|             let [x, y] = actorData.actor.get_transformed_position(); |             let [x, y] = actorData.actor.get_transformed_position(); | ||||||
| @@ -954,7 +963,7 @@ const LayoutManager = new Lang.Class({ | |||||||
|             w = Math.round(w); |             w = Math.round(w); | ||||||
|             h = Math.round(h); |             h = Math.round(h); | ||||||
|  |  | ||||||
|             if (actorData.affectsInputRegion && wantsInputRegion && actorData.actor.get_paint_visibility()) |             if (wantsInputRegion && actorData.actor.get_paint_visibility()) | ||||||
|                 rects.push(new Meta.Rectangle({ x: x, y: y, width: w, height: h })); |                 rects.push(new Meta.Rectangle({ x: x, y: y, width: w, height: h })); | ||||||
|  |  | ||||||
|             if (actorData.affectsStruts) { |             if (actorData.affectsStruts) { | ||||||
| @@ -964,43 +973,87 @@ const LayoutManager = new Lang.Class({ | |||||||
|                 let y1 = Math.max(y, 0); |                 let y1 = Math.max(y, 0); | ||||||
|                 let y2 = Math.min(y + h, global.screen_height); |                 let y2 = Math.min(y + h, global.screen_height); | ||||||
|  |  | ||||||
|                 // Metacity wants to know what side of the monitor the |                 // NetWM struts are not really powerful enought to handle | ||||||
|                 // strut is considered to be attached to. First, we find |                 // a multi-monitor scenario, they only describe what happens | ||||||
|                 // the monitor that contains the strut. If the actor is |                 // around the outer sides of the full display region. However | ||||||
|  |                 // it can describe a partial region along each side, so | ||||||
|  |                 // we can support having the struts only affect the | ||||||
|  |                 // primary monitor. This should be enough as we only have | ||||||
|  |                 // chrome affecting the struts on the primary monitor so | ||||||
|  |                 // far. | ||||||
|  |                 // | ||||||
|  |                 // Metacity wants to know what side of the screen the | ||||||
|  |                 // strut is considered to be attached to. If the actor is | ||||||
|                 // only touching one edge, or is touching the entire |                 // only touching one edge, or is touching the entire | ||||||
|                 // border of that monitor, then it's obvious which side |                 // border of the primary monitor, then it's obvious which | ||||||
|                 // to call it. If it's in a corner, we pick a side |                 // side to call it. If it's in a corner, we pick a side | ||||||
|                 // arbitrarily. If it doesn't touch any edges, or it |                 // arbitrarily. If it doesn't touch any edges, or it spans | ||||||
|                 // spans the width/height across the middle of the |                 // the width/height across the middle of the screen, then | ||||||
|                 // screen, then we don't create a strut for it at all. |                 // we don't create a strut for it at all. | ||||||
|  |  | ||||||
|                 let monitor = this.findMonitorForActor(actorData.actor); |  | ||||||
|                 let side; |                 let side; | ||||||
|                 if (x1 <= monitor.x && x2 >= monitor.x + monitor.width) { |                 let primary = this.primaryMonitor; | ||||||
|                     if (y1 <= monitor.y) |                 if (x1 <= primary.x && x2 >= primary.x + primary.width) { | ||||||
|  |                     if (y1 <= primary.y) | ||||||
|                         side = Meta.Side.TOP; |                         side = Meta.Side.TOP; | ||||||
|                     else if (y2 >= monitor.y + monitor.height) |                     else if (y2 >= primary.y + primary.height) | ||||||
|                         side = Meta.Side.BOTTOM; |                         side = Meta.Side.BOTTOM; | ||||||
|                     else |                     else | ||||||
|                         continue; |                         continue; | ||||||
|                 } else if (y1 <= monitor.y && y2 >= monitor.y + monitor.height) { |                 } else if (y1 <= primary.y && y2 >= primary.y + primary.height) { | ||||||
|                     if (x1 <= monitor.x) |                     if (x1 <= 0) | ||||||
|                         side = Meta.Side.LEFT; |                         side = Meta.Side.LEFT; | ||||||
|                     else if (x2 >= monitor.x + monitor.width) |                     else if (x2 >= primary.x + primary.width) | ||||||
|                         side = Meta.Side.RIGHT; |                         side = Meta.Side.RIGHT; | ||||||
|                     else |                     else | ||||||
|                         continue; |                         continue; | ||||||
|                 } else if (x1 <= monitor.x) |                 } else if (x1 <= 0) | ||||||
|                     side = Meta.Side.LEFT; |                     side = Meta.Side.LEFT; | ||||||
|                 else if (y1 <= monitor.y) |                 else if (y1 <= 0) | ||||||
|                     side = Meta.Side.TOP; |                     side = Meta.Side.TOP; | ||||||
|                 else if (x2 >= monitor.x + monitor.width) |                 else if (x2 >= global.screen_width) | ||||||
|                     side = Meta.Side.RIGHT; |                     side = Meta.Side.RIGHT; | ||||||
|                 else if (y2 >= monitor.y + monitor.height) |                 else if (y2 >= global.screen_height) | ||||||
|                     side = Meta.Side.BOTTOM; |                     side = Meta.Side.BOTTOM; | ||||||
|                 else |                 else | ||||||
|                     continue; |                     continue; | ||||||
|  |  | ||||||
|  |                 // Ensure that the strut rects goes all the way to the screen edge, | ||||||
|  |                 // as this really what mutter expects. However skip this step | ||||||
|  |                 // in cases where this would render an entire monitor unusable. | ||||||
|  |                 switch (side) { | ||||||
|  |                 case Meta.Side.TOP: | ||||||
|  |                     let hasMonitorsAbove = this.monitors.some(Lang.bind(this, | ||||||
|  |                         function(mon) { | ||||||
|  |                             return this._isAboveOrBelowPrimary(mon) && | ||||||
|  |                                    mon.y < primary.y; | ||||||
|  |                         })); | ||||||
|  |                     if (!hasMonitorsAbove) | ||||||
|  |                         y1 = 0; | ||||||
|  |                     break; | ||||||
|  |                 case Meta.Side.BOTTOM: | ||||||
|  |                     if (this.primaryIndex == this.bottomIndex) | ||||||
|  |                         y2 = global.screen_height; | ||||||
|  |                     break; | ||||||
|  |                 case Meta.Side.LEFT: | ||||||
|  |                     let hasMonitorsLeft = this.monitors.some(Lang.bind(this, | ||||||
|  |                         function(mon) { | ||||||
|  |                             return !this._isAboveOrBelowPrimary(mon) && | ||||||
|  |                                    mon.x < primary.x; | ||||||
|  |                         })); | ||||||
|  |                     if (!hasMonitorsLeft) | ||||||
|  |                         x1 = 0; | ||||||
|  |                     break; | ||||||
|  |                 case Meta.Side.RIGHT: | ||||||
|  |                     let hasMonitorsRight = this.monitors.some(Lang.bind(this, | ||||||
|  |                         function(mon) { | ||||||
|  |                             return !this._isAboveOrBelowPrimary(mon) && | ||||||
|  |                                    mon.x > primary.x; | ||||||
|  |                         })); | ||||||
|  |                     if (!hasMonitorsRight) | ||||||
|  |                         x2 = global.screen_width; | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|                 let strutRect = new Meta.Rectangle({ x: x1, y: y1, width: x2 - x1, height: y2 - y1}); |                 let strutRect = new Meta.Rectangle({ x: x1, y: y1, width: x2 - x1, height: y2 - y1}); | ||||||
|                 let strut = new Meta.Strut({ rect: strutRect, side: side }); |                 let strut = new Meta.Strut({ rect: strutRect, side: side }); | ||||||
|                 struts.push(strut); |                 struts.push(strut); | ||||||
| @@ -1017,13 +1070,7 @@ const LayoutManager = new Lang.Class({ | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         return GLib.SOURCE_REMOVE; |         return GLib.SOURCE_REMOVE; | ||||||
|     }, |     } | ||||||
|  |  | ||||||
|     modalEnded: function() { |  | ||||||
|         // We don't update the stage input region while in a modal, |  | ||||||
|         // so queue an update now. |  | ||||||
|         this._queueUpdateRegions(); |  | ||||||
|     }, |  | ||||||
| }); | }); | ||||||
| Signals.addSignalMethods(LayoutManager.prototype); | Signals.addSignalMethods(LayoutManager.prototype); | ||||||
|  |  | ||||||
| @@ -1051,8 +1098,8 @@ const HotCorner = new Lang.Class({ | |||||||
|  |  | ||||||
|         this._pressureBarrier = new PressureBarrier(HOT_CORNER_PRESSURE_THRESHOLD, |         this._pressureBarrier = new PressureBarrier(HOT_CORNER_PRESSURE_THRESHOLD, | ||||||
|                                                     HOT_CORNER_PRESSURE_TIMEOUT, |                                                     HOT_CORNER_PRESSURE_TIMEOUT, | ||||||
|                                                     Shell.ActionMode.NORMAL | |                                                     Shell.KeyBindingMode.NORMAL | | ||||||
|                                                     Shell.ActionMode.OVERVIEW); |                                                     Shell.KeyBindingMode.OVERVIEW); | ||||||
|         this._pressureBarrier.connect('trigger', Lang.bind(this, this._toggleOverview)); |         this._pressureBarrier.connect('trigger', Lang.bind(this, this._toggleOverview)); | ||||||
|  |  | ||||||
|         // Cache the three ripples instead of dynamically creating and destroying them. |         // Cache the three ripples instead of dynamically creating and destroying them. | ||||||
| @@ -1229,10 +1276,10 @@ const HotCorner = new Lang.Class({ | |||||||
| const PressureBarrier = new Lang.Class({ | const PressureBarrier = new Lang.Class({ | ||||||
|     Name: 'PressureBarrier', |     Name: 'PressureBarrier', | ||||||
|  |  | ||||||
|     _init: function(threshold, timeout, actionMode) { |     _init: function(threshold, timeout, keybindingMode) { | ||||||
|         this._threshold = threshold; |         this._threshold = threshold; | ||||||
|         this._timeout = timeout; |         this._timeout = timeout; | ||||||
|         this._actionMode = actionMode; |         this._keybindingMode = keybindingMode; | ||||||
|         this._barriers = []; |         this._barriers = []; | ||||||
|         this._eventFilter = null; |         this._eventFilter = null; | ||||||
|  |  | ||||||
| @@ -1315,11 +1362,8 @@ const PressureBarrier = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onBarrierLeft: function(barrier, event) { |     _onBarrierLeft: function(barrier, event) { | ||||||
|         barrier._isHit = false; |  | ||||||
|         if (this._barriers.every(function(b) { return !b._isHit; })) { |  | ||||||
|         this._reset(); |         this._reset(); | ||||||
|         this._isTriggered = false; |         this._isTriggered = false; | ||||||
|         } |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _trigger: function() { |     _trigger: function() { | ||||||
| @@ -1329,8 +1373,6 @@ const PressureBarrier = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _onBarrierHit: function(barrier, event) { |     _onBarrierHit: function(barrier, event) { | ||||||
|         barrier._isHit = true; |  | ||||||
|  |  | ||||||
|         // If we've triggered the barrier, wait until the pointer has the |         // If we've triggered the barrier, wait until the pointer has the | ||||||
|         // left the barrier hitbox until we trigger it again. |         // left the barrier hitbox until we trigger it again. | ||||||
|         if (this._isTriggered) |         if (this._isTriggered) | ||||||
| @@ -1340,7 +1382,7 @@ const PressureBarrier = new Lang.Class({ | |||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         // Throw out all events not in the proper keybinding mode |         // Throw out all events not in the proper keybinding mode | ||||||
|         if (!(this._actionMode & Main.actionMode)) |         if (!(this._keybindingMode & Main.keybindingMode)) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         let slide = this._getDistanceAlongBarrier(barrier, event); |         let slide = this._getDistanceAlongBarrier(barrier, event); | ||||||
|   | |||||||
| @@ -1,273 +0,0 @@ | |||||||
| const Clutter = imports.gi.Clutter; |  | ||||||
| const GLib = imports.gi.GLib; |  | ||||||
| const GObject = imports.gi.GObject; |  | ||||||
| const Meta = imports.gi.Meta; |  | ||||||
| const Shell = imports.gi.Shell; |  | ||||||
| const St = imports.gi.St; |  | ||||||
|  |  | ||||||
| const CtrlAltTab = imports.ui.ctrlAltTab; |  | ||||||
| const Lang = imports.lang; |  | ||||||
| const Layout = imports.ui.layout; |  | ||||||
| const Main = imports.ui.main; |  | ||||||
| const Overview = imports.ui.overview; |  | ||||||
| const OverviewControls = imports.ui.overviewControls; |  | ||||||
| const Tweener = imports.ui.tweener; |  | ||||||
|  |  | ||||||
| const STANDARD_TRAY_ICON_IMPLEMENTATIONS = { |  | ||||||
|     'bluetooth-applet': 'bluetooth', |  | ||||||
|     'gnome-volume-control-applet': 'volume', // renamed to gnome-sound-applet |  | ||||||
|                                              // when moved to control center |  | ||||||
|     'gnome-sound-applet': 'volume', |  | ||||||
|     'nm-applet': 'network', |  | ||||||
|     'gnome-power-manager': 'battery', |  | ||||||
|     'keyboard': 'keyboard', |  | ||||||
|     'a11y-keyboard': 'a11y', |  | ||||||
|     'kbd-scrolllock': 'keyboard', |  | ||||||
|     'kbd-numlock': 'keyboard', |  | ||||||
|     'kbd-capslock': 'keyboard', |  | ||||||
|     'ibus-ui-gtk': 'keyboard' |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| // Offset of the original position from the bottom-right corner |  | ||||||
| const CONCEALED_WIDTH = 3; |  | ||||||
| const REVEAL_ANIMATION_TIME = 0.2; |  | ||||||
| const TEMP_REVEAL_TIME = 2; |  | ||||||
|  |  | ||||||
| const BARRIER_THRESHOLD = 70; |  | ||||||
| const BARRIER_TIMEOUT = 1000; |  | ||||||
|  |  | ||||||
| const LegacyTray = new Lang.Class({ |  | ||||||
|     Name: 'LegacyTray', |  | ||||||
|  |  | ||||||
|     _init: function() { |  | ||||||
|         this.actor = new St.Widget({ clip_to_allocation: true, |  | ||||||
|                                      layout_manager: new Clutter.BinLayout() }); |  | ||||||
|         let constraint = new Layout.MonitorConstraint({ primary: true, |  | ||||||
|                                                         work_area: true }); |  | ||||||
|         this.actor.add_constraint(constraint); |  | ||||||
|  |  | ||||||
|         this._slideLayout = new OverviewControls.SlideLayout(); |  | ||||||
|         this._slideLayout.translationX = 0; |  | ||||||
|         this._slideLayout.slideDirection = OverviewControls.SlideDirection.LEFT; |  | ||||||
|  |  | ||||||
|         this._slider = new St.Widget({ style_class: 'legacy-tray', |  | ||||||
|                                        x_expand: true, y_expand: true, |  | ||||||
|                                        x_align: Clutter.ActorAlign.START, |  | ||||||
|                                        y_align: Clutter.ActorAlign.END, |  | ||||||
|                                        layout_manager: this._slideLayout }); |  | ||||||
|         this.actor.add_actor(this._slider); |  | ||||||
|         this._slider.connect('notify::allocation', Lang.bind(this, this._syncBarrier)); |  | ||||||
|  |  | ||||||
|         this._box = new St.BoxLayout(); |  | ||||||
|         this._slider.add_actor(this._box); |  | ||||||
|  |  | ||||||
|         this._concealHandle = new St.Button({ style_class: 'legacy-tray-handle', |  | ||||||
|                                               /* translators: 'Hide' is a verb */ |  | ||||||
|                                               accessible_name: _("Hide tray"), |  | ||||||
|                                               can_focus: true }); |  | ||||||
|         this._concealHandle.child = new St.Icon({ icon_name: 'go-previous-symbolic' }); |  | ||||||
|         this._box.add_child(this._concealHandle); |  | ||||||
|  |  | ||||||
|         this._iconBox = new St.BoxLayout({ style_class: 'legacy-tray-icon-box' }); |  | ||||||
|         this._box.add_actor(this._iconBox); |  | ||||||
|  |  | ||||||
|         this._revealHandle = new St.Button({ style_class: 'legacy-tray-handle' }); |  | ||||||
|         this._revealHandle.child = new St.Icon({ icon_name: 'go-next-symbolic' }); |  | ||||||
|         this._box.add_child(this._revealHandle); |  | ||||||
|  |  | ||||||
|         this._revealHandle.bind_property('visible', |  | ||||||
|                                          this._concealHandle, 'visible', |  | ||||||
|                                          GObject.BindingFlags.BIDIRECTIONAL | |  | ||||||
|                                          GObject.BindingFlags.INVERT_BOOLEAN); |  | ||||||
|         this._revealHandle.connect('notify::visible', |  | ||||||
|                                    Lang.bind(this, this._sync)); |  | ||||||
|         this._revealHandle.connect('notify::hover', |  | ||||||
|                                    Lang.bind(this ,this._sync)); |  | ||||||
|         this._revealHandle.connect('clicked', Lang.bind(this, |  | ||||||
|             function() { |  | ||||||
|                 this._concealHandle.show(); |  | ||||||
|             })); |  | ||||||
|         this._concealHandle.connect('clicked', Lang.bind(this, |  | ||||||
|             function() { |  | ||||||
|                 this._revealHandle.show(); |  | ||||||
|             })); |  | ||||||
|  |  | ||||||
|         this._horizontalBarrier = null; |  | ||||||
|         this._pressureBarrier = new Layout.PressureBarrier(BARRIER_THRESHOLD, |  | ||||||
|                                                            BARRIER_TIMEOUT, |  | ||||||
|                                                            Shell.ActionMode.NORMAL); |  | ||||||
|         this._pressureBarrier.connect('trigger', Lang.bind(this, function() { |  | ||||||
|             this._concealHandle.show(); |  | ||||||
|         })); |  | ||||||
|  |  | ||||||
|         Main.layoutManager.addChrome(this.actor, { affectsInputRegion: false }); |  | ||||||
|         Main.layoutManager.trackChrome(this._slider, { affectsInputRegion: true }); |  | ||||||
|         Main.uiGroup.set_child_below_sibling(this.actor, Main.layoutManager.modalDialogGroup); |  | ||||||
|         Main.ctrlAltTabManager.addGroup(this.actor, |  | ||||||
|                                         _("Status Icons"), 'focus-legacy-systray-symbolic', |  | ||||||
|                                         { sortGroup: CtrlAltTab.SortGroup.BOTTOM }); |  | ||||||
|  |  | ||||||
|         this._trayManager = new Shell.TrayManager(); |  | ||||||
|         this._trayIconAddedId = this._trayManager.connect('tray-icon-added', Lang.bind(this, this._onTrayIconAdded)); |  | ||||||
|         this._trayIconRemovedId = this._trayManager.connect('tray-icon-removed', Lang.bind(this, this._onTrayIconRemoved)); |  | ||||||
|         this._trayManager.manage_screen(global.screen, this.actor); |  | ||||||
|  |  | ||||||
|         Main.overview.connect('showing', Lang.bind(this, |  | ||||||
|             function() { |  | ||||||
|                 Tweener.removeTweens(this._slider); |  | ||||||
|                 Tweener.addTween(this._slider, { opacity: 0, |  | ||||||
|                                                  time: Overview.ANIMATION_TIME, |  | ||||||
|                                                  transition: 'easeOutQuad' }); |  | ||||||
|             })); |  | ||||||
|         Main.overview.connect('shown', Lang.bind(this, this._sync)); |  | ||||||
|         Main.overview.connect('hiding', Lang.bind(this, |  | ||||||
|             function() { |  | ||||||
|                 this._sync(); |  | ||||||
|                 Tweener.removeTweens(this._slider); |  | ||||||
|                 Tweener.addTween(this._slider, { opacity: 255, |  | ||||||
|                                                  time: Overview.ANIMATION_TIME, |  | ||||||
|                                                  transition: 'easeOutQuad' }); |  | ||||||
|             })); |  | ||||||
|  |  | ||||||
|         Main.layoutManager.connect('monitors-changed', |  | ||||||
|                                    Lang.bind(this, this._sync)); |  | ||||||
|         global.screen.connect('in-fullscreen-changed', |  | ||||||
|                               Lang.bind(this, this._sync)); |  | ||||||
|         Main.sessionMode.connect('updated', Lang.bind(this, this._sync)); |  | ||||||
|  |  | ||||||
|         this._sync(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _onTrayIconAdded: function(tm, icon) { |  | ||||||
|         let wmClass = icon.wm_class ? icon.wm_class.toLowerCase() : ''; |  | ||||||
|         if (STANDARD_TRAY_ICON_IMPLEMENTATIONS[wmClass] !== undefined) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         let button = new St.Button({ child: icon, |  | ||||||
|                                      style_class: 'legacy-tray-icon', |  | ||||||
|                                      button_mask: St.ButtonMask.ONE | |  | ||||||
|                                                   St.ButtonMask.TWO | |  | ||||||
|                                                   St.ButtonMask.THREE, |  | ||||||
|                                      can_focus: true, |  | ||||||
|                                      x_fill: true, y_fill: true }); |  | ||||||
|  |  | ||||||
|         let app = Shell.WindowTracker.get_default().get_app_from_pid(icon.pid); |  | ||||||
|         if (!app) |  | ||||||
|             app = Shell.AppSystem.get_default().lookup_startup_wmclass(wmClass); |  | ||||||
|         if (!app) |  | ||||||
|             app = Shell.AppSystem.get_default().lookup_desktop_wmclass(wmClass); |  | ||||||
|         if (app) |  | ||||||
|             button.accessible_name = app.get_name(); |  | ||||||
|         else |  | ||||||
|             button.accessible_name = icon.title; |  | ||||||
|  |  | ||||||
|         button.connect('clicked', |  | ||||||
|             function() { |  | ||||||
|                 icon.click(Clutter.get_current_event()); |  | ||||||
|             }); |  | ||||||
|         button.connect('key-press-event', |  | ||||||
|             function() { |  | ||||||
|                 icon.click(Clutter.get_current_event()); |  | ||||||
|                 return Clutter.EVENT_PROPAGATE; |  | ||||||
|             }); |  | ||||||
|         button.connect('key-focus-in', Lang.bind(this, |  | ||||||
|             function() { |  | ||||||
|                 this._concealHandle.show(); |  | ||||||
|             })); |  | ||||||
|  |  | ||||||
|         this._iconBox.add_actor(button); |  | ||||||
|  |  | ||||||
|         if (!this._concealHandle.visible) { |  | ||||||
|             this._concealHandle.show(); |  | ||||||
|             GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, TEMP_REVEAL_TIME, |  | ||||||
|                 Lang.bind(this, function() { |  | ||||||
|                     this._concealHandle.hide(); |  | ||||||
|                     return GLib.SOURCE_REMOVE; |  | ||||||
|                 })); |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _onTrayIconRemoved: function(tm, icon) { |  | ||||||
|         if (!this.actor.contains(icon)) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         icon.get_parent().destroy(); |  | ||||||
|         this._sync(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _syncBarrier: function() { |  | ||||||
|         let rtl = (this._slider.get_text_direction() == Clutter.TextDirection.RTL); |  | ||||||
|         let [x, y] = this._slider.get_transformed_position(); |  | ||||||
|         let [w, h] = this._slider.get_transformed_size(); |  | ||||||
|  |  | ||||||
|         let x1 = Math.round(x); |  | ||||||
|         if (rtl) |  | ||||||
|             x1 += Math.round(w); |  | ||||||
|  |  | ||||||
|         let x2 = x1; |  | ||||||
|         let y1 = Math.round(y); |  | ||||||
|         let y2 = y1 + Math.round(h); |  | ||||||
|  |  | ||||||
|         if (this._horizontalBarrier && |  | ||||||
|             this._horizontalBarrier.x1 == x1 && |  | ||||||
|             this._horizontalBarrier.y1 == y1 && |  | ||||||
|             this._horizontalBarrier.x2 == x2 && |  | ||||||
|             this._horizontalBarrier.y2 == y2) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         this._unsetBarrier(); |  | ||||||
|  |  | ||||||
|         let directions = (rtl ? Meta.BarrierDirection.NEGATIVE_X : Meta.BarrierDirection.POSITIVE_X); |  | ||||||
|         this._horizontalBarrier = new Meta.Barrier({ display: global.display, |  | ||||||
|                                                      x1: x1, x2: x2, |  | ||||||
|                                                      y1: y1, y2: y2, |  | ||||||
|                                                      directions: directions }); |  | ||||||
|         this._pressureBarrier.addBarrier(this._horizontalBarrier); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _unsetBarrier: function() { |  | ||||||
|         if (this._horizontalBarrier == null) |  | ||||||
|             return; |  | ||||||
|  |  | ||||||
|         this._pressureBarrier.removeBarrier(this._horizontalBarrier); |  | ||||||
|         this._horizontalBarrier.destroy(); |  | ||||||
|         this._horizontalBarrier = null; |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _sync: function() { |  | ||||||
|         // FIXME: we no longer treat tray icons as notifications |  | ||||||
|         let allowed = Main.sessionMode.hasNotifications; |  | ||||||
|         let hasIcons = this._iconBox.get_n_children() > 0; |  | ||||||
|         let inOverview = Main.overview.visible && !Main.overview.animationInProgress; |  | ||||||
|         let inFullscreen = Main.layoutManager.primaryMonitor.inFullscreen; |  | ||||||
|         this.actor.visible = allowed && hasIcons && !inOverview && !inFullscreen; |  | ||||||
|  |  | ||||||
|         if (!hasIcons) |  | ||||||
|             this._concealHandle.hide(); |  | ||||||
|  |  | ||||||
|         let targetSlide; |  | ||||||
|         if (this._concealHandle.visible) { |  | ||||||
|             targetSlide = 1.0; |  | ||||||
|         } else if (!hasIcons) { |  | ||||||
|             targetSlide = 0.0; |  | ||||||
|         } else { |  | ||||||
|             let [, boxWidth] = this._box.get_preferred_width(-1); |  | ||||||
|             let [, handleWidth] = this._revealHandle.get_preferred_width(-1); |  | ||||||
|  |  | ||||||
|             if (this._revealHandle.hover) |  | ||||||
|                 targetSlide = handleWidth / boxWidth; |  | ||||||
|             else |  | ||||||
|                 targetSlide = CONCEALED_WIDTH / boxWidth; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (this.actor.visible) { |  | ||||||
|             Tweener.addTween(this._slideLayout, |  | ||||||
|                              { slideX: targetSlide, |  | ||||||
|                                time: REVEAL_ANIMATION_TIME, |  | ||||||
|                                transition: 'easeOutQuad' }); |  | ||||||
|         } else { |  | ||||||
|             this._slideLayout.slideX = targetSlide; |  | ||||||
|             this._unsetBarrier(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
| @@ -105,8 +105,8 @@ const Lightbox = new Lang.Class({ | |||||||
|         this._container = container; |         this._container = container; | ||||||
|         this._children = container.get_children(); |         this._children = container.get_children(); | ||||||
|         this._fadeFactor = params.fadeFactor; |         this._fadeFactor = params.fadeFactor; | ||||||
|         this._radialEffect = Clutter.feature_available(Clutter.FeatureFlags.SHADERS_GLSL) && params.radialEffect; |         this._radialEffect = params.radialEffect; | ||||||
|         if (this._radialEffect) |         if (params.radialEffect) | ||||||
|             this.actor = new RadialShaderQuad({ x: 0, |             this.actor = new RadialShaderQuad({ x: 0, | ||||||
|                                                 y: 0, |                                                 y: 0, | ||||||
|                                                 reactive: params.inhibitEvents }); |                                                 reactive: params.inhibitEvents }); | ||||||
|   | |||||||
| @@ -797,7 +797,7 @@ const LookingGlass = new Lang.Class({ | |||||||
|                                         reactive: true }); |                                         reactive: true }); | ||||||
|         this.actor.connect('key-press-event', Lang.bind(this, this._globalKeyPressEvent)); |         this.actor.connect('key-press-event', Lang.bind(this, this._globalKeyPressEvent)); | ||||||
|  |  | ||||||
|         this._interfaceSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' }); |         this._interfaceSettings = new Gio.Settings({ schema: 'org.gnome.desktop.interface' }); | ||||||
|         this._interfaceSettings.connect('changed::monospace-font-name', |         this._interfaceSettings.connect('changed::monospace-font-name', | ||||||
|                                         Lang.bind(this, this._updateFont)); |                                         Lang.bind(this, this._updateFont)); | ||||||
|         this._updateFont(); |         this._updateFont(); | ||||||
| @@ -1040,7 +1040,7 @@ const LookingGlass = new Lang.Class({ | |||||||
|         let availableHeight = primary.height - Main.layoutManager.keyboardBox.height; |         let availableHeight = primary.height - Main.layoutManager.keyboardBox.height; | ||||||
|         let myHeight = Math.min(primary.height * 0.7, availableHeight * 0.9); |         let myHeight = Math.min(primary.height * 0.7, availableHeight * 0.9); | ||||||
|         this.actor.x = primary.x + (primary.width - myWidth) / 2; |         this.actor.x = primary.x + (primary.width - myWidth) / 2; | ||||||
|         this._hiddenY = primary.y + Main.layoutManager.panelBox.height - myHeight; |         this._hiddenY = primary.y + Main.layoutManager.panelBox.height - myHeight - 4; // -4 to hide the top corners | ||||||
|         this._targetY = this._hiddenY + myHeight; |         this._targetY = this._hiddenY + myHeight; | ||||||
|         this.actor.y = this._hiddenY; |         this.actor.y = this._hiddenY; | ||||||
|         this.actor.width = myWidth; |         this.actor.width = myWidth; | ||||||
| @@ -1086,7 +1086,7 @@ const LookingGlass = new Lang.Class({ | |||||||
|         if (this._open) |         if (this._open) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         if (!Main.pushModal(this._entry, { actionMode: Shell.ActionMode.LOOKING_GLASS })) |         if (!Main.pushModal(this._entry, { keybindingMode: Shell.KeyBindingMode.LOOKING_GLASS })) | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         this._notebook.selectIndex(0); |         this._notebook.selectIndex(0); | ||||||
|   | |||||||
| @@ -4,7 +4,6 @@ const Atspi = imports.gi.Atspi; | |||||||
| const Clutter = imports.gi.Clutter; | const Clutter = imports.gi.Clutter; | ||||||
| const GDesktopEnums = imports.gi.GDesktopEnums; | const GDesktopEnums = imports.gi.GDesktopEnums; | ||||||
| const Gio = imports.gi.Gio; | const Gio = imports.gi.Gio; | ||||||
| const GLib = imports.gi.GLib; |  | ||||||
| const Shell = imports.gi.Shell; | const Shell = imports.gi.Shell; | ||||||
| const St = imports.gi.St; | const St = imports.gi.St; | ||||||
| const Lang = imports.lang; | const Lang = imports.lang; | ||||||
| @@ -23,8 +22,6 @@ const MOUSE_POLL_FREQUENCY = 50; | |||||||
| const CROSSHAIRS_CLIP_SIZE = [100, 100]; | const CROSSHAIRS_CLIP_SIZE = [100, 100]; | ||||||
| const NO_CHANGE = 0.0; | const NO_CHANGE = 0.0; | ||||||
|  |  | ||||||
| const POINTER_REST_TIME = 1000; // milliseconds |  | ||||||
|  |  | ||||||
| // Settings | // Settings | ||||||
| const APPLICATIONS_SCHEMA       = 'org.gnome.desktop.a11y.applications'; | const APPLICATIONS_SCHEMA       = 'org.gnome.desktop.a11y.applications'; | ||||||
| const SHOW_KEY                  = 'screen-magnifier-enabled'; | const SHOW_KEY                  = 'screen-magnifier-enabled'; | ||||||
| @@ -444,8 +441,57 @@ const Magnifier = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _settingsInit: function(zoomRegion) { |     _settingsInit: function(zoomRegion) { | ||||||
|         this._appSettings = new Gio.Settings({ schema_id: APPLICATIONS_SCHEMA }); |         this._appSettings = new Gio.Settings({ schema: APPLICATIONS_SCHEMA }); | ||||||
|         this._settings = new Gio.Settings({ schema_id: MAGNIFIER_SCHEMA }); |         this._settings = new Gio.Settings({ schema: MAGNIFIER_SCHEMA }); | ||||||
|  |  | ||||||
|  |         if (zoomRegion) { | ||||||
|  |             // Mag factor is accurate to two decimal places. | ||||||
|  |             let aPref = parseFloat(this._settings.get_double(MAG_FACTOR_KEY).toFixed(2)); | ||||||
|  |             if (aPref != 0.0) | ||||||
|  |                 zoomRegion.setMagFactor(aPref, aPref); | ||||||
|  |  | ||||||
|  |             aPref = this._settings.get_enum(SCREEN_POSITION_KEY); | ||||||
|  |             if (aPref) | ||||||
|  |                 zoomRegion.setScreenPosition(aPref); | ||||||
|  |  | ||||||
|  |             zoomRegion.setLensMode(this._settings.get_boolean(LENS_MODE_KEY)); | ||||||
|  |             zoomRegion.setClampScrollingAtEdges(!this._settings.get_boolean(CLAMP_MODE_KEY)); | ||||||
|  |  | ||||||
|  |             aPref = this._settings.get_enum(MOUSE_TRACKING_KEY); | ||||||
|  |             if (aPref) | ||||||
|  |                 zoomRegion.setMouseTrackingMode(aPref); | ||||||
|  |  | ||||||
|  |             aPref = this._settings.get_enum(FOCUS_TRACKING_KEY); | ||||||
|  |             if (aPref) | ||||||
|  |                 zoomRegion.setFocusTrackingMode(aPref); | ||||||
|  |  | ||||||
|  |             aPref = this._settings.get_enum(CARET_TRACKING_KEY); | ||||||
|  |             if (aPref) | ||||||
|  |                 zoomRegion.setCaretTrackingMode(aPref); | ||||||
|  |  | ||||||
|  |             aPref = this._settings.get_boolean(INVERT_LIGHTNESS_KEY); | ||||||
|  |             if (aPref) | ||||||
|  |                 zoomRegion.setInvertLightness(aPref); | ||||||
|  |  | ||||||
|  |             aPref = this._settings.get_double(COLOR_SATURATION_KEY); | ||||||
|  |             if (aPref) | ||||||
|  |                 zoomRegion.setColorSaturation(aPref); | ||||||
|  |  | ||||||
|  |             let bc = {}; | ||||||
|  |             bc.r = this._settings.get_double(BRIGHT_RED_KEY); | ||||||
|  |             bc.g = this._settings.get_double(BRIGHT_GREEN_KEY); | ||||||
|  |             bc.b = this._settings.get_double(BRIGHT_BLUE_KEY); | ||||||
|  |             zoomRegion.setBrightness(bc); | ||||||
|  |  | ||||||
|  |             bc.r = this._settings.get_double(CONTRAST_RED_KEY); | ||||||
|  |             bc.g = this._settings.get_double(CONTRAST_GREEN_KEY); | ||||||
|  |             bc.b = this._settings.get_double(CONTRAST_BLUE_KEY); | ||||||
|  |             zoomRegion.setContrast(bc); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         let showCrosshairs = this._settings.get_boolean(SHOW_CROSS_HAIRS_KEY); | ||||||
|  |         this.addCrosshairs(); | ||||||
|  |         this.setCrosshairsVisible(showCrosshairs); | ||||||
|  |  | ||||||
|         this._appSettings.connect('changed::' + SHOW_KEY, |         this._appSettings.connect('changed::' + SHOW_KEY, | ||||||
|                                   Lang.bind(this, function() { |                                   Lang.bind(this, function() { | ||||||
| @@ -515,56 +561,6 @@ const Magnifier = new Lang.Class({ | |||||||
|                                Lang.bind(this, function() { |                                Lang.bind(this, function() { | ||||||
|             this.setCrosshairsClip(this._settings.get_boolean(CROSS_HAIRS_CLIP_KEY)); |             this.setCrosshairsClip(this._settings.get_boolean(CROSS_HAIRS_CLIP_KEY)); | ||||||
|         })); |         })); | ||||||
|  |  | ||||||
|         if (zoomRegion) { |  | ||||||
|             // Mag factor is accurate to two decimal places. |  | ||||||
|             let aPref = parseFloat(this._settings.get_double(MAG_FACTOR_KEY).toFixed(2)); |  | ||||||
|             if (aPref != 0.0) |  | ||||||
|                 zoomRegion.setMagFactor(aPref, aPref); |  | ||||||
|  |  | ||||||
|             aPref = this._settings.get_enum(SCREEN_POSITION_KEY); |  | ||||||
|             if (aPref) |  | ||||||
|                 zoomRegion.setScreenPosition(aPref); |  | ||||||
|  |  | ||||||
|             zoomRegion.setLensMode(this._settings.get_boolean(LENS_MODE_KEY)); |  | ||||||
|             zoomRegion.setClampScrollingAtEdges(!this._settings.get_boolean(CLAMP_MODE_KEY)); |  | ||||||
|  |  | ||||||
|             aPref = this._settings.get_enum(MOUSE_TRACKING_KEY); |  | ||||||
|             if (aPref) |  | ||||||
|                 zoomRegion.setMouseTrackingMode(aPref); |  | ||||||
|  |  | ||||||
|             aPref = this._settings.get_enum(FOCUS_TRACKING_KEY); |  | ||||||
|             if (aPref) |  | ||||||
|                 zoomRegion.setFocusTrackingMode(aPref); |  | ||||||
|  |  | ||||||
|             aPref = this._settings.get_enum(CARET_TRACKING_KEY); |  | ||||||
|             if (aPref) |  | ||||||
|                 zoomRegion.setCaretTrackingMode(aPref); |  | ||||||
|  |  | ||||||
|             aPref = this._settings.get_boolean(INVERT_LIGHTNESS_KEY); |  | ||||||
|             if (aPref) |  | ||||||
|                 zoomRegion.setInvertLightness(aPref); |  | ||||||
|  |  | ||||||
|             aPref = this._settings.get_double(COLOR_SATURATION_KEY); |  | ||||||
|             if (aPref) |  | ||||||
|                 zoomRegion.setColorSaturation(aPref); |  | ||||||
|  |  | ||||||
|             let bc = {}; |  | ||||||
|             bc.r = this._settings.get_double(BRIGHT_RED_KEY); |  | ||||||
|             bc.g = this._settings.get_double(BRIGHT_GREEN_KEY); |  | ||||||
|             bc.b = this._settings.get_double(BRIGHT_BLUE_KEY); |  | ||||||
|             zoomRegion.setBrightness(bc); |  | ||||||
|  |  | ||||||
|             bc.r = this._settings.get_double(CONTRAST_RED_KEY); |  | ||||||
|             bc.g = this._settings.get_double(CONTRAST_GREEN_KEY); |  | ||||||
|             bc.b = this._settings.get_double(CONTRAST_BLUE_KEY); |  | ||||||
|             zoomRegion.setContrast(bc); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         let showCrosshairs = this._settings.get_boolean(SHOW_CROSS_HAIRS_KEY); |  | ||||||
|         this.addCrosshairs(); |  | ||||||
|         this.setCrosshairsVisible(showCrosshairs); |  | ||||||
|  |  | ||||||
|         return this._appSettings.get_boolean(SHOW_KEY); |         return this._appSettings.get_boolean(SHOW_KEY); | ||||||
|    }, |    }, | ||||||
|  |  | ||||||
| @@ -712,9 +708,6 @@ const ZoomRegion = new Lang.Class({ | |||||||
|         this._xCaret = 0; |         this._xCaret = 0; | ||||||
|         this._yCaret = 0; |         this._yCaret = 0; | ||||||
|  |  | ||||||
|         this._pointerIdleMonitor = Meta.IdleMonitor.get_for_device(Meta.VIRTUAL_CORE_POINTER_ID); |  | ||||||
|         this._scrollContentsTimerId = 0; |  | ||||||
|  |  | ||||||
|         Main.layoutManager.connect('monitors-changed', |         Main.layoutManager.connect('monitors-changed', | ||||||
|                                    Lang.bind(this, this._monitorsChanged)); |                                    Lang.bind(this, this._monitorsChanged)); | ||||||
|         this._focusCaretTracker.connect('caret-moved', |         this._focusCaretTracker.connect('caret-moved', | ||||||
| @@ -1074,26 +1067,6 @@ const ZoomRegion = new Lang.Class({ | |||||||
|         return this._isMouseOverRegion(); |         return this._isMouseOverRegion(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _clearScrollContentsTimer: function() { |  | ||||||
|         if (this._scrollContentsTimerId != 0) { |  | ||||||
|             Mainloop.source_remove(this._scrollContentsTimerId); |  | ||||||
|             this._scrollContentsTimerId = 0; |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     _scrollContentsToDelayed: function(x, y) { |  | ||||||
|         if (this._pointerIdleMonitor.get_idletime() >= POINTER_REST_TIME) { |  | ||||||
|             this.scrollContentsTo(x, y); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this._clearScrollContentsTimer(); |  | ||||||
|         this._scrollContentsTimerId = Mainloop.timeout_add(POINTER_REST_TIME, Lang.bind(this, function() { |  | ||||||
|             this._scrollContentsToDelayed(x, y); |  | ||||||
|             return GLib.SOURCE_REMOVE; |  | ||||||
|         })); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * scrollContentsTo: |      * scrollContentsTo: | ||||||
|      * Shift the contents of the magnified view such it is centered on the given |      * Shift the contents of the magnified view such it is centered on the given | ||||||
| @@ -1102,8 +1075,6 @@ const ZoomRegion = new Lang.Class({ | |||||||
|      * @y:      The y-coord of the point to center on. |      * @y:      The y-coord of the point to center on. | ||||||
|      */ |      */ | ||||||
|     scrollContentsTo: function(x, y) { |     scrollContentsTo: function(x, y) { | ||||||
|         this._clearScrollContentsTimer(); |  | ||||||
|  |  | ||||||
|         this._followingCursor = false; |         this._followingCursor = false; | ||||||
|         this._changeROI({ xCenter: x, |         this._changeROI({ xCenter: x, | ||||||
|                           yCenter: y }); |                           yCenter: y }); | ||||||
| @@ -1227,7 +1198,12 @@ const ZoomRegion = new Lang.Class({ | |||||||
|  |  | ||||||
|         // Add a background for when the magnified uiGroup is scrolled |         // Add a background for when the magnified uiGroup is scrolled | ||||||
|         // out of view (don't want to see desktop showing through). |         // out of view (don't want to see desktop showing through). | ||||||
|         this._background = (new Background.SystemBackground()).actor; |         this._background = new Clutter.Actor({ background_color: Main.DEFAULT_BACKGROUND_COLOR, | ||||||
|  |                                                layout_manager: new Clutter.BinLayout(), | ||||||
|  |                                                width: global.screen_width, | ||||||
|  |                                                height: global.screen_height }); | ||||||
|  |         let noiseTexture = (new Background.SystemBackground()).actor; | ||||||
|  |         this._background.add_actor(noiseTexture); | ||||||
|         mainGroup.add_actor(this._background); |         mainGroup.add_actor(this._background); | ||||||
|  |  | ||||||
|         // Clone the group that contains all of UI on the screen.  This is the |         // Clone the group that contains all of UI on the screen.  This is the | ||||||
| @@ -1409,7 +1385,7 @@ const ZoomRegion = new Lang.Class({ | |||||||
|         else if (this._caretTrackingMode == GDesktopEnums.MagnifierCaretTrackingMode.CENTERED) |         else if (this._caretTrackingMode == GDesktopEnums.MagnifierCaretTrackingMode.CENTERED) | ||||||
|             [xCaret, yCaret] = this._centerFromPointCentered(xCaret, yCaret); |             [xCaret, yCaret] = this._centerFromPointCentered(xCaret, yCaret); | ||||||
|  |  | ||||||
|         this._scrollContentsToDelayed(xCaret, yCaret); |         this.scrollContentsTo(xCaret, yCaret); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _centerFromFocusPosition: function() { |     _centerFromFocusPosition: function() { | ||||||
| @@ -1423,7 +1399,7 @@ const ZoomRegion = new Lang.Class({ | |||||||
|         else if (this._focusTrackingMode == GDesktopEnums.MagnifierFocusTrackingMode.CENTERED) |         else if (this._focusTrackingMode == GDesktopEnums.MagnifierFocusTrackingMode.CENTERED) | ||||||
|             [xFocus, yFocus] = this._centerFromPointCentered(xFocus, yFocus); |             [xFocus, yFocus] = this._centerFromPointCentered(xFocus, yFocus); | ||||||
|  |  | ||||||
|         this._scrollContentsToDelayed(xFocus, yFocus); |         this.scrollContentsTo(xFocus, yFocus); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _centerFromPointPush: function(xPoint, yPoint) { |     _centerFromPointPush: function(xPoint, yPoint) { | ||||||
|   | |||||||
							
								
								
									
										167
									
								
								js/ui/main.js
									
									
									
									
									
								
							
							
						
						| @@ -4,7 +4,6 @@ const Clutter = imports.gi.Clutter; | |||||||
| const Gdk = imports.gi.Gdk; | const Gdk = imports.gi.Gdk; | ||||||
| const Gio = imports.gi.Gio; | const Gio = imports.gi.Gio; | ||||||
| const GLib = imports.gi.GLib; | const GLib = imports.gi.GLib; | ||||||
| const Gtk = imports.gi.Gtk; |  | ||||||
| const Lang = imports.lang; | const Lang = imports.lang; | ||||||
| const Mainloop = imports.mainloop; | const Mainloop = imports.mainloop; | ||||||
| const Meta = imports.gi.Meta; | const Meta = imports.gi.Meta; | ||||||
| @@ -18,11 +17,8 @@ const Environment = imports.ui.environment; | |||||||
| const ExtensionSystem = imports.ui.extensionSystem; | const ExtensionSystem = imports.ui.extensionSystem; | ||||||
| const ExtensionDownloader = imports.ui.extensionDownloader; | const ExtensionDownloader = imports.ui.extensionDownloader; | ||||||
| const Keyboard = imports.ui.keyboard; | const Keyboard = imports.ui.keyboard; | ||||||
| const LegacyTray = imports.ui.legacyTray; |  | ||||||
| const MessageTray = imports.ui.messageTray; | const MessageTray = imports.ui.messageTray; | ||||||
| const ModalDialog = imports.ui.modalDialog; |  | ||||||
| const OsdWindow = imports.ui.osdWindow; | const OsdWindow = imports.ui.osdWindow; | ||||||
| const OsdMonitorLabeler = imports.ui.osdMonitorLabeler; |  | ||||||
| const Overview = imports.ui.overview; | const Overview = imports.ui.overview; | ||||||
| const Panel = imports.ui.panel; | const Panel = imports.ui.panel; | ||||||
| const Params = imports.misc.params; | const Params = imports.misc.params; | ||||||
| @@ -43,6 +39,8 @@ const Magnifier = imports.ui.magnifier; | |||||||
| const XdndHandler = imports.ui.xdndHandler; | const XdndHandler = imports.ui.xdndHandler; | ||||||
| const Util = imports.misc.util; | const Util = imports.misc.util; | ||||||
|  |  | ||||||
|  | const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff); | ||||||
|  |  | ||||||
| const A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard'; | const A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard'; | ||||||
| const STICKY_KEYS_ENABLE = 'stickykeys-enable'; | const STICKY_KEYS_ENABLE = 'stickykeys-enable'; | ||||||
| const GNOMESHELL_STARTED_MESSAGE_ID = 'f3ea493c22934e26811cd62abe8e203a'; | const GNOMESHELL_STARTED_MESSAGE_ID = 'f3ea493c22934e26811cd62abe8e203a'; | ||||||
| @@ -53,21 +51,19 @@ let overview = null; | |||||||
| let runDialog = null; | let runDialog = null; | ||||||
| let lookingGlass = null; | let lookingGlass = null; | ||||||
| let wm = null; | let wm = null; | ||||||
| let legacyTray = null; |  | ||||||
| let messageTray = null; | let messageTray = null; | ||||||
| let screenShield = null; | let screenShield = null; | ||||||
| let notificationDaemon = null; | let notificationDaemon = null; | ||||||
| let windowAttentionHandler = null; | let windowAttentionHandler = null; | ||||||
| let ctrlAltTabManager = null; | let ctrlAltTabManager = null; | ||||||
| let osdWindowManager = null; | let osdWindowManager = null; | ||||||
| let osdMonitorLabeler = null; |  | ||||||
| let sessionMode = null; | let sessionMode = null; | ||||||
| let shellDBusService = null; | let shellDBusService = null; | ||||||
| let shellMountOpDBusService = null; | let shellMountOpDBusService = null; | ||||||
| let screenSaverDBus = null; | let screenSaverDBus = null; | ||||||
| let screencastService = null; | let screencastService = null; | ||||||
| let modalCount = 0; | let modalCount = 0; | ||||||
| let actionMode = Shell.ActionMode.NONE; | let keybindingMode = Shell.KeyBindingMode.NONE; | ||||||
| let modalActorFocusStack = []; | let modalActorFocusStack = []; | ||||||
| let uiGroup = null; | let uiGroup = null; | ||||||
| let magnifier = null; | let magnifier = null; | ||||||
| @@ -78,22 +74,21 @@ let _startDate; | |||||||
| let _defaultCssStylesheet = null; | let _defaultCssStylesheet = null; | ||||||
| let _cssStylesheet = null; | let _cssStylesheet = null; | ||||||
| let _a11ySettings = null; | let _a11ySettings = null; | ||||||
| let _themeResource = null; | let dynamicWorkspacesSchema = null; | ||||||
|  |  | ||||||
| function _sessionUpdated() { | function _sessionUpdated() { | ||||||
|     if (sessionMode.isPrimary) |  | ||||||
|     _loadDefaultStylesheet(); |     _loadDefaultStylesheet(); | ||||||
|  |  | ||||||
|     wm.setCustomKeybindingHandler('panel-main-menu', |     wm.setCustomKeybindingHandler('panel-main-menu', | ||||||
|                                   Shell.ActionMode.NORMAL | |                                   Shell.KeyBindingMode.NORMAL | | ||||||
|                                   Shell.ActionMode.OVERVIEW, |                                   Shell.KeyBindingMode.OVERVIEW, | ||||||
|                                   sessionMode.hasOverview ? Lang.bind(overview, overview.toggle) : null); |                                   sessionMode.hasOverview ? Lang.bind(overview, overview.toggle) : null); | ||||||
|     wm.allowKeybinding('overlay-key', Shell.ActionMode.NORMAL | |     wm.allowKeybinding('overlay-key', Shell.KeyBindingMode.NORMAL | | ||||||
|                                       Shell.ActionMode.OVERVIEW); |                                       Shell.KeyBindingMode.OVERVIEW); | ||||||
|  |  | ||||||
|     wm.setCustomKeybindingHandler('panel-run-dialog', |     wm.setCustomKeybindingHandler('panel-run-dialog', | ||||||
|                                   Shell.ActionMode.NORMAL | |                                   Shell.KeyBindingMode.NORMAL | | ||||||
|                                   Shell.ActionMode.OVERVIEW, |                                   Shell.KeyBindingMode.OVERVIEW, | ||||||
|                                   sessionMode.hasRunDialog ? openRunDialog : null); |                                   sessionMode.hasRunDialog ? openRunDialog : null); | ||||||
|  |  | ||||||
|     if (!sessionMode.hasRunDialog) { |     if (!sessionMode.hasRunDialog) { | ||||||
| @@ -116,8 +111,7 @@ function start() { | |||||||
|  |  | ||||||
|     sessionMode = new SessionMode.SessionMode(); |     sessionMode = new SessionMode.SessionMode(); | ||||||
|     sessionMode.connect('updated', _sessionUpdated); |     sessionMode.connect('updated', _sessionUpdated); | ||||||
|     Gtk.Settings.get_default().connect('notify::gtk-theme-name', |     _initializePrefs(); | ||||||
|                                        _loadDefaultStylesheet); |  | ||||||
|     _initializeUI(); |     _initializeUI(); | ||||||
|  |  | ||||||
|     shellDBusService = new ShellDBus.GnomeShell(); |     shellDBusService = new ShellDBus.GnomeShell(); | ||||||
| @@ -126,6 +120,17 @@ function start() { | |||||||
|     _sessionUpdated(); |     _sessionUpdated(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function _initializePrefs() { | ||||||
|  |     let keys = new Gio.Settings({ schema: sessionMode.overridesSchema }).list_keys(); | ||||||
|  |     for (let i = 0; i < keys.length; i++) | ||||||
|  |         Meta.prefs_override_preference_schema(keys[i], sessionMode.overridesSchema); | ||||||
|  |  | ||||||
|  |     if (keys.indexOf('dynamic-workspaces') > -1) | ||||||
|  |         dynamicWorkspacesSchema = sessionMode.overridesSchema; | ||||||
|  |     else | ||||||
|  |         dynamicWorkspacesSchema = 'org.gnome.mutter'; | ||||||
|  | } | ||||||
|  |  | ||||||
| function _initializeUI() { | function _initializeUI() { | ||||||
|     // Ensure ShellWindowTracker and ShellAppUsage are initialized; this will |     // Ensure ShellWindowTracker and ShellAppUsage are initialized; this will | ||||||
|     // also initialize ShellAppSystem first.  ShellAppSystem |     // also initialize ShellAppSystem first.  ShellAppSystem | ||||||
| @@ -138,7 +143,6 @@ function _initializeUI() { | |||||||
|     Shell.WindowTracker.get_default(); |     Shell.WindowTracker.get_default(); | ||||||
|     Shell.AppUsage.get_default(); |     Shell.AppUsage.get_default(); | ||||||
|  |  | ||||||
|     reloadThemeResource(); |  | ||||||
|     _loadDefaultStylesheet(); |     _loadDefaultStylesheet(); | ||||||
|  |  | ||||||
|     // Setup the stage hierarchy early |     // Setup the stage hierarchy early | ||||||
| @@ -153,16 +157,14 @@ function _initializeUI() { | |||||||
|     xdndHandler = new XdndHandler.XdndHandler(); |     xdndHandler = new XdndHandler.XdndHandler(); | ||||||
|     ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager(); |     ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager(); | ||||||
|     osdWindowManager = new OsdWindow.OsdWindowManager(); |     osdWindowManager = new OsdWindow.OsdWindowManager(); | ||||||
|     osdMonitorLabeler = new OsdMonitorLabeler.OsdMonitorLabeler(); |  | ||||||
|     overview = new Overview.Overview(); |     overview = new Overview.Overview(); | ||||||
|     wm = new WindowManager.WindowManager(); |     wm = new WindowManager.WindowManager(); | ||||||
|     magnifier = new Magnifier.Magnifier(); |     magnifier = new Magnifier.Magnifier(); | ||||||
|     if (LoginManager.canLock()) |     if (LoginManager.canLock()) | ||||||
|         screenShield = new ScreenShield.ScreenShield(); |         screenShield = new ScreenShield.ScreenShield(); | ||||||
|  |  | ||||||
|     legacyTray = new LegacyTray.LegacyTray(); |  | ||||||
|     messageTray = new MessageTray.MessageTray(); |  | ||||||
|     panel = new Panel.Panel(); |     panel = new Panel.Panel(); | ||||||
|  |     messageTray = new MessageTray.MessageTray(); | ||||||
|     keyboard = new Keyboard.Keyboard(); |     keyboard = new Keyboard.Keyboard(); | ||||||
|     notificationDaemon = new NotificationDaemon.NotificationDaemon(); |     notificationDaemon = new NotificationDaemon.NotificationDaemon(); | ||||||
|     windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler(); |     windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler(); | ||||||
| @@ -171,23 +173,13 @@ function _initializeUI() { | |||||||
|     layoutManager.init(); |     layoutManager.init(); | ||||||
|     overview.init(); |     overview.init(); | ||||||
|  |  | ||||||
|     _a11ySettings = new Gio.Settings({ schema_id: A11Y_SCHEMA }); |     _a11ySettings = new Gio.Settings({ schema: A11Y_SCHEMA }); | ||||||
|  |  | ||||||
|     global.display.connect('overlay-key', Lang.bind(overview, function () { |     global.display.connect('overlay-key', Lang.bind(overview, function () { | ||||||
|         if (!_a11ySettings.get_boolean (STICKY_KEYS_ENABLE)) |         if (!_a11ySettings.get_boolean (STICKY_KEYS_ENABLE)) | ||||||
|             overview.toggle(); |             overview.toggle(); | ||||||
|     })); |     })); | ||||||
|  |  | ||||||
|     global.display.connect('show-restart-message', function(display, message) { |  | ||||||
|         showRestartMessage(message); |  | ||||||
|         return true; |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     global.display.connect('restart', function() { |  | ||||||
|         global.reexec_self(); |  | ||||||
|         return true; |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     // Provide the bus object for gnome-session to |     // Provide the bus object for gnome-session to | ||||||
|     // initiate logouts. |     // initiate logouts. | ||||||
|     EndSessionDialog.init(); |     EndSessionDialog.init(); | ||||||
| @@ -214,52 +206,32 @@ function _initializeUI() { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     layoutManager.connect('startup-complete', function() { |     layoutManager.connect('startup-complete', function() { | ||||||
|         if (actionMode == Shell.ActionMode.NONE) { |                               if (keybindingMode == Shell.KeyBindingMode.NONE) { | ||||||
|             actionMode = Shell.ActionMode.NORMAL; |                                   keybindingMode = Shell.KeyBindingMode.NORMAL; | ||||||
|                               } |                               } | ||||||
|                               if (screenShield) { |                               if (screenShield) { | ||||||
|                                   screenShield.lockIfWasLocked(); |                                   screenShield.lockIfWasLocked(); | ||||||
|                               } |                               } | ||||||
|         if (sessionMode.currentMode != 'gdm' && |                               if (LoginManager.haveSystemd() && | ||||||
|  |                                   sessionMode.currentMode != 'gdm' && | ||||||
|                                   sessionMode.currentMode != 'initial-setup') { |                                   sessionMode.currentMode != 'initial-setup') { | ||||||
|             Shell.Global.log_structured('GNOME Shell started at ' + _startDate, |                                   // Do not import globally to not depend | ||||||
|  |                                   // on systemd on non-systemd systems. | ||||||
|  |                                   let GSystem = imports.gi.GSystem; | ||||||
|  |                                   GSystem.log_structured_print('GNOME Shell started at ' + _startDate, | ||||||
|                                                                ['MESSAGE_ID=' + GNOMESHELL_STARTED_MESSAGE_ID]); |                                                                ['MESSAGE_ID=' + GNOMESHELL_STARTED_MESSAGE_ID]); | ||||||
|  |                               } else { | ||||||
|  |                                   log('GNOME Shell started at ' + _startDate); | ||||||
|                               } |                               } | ||||||
|                           }); |                           }); | ||||||
| } | } | ||||||
|  |  | ||||||
| function _getStylesheet(name) { |  | ||||||
|     let stylesheet; |  | ||||||
|  |  | ||||||
|     stylesheet = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/' + name); |  | ||||||
|     if (stylesheet.query_exists(null)) |  | ||||||
|         return stylesheet; |  | ||||||
|  |  | ||||||
|     stylesheet = Gio.File.new_for_path(global.datadir + '/theme/' + name); |  | ||||||
|     if (stylesheet.query_exists(null)) |  | ||||||
|         return stylesheet; |  | ||||||
|  |  | ||||||
|     return null; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function _getDefaultStylesheet() { |  | ||||||
|     let stylesheet = null; |  | ||||||
|     let name = sessionMode.stylesheetName; |  | ||||||
|  |  | ||||||
|     // Look for a high-contrast variant first when using GTK+'s HighContrast |  | ||||||
|     // theme |  | ||||||
|     if (Gtk.Settings.get_default().gtk_theme_name == 'HighContrast') |  | ||||||
|         stylesheet = _getStylesheet(name.replace('.css', '-high-contrast.css')); |  | ||||||
|  |  | ||||||
|     if (stylesheet == null) |  | ||||||
|         stylesheet = _getStylesheet(sessionMode.stylesheetName); |  | ||||||
|  |  | ||||||
|     return stylesheet; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function _loadDefaultStylesheet() { | function _loadDefaultStylesheet() { | ||||||
|     let stylesheet = _getDefaultStylesheet(); |     if (!sessionMode.isPrimary) | ||||||
|     if (_defaultCssStylesheet && _defaultCssStylesheet.equal(stylesheet)) |         return; | ||||||
|  |  | ||||||
|  |     let stylesheet = global.datadir + '/theme/' + sessionMode.stylesheetName; | ||||||
|  |     if (_defaultCssStylesheet == stylesheet) | ||||||
|         return; |         return; | ||||||
|  |  | ||||||
|     _defaultCssStylesheet = stylesheet; |     _defaultCssStylesheet = stylesheet; | ||||||
| @@ -271,10 +243,11 @@ function _loadDefaultStylesheet() { | |||||||
|  * |  * | ||||||
|  * Get the theme CSS file that the shell will load |  * Get the theme CSS file that the shell will load | ||||||
|  * |  * | ||||||
|  * Returns: A #GFile that contains the theme CSS, |  * Returns: A file path that contains the theme CSS, | ||||||
|  *          null if using the default |  *          null if using the default | ||||||
|  */ |  */ | ||||||
| function getThemeStylesheet() { | function getThemeStylesheet() | ||||||
|  | { | ||||||
|     return _cssStylesheet; |     return _cssStylesheet; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -285,16 +258,9 @@ function getThemeStylesheet() { | |||||||
|  * |  * | ||||||
|  * Set the theme CSS file that the shell will load |  * Set the theme CSS file that the shell will load | ||||||
|  */ |  */ | ||||||
| function setThemeStylesheet(cssStylesheet) { | function setThemeStylesheet(cssStylesheet) | ||||||
|     _cssStylesheet = cssStylesheet ? Gio.File.new_for_path(cssStylesheet) : null; | { | ||||||
| } |     _cssStylesheet = cssStylesheet; | ||||||
|  |  | ||||||
| function reloadThemeResource() { |  | ||||||
|     if (_themeResource) |  | ||||||
|         _themeResource._unregister(); |  | ||||||
|  |  | ||||||
|     _themeResource = Gio.Resource.load(global.datadir + '/gnome-shell-theme.gresource'); |  | ||||||
|     _themeResource._register(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -379,7 +345,7 @@ function _findModal(actor) { | |||||||
|  *  - options: Meta.ModalOptions flags to indicate that the pointer is |  *  - options: Meta.ModalOptions flags to indicate that the pointer is | ||||||
|  *             already grabbed |  *             already grabbed | ||||||
|  * |  * | ||||||
|  *  - actionMode: used to set the current Shell.ActionMode to filter |  *  - keybindingMode: used to set the current Shell.KeyBindingMode to filter | ||||||
|  *                    global keybindings; the default of NONE will filter |  *                    global keybindings; the default of NONE will filter | ||||||
|  *                    out all keybindings |  *                    out all keybindings | ||||||
|  * |  * | ||||||
| @@ -388,7 +354,7 @@ function _findModal(actor) { | |||||||
| function pushModal(actor, params) { | function pushModal(actor, params) { | ||||||
|     params = Params.parse(params, { timestamp: global.get_current_time(), |     params = Params.parse(params, { timestamp: global.get_current_time(), | ||||||
|                                     options: 0, |                                     options: 0, | ||||||
|                                     actionMode: Shell.ActionMode.NONE }); |                                     keybindingMode: Shell.KeyBindingMode.NONE }); | ||||||
|  |  | ||||||
|     if (modalCount == 0) { |     if (modalCount == 0) { | ||||||
|         if (!global.begin_modal(params.timestamp, params.options)) { |         if (!global.begin_modal(params.timestamp, params.options)) { | ||||||
| @@ -418,9 +384,9 @@ function pushModal(actor, params) { | |||||||
|                                 destroyId: actorDestroyId, |                                 destroyId: actorDestroyId, | ||||||
|                                 prevFocus: prevFocus, |                                 prevFocus: prevFocus, | ||||||
|                                 prevFocusDestroyId: prevFocusDestroyId, |                                 prevFocusDestroyId: prevFocusDestroyId, | ||||||
|                                 actionMode: actionMode }); |                                 keybindingMode: keybindingMode }); | ||||||
|  |  | ||||||
|     actionMode = params.actionMode; |     keybindingMode = params.keybindingMode; | ||||||
|     global.stage.set_key_focus(actor); |     global.stage.set_key_focus(actor); | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| @@ -446,7 +412,7 @@ function popModal(actor, timestamp) { | |||||||
|     if (focusIndex < 0) { |     if (focusIndex < 0) { | ||||||
|         global.stage.set_key_focus(null); |         global.stage.set_key_focus(null); | ||||||
|         global.end_modal(timestamp); |         global.end_modal(timestamp); | ||||||
|         actionMode = Shell.ActionMode.NORMAL; |         keybindingMode = Shell.KeyBindingMode.NORMAL; | ||||||
|  |  | ||||||
|         throw new Error('incorrect pop'); |         throw new Error('incorrect pop'); | ||||||
|     } |     } | ||||||
| @@ -459,7 +425,7 @@ function popModal(actor, timestamp) { | |||||||
|     if (focusIndex == modalActorFocusStack.length - 1) { |     if (focusIndex == modalActorFocusStack.length - 1) { | ||||||
|         if (record.prevFocus) |         if (record.prevFocus) | ||||||
|             record.prevFocus.disconnect(record.prevFocusDestroyId); |             record.prevFocus.disconnect(record.prevFocusDestroyId); | ||||||
|         actionMode = record.actionMode; |         keybindingMode = record.keybindingMode; | ||||||
|         global.stage.set_key_focus(record.prevFocus); |         global.stage.set_key_focus(record.prevFocus); | ||||||
|     } else { |     } else { | ||||||
|         // If we have: |         // If we have: | ||||||
| @@ -484,7 +450,7 @@ function popModal(actor, timestamp) { | |||||||
|         for (let i = modalActorFocusStack.length - 1; i > focusIndex; i--) { |         for (let i = modalActorFocusStack.length - 1; i > focusIndex; i--) { | ||||||
|             modalActorFocusStack[i].prevFocus = modalActorFocusStack[i - 1].prevFocus; |             modalActorFocusStack[i].prevFocus = modalActorFocusStack[i - 1].prevFocus; | ||||||
|             modalActorFocusStack[i].prevFocusDestroyId = modalActorFocusStack[i - 1].prevFocusDestroyId; |             modalActorFocusStack[i].prevFocusDestroyId = modalActorFocusStack[i - 1].prevFocusDestroyId; | ||||||
|             modalActorFocusStack[i].actionMode = modalActorFocusStack[i - 1].actionMode; |             modalActorFocusStack[i].keybindingMode = modalActorFocusStack[i - 1].keybindingMode; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     modalActorFocusStack.splice(focusIndex, 1); |     modalActorFocusStack.splice(focusIndex, 1); | ||||||
| @@ -492,10 +458,9 @@ function popModal(actor, timestamp) { | |||||||
|     if (modalCount > 0) |     if (modalCount > 0) | ||||||
|         return; |         return; | ||||||
|  |  | ||||||
|     layoutManager.modalEnded(); |  | ||||||
|     global.end_modal(timestamp); |     global.end_modal(timestamp); | ||||||
|     Meta.enable_unredirect_for_screen(global.screen); |     Meta.enable_unredirect_for_screen(global.screen); | ||||||
|     actionMode = Shell.ActionMode.NORMAL; |     keybindingMode = Shell.KeyBindingMode.NORMAL; | ||||||
| } | } | ||||||
|  |  | ||||||
| function createLookingGlass() { | function createLookingGlass() { | ||||||
| @@ -536,7 +501,6 @@ function activateWindow(window, time, workspaceNum) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     overview.hide(); |     overview.hide(); | ||||||
|     panel.closeCalendar(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // TODO - replace this timeout with some system to guess when the user might | // TODO - replace this timeout with some system to guess when the user might | ||||||
| @@ -657,28 +621,3 @@ function queueDeferredWork(workId) { | |||||||
|         GLib.Source.set_name_by_id(_deferredTimeoutId, '[gnome-shell] _runAllDeferredWork'); |         GLib.Source.set_name_by_id(_deferredTimeoutId, '[gnome-shell] _runAllDeferredWork'); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| const RestartMessage = new Lang.Class({ |  | ||||||
|     Name: 'RestartMessage', |  | ||||||
|     Extends: ModalDialog.ModalDialog, |  | ||||||
|  |  | ||||||
|     _init : function(message) { |  | ||||||
|         this.parent({ shellReactive: true, |  | ||||||
|                       styleClass: 'restart-message headline', |  | ||||||
|                       shouldFadeIn: false, |  | ||||||
|                       destroyOnClose: true }); |  | ||||||
|  |  | ||||||
|         let label = new St.Label({ text: message }); |  | ||||||
|  |  | ||||||
|         this.contentLayout.add(label, { x_fill: false, |  | ||||||
|                                         y_fill: false, |  | ||||||
|                                         x_align: St.Align.MIDDLE, |  | ||||||
|                                         y_align: St.Align.MIDDLE }); |  | ||||||
|         this.buttonLayout.hide(); |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| function showRestartMessage(message) { |  | ||||||
|     let restartMessage = new RestartMessage(message); |  | ||||||
|     restartMessage.open(); |  | ||||||
| } |  | ||||||
|   | |||||||
							
								
								
									
										1815
									
								
								js/ui/messageTray.js
									
									
									
									
									
								
							
							
						
						| @@ -14,6 +14,7 @@ const Atk = imports.gi.Atk; | |||||||
|  |  | ||||||
| const Params = imports.misc.params; | const Params = imports.misc.params; | ||||||
|  |  | ||||||
|  | const Animation = imports.ui.animation; | ||||||
| const Layout = imports.ui.layout; | const Layout = imports.ui.layout; | ||||||
| const Lightbox = imports.ui.lightbox; | const Lightbox = imports.ui.lightbox; | ||||||
| const Main = imports.ui.main; | const Main = imports.ui.main; | ||||||
| @@ -22,6 +23,10 @@ const Tweener = imports.ui.tweener; | |||||||
| const OPEN_AND_CLOSE_TIME = 0.1; | const OPEN_AND_CLOSE_TIME = 0.1; | ||||||
| const FADE_OUT_DIALOG_TIME = 1.0; | const FADE_OUT_DIALOG_TIME = 1.0; | ||||||
|  |  | ||||||
|  | const WORK_SPINNER_ICON_SIZE = 24; | ||||||
|  | const WORK_SPINNER_ANIMATION_DELAY = 1.0; | ||||||
|  | const WORK_SPINNER_ANIMATION_TIME = 0.3; | ||||||
|  |  | ||||||
| const State = { | const State = { | ||||||
|     OPENED: 0, |     OPENED: 0, | ||||||
|     CLOSED: 1, |     CLOSED: 1, | ||||||
| @@ -36,17 +41,15 @@ const ModalDialog = new Lang.Class({ | |||||||
|     _init: function(params) { |     _init: function(params) { | ||||||
|         params = Params.parse(params, { shellReactive: false, |         params = Params.parse(params, { shellReactive: false, | ||||||
|                                         styleClass: null, |                                         styleClass: null, | ||||||
|                                         actionMode: Shell.ActionMode.SYSTEM_MODAL, |                                         keybindingMode: Shell.KeyBindingMode.SYSTEM_MODAL, | ||||||
|                                         shouldFadeIn: true, |                                         shouldFadeIn: true, | ||||||
|                                         shouldFadeOut: true, |  | ||||||
|                                         destroyOnClose: true }); |                                         destroyOnClose: true }); | ||||||
|  |  | ||||||
|         this.state = State.CLOSED; |         this.state = State.CLOSED; | ||||||
|         this._hasModal = false; |         this._hasModal = false; | ||||||
|         this._actionMode = params.actionMode; |         this._keybindingMode = params.keybindingMode; | ||||||
|         this._shellReactive = params.shellReactive; |         this._shellReactive = params.shellReactive; | ||||||
|         this._shouldFadeIn = params.shouldFadeIn; |         this._shouldFadeIn = params.shouldFadeIn; | ||||||
|         this._shouldFadeOut = params.shouldFadeOut; |  | ||||||
|         this._destroyOnClose = params.destroyOnClose; |         this._destroyOnClose = params.destroyOnClose; | ||||||
|  |  | ||||||
|         this._group = new St.Widget({ visible: false, |         this._group = new St.Widget({ visible: false, | ||||||
| @@ -74,8 +77,6 @@ const ModalDialog = new Lang.Class({ | |||||||
|         this._group.add_actor(this._backgroundBin); |         this._group.add_actor(this._backgroundBin); | ||||||
|  |  | ||||||
|         this.dialogLayout = new St.BoxLayout({ style_class: 'modal-dialog', |         this.dialogLayout = new St.BoxLayout({ style_class: 'modal-dialog', | ||||||
|                                                x_align:      Clutter.ActorAlign.CENTER, |  | ||||||
|                                                y_align:      Clutter.ActorAlign.CENTER, |  | ||||||
|                                                vertical:    true }); |                                                vertical:    true }); | ||||||
|         // modal dialogs are fixed width and grow vertically; set the request |         // modal dialogs are fixed width and grow vertically; set the request | ||||||
|         // mode accordingly so wrapped labels are handled correctly during |         // mode accordingly so wrapped labels are handled correctly during | ||||||
| @@ -97,8 +98,7 @@ const ModalDialog = new Lang.Class({ | |||||||
|         this.backgroundStack.add_actor(this.dialogLayout); |         this.backgroundStack.add_actor(this.dialogLayout); | ||||||
|  |  | ||||||
|  |  | ||||||
|         this.contentLayout = new St.BoxLayout({ vertical: true, |         this.contentLayout = new St.BoxLayout({ vertical: true }); | ||||||
|                                                 style_class: "modal-dialog-content-box" }); |  | ||||||
|         this.dialogLayout.add(this.contentLayout, |         this.dialogLayout.add(this.contentLayout, | ||||||
|                               { expand:  true, |                               { expand:  true, | ||||||
|                                 x_fill:  true, |                                 x_fill:  true, | ||||||
| @@ -106,7 +106,8 @@ const ModalDialog = new Lang.Class({ | |||||||
|                                 x_align: St.Align.MIDDLE, |                                 x_align: St.Align.MIDDLE, | ||||||
|                                 y_align: St.Align.START }); |                                 y_align: St.Align.START }); | ||||||
|  |  | ||||||
|         this.buttonLayout = new St.Widget ({ layout_manager: new Clutter.BoxLayout ({ homogeneous:true }) }); |         this.buttonLayout = new St.BoxLayout({ style_class: 'modal-dialog-button-box', | ||||||
|  |                                                vertical: false }); | ||||||
|         this.dialogLayout.add(this.buttonLayout, |         this.dialogLayout.add(this.buttonLayout, | ||||||
|                               { x_align: St.Align.MIDDLE, |                               { x_align: St.Align.MIDDLE, | ||||||
|                                 y_align: St.Align.END }); |                                 y_align: St.Align.END }); | ||||||
| @@ -115,6 +116,8 @@ const ModalDialog = new Lang.Class({ | |||||||
|         this._initialKeyFocus = this.dialogLayout; |         this._initialKeyFocus = this.dialogLayout; | ||||||
|         this._initialKeyFocusDestroyId = 0; |         this._initialKeyFocusDestroyId = 0; | ||||||
|         this._savedKeyFocus = null; |         this._savedKeyFocus = null; | ||||||
|  |  | ||||||
|  |         this._workSpinner = null; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     destroy: function() { |     destroy: function() { | ||||||
| @@ -142,12 +145,16 @@ const ModalDialog = new Lang.Class({ | |||||||
|             else |             else | ||||||
|                 x_alignment = St.Align.MIDDLE; |                 x_alignment = St.Align.MIDDLE; | ||||||
|  |  | ||||||
|             this.addButton(buttonInfo); |             this.addButton(buttonInfo, { expand: true, | ||||||
|  |                                          x_fill: false, | ||||||
|  |                                          y_fill: false, | ||||||
|  |                                          x_align: x_alignment, | ||||||
|  |                                          y_align: St.Align.MIDDLE }); | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     addButton: function(buttonInfo) { |     addButton: function(buttonInfo, layoutInfo) { | ||||||
|         let label = buttonInfo['label'] |         let label = buttonInfo['label']; | ||||||
|         let action = buttonInfo['action']; |         let action = buttonInfo['action']; | ||||||
|         let key = buttonInfo['key']; |         let key = buttonInfo['key']; | ||||||
|         let isDefault = buttonInfo['default']; |         let isDefault = buttonInfo['default']; | ||||||
| @@ -161,12 +168,10 @@ const ModalDialog = new Lang.Class({ | |||||||
|         else |         else | ||||||
|             keys = []; |             keys = []; | ||||||
|  |  | ||||||
|         let button = new St.Button({ style_class: 'modal-dialog-linked-button', |         let button = new St.Button({ style_class: 'modal-dialog-button', | ||||||
|                                      button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, |                                      button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, | ||||||
|                                      reactive:    true, |                                      reactive:    true, | ||||||
|                                      can_focus:   true, |                                      can_focus:   true, | ||||||
|                                      x_expand:    true, |  | ||||||
|                                      y_expand:    true, |  | ||||||
|                                      label:       label }); |                                      label:       label }); | ||||||
|         button.connect('clicked', action); |         button.connect('clicked', action); | ||||||
|  |  | ||||||
| @@ -181,11 +186,47 @@ const ModalDialog = new Lang.Class({ | |||||||
|         for (let i in keys) |         for (let i in keys) | ||||||
|             this._buttonKeys[keys[i]] = buttonInfo; |             this._buttonKeys[keys[i]] = buttonInfo; | ||||||
|  |  | ||||||
|         this.buttonLayout.add_actor(button); |         this.buttonLayout.add(button, layoutInfo); | ||||||
|  |  | ||||||
|         return button; |         return button; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|  |     placeSpinner: function(layoutInfo) { | ||||||
|  |         let spinnerIcon = global.datadir + '/theme/process-working.svg'; | ||||||
|  |         this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE); | ||||||
|  |         this._workSpinner.actor.opacity = 0; | ||||||
|  |         this._workSpinner.actor.show(); | ||||||
|  |  | ||||||
|  |         this.buttonLayout.add(this._workSpinner.actor, layoutInfo); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     setWorking: function(working) { | ||||||
|  |         if (!this._workSpinner) | ||||||
|  |             return; | ||||||
|  |  | ||||||
|  |         Tweener.removeTweens(this._workSpinner.actor); | ||||||
|  |         if (working) { | ||||||
|  |             this._workSpinner.play(); | ||||||
|  |             Tweener.addTween(this._workSpinner.actor, | ||||||
|  |                              { opacity: 255, | ||||||
|  |                                delay: WORK_SPINNER_ANIMATION_DELAY, | ||||||
|  |                                time: WORK_SPINNER_ANIMATION_TIME, | ||||||
|  |                                transition: 'linear' | ||||||
|  |                              }); | ||||||
|  |         } else { | ||||||
|  |             Tweener.addTween(this._workSpinner.actor, | ||||||
|  |                              { opacity: 0, | ||||||
|  |                                time: WORK_SPINNER_ANIMATION_TIME, | ||||||
|  |                                transition: 'linear', | ||||||
|  |                                onCompleteScope: this, | ||||||
|  |                                onComplete: function() { | ||||||
|  |                                    if (this._workSpinner) | ||||||
|  |                                        this._workSpinner.stop(); | ||||||
|  |                                } | ||||||
|  |                              }); | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|     _onKeyPressEvent: function(object, event) { |     _onKeyPressEvent: function(object, event) { | ||||||
|         this._pressedKey = event.get_key_symbol(); |         this._pressedKey = event.get_key_symbol(); | ||||||
|         return Clutter.EVENT_PROPAGATE; |         return Clutter.EVENT_PROPAGATE; | ||||||
| @@ -266,15 +307,6 @@ const ModalDialog = new Lang.Class({ | |||||||
|         return true; |         return true; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _closeComplete: function() { |  | ||||||
|         this.state = State.CLOSED; |  | ||||||
|         this._group.hide(); |  | ||||||
|         this.emit('closed'); |  | ||||||
|  |  | ||||||
|         if (this._destroyOnClose) |  | ||||||
|             this.destroy(); |  | ||||||
|     }, |  | ||||||
|  |  | ||||||
|     close: function(timestamp) { |     close: function(timestamp) { | ||||||
|         if (this.state == State.CLOSED || this.state == State.CLOSING) |         if (this.state == State.CLOSED || this.state == State.CLOSING) | ||||||
|             return; |             return; | ||||||
| @@ -283,16 +315,20 @@ const ModalDialog = new Lang.Class({ | |||||||
|         this.popModal(timestamp); |         this.popModal(timestamp); | ||||||
|         this._savedKeyFocus = null; |         this._savedKeyFocus = null; | ||||||
|  |  | ||||||
|         if (this._shouldFadeOut) |  | ||||||
|         Tweener.addTween(this._group, |         Tweener.addTween(this._group, | ||||||
|                          { opacity: 0, |                          { opacity: 0, | ||||||
|                            time: OPEN_AND_CLOSE_TIME, |                            time: OPEN_AND_CLOSE_TIME, | ||||||
|                            transition: 'easeOutQuad', |                            transition: 'easeOutQuad', | ||||||
|                            onComplete: Lang.bind(this, |                            onComplete: Lang.bind(this, | ||||||
|                                                      this._closeComplete) |                                function() { | ||||||
|  |                                    this.state = State.CLOSED; | ||||||
|  |                                    this._group.hide(); | ||||||
|  |                                    this.emit('closed'); | ||||||
|  |  | ||||||
|  |                                    if (this._destroyOnClose) | ||||||
|  |                                        this.destroy(); | ||||||
|                                }) |                                }) | ||||||
|         else |                          }); | ||||||
|             this._closeComplete(); |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     // Drop modal status without closing the dialog; this makes the |     // Drop modal status without closing the dialog; this makes the | ||||||
| @@ -319,7 +355,7 @@ const ModalDialog = new Lang.Class({ | |||||||
|         if (this._hasModal) |         if (this._hasModal) | ||||||
|             return true; |             return true; | ||||||
|         if (!Main.pushModal(this._group, { timestamp: timestamp, |         if (!Main.pushModal(this._group, { timestamp: timestamp, | ||||||
|                                            actionMode: this._actionMode })) |                                            keybindingMode: this._keybindingMode })) | ||||||
|             return false; |             return false; | ||||||
|  |  | ||||||
|         this._hasModal = true; |         this._hasModal = true; | ||||||
|   | |||||||
| @@ -105,10 +105,16 @@ const FdoNotificationDaemon = new Lang.Class({ | |||||||
|  |  | ||||||
|         this._nextNotificationId = 1; |         this._nextNotificationId = 1; | ||||||
|  |  | ||||||
|  |         this._trayManager = new Shell.TrayManager(); | ||||||
|  |         this._trayIconAddedId = this._trayManager.connect('tray-icon-added', Lang.bind(this, this._onTrayIconAdded)); | ||||||
|  |         this._trayIconRemovedId = this._trayManager.connect('tray-icon-removed', Lang.bind(this, this._onTrayIconRemoved)); | ||||||
|  |  | ||||||
|         Shell.WindowTracker.get_default().connect('notify::focus-app', |         Shell.WindowTracker.get_default().connect('notify::focus-app', | ||||||
|             Lang.bind(this, this._onFocusAppChanged)); |             Lang.bind(this, this._onFocusAppChanged)); | ||||||
|         Main.overview.connect('hidden', |         Main.overview.connect('hidden', | ||||||
|             Lang.bind(this, this._onFocusAppChanged)); |             Lang.bind(this, this._onFocusAppChanged)); | ||||||
|  |  | ||||||
|  |         this._trayManager.manage_screen(global.screen, Main.messageTray.actor); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _imageForNotificationData: function(hints) { |     _imageForNotificationData: function(hints) { | ||||||
| @@ -149,10 +155,11 @@ const FdoNotificationDaemon = new Lang.Class({ | |||||||
|         return null; |         return null; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _lookupSource: function(title, pid) { |     _lookupSource: function(title, pid, trayIcon) { | ||||||
|         for (let i = 0; i < this._sources.length; i++) { |         for (let i = 0; i < this._sources.length; i++) { | ||||||
|             let source = this._sources[i]; |             let source = this._sources[i]; | ||||||
|             if (source.pid == pid && source.initialTitle == title) |             if (source.pid == pid && | ||||||
|  |                 (source.initialTitle == title || source.trayIcon || trayIcon)) | ||||||
|                 return source; |                 return source; | ||||||
|         } |         } | ||||||
|         return null; |         return null; | ||||||
| @@ -169,7 +176,7 @@ const FdoNotificationDaemon = new Lang.Class({ | |||||||
|     // |     // | ||||||
|     // Either a pid or ndata.notification is needed to retrieve or |     // Either a pid or ndata.notification is needed to retrieve or | ||||||
|     // create a source. |     // create a source. | ||||||
|     _getSource: function(title, pid, ndata, sender) { |     _getSource: function(title, pid, ndata, sender, trayIcon) { | ||||||
|         if (!pid && !(ndata && ndata.notification)) |         if (!pid && !(ndata && ndata.notification)) | ||||||
|             return null; |             return null; | ||||||
|  |  | ||||||
| @@ -180,13 +187,13 @@ const FdoNotificationDaemon = new Lang.Class({ | |||||||
|         if (ndata && ndata.notification) |         if (ndata && ndata.notification) | ||||||
|             return ndata.notification.source; |             return ndata.notification.source; | ||||||
|  |  | ||||||
|         let source = this._lookupSource(title, pid); |         let source = this._lookupSource(title, pid, trayIcon); | ||||||
|         if (source) { |         if (source) { | ||||||
|             source.setTitle(title); |             source.setTitle(title); | ||||||
|             return source; |             return source; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         let source = new FdoNotificationDaemonSource(title, pid, sender, ndata ? ndata.hints['desktop-entry'] : null); |         let source = new FdoNotificationDaemonSource(title, pid, sender, trayIcon, ndata ? ndata.hints['desktop-entry'] : null); | ||||||
|  |  | ||||||
|         this._sources.push(source); |         this._sources.push(source); | ||||||
|         source.connect('destroy', Lang.bind(this, function() { |         source.connect('destroy', Lang.bind(this, function() { | ||||||
| @@ -212,10 +219,13 @@ const FdoNotificationDaemon = new Lang.Class({ | |||||||
|  |  | ||||||
|         // Filter out chat, presence, calls and invitation notifications from |         // Filter out chat, presence, calls and invitation notifications from | ||||||
|         // Empathy, since we handle that information from telepathyClient.js |         // Empathy, since we handle that information from telepathyClient.js | ||||||
|         // |         if (appName == 'Empathy' && (hints['category'] == 'im.received' || | ||||||
|         // Note that empathy uses im.received for one to one chats and |               hints['category'] == 'x-empathy.im.room-invitation' || | ||||||
|         // x-empathy.im.mentioned for multi-user, so we're good here |               hints['category'] == 'x-empathy.call.incoming' || | ||||||
|         if (appName == 'Empathy' && hints['category'] == 'im.received') { |               hints['category'] == 'x-empathy.transfer.incoming' || | ||||||
|  |               hints['category'] == 'x-empathy.im.subscription-request' || | ||||||
|  |               hints['category'] == 'presence.online' || | ||||||
|  |               hints['category'] == 'presence.offline')) { | ||||||
|             // Ignore replacesId since we already sent back a |             // Ignore replacesId since we already sent back a | ||||||
|             // NotificationClosed for that id. |             // NotificationClosed for that id. | ||||||
|             id = this._nextNotificationId++; |             id = this._nextNotificationId++; | ||||||
| @@ -308,6 +318,20 @@ const FdoNotificationDaemon = new Lang.Class({ | |||||||
|         return invocation.return_value(GLib.Variant.new('(u)', [id])); |         return invocation.return_value(GLib.Variant.new('(u)', [id])); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|  |     _makeButton: function(id, label, useActionIcons) { | ||||||
|  |         let button = new St.Button({ can_focus: true, | ||||||
|  |                                      x_expand: true, | ||||||
|  |                                      style_class: 'notification-button' }); | ||||||
|  |         let iconName = id.endsWith('-symbolic') ? id : id + '-symbolic'; | ||||||
|  |  | ||||||
|  |         if (useActionIcons && Gtk.IconTheme.get_default().has_icon(iconName)) { | ||||||
|  |             button.child = new St.Icon({ icon_name: iconName, icon_size: 16 }); | ||||||
|  |         } else { | ||||||
|  |             button.label = label; | ||||||
|  |         } | ||||||
|  |         return button; | ||||||
|  |     }, | ||||||
|  |  | ||||||
|     _notifyForSource: function(source, ndata) { |     _notifyForSource: function(source, ndata) { | ||||||
|         let [id, icon, summary, body, actions, hints, notification] = |         let [id, icon, summary, body, actions, hints, notification] = | ||||||
|             [ndata.id, ndata.icon, ndata.summary, ndata.body, |             [ndata.id, ndata.icon, ndata.summary, ndata.body, | ||||||
| @@ -335,6 +359,9 @@ const FdoNotificationDaemon = new Lang.Class({ | |||||||
|                 })); |                 })); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         // Mark music notifications so they can be shown in the screen shield | ||||||
|  |         notification.isMusic = (ndata.hints['category'] == 'x-gnome.music'); | ||||||
|  |  | ||||||
|         let gicon = this._iconForNotificationData(icon, hints); |         let gicon = this._iconForNotificationData(icon, hints); | ||||||
|         let gimage = this._imageForNotificationData(hints); |         let gimage = this._imageForNotificationData(hints); | ||||||
|  |  | ||||||
| @@ -344,7 +371,8 @@ const FdoNotificationDaemon = new Lang.Class({ | |||||||
|         // the 'image-data' hint. These applications don't typically pass in 'app_icon' |         // the 'image-data' hint. These applications don't typically pass in 'app_icon' | ||||||
|         // argument to Notify() and actually expect the pixbuf to be shown as an icon. |         // argument to Notify() and actually expect the pixbuf to be shown as an icon. | ||||||
|         // So the logic here does the right thing for this case. If both an icon and either |         // So the logic here does the right thing for this case. If both an icon and either | ||||||
|         // one of 'image-data' or 'image-path' are specified, the icon and takes precedence. |         // one of 'image-data' or 'image-path' are specified, we show both an icon and | ||||||
|  |         // a large image. | ||||||
|         if (!gicon && gimage) |         if (!gicon && gimage) | ||||||
|             gicon = gimage; |             gicon = gimage; | ||||||
|         else if (!gicon) |         else if (!gicon) | ||||||
| @@ -359,23 +387,26 @@ const FdoNotificationDaemon = new Lang.Class({ | |||||||
|         let hasDefaultAction = false; |         let hasDefaultAction = false; | ||||||
|  |  | ||||||
|         if (actions.length) { |         if (actions.length) { | ||||||
|  |             let useActionIcons = (hints['action-icons'] == true); | ||||||
|  |  | ||||||
|             for (let i = 0; i < actions.length - 1; i += 2) { |             for (let i = 0; i < actions.length - 1; i += 2) { | ||||||
|                 let [actionId, label] = [actions[i], actions[i+1]]; |                 let [actionId, label] = [actions[i], actions[i+1]]; | ||||||
|                 if (actionId == 'default') |                 if (actionId == 'default') { | ||||||
|                     hasDefaultAction = true; |                     hasDefaultAction = true; | ||||||
|                 else |                 } else { | ||||||
|                     notification.addAction(label, Lang.bind(this, function() { |                     notification.addButton(this._makeButton(actionId, label, useActionIcons), Lang.bind(this, function() { | ||||||
|                         this._emitActionInvoked(ndata.id, actionId); |                         this._emitActionInvoked(ndata.id, actionId); | ||||||
|                     })); |                     })); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|         if (hasDefaultAction) { |         if (hasDefaultAction) { | ||||||
|             notification.connect('activated', Lang.bind(this, function() { |             notification.connect('clicked', Lang.bind(this, function() { | ||||||
|                 this._emitActionInvoked(ndata.id, 'default'); |                 this._emitActionInvoked(ndata.id, 'default'); | ||||||
|             })); |             })); | ||||||
|         } else { |         } else { | ||||||
|             notification.connect('activated', Lang.bind(this, function() { |             notification.connect('clicked', Lang.bind(this, function() { | ||||||
|                 source.open(); |                 source.open(); | ||||||
|             })); |             })); | ||||||
|         } |         } | ||||||
| @@ -391,7 +422,6 @@ const FdoNotificationDaemon = new Lang.Class({ | |||||||
|                 notification.setUrgency(MessageTray.Urgency.CRITICAL); |                 notification.setUrgency(MessageTray.Urgency.CRITICAL); | ||||||
|                 break; |                 break; | ||||||
|         } |         } | ||||||
|         notification.setResident(hints.resident == true); |  | ||||||
|         // 'transient' is a reserved keyword in JS, so we have to retrieve the value |         // 'transient' is a reserved keyword in JS, so we have to retrieve the value | ||||||
|         // of the 'transient' hint with hints['transient'] rather than hints.transient |         // of the 'transient' hint with hints['transient'] rather than hints.transient | ||||||
|         notification.setTransient(hints['transient'] == true); |         notification.setTransient(hints['transient'] == true); | ||||||
| @@ -412,14 +442,13 @@ const FdoNotificationDaemon = new Lang.Class({ | |||||||
|     GetCapabilities: function() { |     GetCapabilities: function() { | ||||||
|         return [ |         return [ | ||||||
|             'actions', |             'actions', | ||||||
|             // 'action-icons', |             'action-icons', | ||||||
|             'body', |             'body', | ||||||
|             // 'body-hyperlinks', |             // 'body-hyperlinks', | ||||||
|             // 'body-images', |             // 'body-images', | ||||||
|             'body-markup', |             'body-markup', | ||||||
|             // 'icon-multi', |             // 'icon-multi', | ||||||
|             'icon-static', |             'icon-static', | ||||||
|             'persistence', |  | ||||||
|             'sound', |             'sound', | ||||||
|         ]; |         ]; | ||||||
|     }, |     }, | ||||||
| @@ -441,7 +470,7 @@ const FdoNotificationDaemon = new Lang.Class({ | |||||||
|         for (let i = 0; i < this._sources.length; i++) { |         for (let i = 0; i < this._sources.length; i++) { | ||||||
|             let source = this._sources[i]; |             let source = this._sources[i]; | ||||||
|             if (source.app == tracker.focus_app) { |             if (source.app == tracker.focus_app) { | ||||||
|                 source.destroyNonResidentNotifications(); |                 source.destroyNotifications(); | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -455,6 +484,16 @@ const FdoNotificationDaemon = new Lang.Class({ | |||||||
|     _emitActionInvoked: function(id, action) { |     _emitActionInvoked: function(id, action) { | ||||||
|         this._dbusImpl.emit_signal('ActionInvoked', |         this._dbusImpl.emit_signal('ActionInvoked', | ||||||
|                                    GLib.Variant.new('(us)', [id, action])); |                                    GLib.Variant.new('(us)', [id, action])); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _onTrayIconAdded: function(o, icon) { | ||||||
|  |         let source = this._getSource(icon.title || icon.wm_class || C_("program", "Unknown"), icon.pid, null, null, icon); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _onTrayIconRemoved: function(o, icon) { | ||||||
|  |         let source = this._lookupSource(null, icon.pid, true); | ||||||
|  |         if (source) | ||||||
|  |             source.destroy(); | ||||||
|     } |     } | ||||||
| }); | }); | ||||||
|  |  | ||||||
| @@ -462,9 +501,10 @@ const FdoNotificationDaemonSource = new Lang.Class({ | |||||||
|     Name: 'FdoNotificationDaemonSource', |     Name: 'FdoNotificationDaemonSource', | ||||||
|     Extends: MessageTray.Source, |     Extends: MessageTray.Source, | ||||||
|  |  | ||||||
|     _init: function(title, pid, sender, appId) { |     _init: function(title, pid, sender, trayIcon, appId) { | ||||||
|         // Need to set the app before chaining up, so |         // Need to set the app before chaining up, so | ||||||
|         // methods called from the parent constructor can find it |         // methods called from the parent constructor can find it | ||||||
|  |         this.trayIcon = trayIcon; | ||||||
|         this.pid = pid; |         this.pid = pid; | ||||||
|         this.app = this._getApp(appId); |         this.app = this._getApp(appId); | ||||||
|  |  | ||||||
| @@ -484,6 +524,12 @@ const FdoNotificationDaemonSource = new Lang.Class({ | |||||||
|                                                               Lang.bind(this, this._onNameVanished)); |                                                               Lang.bind(this, this._onNameVanished)); | ||||||
|         else |         else | ||||||
|             this._nameWatcherId = 0; |             this._nameWatcherId = 0; | ||||||
|  |  | ||||||
|  |         if (this.trayIcon) { | ||||||
|  |             // Try again finding the app, using the WM_CLASS from the tray icon | ||||||
|  |             this._setSummaryIcon(this.trayIcon); | ||||||
|  |             this.useNotificationIcon = false; | ||||||
|  |         } | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     _createPolicy: function() { |     _createPolicy: function() { | ||||||
| @@ -501,22 +547,46 @@ const FdoNotificationDaemonSource = new Lang.Class({ | |||||||
|         // of which аre removed from DBus immediately. |         // of which аre removed from DBus immediately. | ||||||
|         // Sender being removed from DBus would normally result in a tray icon being removed, |         // Sender being removed from DBus would normally result in a tray icon being removed, | ||||||
|         // so allow the code path that handles the tray icon being removed to handle that case. |         // so allow the code path that handles the tray icon being removed to handle that case. | ||||||
|         if (this.app) |         if (!this.trayIcon && this.app) | ||||||
|             this.destroy(); |             this.destroy(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     processNotification: function(notification, gicon) { |     processNotification: function(notification, gicon) { | ||||||
|         if (gicon) |         if (gicon) | ||||||
|             this._gicon = gicon; |             this._gicon = gicon; | ||||||
|  |         if (!this.trayIcon) | ||||||
|             this.iconUpdated(); |             this.iconUpdated(); | ||||||
|  |  | ||||||
|         let tracker = Shell.WindowTracker.get_default(); |         let tracker = Shell.WindowTracker.get_default(); | ||||||
|         if (notification.resident && this.app && tracker.focus_app == this.app) |         if (this.app && tracker.focus_app == this.app) | ||||||
|             this.pushNotification(notification); |             this.pushNotification(notification); | ||||||
|         else |         else | ||||||
|             this.notify(notification); |             this.notify(notification); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|  |     handleSummaryClick: function(button) { | ||||||
|  |         if (!this.trayIcon) | ||||||
|  |             return false; | ||||||
|  |  | ||||||
|  |         let event = Clutter.get_current_event(); | ||||||
|  |  | ||||||
|  |         // Left clicks are passed through only where there aren't unacknowledged | ||||||
|  |         // notifications, so it possible to open them in summary mode; right | ||||||
|  |         // clicks are always forwarded, as the right click menu is not useful for | ||||||
|  |         // tray icons | ||||||
|  |         if (button == 1 && | ||||||
|  |             this.notifications.length > 0) | ||||||
|  |             return false; | ||||||
|  |  | ||||||
|  |         let id = global.stage.connect('deactivate', Lang.bind(this, function () { | ||||||
|  |             global.stage.disconnect(id); | ||||||
|  |             this.trayIcon.click(event); | ||||||
|  |         })); | ||||||
|  |  | ||||||
|  |         Main.overview.hide(); | ||||||
|  |         return true; | ||||||
|  |     }, | ||||||
|  |  | ||||||
|     _getApp: function(appId) { |     _getApp: function(appId) { | ||||||
|         let app; |         let app; | ||||||
|  |  | ||||||
| @@ -524,6 +594,16 @@ const FdoNotificationDaemonSource = new Lang.Class({ | |||||||
|         if (app != null) |         if (app != null) | ||||||
|             return app; |             return app; | ||||||
|  |  | ||||||
|  |         if (this.trayIcon) { | ||||||
|  |             app = Shell.AppSystem.get_default().lookup_startup_wmclass(this.trayIcon.wm_class); | ||||||
|  |             if (app != null) | ||||||
|  |                 return app; | ||||||
|  |  | ||||||
|  |             app = Shell.AppSystem.get_default().lookup_desktop_wmclass(this.trayIcon.wm_class); | ||||||
|  |             if (app != null) | ||||||
|  |                 return app; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         if (appId) { |         if (appId) { | ||||||
|             app = Shell.AppSystem.get_default().lookup_app(appId + '.desktop'); |             app = Shell.AppSystem.get_default().lookup_app(appId + '.desktop'); | ||||||
|             if (app != null) |             if (app != null) | ||||||
| @@ -545,7 +625,12 @@ const FdoNotificationDaemonSource = new Lang.Class({ | |||||||
|  |  | ||||||
|     open: function() { |     open: function() { | ||||||
|         this.openApp(); |         this.openApp(); | ||||||
|         this.destroyNonResidentNotifications(); |         this.destroyNotifications(); | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     _lastNotificationRemoved: function() { | ||||||
|  |         if (!this.trayIcon) | ||||||
|  |             this.destroy(); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     openApp: function() { |     openApp: function() { | ||||||
| @@ -554,7 +639,6 @@ const FdoNotificationDaemonSource = new Lang.Class({ | |||||||
|  |  | ||||||
|         this.app.activate(); |         this.app.activate(); | ||||||
|         Main.overview.hide(); |         Main.overview.hide(); | ||||||
|         Main.panel.closeCalendar(); |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     destroy: function() { |     destroy: function() { | ||||||
| @@ -567,7 +651,11 @@ const FdoNotificationDaemonSource = new Lang.Class({ | |||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     createIcon: function(size) { |     createIcon: function(size) { | ||||||
|         if (this.app) { |         if (this.trayIcon) { | ||||||
|  |             return new Clutter.Clone({ width: size, | ||||||
|  |                                        height: size, | ||||||
|  |                                        source: this.trayIcon }); | ||||||
|  |         } else if (this.app) { | ||||||
|             return this.app.create_icon_texture(size); |             return this.app.create_icon_texture(size); | ||||||
|         } else if (this._gicon) { |         } else if (this._gicon) { | ||||||
|             return new St.Icon({ gicon: this._gicon, |             return new St.Icon({ gicon: this._gicon, | ||||||
| @@ -578,12 +666,6 @@ const FdoNotificationDaemonSource = new Lang.Class({ | |||||||
|     } |     } | ||||||
| }); | }); | ||||||
|  |  | ||||||
| const PRIORITY_URGENCY_MAP = { |  | ||||||
|     low: MessageTray.Urgency.LOW, |  | ||||||
|     normal: MessageTray.Urgency.NORMAL, |  | ||||||
|     high: MessageTray.Urgency.HIGH, |  | ||||||
|     urgent: MessageTray.Urgency.CRITICAL |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| const GtkNotificationDaemonNotification = new Lang.Class({ | const GtkNotificationDaemonNotification = new Lang.Class({ | ||||||
|     Name: 'GtkNotificationDaemonNotification', |     Name: 'GtkNotificationDaemonNotification', | ||||||
| @@ -597,20 +679,12 @@ const GtkNotificationDaemonNotification = new Lang.Class({ | |||||||
|               "body": body, |               "body": body, | ||||||
|               "icon": gicon, |               "icon": gicon, | ||||||
|               "urgent": urgent, |               "urgent": urgent, | ||||||
|               "priority": priority, |  | ||||||
|               "buttons": buttons, |               "buttons": buttons, | ||||||
|               "default-action": defaultAction, |               "default-action": defaultAction, | ||||||
|               "default-action-target": defaultActionTarget } = notification; |               "default-action-target": defaultActionTarget } = notification; | ||||||
|  |  | ||||||
|         if (priority) { |  | ||||||
|             let urgency = PRIORITY_URGENCY_MAP[priority.unpack()]; |  | ||||||
|             this.setUrgency(urgency != undefined ? urgency : MessageTray.Urgency.NORMAL); |  | ||||||
|         } else if (urgent) { |  | ||||||
|         this.setUrgency(urgent.unpack() ? MessageTray.Urgency.CRITICAL |         this.setUrgency(urgent.unpack() ? MessageTray.Urgency.CRITICAL | ||||||
|                                         : MessageTray.Urgency.NORMAL); |                                         : MessageTray.Urgency.NORMAL); | ||||||
|         } else { |  | ||||||
|             this.setUrgency(MessageTray.Urgency.NORMAL); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (buttons) { |         if (buttons) { | ||||||
|             buttons.deep_unpack().forEach(Lang.bind(this, function(button) { |             buttons.deep_unpack().forEach(Lang.bind(this, function(button) { | ||||||
| @@ -642,7 +716,7 @@ const GtkNotificationDaemonNotification = new Lang.Class({ | |||||||
|         this._activateAction(action.unpack(), actionTarget); |         this._activateAction(action.unpack(), actionTarget); | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     activate: function() { |     _onClicked: function() { | ||||||
|         this._activateAction(this._defaultAction, this._defaultActionTarget); |         this._activateAction(this._defaultAction, this._defaultActionTarget); | ||||||
|         this.parent(); |         this.parent(); | ||||||
|     }, |     }, | ||||||
| @@ -709,17 +783,11 @@ const GtkNotificationDaemonAppSource = new Lang.Class({ | |||||||
|     activateAction: function(actionId, target) { |     activateAction: function(actionId, target) { | ||||||
|         let app = this._createApp(); |         let app = this._createApp(); | ||||||
|         app.ActivateActionRemote(actionId, target ? [target] : [], getPlatformData()); |         app.ActivateActionRemote(actionId, target ? [target] : [], getPlatformData()); | ||||||
|  |  | ||||||
|         Main.overview.hide(); |  | ||||||
|         Main.panel.closeCalendar(); |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     open: function() { |     open: function() { | ||||||
|         let app = this._createApp(); |         let app = this._createApp(); | ||||||
|         app.ActivateRemote(getPlatformData()); |         app.ActivateRemote(getPlatformData()); | ||||||
|  |  | ||||||
|         Main.overview.hide(); |  | ||||||
|         Main.panel.closeCalendar(); |  | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     addNotification: function(notificationId, notificationParams, showBanner) { |     addNotification: function(notificationId, notificationParams, showBanner) { | ||||||
|   | |||||||