Compare commits
	
		
			106 Commits
		
	
	
		
			3.24.3
			...
			wip/raresv
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | de814752d6 | ||
|   | c36f006b88 | ||
|   | bf884ae9ea | ||
|   | 7bbff9d0c0 | ||
|   | 04ad2b24d8 | ||
|   | 4ffbec5b75 | ||
|   | d35f2d375b | ||
|   | 235d4b244d | ||
|   | 9a007058ae | ||
|   | 985e53a04e | ||
|   | aed6d466cb | ||
|   | c62e3614d5 | ||
|   | 8dae0b5767 | ||
|   | a00a186772 | ||
|   | e3330b638a | ||
|   | bdc15d680a | ||
|   | 82e20f94f4 | ||
|   | 5221744d1d | ||
|   | 293d1697fe | ||
|   | 9c8a470934 | ||
|   | 9c4e875de4 | ||
|   | 0e922eee36 | ||
|   | 875a1d6159 | ||
|   | e995730a4d | ||
|   | 3d209838a1 | ||
|   | 69396bbc1f | ||
|   | a0140fb2c7 | ||
|   | d8e7fc403b | ||
|   | 3d6fdc8ae2 | ||
|   | 47b109d25b | ||
|   | 6ed7034a6b | ||
|   | 4e07d0b073 | ||
|   | 708f65e388 | ||
|   | 8783654b38 | ||
|   | 4c72244c2e | ||
|   | 9e0e7a4067 | ||
|   | a256a35779 | ||
|   | d5cac6559d | ||
|   | ce262b36d4 | ||
|   | 02a72b12bb | ||
|   | 7f7d18749e | ||
|   | 2e1e00c3de | ||
|   | e2838a7e06 | ||
|   | ad2cb22785 | ||
|   | 7ad6bd95f7 | ||
|   | 50d37e74a3 | ||
|   | c22287b517 | ||
|   | 73cffb3c7f | ||
|   | 4bada06917 | ||
|   | 31a4705789 | ||
|   | 60c00f0472 | ||
|   | e7bf23890b | ||
|   | 15d387df5f | ||
|   | e02d6e5285 | ||
|   | 19d0169de4 | ||
|   | 7a2d4959f2 | ||
|   | 6b3c9539f6 | ||
|   | 7e7e3ec016 | ||
|   | 83fb34608c | ||
|   | a72f0604dc | ||
|   | 4dfad536a3 | ||
|   | 0dca5e513b | ||
|   | 7090592477 | ||
|   | 63f2fdd1a4 | ||
|   | e94de67bd2 | ||
|   | 817ff52414 | ||
|   | a55599a239 | ||
|   | 94114d82ff | ||
|   | 7cc88f96c4 | ||
|   | 447bf55e45 | ||
|   | 9d53a7700a | ||
|   | 51145a3d41 | ||
|   | 1297315cc2 | ||
|   | b859a7f763 | ||
|   | 41baf0fc74 | ||
|   | c324395ee6 | ||
|   | aecd1c126a | ||
|   | 9b7304488e | ||
|   | 6362b3d057 | ||
|   | 0142fae742 | ||
|   | 73680e2433 | ||
|   | e38c26894b | ||
|   | 28ca96064b | ||
|   | be95a63a03 | ||
|   | 2a3a5dfc0b | ||
|   | 94a0ae1ec3 | ||
|   | 44fb014a0d | ||
|   | 8007f4dda3 | ||
|   | ff425d1db7 | ||
|   | 9a65f20d91 | ||
|   | 0770383f78 | ||
|   | 06fdf2fdc8 | ||
|   | 7a20683728 | ||
|   | 8e443a2aff | ||
|   | fcbb942e24 | ||
|   | 1508d76d32 | ||
|   | ef9dee2a05 | ||
|   | 2714d8d0ce | ||
|   | 243dae14ea | ||
|   | 2cce1b9ea0 | ||
|   | 89f4e983d6 | ||
|   | f680cf6050 | ||
|   | 4cd4678194 | ||
|   | 082bc20bb9 | ||
|   | 32ea7d763a | ||
|   | 44e80f4c46 | 
							
								
								
									
										55
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								NEWS
									
									
									
									
									
								
							| @@ -1,35 +1,37 @@ | ||||
| 3.24.3 | ||||
| 3.25.3 | ||||
| ====== | ||||
| * Bypass proxies for captive portal [Bastien; #769692] | ||||
| * Fix missing icons in freedesktop notifications [Florian; #784245] | ||||
| * Fix blocked clicks in shutdown dialog [Florian; #781738] | ||||
| * Implement tablet rings/strips configuration [Carlos; #782033] | ||||
| * Misc. bug fixes [Matthias, Jeremy, Bastien, Florian; #780215, #782802, | ||||
|   #783286, #784130, #784353, #781471] | ||||
| * Correctly handle "text-shadow: none;" [Matt; #783485] | ||||
| * Add StEntry:hint-actor property [Mario; #783484] | ||||
| * Support text-shadow CSS property in StEntry [Mario; #783484] | ||||
| * Misc. bug fixes [Jonas, Florian, Bastien, Ting-Wei, Cosimo, Mario, Sebastian; | ||||
|   #777732, #783202, #783210, #783206, #783286, #783439, #783483, #783823, | ||||
|   #781950] | ||||
|  | ||||
| Contributors: | ||||
|   Jeremy Bicha, Carlos Garnacho, Matthias Liertzer, Florian Müllner, | ||||
|   Bastien Nocera | ||||
|   Jonas Ådahl, Cosimo Cecchi, Sebastian Keller, Ting-Wei Lan, Florian Müllner, | ||||
|   Bastien Nocera, Mario Sanchez Prada, Matt Watson | ||||
|  | ||||
| Translations: | ||||
|   Christian Stadelmann [de], Марко Костић [sr], Милош Поповић [sr@latin], | ||||
|   Furkan Ahmet Kara [tr], Jeremy Bicha [es, he] | ||||
|  | ||||
| 3.24.2 | ||||
| 3.25.2 | ||||
| ====== | ||||
| * Only fetch weather information when there's a valid location [Rares; #780404] | ||||
| * Handle extension errors during reload due to settings change [Emilio; #781728] | ||||
| * Fix StEntry::primary-icon-clicked emission [Florian; #782190] | ||||
| * Allow search providers to provide clipboard text for results [Daiki; #775099] | ||||
| * Misc. bug fixes [Florian; #781545] | ||||
| * Add an optional icon parameter to PopupMenu.addAction() [Mario; #782166] | ||||
| * Allow search providers to include clipboard text with results [Daiki; #775099] | ||||
| * Reduce dependency on Caribou [Carlos; #777342] | ||||
| * Add transparency to top bar when free floating [Alessandro; #747163] | ||||
| * Animate maximize/unmaximize operations [Alessandro; #766685] | ||||
| * Misc. bug fixes [Florian, Matthias, Jeremy, Michael, Carlos, Lan; #782000, | ||||
|   #780215, #782802, #782637, #782930, #755164, #780215, #782982] | ||||
|  | ||||
| Contributors: | ||||
|   Florian Müllner, Emilio Pozuelo Monfort, Daiki Ueno, Rares Visalom | ||||
|   Jeremy Bicha, Michael Biebl, Alessandro Bono, Carlos Garnacho, Ting-Wei Lan, | ||||
|   Matthias Liertzer, Florian Müllner, Mario Sanchez Prada, Daiki Ueno | ||||
|  | ||||
| Translations: | ||||
|   Milo Casagrande [it], Милош Поповић [sr], Khaled Hosny [ar] | ||||
|   Jordi Mas [ca], Christian Stadelmann [de], Милош Поповић [sr], | ||||
|   Милош Поповић [sr@latin], Furkan Ahmet Kara [tr] | ||||
|  | ||||
| 3.24.1 | ||||
| 3.25.1 | ||||
| ====== | ||||
| * Close Wifi selection dialog on lock [Florian; #780054] | ||||
| * Fix DND over window previews in overview [Florian; #737166] | ||||
| @@ -37,11 +39,15 @@ Translations: | ||||
| * Follow GNOME Weather's location permissions [Florian; #780252] | ||||
| * Fix portals that require a new window to be loaded [Catalin; #759044] | ||||
| * Fix restricting menus to screen height on HiDPI displays [Cosimo; #753305] | ||||
| * Misc. bug fixes and cleanups [Florian, Cosimo, Bastien, Catalin, Carlos; | ||||
|   #780063, #780321, #780381, #780453, #758873, #780606, #642652] | ||||
| * Misc. bug fixes and cleanups [Florian, Cosimo, Bastien, Catalin, Carlos G., | ||||
|   Jonas, Carlos S., Xiaoguang, Rares, Emilio; #780063, #780321, #780381, | ||||
|   #780453, #758873, #780606, #642652, #777732, #780157, #781482, #780404, | ||||
|   #781545, #781728] | ||||
|  | ||||
| Contributors: | ||||
|   Cosimo Cecchi, Carlos Garnacho, Catalin Iacob, Florian Müllner, Bastien Nocera | ||||
|   Jonas Ådahl, Cosimo Cecchi, Philip Chimento, Carlos Garnacho, Catalin Iacob, | ||||
|   Florian Müllner, Bastien Nocera, Emilio Pozuelo Monfort, Carlos Soriano, | ||||
|   Rares Visalom, Xiaoguang Wang | ||||
|  | ||||
| Translations: | ||||
|   Marek Cernocky [cs], Piotr Drąg [pl], Anders Jonsson [sv], Stas Solovey [ru], | ||||
| @@ -51,7 +57,8 @@ Translations: | ||||
|   Changwoo Ryu [ko], Mario Blättermann [de], Fran Dieguez [gl], | ||||
|   Dušan Kazik [sk], Yuras Shumovich [be], Fabio Tomat [fur], | ||||
|   Kjartan Maraas [nb], Aurimas Černius [lt], Trần Ngọc Quân [vi], | ||||
|   Rūdolfs Mazurs [lv], Ask Hjorth Larsen [da], Tom Tryfonidis [el], gogo [hr] | ||||
|   Rūdolfs Mazurs [lv], Γιάννης Κουτσούκος [el], gogo [hr], Марко Костић [sr], | ||||
|   Jordi Mas [ca], Khaled Hosny [ar] | ||||
|  | ||||
| 3.24.0 | ||||
| ====== | ||||
|   | ||||
							
								
								
									
										14
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								configure.ac
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| AC_PREREQ(2.63) | ||||
| AC_INIT([gnome-shell],[3.24.3],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell]) | ||||
| AC_INIT([gnome-shell],[3.25.3],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell]) | ||||
| AX_IS_RELEASE([git-directory]) | ||||
|  | ||||
| AC_CONFIG_HEADERS([config.h]) | ||||
| @@ -61,7 +61,6 @@ if $PKG_CONFIG --exists gstreamer-1.0 '>=' $GSTREAMER_MIN_VERSION ; then | ||||
|    AC_MSG_RESULT(yes) | ||||
|    build_recorder=true | ||||
|    recorder_modules="gstreamer-1.0 gstreamer-base-1.0 x11 gtk+-3.0" | ||||
|    PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules $LIBMUTTER_CLUTTER) | ||||
| else | ||||
|    AC_MSG_RESULT(no) | ||||
| fi | ||||
| @@ -85,9 +84,9 @@ AC_MSG_RESULT($enable_systemd) | ||||
|  | ||||
| GOBJECT_INTROSPECTION_MIN_VERSION=1.49.1 | ||||
| GJS_MIN_VERSION=1.47.0 | ||||
| MUTTER_MIN_VERSION=3.24.0 | ||||
| MUTTER_MIN_VERSION=3.25.3 | ||||
| GTK_MIN_VERSION=3.15.0 | ||||
| GIO_MIN_VERSION=2.45.3 | ||||
| GIO_MIN_VERSION=2.53.0 | ||||
| LIBECAL_MIN_VERSION=3.5.3 | ||||
| LIBEDATASERVER_MIN_VERSION=3.17.2 | ||||
| POLKIT_MIN_VERSION=0.100 | ||||
| @@ -159,9 +158,6 @@ AC_SUBST(MUTTER_GIR_DIR) | ||||
| MUTTER_TYPELIB_DIR=`$PKG_CONFIG --variable=typelibdir $LIBMUTTER` | ||||
| AC_SUBST(MUTTER_TYPELIB_DIR) | ||||
|  | ||||
| GJS_CONSOLE=`$PKG_CONFIG --variable=gjs_console gjs-1.0` | ||||
| AC_SUBST(GJS_CONSOLE) | ||||
|  | ||||
| GLIB_COMPILE_RESOURCES=`$PKG_CONFIG --variable glib_compile_resources gio-2.0` | ||||
| AC_SUBST(GLIB_COMPILE_RESOURCES) | ||||
|  | ||||
| @@ -190,7 +186,7 @@ if test "x$enable_networkmanager" != "xno"; then | ||||
|                      [libnm-glib | ||||
|                      libnm-util >= $NETWORKMANAGER_MIN_VERSION | ||||
|                      libnm-gtk >= $NETWORKMANAGER_MIN_VERSION | ||||
|                      libsecret-unstable], | ||||
|                      libsecret-1 >= 0.18], | ||||
|                      [have_networkmanager=yes], | ||||
|                      [have_networkmanager=no]) | ||||
|  | ||||
| @@ -250,7 +246,7 @@ if test -z "$GDBUS_CODEGEN"; then | ||||
|   AC_MSG_ERROR([gdbus-codegen not found]) | ||||
| fi | ||||
|  | ||||
| AC_PATH_PROG([SASS],[sass],[]) | ||||
| AC_PATH_PROG([SASSC],[sassc],[]) | ||||
|  | ||||
| AC_CONFIG_FILES([ | ||||
|   Makefile | ||||
|   | ||||
| @@ -1,15 +1,15 @@ | ||||
| CLEANFILES = | ||||
| NULL = | ||||
|  | ||||
| portaldir = $(datadir)/xdg-desktop-portal/portals | ||||
| portal_DATA = gnome-shell.portal | ||||
|  | ||||
| desktopdir=$(datadir)/applications | ||||
| desktop_DATA = org.gnome.Shell.desktop gnome-shell-extension-prefs.desktop | ||||
|  | ||||
| if HAVE_NETWORKMANAGER | ||||
| desktop_DATA += org.gnome.Shell.PortalHelper.desktop | ||||
|  | ||||
| portaldir = $(datadir)/xdg-desktop-portal/portals | ||||
| portal_DATA = gnome-shell.portal | ||||
|  | ||||
| servicedir = $(datadir)/dbus-1/services | ||||
| service_DATA = org.gnome.Shell.PortalHelper.service | ||||
|  | ||||
| @@ -56,7 +56,6 @@ theme_sources = 						\ | ||||
|  | ||||
| dist_theme_files =						\ | ||||
| 	$(theme_sources)					\ | ||||
| 	theme/Gemfile						\ | ||||
| 	theme/HACKING						\ | ||||
| 	theme/README						\ | ||||
| 	theme/gnome-shell-sass/COPYING				\ | ||||
| @@ -64,14 +63,14 @@ dist_theme_files =						\ | ||||
| 	theme/gnome-shell-sass/NEWS				\ | ||||
| 	theme/gnome-shell-sass/README				\ | ||||
| 	theme/gnome-shell-sass/gnome-shell-sass.doap		\ | ||||
| 	theme/pad-osd.css						\ | ||||
| 	theme/pad-osd.css					\ | ||||
| 	theme/parse-sass.sh					\ | ||||
| 	$(NULL) | ||||
|  | ||||
| %.css: %.scss $(theme_sources) | ||||
| 	@if test -n "$(SASS)"; then \ | ||||
| 	@if test -n "$(SASSC)"; then \ | ||||
| 		if $(AM_V_P); then PS4= set -x; else echo "  GEN      $@"; fi; \ | ||||
| 		$(SASS) --sourcemap=none -f -q --update $<; \ | ||||
| 		$(SASSC) -a $< $@; \ | ||||
| 	fi | ||||
|  | ||||
| resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir)/theme --generate-dependencies $(srcdir)/gnome-shell-theme.gresource.xml) | ||||
|   | ||||
| @@ -1 +0,0 @@ | ||||
| gem "sass", "~> 3.4.0" | ||||
| @@ -3,10 +3,10 @@ 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. | ||||
|   run `./parse-sass.sh` manually if it doesn't) | ||||
| * Most SASS preprocessors should produce similar results, however the build system | ||||
|   integration and 'parse-sass.sh' script use sassc. You should be able to install | ||||
|   it with `pkcon install sassc` or your distribution's package manager. | ||||
|  | ||||
| How to tweak the theme | ||||
| ---------------------- | ||||
| @@ -31,6 +31,4 @@ _common.scss        - actual definitions of style for each widget. This is where | ||||
|                       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`. | ||||
| _common.scss file, you can either run make or the ./parse-sass.sh script. | ||||
|   | ||||
| @@ -118,6 +118,7 @@ StEntry { | ||||
| /* Scrollbars */ | ||||
| StScrollView.vfade { | ||||
|   -st-vfade-offset: 68px; } | ||||
|  | ||||
| StScrollView.hfade { | ||||
|   -st-hfade-offset: 68px; } | ||||
|  | ||||
| @@ -152,14 +153,18 @@ StScrollBar { | ||||
| /* Check Boxes */ | ||||
| .check-box StBoxLayout { | ||||
|   spacing: .8em; } | ||||
|  | ||||
| .check-box StBin { | ||||
|   width: 24px; | ||||
|   height: 22px; | ||||
|   background-image: url("resource:///org/gnome/shell/theme/checkbox-off.svg"); } | ||||
|  | ||||
| .check-box:focus StBin { | ||||
|   background-image: url("resource:///org/gnome/shell/theme/checkbox-off-focused.svg"); } | ||||
|  | ||||
| .check-box:checked StBin { | ||||
|   background-image: url("resource:///org/gnome/shell/theme/checkbox.svg"); } | ||||
|  | ||||
| .check-box:focus:checked StBin { | ||||
|   background-image: url("resource:///org/gnome/shell/theme/checkbox-focused.svg"); } | ||||
|  | ||||
| @@ -300,7 +305,7 @@ StScrollBar { | ||||
|   padding-bottom: 6px; } | ||||
|  | ||||
| .mount-question-dialog-subject { | ||||
|   max-width: 500px; } | ||||
|   max-width: 34em; } | ||||
|  | ||||
| .show-processes-dialog-subject:rtl, | ||||
| .mount-question-dialog-subject:rtl { | ||||
| @@ -337,6 +342,7 @@ StScrollBar { | ||||
|  | ||||
| .show-processes-dialog-app-list-item-icon:ltr { | ||||
|   padding-right: 17px; } | ||||
|  | ||||
| .show-processes-dialog-app-list-item-icon:rtl { | ||||
|   padding-left: 17px; } | ||||
|  | ||||
| @@ -345,7 +351,7 @@ StScrollBar { | ||||
|  | ||||
| /* Password or Authentication Dialog */ | ||||
| .prompt-dialog { | ||||
|   width: 500px; | ||||
|   width: 34em; | ||||
|   border: 3px solid rgba(238, 238, 236, 0.2); } | ||||
|  | ||||
| .prompt-dialog-main-layout { | ||||
| @@ -669,7 +675,9 @@ StScrollBar { | ||||
|  | ||||
| /* TOP BAR */ | ||||
| #panel { | ||||
|   background-color: black; | ||||
|   background-color: rgba(0, 0, 0, 0.2); | ||||
|   /* transition from solid to transparent */ | ||||
|   transition-duration: 500ms; | ||||
|   font-weight: bold; | ||||
|   height: 1.86em; } | ||||
|   #panel.unlock-screen, #panel.login-screen, #panel.lock-screen { | ||||
| @@ -678,7 +686,7 @@ StScrollBar { | ||||
|     spacing: 4px; } | ||||
|   #panel .panel-corner { | ||||
|     -panel-corner-radius: 6px; | ||||
|     -panel-corner-background-color: black; | ||||
|     -panel-corner-background-color: rgba(0, 0, 0, 0.2); | ||||
|     -panel-corner-border-width: 2px; | ||||
|     -panel-corner-border-color: transparent; } | ||||
|     #panel .panel-corner:active, #panel .panel-corner:overview, #panel .panel-corner:focus { | ||||
| @@ -691,14 +699,24 @@ StScrollBar { | ||||
|     -natural-hpadding: 12px; | ||||
|     -minimum-hpadding: 6px; | ||||
|     font-weight: bold; | ||||
|     color: #ccc; | ||||
|     color: #eee; | ||||
|     text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.9); | ||||
|     transition-duration: 100ms; } | ||||
|     #panel .panel-button .app-menu-icon { | ||||
|       -st-icon-style: symbolic; | ||||
|       margin-left: 4px; | ||||
|       margin-right: 4px; } | ||||
|     #panel .panel-button .system-status-icon, | ||||
|     #panel .panel-button .app-menu-icon > StIcon, | ||||
|     #panel .panel-button .popup-menu-arrow { | ||||
|       icon-shadow: 0px 0px 2px rgba(0, 0, 0, 0.9); } | ||||
|     #panel .panel-button:hover { | ||||
|       color: white; } | ||||
|       color: white; | ||||
|       text-shadow: 0px 0px 8px black; } | ||||
|       #panel .panel-button:hover .system-status-icon, | ||||
|       #panel .panel-button:hover .app-menu-icon > StIcon, | ||||
|       #panel .panel-button:hover .popup-menu-arrow { | ||||
|         icon-shadow: 0px 0px 8px black; } | ||||
|     #panel .panel-button:active, #panel .panel-button:overview, #panel .panel-button:focus, #panel .panel-button:checked { | ||||
|       background-color: rgba(0, 0, 0, 0.01); | ||||
|       box-shadow: inset 0 -2px 0px #256ab1; | ||||
| @@ -708,9 +726,17 @@ StScrollBar { | ||||
|     #panel .panel-button .system-status-icon { | ||||
|       icon-size: 1.09em; | ||||
|       padding: 0 5px; } | ||||
|     .unlock-screen #panel .panel-button, .login-screen #panel .panel-button, .lock-screen #panel .panel-button { | ||||
|     .unlock-screen #panel .panel-button, | ||||
|     .login-screen #panel .panel-button, | ||||
|     .lock-screen #panel .panel-button { | ||||
|       color: white; } | ||||
|       .unlock-screen #panel .panel-button:focus, .unlock-screen #panel .panel-button:hover, .unlock-screen #panel .panel-button:active, .login-screen #panel .panel-button:focus, .login-screen #panel .panel-button:hover, .login-screen #panel .panel-button:active, .lock-screen #panel .panel-button:focus, .lock-screen #panel .panel-button:hover, .lock-screen #panel .panel-button:active { | ||||
|       .unlock-screen #panel .panel-button:focus, .unlock-screen #panel .panel-button:hover, .unlock-screen #panel .panel-button:active, | ||||
|       .login-screen #panel .panel-button:focus, | ||||
|       .login-screen #panel .panel-button:hover, | ||||
|       .login-screen #panel .panel-button:active, | ||||
|       .lock-screen #panel .panel-button:focus, | ||||
|       .lock-screen #panel .panel-button:hover, | ||||
|       .lock-screen #panel .panel-button:active { | ||||
|         color: white; } | ||||
|   #panel .panel-status-indicators-box, | ||||
|   #panel .panel-status-menu-box { | ||||
| @@ -719,6 +745,21 @@ StScrollBar { | ||||
|     spacing: 0; } | ||||
|   #panel .screencast-indicator { | ||||
|     color: #f57900; } | ||||
|   #panel.solid { | ||||
|     background-color: black; | ||||
|     /* transition from transparent to solid */ | ||||
|     transition-duration: 300ms; } | ||||
|     #panel.solid .panel-corner { | ||||
|       -panel-corner-background-color: black; } | ||||
|     #panel.solid .panel-button { | ||||
|       color: #ccc; | ||||
|       text-shadow: none; } | ||||
|       #panel.solid .panel-button:hover { | ||||
|         color: white; } | ||||
|     #panel.solid .system-status-icon, | ||||
|     #panel.solid .app-menu-icon > StIcon, | ||||
|     #panel.solid .popup-menu-arrow { | ||||
|       icon-shadow: none; } | ||||
|  | ||||
| #calendarArea { | ||||
|   padding: 0.75em 1.0em; } | ||||
| @@ -769,6 +810,7 @@ StScrollBar { | ||||
| .events-section-title:hover, | ||||
| .events-section-title:focus { | ||||
|   background-color: #0d0d0d; } | ||||
|  | ||||
| .datemenu-today-button:active, | ||||
| .world-clocks-button:active, | ||||
| .weather-button:active, | ||||
| @@ -910,7 +952,7 @@ StScrollBar { | ||||
|   color: #999999; | ||||
|   font-size: 0.7em; | ||||
|   /* HACK: the label should be baseline-aligned with a 1em label, | ||||
|            fake this with some bottom padding */ | ||||
|                      fake this with some bottom padding */ | ||||
|   padding-bottom: 0.13em; } | ||||
|  | ||||
| .message-secondary-bin > StIcon { | ||||
| @@ -1010,9 +1052,9 @@ StScrollBar { | ||||
|  | ||||
| /* NETWORK DIALOGS */ | ||||
| .nm-dialog { | ||||
|   max-height: 500px; | ||||
|   min-height: 450px; | ||||
|   min-width: 470px; } | ||||
|   max-height: 34em; | ||||
|   min-height: 31em; | ||||
|   min-width: 32em; } | ||||
|  | ||||
| .nm-dialog-content { | ||||
|   spacing: 20px; | ||||
| @@ -1138,14 +1180,19 @@ StScrollBar { | ||||
|  | ||||
| .list-search-result-content { | ||||
|   spacing: 12px; | ||||
|   padding: 12px; } | ||||
|   padding: 2px; } | ||||
|  | ||||
| .list-search-result-title { | ||||
|   font-size: 1.5em; | ||||
|   color: #e2e2df; } | ||||
|  | ||||
| .list-search-result-provider { | ||||
|   color: #e2e2df; | ||||
|   margin-top: 0.24em; } | ||||
|  | ||||
| .list-search-result-description { | ||||
|   color: #cacac4; } | ||||
|   color: #cacac4; | ||||
|   margin-left: 30px; } | ||||
|  | ||||
| .search-provider-icon { | ||||
|   padding: 15px; } | ||||
| @@ -1215,6 +1262,7 @@ StScrollBar { | ||||
| .list-search-result:active, | ||||
| .list-search-result:checked { | ||||
|   background-color: rgba(23, 25, 26, 0.9); } | ||||
|  | ||||
| .search-provider-icon:focus, .search-provider-icon:selected, .search-provider-icon:hover, | ||||
| .list-search-result:focus, | ||||
| .list-search-result:selected, | ||||
| @@ -1222,7 +1270,8 @@ StScrollBar { | ||||
|   background-color: rgba(238, 238, 236, 0.1); | ||||
|   transition-duration: 200ms; } | ||||
|  | ||||
| .app-well-app:active .overview-icon, .app-well-app:checked .overview-icon, | ||||
| .app-well-app:active .overview-icon, | ||||
| .app-well-app:checked .overview-icon, | ||||
| .app-well-app.app-folder:active .overview-icon, | ||||
| .app-well-app.app-folder:checked .overview-icon, | ||||
| .show-apps:active .overview-icon, | ||||
| @@ -1231,7 +1280,10 @@ StScrollBar { | ||||
| .grid-search-result:checked .overview-icon { | ||||
|   background-color: rgba(23, 25, 26, 0.9); | ||||
|   box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.7); } | ||||
| .app-well-app:hover .overview-icon, .app-well-app:focus .overview-icon, .app-well-app:selected .overview-icon, | ||||
|  | ||||
| .app-well-app:hover .overview-icon, | ||||
| .app-well-app:focus .overview-icon, | ||||
| .app-well-app:selected .overview-icon, | ||||
| .app-well-app.app-folder:hover .overview-icon, | ||||
| .app-well-app.app-folder:focus .overview-icon, | ||||
| .app-well-app.app-folder:selected .overview-icon, | ||||
| @@ -1657,10 +1709,12 @@ StScrollBar { | ||||
|  | ||||
| .login-dialog-user-selection-box { | ||||
|   padding: 100px 0px; } | ||||
|   .login-dialog-user-selection-box .login-dialog-not-listed-label { | ||||
|     padding-left: 2px; } | ||||
|     .login-dialog-not-listed-button:focus .login-dialog-user-selection-box .login-dialog-not-listed-label, .login-dialog-not-listed-button:hover .login-dialog-user-selection-box .login-dialog-not-listed-label { | ||||
|       color: #eeeeec; } | ||||
|  | ||||
| .login-dialog-not-listed-label { | ||||
|   padding-left: 2px; } | ||||
|   .login-dialog-not-listed-button:focus .login-dialog-not-listed-label, | ||||
|   .login-dialog-not-listed-button:hover .login-dialog-not-listed-label { | ||||
|     color: #eeeeec; } | ||||
|  | ||||
| .login-dialog-not-listed-label { | ||||
|   font-size: 90%; | ||||
| @@ -1709,6 +1763,7 @@ StScrollBar { | ||||
|  | ||||
| .user-widget-label:ltr { | ||||
|   padding-left: 18px; } | ||||
|  | ||||
| .user-widget-label:rtl { | ||||
|   padding-right: 18px; } | ||||
|  | ||||
| @@ -1836,6 +1891,7 @@ StScrollBar { | ||||
| .lg-dialog StEntry { | ||||
|   selection-background-color: #bbbbbb; | ||||
|   selected-color: #333333; } | ||||
|  | ||||
| .lg-dialog .shell-link { | ||||
|   color: #999999; } | ||||
|   .lg-dialog .shell-link:hover { | ||||
|   | ||||
 Submodule data/theme/gnome-shell-sass updated: e94bce1fcf...664cd88ee6
									
								
							| @@ -118,6 +118,7 @@ StEntry { | ||||
| /* Scrollbars */ | ||||
| StScrollView.vfade { | ||||
|   -st-vfade-offset: 68px; } | ||||
|  | ||||
| StScrollView.hfade { | ||||
|   -st-hfade-offset: 68px; } | ||||
|  | ||||
| @@ -152,14 +153,18 @@ StScrollBar { | ||||
| /* Check Boxes */ | ||||
| .check-box StBoxLayout { | ||||
|   spacing: .8em; } | ||||
|  | ||||
| .check-box StBin { | ||||
|   width: 24px; | ||||
|   height: 22px; | ||||
|   background-image: url("resource:///org/gnome/shell/theme/checkbox-off.svg"); } | ||||
|  | ||||
| .check-box:focus StBin { | ||||
|   background-image: url("resource:///org/gnome/shell/theme/checkbox-off-focused.svg"); } | ||||
|  | ||||
| .check-box:checked StBin { | ||||
|   background-image: url("resource:///org/gnome/shell/theme/checkbox.svg"); } | ||||
|  | ||||
| .check-box:focus:checked StBin { | ||||
|   background-image: url("resource:///org/gnome/shell/theme/checkbox-focused.svg"); } | ||||
|  | ||||
| @@ -300,7 +305,7 @@ StScrollBar { | ||||
|   padding-bottom: 6px; } | ||||
|  | ||||
| .mount-question-dialog-subject { | ||||
|   max-width: 500px; } | ||||
|   max-width: 34em; } | ||||
|  | ||||
| .show-processes-dialog-subject:rtl, | ||||
| .mount-question-dialog-subject:rtl { | ||||
| @@ -337,6 +342,7 @@ StScrollBar { | ||||
|  | ||||
| .show-processes-dialog-app-list-item-icon:ltr { | ||||
|   padding-right: 17px; } | ||||
|  | ||||
| .show-processes-dialog-app-list-item-icon:rtl { | ||||
|   padding-left: 17px; } | ||||
|  | ||||
| @@ -345,7 +351,7 @@ StScrollBar { | ||||
|  | ||||
| /* Password or Authentication Dialog */ | ||||
| .prompt-dialog { | ||||
|   width: 500px; | ||||
|   width: 34em; | ||||
|   border: 3px solid rgba(238, 238, 236, 0.2); } | ||||
|  | ||||
| .prompt-dialog-main-layout { | ||||
| @@ -669,7 +675,9 @@ StScrollBar { | ||||
|  | ||||
| /* TOP BAR */ | ||||
| #panel { | ||||
|   background-color: black; | ||||
|   background-color: rgba(0, 0, 0, 0.2); | ||||
|   /* transition from solid to transparent */ | ||||
|   transition-duration: 500ms; | ||||
|   font-weight: bold; | ||||
|   height: 1.86em; } | ||||
|   #panel.unlock-screen, #panel.login-screen, #panel.lock-screen { | ||||
| @@ -678,7 +686,7 @@ StScrollBar { | ||||
|     spacing: 4px; } | ||||
|   #panel .panel-corner { | ||||
|     -panel-corner-radius: 6px; | ||||
|     -panel-corner-background-color: black; | ||||
|     -panel-corner-background-color: rgba(0, 0, 0, 0.2); | ||||
|     -panel-corner-border-width: 2px; | ||||
|     -panel-corner-border-color: transparent; } | ||||
|     #panel .panel-corner:active, #panel .panel-corner:overview, #panel .panel-corner:focus { | ||||
| @@ -691,14 +699,24 @@ StScrollBar { | ||||
|     -natural-hpadding: 12px; | ||||
|     -minimum-hpadding: 6px; | ||||
|     font-weight: bold; | ||||
|     color: #ccc; | ||||
|     color: #eee; | ||||
|     text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.9); | ||||
|     transition-duration: 100ms; } | ||||
|     #panel .panel-button .app-menu-icon { | ||||
|       -st-icon-style: symbolic; | ||||
|       margin-left: 4px; | ||||
|       margin-right: 4px; } | ||||
|     #panel .panel-button .system-status-icon, | ||||
|     #panel .panel-button .app-menu-icon > StIcon, | ||||
|     #panel .panel-button .popup-menu-arrow { | ||||
|       icon-shadow: 0px 0px 2px rgba(0, 0, 0, 0.9); } | ||||
|     #panel .panel-button:hover { | ||||
|       color: white; } | ||||
|       color: white; | ||||
|       text-shadow: 0px 0px 8px black; } | ||||
|       #panel .panel-button:hover .system-status-icon, | ||||
|       #panel .panel-button:hover .app-menu-icon > StIcon, | ||||
|       #panel .panel-button:hover .popup-menu-arrow { | ||||
|         icon-shadow: 0px 0px 8px black; } | ||||
|     #panel .panel-button:active, #panel .panel-button:overview, #panel .panel-button:focus, #panel .panel-button:checked { | ||||
|       background-color: rgba(0, 0, 0, 0.01); | ||||
|       box-shadow: inset 0 -2px 0px #256ab1; | ||||
| @@ -708,9 +726,17 @@ StScrollBar { | ||||
|     #panel .panel-button .system-status-icon { | ||||
|       icon-size: 1.09em; | ||||
|       padding: 0 5px; } | ||||
|     .unlock-screen #panel .panel-button, .login-screen #panel .panel-button, .lock-screen #panel .panel-button { | ||||
|     .unlock-screen #panel .panel-button, | ||||
|     .login-screen #panel .panel-button, | ||||
|     .lock-screen #panel .panel-button { | ||||
|       color: white; } | ||||
|       .unlock-screen #panel .panel-button:focus, .unlock-screen #panel .panel-button:hover, .unlock-screen #panel .panel-button:active, .login-screen #panel .panel-button:focus, .login-screen #panel .panel-button:hover, .login-screen #panel .panel-button:active, .lock-screen #panel .panel-button:focus, .lock-screen #panel .panel-button:hover, .lock-screen #panel .panel-button:active { | ||||
|       .unlock-screen #panel .panel-button:focus, .unlock-screen #panel .panel-button:hover, .unlock-screen #panel .panel-button:active, | ||||
|       .login-screen #panel .panel-button:focus, | ||||
|       .login-screen #panel .panel-button:hover, | ||||
|       .login-screen #panel .panel-button:active, | ||||
|       .lock-screen #panel .panel-button:focus, | ||||
|       .lock-screen #panel .panel-button:hover, | ||||
|       .lock-screen #panel .panel-button:active { | ||||
|         color: white; } | ||||
|   #panel .panel-status-indicators-box, | ||||
|   #panel .panel-status-menu-box { | ||||
| @@ -719,6 +745,21 @@ StScrollBar { | ||||
|     spacing: 0; } | ||||
|   #panel .screencast-indicator { | ||||
|     color: #f57900; } | ||||
|   #panel.solid { | ||||
|     background-color: black; | ||||
|     /* transition from transparent to solid */ | ||||
|     transition-duration: 300ms; } | ||||
|     #panel.solid .panel-corner { | ||||
|       -panel-corner-background-color: black; } | ||||
|     #panel.solid .panel-button { | ||||
|       color: #ccc; | ||||
|       text-shadow: none; } | ||||
|       #panel.solid .panel-button:hover { | ||||
|         color: white; } | ||||
|     #panel.solid .system-status-icon, | ||||
|     #panel.solid .app-menu-icon > StIcon, | ||||
|     #panel.solid .popup-menu-arrow { | ||||
|       icon-shadow: none; } | ||||
|  | ||||
| #calendarArea { | ||||
|   padding: 0.75em 1.0em; } | ||||
| @@ -769,6 +810,7 @@ StScrollBar { | ||||
| .events-section-title:hover, | ||||
| .events-section-title:focus { | ||||
|   background-color: #454c4c; } | ||||
|  | ||||
| .datemenu-today-button:active, | ||||
| .world-clocks-button:active, | ||||
| .weather-button:active, | ||||
| @@ -910,7 +952,7 @@ StScrollBar { | ||||
|   color: #8e8e80; | ||||
|   font-size: 0.7em; | ||||
|   /* HACK: the label should be baseline-aligned with a 1em label, | ||||
|            fake this with some bottom padding */ | ||||
|                      fake this with some bottom padding */ | ||||
|   padding-bottom: 0.13em; } | ||||
|  | ||||
| .message-secondary-bin > StIcon { | ||||
| @@ -1010,9 +1052,9 @@ StScrollBar { | ||||
|  | ||||
| /* NETWORK DIALOGS */ | ||||
| .nm-dialog { | ||||
|   max-height: 500px; | ||||
|   min-height: 450px; | ||||
|   min-width: 470px; } | ||||
|   max-height: 34em; | ||||
|   min-height: 31em; | ||||
|   min-width: 32em; } | ||||
|  | ||||
| .nm-dialog-content { | ||||
|   spacing: 20px; | ||||
| @@ -1129,23 +1171,30 @@ StScrollBar { | ||||
| .list-search-results { | ||||
|   spacing: 3px; } | ||||
|  | ||||
| .list-search-provider-details { | ||||
|   spacing: 3px; | ||||
|   width: 150px; | ||||
|   margin-left: 30px; } | ||||
|  | ||||
| .search-section-separator { | ||||
|   -gradient-height: 1px; | ||||
|   -gradient-start: rgba(255, 255, 255, 0); | ||||
|   -gradient-end: rgba(255, 255, 255, 0.1); | ||||
|   -margin-horizontal: 1.5em; | ||||
|   height: 1px; } | ||||
|   height: 2px; | ||||
|   background-color: rgba(255, 255, 255, 0.2); } | ||||
|  | ||||
| .list-search-result-content { | ||||
|   spacing: 12px; | ||||
|   padding: 12px; } | ||||
|   padding: 2px; } | ||||
|  | ||||
| .list-search-result-title { | ||||
|   font-size: 1.5em; | ||||
|   color: #e2e2df; } | ||||
|  | ||||
| .list-search-result-provider { | ||||
|   color: #e2e2df; | ||||
|   margin-top: 0.24em; | ||||
|  } | ||||
|  | ||||
| .list-search-result-description { | ||||
|   color: #cacac4; } | ||||
|   color: rgba(202, 202, 196, 0.5); | ||||
|   margin-left: 30px; } | ||||
|  | ||||
| .search-provider-icon { | ||||
|   padding: 15px; } | ||||
| @@ -1215,6 +1264,7 @@ StScrollBar { | ||||
| .list-search-result:active, | ||||
| .list-search-result:checked { | ||||
|   background-color: rgba(23, 25, 26, 0.9); } | ||||
|  | ||||
| .search-provider-icon:focus, .search-provider-icon:selected, .search-provider-icon:hover, | ||||
| .list-search-result:focus, | ||||
| .list-search-result:selected, | ||||
| @@ -1222,7 +1272,8 @@ StScrollBar { | ||||
|   background-color: rgba(238, 238, 236, 0.1); | ||||
|   transition-duration: 200ms; } | ||||
|  | ||||
| .app-well-app:active .overview-icon, .app-well-app:checked .overview-icon, | ||||
| .app-well-app:active .overview-icon, | ||||
| .app-well-app:checked .overview-icon, | ||||
| .app-well-app.app-folder:active .overview-icon, | ||||
| .app-well-app.app-folder:checked .overview-icon, | ||||
| .show-apps:active .overview-icon, | ||||
| @@ -1231,7 +1282,10 @@ StScrollBar { | ||||
| .grid-search-result:checked .overview-icon { | ||||
|   background-color: rgba(23, 25, 26, 0.9); | ||||
|   box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.7); } | ||||
| .app-well-app:hover .overview-icon, .app-well-app:focus .overview-icon, .app-well-app:selected .overview-icon, | ||||
|  | ||||
| .app-well-app:hover .overview-icon, | ||||
| .app-well-app:focus .overview-icon, | ||||
| .app-well-app:selected .overview-icon, | ||||
| .app-well-app.app-folder:hover .overview-icon, | ||||
| .app-well-app.app-folder:focus .overview-icon, | ||||
| .app-well-app.app-folder:selected .overview-icon, | ||||
| @@ -1657,10 +1711,12 @@ StScrollBar { | ||||
|  | ||||
| .login-dialog-user-selection-box { | ||||
|   padding: 100px 0px; } | ||||
|   .login-dialog-user-selection-box .login-dialog-not-listed-label { | ||||
|     padding-left: 2px; } | ||||
|     .login-dialog-not-listed-button:focus .login-dialog-user-selection-box .login-dialog-not-listed-label, .login-dialog-not-listed-button:hover .login-dialog-user-selection-box .login-dialog-not-listed-label { | ||||
|       color: #eeeeec; } | ||||
|  | ||||
| .login-dialog-not-listed-label { | ||||
|   padding-left: 2px; } | ||||
|   .login-dialog-not-listed-button:focus .login-dialog-not-listed-label, | ||||
|   .login-dialog-not-listed-button:hover .login-dialog-not-listed-label { | ||||
|     color: #eeeeec; } | ||||
|  | ||||
| .login-dialog-not-listed-label { | ||||
|   font-size: 90%; | ||||
| @@ -1709,6 +1765,7 @@ StScrollBar { | ||||
|  | ||||
| .user-widget-label:ltr { | ||||
|   padding-left: 18px; } | ||||
|  | ||||
| .user-widget-label:rtl { | ||||
|   padding-right: 18px; } | ||||
|  | ||||
| @@ -1836,6 +1893,7 @@ StScrollBar { | ||||
| .lg-dialog StEntry { | ||||
|   selection-background-color: #bbbbbb; | ||||
|   selected-color: #333333; } | ||||
|  | ||||
| .lg-dialog .shell-link { | ||||
|   color: #999999; } | ||||
|   .lg-dialog .shell-link:hover { | ||||
|   | ||||
| @@ -1,3 +1,7 @@ | ||||
| #!/usr/bin/bash | ||||
| #!/usr/bin/sh | ||||
|  | ||||
| bundle exec sass --update --sourcemap=none . | ||||
| srcdir=`dirname $0` | ||||
| for scss in $srcdir/*.scss | ||||
| do | ||||
|   sassc -a $scss ${scss%%.scss}.css | ||||
| done | ||||
|   | ||||
| @@ -113,7 +113,7 @@ expand_content_files= | ||||
| # e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) | ||||
| # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) | ||||
| GTKDOC_CFLAGS=$(GNOME_SHELL_CFLAGS) | ||||
| GTKDOC_LIBS=$(GNOME_SHELL_LIBS) $(top_builddir)/src/libgnome-shell-menu.la $(top_builddir)/src/libgnome-shell-base.la $(top_builddir)/src/libgnome-shell.la -rpath $(MUTTER_TYPELIB_DIR) | ||||
| GTKDOC_LIBS=$(GNOME_SHELL_LIBS) $(top_builddir)/src/libgnome-shell-menu.la $(top_builddir)/src/libgnome-shell.la -rpath $(MUTTER_TYPELIB_DIR) | ||||
|  | ||||
| # This includes the standard gtk-doc make rules, copied by gtkdocize. | ||||
| include $(top_srcdir)/gtk-doc.make | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gio = imports.gi.Gio; | ||||
| const Lang = imports.lang; | ||||
| const Pango = imports.gi.Pango; | ||||
| const Signals = imports.signals; | ||||
| const St = imports.gi.St; | ||||
|  | ||||
| @@ -13,7 +14,6 @@ const Params = imports.misc.params; | ||||
| const ShellEntry = imports.ui.shellEntry; | ||||
| const Tweener = imports.ui.tweener; | ||||
| const UserWidget = imports.ui.userWidget; | ||||
| const Pango = imports.gi.Pango; | ||||
|  | ||||
| const DEFAULT_BUTTON_WELL_ICON_SIZE = 16; | ||||
| const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0; | ||||
| @@ -263,7 +263,7 @@ const AuthPrompt = new Lang.Class({ | ||||
|     _onVerificationComplete: function() { | ||||
|         this.setActorInDefaultButtonWell(null); | ||||
|         this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED; | ||||
| 	this.cancelButton.reactive = false; | ||||
|         this.cancelButton.reactive = false; | ||||
|     }, | ||||
|  | ||||
|     _onReset: function() { | ||||
|   | ||||
| @@ -775,10 +775,12 @@ const LoginDialog = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     _onPrompted: function() { | ||||
|         this._sessionMenuButton.updateSensitivity(true); | ||||
|  | ||||
|         if (this._shouldShowSessionMenuButton()) | ||||
|         if (this._shouldShowSessionMenuButton()) { | ||||
|             this._sessionMenuButton.updateSensitivity(true); | ||||
|             this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor); | ||||
|         } else { | ||||
|             this._sessionMenuButton.updateSensitivity(false); | ||||
|         } | ||||
|         this._showPrompt(); | ||||
|     }, | ||||
|  | ||||
| @@ -881,6 +883,7 @@ const LoginDialog = new Lang.Class({ | ||||
|                                                       })); | ||||
|         this._updateCancelButton(); | ||||
|  | ||||
|         this._sessionMenuButton.updateSensitivity(false); | ||||
|         this._authPrompt.updateSensitivity(true); | ||||
|         this._showPrompt(); | ||||
|     }, | ||||
|   | ||||
| @@ -128,9 +128,6 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|  | ||||
|         this._client = client; | ||||
|  | ||||
|         this._defaultService = null; | ||||
|         this._preemptingService = null; | ||||
|  | ||||
|         this._settings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA }); | ||||
|         this._settings.connect('changed', | ||||
|                                Lang.bind(this, this._updateDefaultService)); | ||||
| @@ -141,9 +138,8 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|  | ||||
|         // We check for smartcards right away, since an inserted smartcard | ||||
|         // at startup should result in immediately initiating authentication. | ||||
|         // This is different than fingeprint readers, where we only check them | ||||
|         // This is different than fingerprint readers, where we only check them | ||||
|         // after a user has been picked. | ||||
|         this.smartcardDetected = false; | ||||
|         this._checkForSmartcard(); | ||||
|  | ||||
|         this._smartcardInsertedId = this._smartcardManager.connect('smartcard-inserted', | ||||
|   | ||||
| @@ -69,7 +69,7 @@ const HistoryManager = new Lang.Class({ | ||||
|             this._indexChanged(); | ||||
|         } | ||||
|  | ||||
|         return this._historyIndex ? this._history[this._historyIndex -1] : null; | ||||
|         return this._historyIndex[this._history.length]; | ||||
|     }, | ||||
|  | ||||
|     addItem: function(input) { | ||||
|   | ||||
| @@ -190,7 +190,7 @@ const IBusManager = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     getEngineDesc: function(id) { | ||||
|         if (!IBus || !this._ready || !this._engines.hasOwnProperty(id)) | ||||
|         if (!IBus || !this._ready) | ||||
|             return null; | ||||
|  | ||||
|         return this._engines[id]; | ||||
|   | ||||
| @@ -46,7 +46,7 @@ const ObjectManager = new Lang.Class({ | ||||
|                                                  g_interface_info: ObjectManagerInfo, | ||||
|                                                  g_name: this._serviceName, | ||||
|                                                  g_object_path: this._managerPath, | ||||
|                                                  g_flags: Gio.DBusProxyFlags.NONE }); | ||||
|                                                  g_flags: Gio.DBusProxyFlags.DO_NOT_AUTO_START }); | ||||
|  | ||||
|         this._interfaceInfos = {}; | ||||
|         this._objects = {}; | ||||
| @@ -65,6 +65,9 @@ const ObjectManager = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     _tryToCompleteLoad: function() { | ||||
|         if (this._numLoadInhibitors == 0) | ||||
|             return; | ||||
|  | ||||
|         this._numLoadInhibitors--; | ||||
|         if (this._numLoadInhibitors == 0) { | ||||
|             if (this._onLoaded) | ||||
| @@ -86,7 +89,7 @@ const ObjectManager = new Lang.Class({ | ||||
|                                        g_object_path: objectPath, | ||||
|                                        g_interface_name: interfaceName, | ||||
|                                        g_interface_info: info, | ||||
|                                        g_flags: Gio.DBusProxyFlags.NONE }); | ||||
|                                        g_flags: Gio.DBusProxyFlags.DO_NOT_AUTO_START }); | ||||
|  | ||||
|         proxy.init_async(GLib.PRIORITY_DEFAULT, | ||||
|                          this._cancellable, | ||||
| @@ -181,6 +184,18 @@ const ObjectManager = new Lang.Class({ | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this._managerProxy.connect('notify::g-name-owner', Lang.bind(this, function() { | ||||
|             if (this._managerProxy.g_name_owner) | ||||
|                 this._onNameAppeared(); | ||||
|             else | ||||
|                 this._onNameVanished(); | ||||
|         })); | ||||
|  | ||||
|         if (this._managerProxy.g_name_owner) | ||||
|             this._onNameAppeared(); | ||||
|     }, | ||||
|  | ||||
|     _onNameAppeared: function() { | ||||
|         this._managerProxy.GetManagedObjectsRemote(Lang.bind(this, function(result, error) { | ||||
|             if (!result) { | ||||
|                 if (error) { | ||||
| @@ -193,6 +208,11 @@ const ObjectManager = new Lang.Class({ | ||||
|  | ||||
|             let [objects] = result; | ||||
|  | ||||
|             if (!objects) { | ||||
|                 this._tryToCompleteLoad(); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             let objectPaths = Object.keys(objects); | ||||
|             for (let i = 0; i < objectPaths.length; i++) { | ||||
|                 let objectPath = objectPaths[i]; | ||||
| @@ -213,6 +233,21 @@ const ObjectManager = new Lang.Class({ | ||||
|         })); | ||||
|     }, | ||||
|  | ||||
|     _onNameVanished: function() { | ||||
|         let objectPaths = Object.keys(this._objects); | ||||
|         for (let i = 0; i < objectPaths.length; i++) { | ||||
|             let object = this._objects[objectPaths]; | ||||
|  | ||||
|             let interfaceNames = Object.keys(object); | ||||
|             for (let j = 0; i < interfaceNames.length; i++) { | ||||
|                 let interfaceName = interfaceNames[i]; | ||||
|  | ||||
|                 if (object[interfaceName]) | ||||
|                     this._removeInterface(objectPath, interfaceName); | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     _registerInterfaces: function(interfaces) { | ||||
|         for (let i = 0; i < interfaces.length; i++) { | ||||
|             let info = Gio.DBusInterfaceInfo.new_for_xml(interfaces[i]); | ||||
|   | ||||
| @@ -218,11 +218,10 @@ function formatTime(time, params) { | ||||
|     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) { | ||||
|     if (clockFormat == '24h') { | ||||
|         // Show only the time if date is on today | ||||
|         if (daysAgo < 1 || params.timeOnly) | ||||
|             /* Translators: Time in 24h format */ | ||||
| @@ -281,10 +280,7 @@ function formatTime(time, params) { | ||||
|             // xgettext:no-c-format | ||||
|             format = N_("%B %d %Y, %l\u2236%M %p"); | ||||
|     } | ||||
|  | ||||
|     let formattedTime = date.format(Shell.util_translate_time_string(format)); | ||||
|     // prepend LTR-mark to colon/ratio to force a text direction on times | ||||
|     return formattedTime.replace(/([:\u2236])/g, '\u200e$1'); | ||||
|     return date.format(Shell.util_translate_time_string(format)); | ||||
| } | ||||
|  | ||||
| function createTimeLabel(date, params) { | ||||
|   | ||||
| @@ -447,7 +447,10 @@ const AllView = new Lang.Class({ | ||||
|             })); | ||||
|         this._grid.connect('space-opened', Lang.bind(this, | ||||
|             function() { | ||||
|                 this._scrollView.get_effect('fade').enabled = false; | ||||
|                 let fadeEffect = this._scrollView.get_effect('fade'); | ||||
|                 if (fadeEffect) | ||||
|                     fadeEffect.enabled = false; | ||||
|  | ||||
|                 this.emit('space-ready'); | ||||
|             })); | ||||
|         this._grid.connect('space-closed', Lang.bind(this, | ||||
| @@ -658,7 +661,11 @@ const AllView = new Lang.Class({ | ||||
|  | ||||
|     _closeSpaceForPopup: function() { | ||||
|         this._updateIconOpacities(false); | ||||
|         this._scrollView.get_effect('fade').enabled = true; | ||||
|  | ||||
|         let fadeEffect = this._scrollView.get_effect('fade'); | ||||
|         if (fadeEffect) | ||||
|             fadeEffect.enabled = true; | ||||
|  | ||||
|         this._grid.closeExtraSpace(); | ||||
|     }, | ||||
|  | ||||
| @@ -1083,8 +1090,6 @@ const AppSearchProvider = new Lang.Class({ | ||||
|     _init: function() { | ||||
|         this._appSys = Shell.AppSystem.get_default(); | ||||
|         this.id = 'applications'; | ||||
|         this.isRemoteProvider = false; | ||||
|         this.canLaunchSearch = false; | ||||
|     }, | ||||
|  | ||||
|     getResultMetas: function(apps, callback) { | ||||
| @@ -1126,7 +1131,7 @@ const AppSearchProvider = new Lang.Class({ | ||||
|         this.getInitialResultSet(terms, callback, cancellable); | ||||
|     }, | ||||
|  | ||||
|     createResultObject: function (resultMeta) { | ||||
|     createResultObject: function (resultMeta, searchResultsView) { | ||||
|         let app = this._appSys.lookup_app(resultMeta['id']); | ||||
|         return new AppIcon(app); | ||||
|     } | ||||
| @@ -1253,7 +1258,6 @@ const FolderIcon = new Lang.Class({ | ||||
|  | ||||
|     _init: function(id, path, parentView) { | ||||
|         this.id = id; | ||||
|         this.name = ''; | ||||
|         this._parentView = parentView; | ||||
|  | ||||
|         this._folder = new Gio.Settings({ schema_id: 'org.gnome.desktop.app-folders.folder', | ||||
|   | ||||
| @@ -6,6 +6,7 @@ const Signals = imports.signals; | ||||
|  | ||||
| const Main = imports.ui.main; | ||||
|  | ||||
| // In alphabetical order | ||||
| const RENAMED_DESKTOP_IDS = { | ||||
|     'baobab.desktop': 'org.gnome.baobab.desktop', | ||||
|     'cheese.desktop': 'org.gnome.Cheese.desktop', | ||||
| @@ -27,6 +28,7 @@ const RENAMED_DESKTOP_IDS = { | ||||
|     'gnome-documents.desktop': 'org.gnome.Documents.desktop', | ||||
|     'gnome-font-viewer.desktop': 'org.gnome.font-viewer.desktop', | ||||
|     'gnome-nibbles.desktop': 'org.gnome.Nibbles.desktop', | ||||
|     'gnome-music.desktop': 'org.gnome.Music.desktop', | ||||
|     'gnome-photos.desktop': 'org.gnome.Photos.desktop', | ||||
|     'gnome-screenshot.desktop': 'org.gnome.Screenshot.desktop', | ||||
|     'gnome-software.desktop': 'org.gnome.Software.desktop', | ||||
|   | ||||
| @@ -761,8 +761,8 @@ const NotificationMessage = new Lang.Class({ | ||||
|     _init: function(notification) { | ||||
|         this.notification = notification; | ||||
|  | ||||
|         this.parent(notification.title, notification.bannerBodyText); | ||||
|         this.setUseBodyMarkup(notification.bannerBodyMarkup); | ||||
|         this.parent(notification.title, notification.bannerBodyText); | ||||
|  | ||||
|         this.setIcon(this._getIcon()); | ||||
|  | ||||
|   | ||||
| @@ -7,7 +7,6 @@ const St = imports.gi.St; | ||||
| const GnomeSession = imports.misc.gnomeSession; | ||||
| const Main = imports.ui.main; | ||||
| const MessageTray = imports.ui.messageTray; | ||||
| const ShellMountOperation = imports.ui.shellMountOperation; | ||||
|  | ||||
| // GSettings keys | ||||
| const SETTINGS_SCHEMA = 'org.gnome.desktop.media-handling'; | ||||
|   | ||||
| @@ -756,44 +756,42 @@ const Dash = new Lang.Class({ | ||||
|         let newIndex = 0; | ||||
|         let oldIndex = 0; | ||||
|         while (newIndex < newApps.length || oldIndex < oldApps.length) { | ||||
|             let oldApp = oldApps.length > oldIndex ? oldApps[oldIndex] : null; | ||||
|             let newApp = newApps.length > newIndex ? newApps[newIndex] : null; | ||||
|  | ||||
|             // No change at oldIndex/newIndex | ||||
|             if (oldApp == newApp) { | ||||
|             if (oldApps[oldIndex] == newApps[newIndex]) { | ||||
|                 oldIndex++; | ||||
|                 newIndex++; | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             // App removed at oldIndex | ||||
|             if (oldApp && newApps.indexOf(oldApp) == -1) { | ||||
|             if (oldApps[oldIndex] && | ||||
|                 newApps.indexOf(oldApps[oldIndex]) == -1) { | ||||
|                 removedActors.push(children[oldIndex]); | ||||
|                 oldIndex++; | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             // App added at newIndex | ||||
|             if (newApp && oldApps.indexOf(newApp) == -1) { | ||||
|                 addedItems.push({ app: newApp, | ||||
|                                   item: this._createAppItem(newApp), | ||||
|             if (newApps[newIndex] && | ||||
|                 oldApps.indexOf(newApps[newIndex]) == -1) { | ||||
|                 addedItems.push({ app: newApps[newIndex], | ||||
|                                   item: this._createAppItem(newApps[newIndex]), | ||||
|                                   pos: newIndex }); | ||||
|                 newIndex++; | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             // App moved | ||||
|             let nextApp = newApps.length > newIndex + 1 ? newApps[newIndex + 1] | ||||
|                                                         : null; | ||||
|             let insertHere = nextApp && nextApp == oldApp; | ||||
|             let insertHere = newApps[newIndex + 1] && | ||||
|                              newApps[newIndex + 1] == oldApps[oldIndex]; | ||||
|             let alreadyRemoved = removedActors.reduce(function(result, actor) { | ||||
|                 let removedApp = actor.child._delegate.app; | ||||
|                 return result || removedApp == newApp; | ||||
|                 return result || removedApp == newApps[newIndex]; | ||||
|             }, false); | ||||
|  | ||||
|             if (insertHere || alreadyRemoved) { | ||||
|                 let newItem = this._createAppItem(newApp); | ||||
|                 addedItems.push({ app: newApp, | ||||
|                 let newItem = this._createAppItem(newApps[newIndex]); | ||||
|                 addedItems.push({ app: newApps[newIndex], | ||||
|                                   item: newItem, | ||||
|                                   pos: newIndex + removedActors.length }); | ||||
|                 newIndex++; | ||||
|   | ||||
| @@ -474,8 +474,6 @@ const DateMenuButton = new Lang.Class({ | ||||
|  | ||||
|         let layout = new FreezableBinLayout(); | ||||
|         let bin = new St.Widget({ layout_manager: layout }); | ||||
|         // For some minimal compatibility with PopupMenuItem | ||||
|         bin._delegate = this; | ||||
|         this.menu.box.add_child(bin); | ||||
|  | ||||
|         hbox = new St.BoxLayout({ name: 'calendarArea' }); | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const FocusCaretTracker = imports.ui.focusCaretTracker; | ||||
| const Atspi = imports.gi.Atspi; | ||||
| const Caribou = imports.gi.Caribou; | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gdk = imports.gi.Gdk; | ||||
| @@ -25,42 +27,6 @@ const KEYBOARD_TYPE = 'keyboard-type'; | ||||
| const A11Y_APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications'; | ||||
| 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> \ | ||||
| <interface name="org.gnome.Caribou.Keyboard"> \ | ||||
| <method name="Show"> \ | ||||
|     <arg type="u" direction="in" /> \ | ||||
| </method> \ | ||||
| <method name="Hide"> \ | ||||
|     <arg type="u" direction="in" /> \ | ||||
| </method> \ | ||||
| <method name="SetCursorLocation"> \ | ||||
|     <arg type="i" direction="in" /> \ | ||||
|     <arg type="i" direction="in" /> \ | ||||
|     <arg type="i" direction="in" /> \ | ||||
|     <arg type="i" direction="in" /> \ | ||||
| </method> \ | ||||
| <method name="SetEntryLocation"> \ | ||||
|     <arg type="i" direction="in" /> \ | ||||
|     <arg type="i" direction="in" /> \ | ||||
|     <arg type="i" direction="in" /> \ | ||||
|     <arg type="i" direction="in" /> \ | ||||
| </method> \ | ||||
| <property name="Name" access="read" type="s" /> \ | ||||
| </interface> \ | ||||
| </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({ | ||||
|     Name: 'Key', | ||||
|  | ||||
| @@ -188,18 +154,19 @@ const Key = new Lang.Class({ | ||||
| Signals.addSignalMethods(Key.prototype); | ||||
|  | ||||
| const Keyboard = new Lang.Class({ | ||||
|     // HACK: we can't set Name, because it collides with Name dbus property | ||||
|     // Name: 'Keyboard', | ||||
|     Name: 'Keyboard', | ||||
|  | ||||
|     _init: function () { | ||||
|         this._impl = Gio.DBusExportedObject.wrapJSObject(CaribouKeyboardIface, this); | ||||
|         this._impl.export(Gio.DBus.session, '/org/gnome/Caribou/Keyboard'); | ||||
|  | ||||
|         this.actor = null; | ||||
|         this._focusInTray = false; | ||||
|         this._focusInExtendedKeys = false; | ||||
|  | ||||
|         this._timestamp = global.display.get_current_time_roundtrip(); | ||||
|         this._focusCaretTracker = new FocusCaretTracker.FocusCaretTracker(); | ||||
|         this._focusCaretTracker.connect('focus-changed', Lang.bind(this, this._onFocusChanged)); | ||||
|         this._focusCaretTracker.connect('caret-moved', Lang.bind(this, this._onCaretMoved)); | ||||
|         this._currentAccessible = null; | ||||
|         this._caretTrackingEnabled = false; | ||||
|         this._updateCaretPositionId = 0; | ||||
|  | ||||
|         this._keyboardSettings = new Gio.Settings({ schema_id: KEYBOARD_SCHEMA }); | ||||
|         this._keyboardSettings.connect('changed', Lang.bind(this, this._sync)); | ||||
| @@ -208,9 +175,7 @@ const Keyboard = new Lang.Class({ | ||||
|         this._daemonProxy = null; | ||||
|         this._lastDeviceId = null; | ||||
|  | ||||
|         if (Meta.is_wayland_compositor() && | ||||
|             Caribou.DisplayAdapter.set_default) | ||||
|             Caribou.DisplayAdapter.set_default(new ShellWaylandAdapter()); | ||||
|         Caribou.DisplayAdapter.set_default(new LocalAdapter()); | ||||
|  | ||||
|         Meta.get_backend().connect('last-device-changed', Lang.bind(this, | ||||
|             function (backend, deviceId) { | ||||
| @@ -240,6 +205,93 @@ const Keyboard = new Lang.Class({ | ||||
|         this._redraw(); | ||||
|     }, | ||||
|  | ||||
|     _setCaretTrackerEnabled: function (enabled) { | ||||
|         if (this._caretTrackingEnabled == enabled) | ||||
|             return; | ||||
|  | ||||
|         this._caretTrackingEnabled = enabled; | ||||
|  | ||||
|         if (enabled) { | ||||
|             this._focusCaretTracker.registerFocusListener(); | ||||
|             this._focusCaretTracker.registerCaretListener(); | ||||
|         } else { | ||||
|             this._focusCaretTracker.deregisterFocusListener(); | ||||
|             this._focusCaretTracker.deregisterCaretListener(); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     _updateCaretPosition: function (accessible) { | ||||
|         if (this._updateCaretPositionId) | ||||
|             GLib.source_remove(this._updateCaretPositionId); | ||||
|         this._updateCaretPositionId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, Lang.bind(this, function() { | ||||
|             this._updateCaretPositionId = 0; | ||||
|  | ||||
|             let currentWindow = global.screen.get_display().focus_window; | ||||
|             if (!currentWindow) | ||||
|                 return GLib.SOURCE_REMOVE; | ||||
|  | ||||
|             let windowRect = currentWindow.get_frame_rect(); | ||||
|             let text = accessible.get_text_iface(); | ||||
|             let component = accessible.get_component_iface(); | ||||
|  | ||||
|             try { | ||||
|                 let caretOffset = text.get_caret_offset(); | ||||
|                 let caretRect = text.get_character_extents(caretOffset, Atspi.CoordType.WINDOW); | ||||
|                 let focusRect = component.get_extents(Atspi.CoordType.WINDOW); | ||||
|  | ||||
|                 caretRect.x += windowRect.x; | ||||
|                 caretRect.y += windowRect.y; | ||||
|                 focusRect.x += windowRect.x; | ||||
|                 focusRect.y += windowRect.y; | ||||
|  | ||||
|                 if (caretRect.width == 0 && caretRect.height == 0) | ||||
|                     caretRect = focusRect; | ||||
|  | ||||
|                 this.setEntryLocation(focusRect.x, focusRect.y, focusRect.width, focusRect.height); | ||||
|                 this.setCursorLocation(caretRect.x, caretRect.y, caretRect.width, caretRect.height); | ||||
|             } catch (e) { | ||||
|                 log('Error updating caret position for OSK: ' + e.message); | ||||
|             } | ||||
|  | ||||
|             return GLib.SOURCE_REMOVE; | ||||
|         })); | ||||
|  | ||||
|         GLib.Source.set_name_by_id(this._updateCaretPositionId, '[gnome-shell] this._updateCaretPosition'); | ||||
|     }, | ||||
|  | ||||
|     _focusIsTextEntry: function (accessible) { | ||||
|         try { | ||||
|             let role = accessible.get_role(); | ||||
|             let stateSet = accessible.get_state_set(); | ||||
|             return stateSet.contains(Atspi.StateType.EDITABLE) || role == Atspi.Role.TERMINAL; | ||||
|         } catch (e) { | ||||
|             log('Error determining accessible role: ' + e.message); | ||||
|             return false; | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     _onFocusChanged: function (caretTracker, event) { | ||||
|         let accessible = event.source; | ||||
|         if (!this._focusIsTextEntry(accessible)) | ||||
|             return; | ||||
|  | ||||
|         let focused = event.detail1 != 0; | ||||
|         if (focused) { | ||||
|             this._currentAccessible = accessible; | ||||
|             this._updateCaretPosition(accessible); | ||||
|             this.show(Main.layoutManager.focusIndex); | ||||
|         } else if (this._currentAccessible == accessible) { | ||||
|             this._currentAccessible = null; | ||||
|             this.hide(); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     _onCaretMoved: function (caretTracker, event) { | ||||
|         let accessible = event.source; | ||||
|         if (this._currentAccessible == accessible) | ||||
|             this._updateCaretPosition(accessible); | ||||
|     }, | ||||
|  | ||||
|     _lastDeviceIsTouchscreen: function () { | ||||
|         if (!this._lastDeviceId) | ||||
|             return false; | ||||
| @@ -262,6 +314,8 @@ const Keyboard = new Lang.Class({ | ||||
|             this._keyboard.keyboard_type == this._keyboardSettings.get_string(KEYBOARD_TYPE)) | ||||
|             return; | ||||
|  | ||||
|         this._setCaretTrackerEnabled(this._enableKeyboard); | ||||
|  | ||||
|         if (this._keyboard) | ||||
|             this._destroyKeyboard(); | ||||
|  | ||||
| @@ -297,23 +351,6 @@ const Keyboard = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     _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 }); | ||||
|         Main.layoutManager.keyboardBox.add_actor(this.actor); | ||||
|         Main.layoutManager.trackChrome(this.actor); | ||||
| @@ -359,17 +396,17 @@ const Keyboard = new Lang.Class({ | ||||
|  | ||||
|         let time = global.get_current_time(); | ||||
|         if (!(focus instanceof Clutter.Text)) { | ||||
|             this.Hide(time); | ||||
|             this.hide(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!this._showIdleId) { | ||||
|           this._showIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, | ||||
|                                            Lang.bind(this, function() { | ||||
|                                                this.Show(time); | ||||
|                                                this.show(Main.layoutManager.focusIndex); | ||||
|                                                return GLib.SOURCE_REMOVE; | ||||
|                                            })); | ||||
|           GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.Show'); | ||||
|           GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.show'); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
| @@ -570,7 +607,7 @@ const Keyboard = new Lang.Class({ | ||||
|     shouldTakeEvent: function(event) { | ||||
|         let actor = event.get_source(); | ||||
|         return Main.layoutManager.keyboardBox.contains(actor) || | ||||
|                !!actor._extended_keys || !!actor.extended_key; | ||||
|                actor._extended_keys || actor.extended_key; | ||||
|     }, | ||||
|  | ||||
|     _clearKeyboardRestTimer: function() { | ||||
| @@ -581,6 +618,10 @@ const Keyboard = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     show: function (monitor) { | ||||
|         if (!this._enableKeyboard) | ||||
|             return; | ||||
|  | ||||
|         this._clearShowIdle(); | ||||
|         this._keyboardRequested = true; | ||||
|  | ||||
|         if (this._keyboardVisible) { | ||||
| @@ -613,6 +654,10 @@ const Keyboard = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     hide: function () { | ||||
|         if (!this._enableKeyboard) | ||||
|             return; | ||||
|  | ||||
|         this._clearShowIdle(); | ||||
|         this._keyboardRequested = false; | ||||
|  | ||||
|         if (!this._keyboardVisible) | ||||
| @@ -664,20 +709,6 @@ const Keyboard = new Lang.Class({ | ||||
|             this._moveTemporarily(); | ||||
|     }, | ||||
|  | ||||
|     // _compareTimestamp: | ||||
|     // | ||||
|     // Compare two timestamps taking into account | ||||
|     // CURRENT_TIME (0) | ||||
|     _compareTimestamp: function(one, two) { | ||||
|         if (one == two) | ||||
|             return 0; | ||||
|         if (one == Clutter.CURRENT_TIME) | ||||
|             return 1; | ||||
|         if (two == Clutter.CURRENT_TIME) | ||||
|             return -1; | ||||
|         return one - two; | ||||
|     }, | ||||
|  | ||||
|     _clearShowIdle: function() { | ||||
|         if (!this._showIdleId) | ||||
|             return; | ||||
| @@ -685,52 +716,19 @@ const Keyboard = new Lang.Class({ | ||||
|         this._showIdleId = 0; | ||||
|     }, | ||||
|  | ||||
|     // D-Bus methods | ||||
|     Show: function(timestamp) { | ||||
|         if (!this._enableKeyboard) | ||||
|             return; | ||||
|  | ||||
|         if (this._compareTimestamp(timestamp, this._timestamp) < 0) | ||||
|             return; | ||||
|  | ||||
|         this._clearShowIdle(); | ||||
|  | ||||
|         if (timestamp != Clutter.CURRENT_TIME) | ||||
|             this._timestamp = timestamp; | ||||
|         this.show(Main.layoutManager.focusIndex); | ||||
|     }, | ||||
|  | ||||
|     Hide: function(timestamp) { | ||||
|         if (!this._enableKeyboard) | ||||
|             return; | ||||
|  | ||||
|         if (this._compareTimestamp(timestamp, this._timestamp) < 0) | ||||
|             return; | ||||
|  | ||||
|         this._clearShowIdle(); | ||||
|  | ||||
|         if (timestamp != Clutter.CURRENT_TIME) | ||||
|             this._timestamp = timestamp; | ||||
|         this.hide(); | ||||
|     }, | ||||
|  | ||||
|     SetCursorLocation: function(x, y, w, h) { | ||||
|     setCursorLocation: function(x, y, w, h) { | ||||
|         if (!this._enableKeyboard) | ||||
|             return; | ||||
|  | ||||
| //        this._setLocation(x, y); | ||||
|     }, | ||||
|  | ||||
|     SetEntryLocation: function(x, y, w, h) { | ||||
|     setEntryLocation: function(x, y, w, h) { | ||||
|         if (!this._enableKeyboard) | ||||
|             return; | ||||
|  | ||||
| //        this._setLocation(x, y); | ||||
|     }, | ||||
|  | ||||
|     get Name() { | ||||
|         return 'gnome-shell'; | ||||
|     } | ||||
| }); | ||||
|  | ||||
| const KeyboardSource = new Lang.Class({ | ||||
| @@ -754,8 +752,8 @@ const KeyboardSource = new Lang.Class({ | ||||
|     } | ||||
| }); | ||||
|  | ||||
| const ShellWaylandAdapter = new Lang.Class({ | ||||
|     Name: 'ShellWaylandAdapter', | ||||
| const LocalAdapter = new Lang.Class({ | ||||
|     Name: 'LocalAdapter', | ||||
|     Extends: Caribou.XAdapter, | ||||
|  | ||||
|     _init: function () { | ||||
|   | ||||
| @@ -896,10 +896,7 @@ const LayoutManager = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     findMonitorForActor: function(actor) { | ||||
|         let index = this.findIndexForActor(actor); | ||||
|         if (index >= 0 && index < this.monitors.length) | ||||
|             return this.monitors[index]; | ||||
|         return null; | ||||
|         return this.monitors[this.findIndexForActor(actor)]; | ||||
|     }, | ||||
|  | ||||
|     _queueUpdateRegions: function() { | ||||
| @@ -969,11 +966,7 @@ const LayoutManager = new Lang.Class({ | ||||
|             if (actorData.affectsInputRegion && wantsInputRegion && actorData.actor.get_paint_visibility()) | ||||
|                 rects.push(new Meta.Rectangle({ x: x, y: y, width: w, height: h })); | ||||
|  | ||||
|             let monitor = null; | ||||
|             if (actorData.affectsStruts) | ||||
|                 monitor = this.findMonitorForActor(actorData.actor); | ||||
|  | ||||
|             if (monitor) { | ||||
|             if (actorData.affectsStruts) { | ||||
|                 // Limit struts to the size of the screen | ||||
|                 let x1 = Math.max(x, 0); | ||||
|                 let x2 = Math.min(x + w, global.screen_width); | ||||
| @@ -990,6 +983,7 @@ const LayoutManager = new Lang.Class({ | ||||
|                 // spans the width/height across the middle of the | ||||
|                 // screen, then we don't create a strut for it at all. | ||||
|  | ||||
|                 let monitor = this.findMonitorForActor(actorData.actor); | ||||
|                 let side; | ||||
|                 if (x1 <= monitor.x && x2 >= monitor.x + monitor.width) { | ||||
|                     if (y1 <= monitor.y) | ||||
|   | ||||
| @@ -783,7 +783,6 @@ const LookingGlass = new Lang.Class({ | ||||
|  | ||||
|         this._open = false; | ||||
|  | ||||
|         this._it = null; | ||||
|         this._offset = 0; | ||||
|         this._results = []; | ||||
|  | ||||
| @@ -834,19 +833,19 @@ const LookingGlass = new Lang.Class({ | ||||
|             return Clutter.EVENT_STOP; | ||||
|         })); | ||||
|  | ||||
|         let gcIcon = new St.Icon({ icon_name: 'gnome-fs-trash-full', | ||||
|         let gcIcon = new St.Icon({ icon_name: 'user-trash-full', | ||||
|                                    icon_size: 24 }); | ||||
|         toolbar.add_actor(gcIcon); | ||||
|         gcIcon.reactive = true; | ||||
|         gcIcon.connect('button-press-event', Lang.bind(this, function () { | ||||
|            gcIcon.icon_name = 'gnome-fs-trash-empty'; | ||||
|            gcIcon.icon_name = 'user-trash'; | ||||
|            System.gc(); | ||||
|            this._timeoutId = Mainloop.timeout_add(500, Lang.bind(this, function () { | ||||
|                 gcIcon.icon_name = 'gnome-fs-trash-full'; | ||||
|                 gcIcon.icon_name = 'user-trash-full'; | ||||
|                 this._timeoutId = 0; | ||||
|                 return GLib.SOURCE_REMOVE; | ||||
|            })); | ||||
|            GLib.Source.set_name_by_id(this._timeoutId, '[gnome-shell] gcIcon.icon_name = \'gnome-fs-trash-full\''); | ||||
|            GLib.Source.set_name_by_id(this._timeoutId, '[gnome-shell] gcIcon.icon_name = \'user-trash-full\''); | ||||
|            return Clutter.EVENT_PROPAGATE; | ||||
|         })); | ||||
|  | ||||
|   | ||||
| @@ -165,11 +165,6 @@ const ScaleLayout = new Lang.Class({ | ||||
|     Name: 'ScaleLayout', | ||||
|     Extends: Clutter.BinLayout, | ||||
|  | ||||
|     _init: function(params) { | ||||
|         this._container = null; | ||||
|         this.parent(params); | ||||
|     }, | ||||
|  | ||||
|     _connectContainer: function(container) { | ||||
|         if (this._container == container) | ||||
|             return; | ||||
| @@ -304,8 +299,6 @@ const Message = new Lang.Class({ | ||||
|     _init: function(title, body) { | ||||
|         this.expanded = false; | ||||
|  | ||||
|         this._useBodyMarkup = false; | ||||
|  | ||||
|         this.actor = new St.Button({ style_class: 'message', | ||||
|                                      accessible_role: Atk.Role.NOTIFICATION, | ||||
|                                      can_focus: true, | ||||
|   | ||||
| @@ -128,10 +128,10 @@ const FdoNotificationDaemon = new Lang.Class({ | ||||
|         switch (hints.urgency) { | ||||
|             case Urgency.LOW: | ||||
|             case Urgency.NORMAL: | ||||
|                 stockIcon = 'dialog-information'; | ||||
|                 stockIcon = 'gtk-dialog-info'; | ||||
|                 break; | ||||
|             case Urgency.CRITICAL: | ||||
|                 stockIcon = 'dialog-error'; | ||||
|                 stockIcon = 'gtk-dialog-error'; | ||||
|                 break; | ||||
|         } | ||||
|         return new Gio.ThemedIcon({ name: stockIcon }); | ||||
| @@ -186,8 +186,7 @@ const FdoNotificationDaemon = new Lang.Class({ | ||||
|             return source; | ||||
|         } | ||||
|  | ||||
|         let appId = ndata ? ndata.hints['desktop-entry'] || null : null; | ||||
|         source = new FdoNotificationDaemonSource(title, pid, sender, appId); | ||||
|         source = new FdoNotificationDaemonSource(title, pid, sender, ndata ? ndata.hints['desktop-entry'] : null); | ||||
|  | ||||
|         this._sources.push(source); | ||||
|         source.connect('destroy', Lang.bind(this, function() { | ||||
| @@ -392,10 +391,10 @@ const FdoNotificationDaemon = new Lang.Class({ | ||||
|                 notification.setUrgency(MessageTray.Urgency.CRITICAL); | ||||
|                 break; | ||||
|         } | ||||
|         notification.setResident(!!hints.resident); | ||||
|         notification.setResident(hints.resident == true); | ||||
|         // '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 | ||||
|         notification.setTransient(!!hints['transient']); | ||||
|         notification.setTransient(hints['transient'] == true); | ||||
|  | ||||
|         let sourceGIcon = source.useNotificationIcon ? gicon : null; | ||||
|         source.processNotification(notification, sourceGIcon); | ||||
|   | ||||
| @@ -120,6 +120,25 @@ const OsdMonitorLabeler = new Lang.Class({ | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     show2: function(client, params) { | ||||
|         if (!this._trackClient(client)) | ||||
|             return; | ||||
|  | ||||
|         this._reset(); | ||||
|  | ||||
|         for (let connector in params) { | ||||
|             let monitor = this._monitorManager.get_monitor_for_connector(connector); | ||||
|             if (monitor == -1) | ||||
|                 continue; | ||||
|             this._monitorLabels.get(monitor).push(params[connector].deep_unpack()); | ||||
|         } | ||||
|  | ||||
|         for (let [monitor, labels] of this._monitorLabels.entries()) { | ||||
|             labels.sort(); | ||||
|             this._osdLabels.push(new OsdMonitorLabel(monitor, labels.join(' '))); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     hide: function(client) { | ||||
|         if (!this._untrackClient(client)) | ||||
|             return; | ||||
|   | ||||
							
								
								
									
										162
									
								
								js/ui/padOsd.js
									
									
									
									
									
								
							
							
						
						
									
										162
									
								
								js/ui/padOsd.js
									
									
									
									
									
								
							| @@ -154,16 +154,9 @@ const ActionComboBox = new Lang.Class({ | ||||
|         this._actionLabels.set(GDesktopEnums.PadButtonAction.SWITCH_MONITOR, _("Switch monitor")); | ||||
|         this._actionLabels.set(GDesktopEnums.PadButtonAction.KEYBINDING, _("Assign keystroke")); | ||||
|  | ||||
|         this._buttonItems = []; | ||||
|  | ||||
|         for (let [action, label] of this._actionLabels.entries()) { | ||||
|             let selectedAction = action; | ||||
|             let item = this._editMenu.addAction(label, Lang.bind(this, function() { this._onActionSelected(selectedAction) })); | ||||
|  | ||||
|             /* These actions only apply to pad buttons */ | ||||
|             if (selectedAction == GDesktopEnums.PadButtonAction.HELP || | ||||
|                 selectedAction == GDesktopEnums.PadButtonAction.SWITCH_MONITOR) | ||||
|                 this._buttonItems.push(item); | ||||
|             this._editMenu.addAction(label, Lang.bind(this, function() { this._onActionSelected(selectedAction) })); | ||||
|         } | ||||
|  | ||||
|         this.setAction(GDesktopEnums.PadButtonAction.NONE); | ||||
| @@ -192,10 +185,6 @@ const ActionComboBox = new Lang.Class({ | ||||
|             this.popup(); | ||||
|         else | ||||
|             this.popdown(); | ||||
|     }, | ||||
|  | ||||
|     setButtonActionsActive: function (active) { | ||||
|         this._buttonItems.forEach(item => { item.setSensitive(active); }); | ||||
|     } | ||||
| }); | ||||
| Signals.addSignalMethods(ActionComboBox.prototype); | ||||
| @@ -234,16 +223,13 @@ const ActionEditor = new Lang.Class({ | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     setSettings: function (settings, action) { | ||||
|     setSettings: function (settings) { | ||||
|         this._buttonSettings = settings; | ||||
|  | ||||
|         this._currentAction = this._buttonSettings.get_enum('action'); | ||||
|         this._currentKeybinding = this._buttonSettings.get_string('keybinding'); | ||||
|         this._actionComboBox.setAction(this._currentAction); | ||||
|         this._updateKeybindingEntryState(); | ||||
|  | ||||
|         let isButton = (action == Meta.PadActionType.BUTTON); | ||||
|         this._actionComboBox.setButtonActionsActive(isButton); | ||||
|     }, | ||||
|  | ||||
|     close: function() { | ||||
| @@ -307,8 +293,6 @@ const PadDiagram = new Lang.Class({ | ||||
|     _init: function (params) { | ||||
|         let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/pad-osd.css'); | ||||
|         let [success, css, etag] = file.load_contents(null); | ||||
|         this._curEdited = null; | ||||
|         this._prevEdited = null; | ||||
|         this._css = css; | ||||
|         this._labels = []; | ||||
|         this._activeButtons = []; | ||||
| @@ -566,39 +550,25 @@ const PadDiagram = new Lang.Class({ | ||||
|         this.add_actor(label); | ||||
|     }, | ||||
|  | ||||
|     _applyLabel: function(label, action, idx, dir, str) { | ||||
|         if (str != null) { | ||||
|             label.set_text(str); | ||||
|  | ||||
|             let [found, x, y, arrangement] = this.getLabelCoords(action, idx, dir); | ||||
|             this._allocateChild(label, x, y, arrangement); | ||||
|         } | ||||
|         label.show(); | ||||
|     }, | ||||
|  | ||||
|     stopEdition: function (continues, str) { | ||||
|     stopEdition: function (str) { | ||||
|         this._editorActor.hide(); | ||||
|  | ||||
|         if (this._prevEdited) { | ||||
|             let [label, action, idx, dir] = this._prevEdited; | ||||
|             this._applyLabel(label, action, idx, dir, str); | ||||
|             this._prevEdited = null; | ||||
|         } | ||||
|  | ||||
|         if (this._curEdited) { | ||||
|             let [label, action, idx, dir] = this._curEdited; | ||||
|             this._applyLabel(label, action, idx, dir, str); | ||||
|             if (continues) | ||||
|                 this._prevEdited = this._curEdited; | ||||
|             if (str != null) { | ||||
|                 label.set_text(str); | ||||
|  | ||||
|                 let [found, x, y, arrangement] = this.getLabelCoords(action, idx, dir); | ||||
|                 this._allocateChild(label, x, y, arrangement); | ||||
|             } | ||||
|             label.show(); | ||||
|             this._curEdited = null; | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     startEdition: function(action, idx, dir) { | ||||
|         let editedLabel; | ||||
|  | ||||
|         if (this._curEdited) | ||||
|             return; | ||||
|         this.stopEdition(); | ||||
|  | ||||
|         for (let i = 0; i < this._labels.length; i++) { | ||||
|             let [label, itemAction, itemIdx, itemDir] = this._labels[i]; | ||||
| @@ -692,7 +662,7 @@ const PadOsd = new Lang.Class({ | ||||
|         this._updatePadChooser(); | ||||
|  | ||||
|         this._actionEditor = new ActionEditor(); | ||||
|         this._actionEditor.connect('done', Lang.bind(this, this._endActionEdition)); | ||||
|         this._actionEditor.connect('done', Lang.bind(this, this._endButtonActionEdition)); | ||||
|  | ||||
|         this._padDiagram = new PadDiagram({ image: this._imagePath, | ||||
|                                             left_handed: settings.get_boolean('left-handed'), | ||||
| @@ -711,17 +681,11 @@ const PadOsd = new Lang.Class({ | ||||
|         } | ||||
|  | ||||
|         for (i = 0; i < padDevice.get_n_rings(); i++) { | ||||
|             let [found] = this._padDiagram.getRingLabelCoords(i, CW); | ||||
|             if (!found) | ||||
|                 break; | ||||
|             this._createLabel(Meta.PadActionType.RING, i, CW); | ||||
|             this._createLabel(Meta.PadActionType.RING, i, CCW); | ||||
|         } | ||||
|  | ||||
|         for (i = 0; i < padDevice.get_n_strips(); i++) { | ||||
|             let [found] = this._padDiagram.getStripLabelCoords(i, UP); | ||||
|             if (!found) | ||||
|                 break; | ||||
|             this._createLabel(Meta.PadActionType.STRIP, i, UP); | ||||
|             this._createLabel(Meta.PadActionType.STRIP, i, DOWN); | ||||
|         } | ||||
| @@ -779,10 +743,8 @@ const PadOsd = new Lang.Class({ | ||||
|         if (event.type() == Clutter.EventType.PAD_BUTTON_PRESS && | ||||
|             event.get_source_device() == this.padDevice) { | ||||
|             this._padDiagram.activateButton(event.get_button()); | ||||
|             let isModeSwitch = this.padDevice.get_mode_switch_button_group(event.get_button()) >= 0; | ||||
|  | ||||
|             /* Buttons that switch between modes cannot be edited */ | ||||
|             if (this._editionMode && !isModeSwitch) | ||||
|             if (this._editionMode) | ||||
|                 this._startButtonActionEdition(event.get_button()); | ||||
|             return Clutter.EVENT_STOP; | ||||
|         } else if (event.type() == Clutter.EventType.PAD_BUTTON_RELEASE && | ||||
| @@ -791,23 +753,11 @@ const PadOsd = new Lang.Class({ | ||||
|             return Clutter.EVENT_STOP; | ||||
|         } else if (event.type() == Clutter.EventType.KEY_PRESS && | ||||
|                    (!this._editionMode || event.get_key_symbol() == Clutter.Escape)) { | ||||
|             if (this._editedAction != null) | ||||
|                 this._endActionEdition(); | ||||
|             if (this._editingButtonAction != null) | ||||
|                 this._endButtonActionEdition(); | ||||
|             else | ||||
|                 this.destroy(); | ||||
|             return Clutter.EVENT_STOP; | ||||
|         } else if (event.get_source_device() == this.padDevice && | ||||
|                    event.type() == Clutter.EventType.PAD_STRIP) { | ||||
|             if (this._editionMode) { | ||||
|                 let [retval, number, mode] = event.get_pad_event_details(); | ||||
|                 this._startStripActionEdition(number, UP, mode); | ||||
|             } | ||||
|         } else if (event.get_source_device() == this.padDevice && | ||||
|                    event.type() == Clutter.EventType.PAD_RING) { | ||||
|             if (this._editionMode) { | ||||
|                 let [retval, number, mode] = event.get_pad_event_details(); | ||||
|                 this._startRingActionEdition(number, CCW, mode); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // If the event comes from another pad in the same group, | ||||
| @@ -840,79 +790,33 @@ const PadOsd = new Lang.Class({ | ||||
|         this._titleLabel.clutter_text.set_markup('<span size="larger"><b>' + title + '</b></span>'); | ||||
|     }, | ||||
|  | ||||
|     _isEditedAction: function (type, number, dir) { | ||||
|         if (!this._editedAction) | ||||
|             return false; | ||||
|  | ||||
|         return (this._editedAction.type == type && | ||||
|                 this._editedAction.number == number && | ||||
|                 this._editedAction.dir == dir); | ||||
|     }, | ||||
|  | ||||
|     _followUpActionEdition: function (str) { | ||||
|         let { type, dir, number, mode } = this._editedAction; | ||||
|         let hasNextAction = (type == Meta.PadActionType.RING && dir == CCW || | ||||
|                              type == Meta.PadActionType.STRIP && dir == UP); | ||||
|         if (!hasNextAction) | ||||
|             return false; | ||||
|  | ||||
|         this._padDiagram.stopEdition(true, str); | ||||
|         this._editedAction = null; | ||||
|         if (type == Meta.PadActionType.RING) | ||||
|             this._startRingActionEdition(number, CW, mode); | ||||
|         else | ||||
|             this._startStripActionEdition(number, DOWN, mode); | ||||
|  | ||||
|         return true; | ||||
|     }, | ||||
|  | ||||
|     _endActionEdition: function () { | ||||
|     _endButtonActionEdition: function () { | ||||
|         this._actionEditor.close(); | ||||
|  | ||||
|         if (this._editedAction != null) { | ||||
|         if (this._editingButtonAction != null) { | ||||
|             let str = global.display.get_pad_action_label(this.padDevice, | ||||
|                                                           this._editedAction.type, | ||||
|                                                           this._editedAction.number); | ||||
|             if (this._followUpActionEdition(str)) | ||||
|                 return; | ||||
|  | ||||
|             this._padDiagram.stopEdition(false, str ? str : _("None")) | ||||
|             this._editedAction = null; | ||||
|                                                           Meta.PadActionType.BUTTON, | ||||
|                                                           this._editingButtonAction); | ||||
|             this._padDiagram.stopEdition(str ? str : _("None")) | ||||
|             this._editingButtonAction = null; | ||||
|         } | ||||
|  | ||||
|         this._editedActionSettings = null; | ||||
|     }, | ||||
|  | ||||
|     _startActionEdition: function (key, type, number, dir, mode) { | ||||
|         if (this._isEditedAction(type, number, dir)) | ||||
|             return; | ||||
|  | ||||
|         this._endActionEdition(); | ||||
|         this._editedAction = { type, number, dir, mode }; | ||||
|  | ||||
|         let settingsPath = this._settings.path + key + '/'; | ||||
|         this._editedActionSettings = Gio.Settings.new_with_path('org.gnome.desktop.peripherals.tablet.pad-button', | ||||
|                                                                 settingsPath); | ||||
|         this._actionEditor.setSettings(this._editedActionSettings, type); | ||||
|         this._padDiagram.startEdition(type, number, dir); | ||||
|         this._editedButtonSettings = null; | ||||
|     }, | ||||
|  | ||||
|     _startButtonActionEdition: function (button) { | ||||
|         if (this._editingButtonAction == button) | ||||
|             return; | ||||
|  | ||||
|         this._endButtonActionEdition(); | ||||
|         this._editingButtonAction = button; | ||||
|  | ||||
|         let ch = String.fromCharCode('A'.charCodeAt() + button); | ||||
|         let key = 'button' + ch; | ||||
|         this._startActionEdition(key, Meta.PadActionType.BUTTON, button); | ||||
|     }, | ||||
|  | ||||
|     _startRingActionEdition: function (ring, dir, mode) { | ||||
|         let ch = String.fromCharCode('A'.charCodeAt() + ring); | ||||
|         let key = 'ring%s-%s-mode-%d'.format(ch, dir == CCW ? 'ccw' : 'cw', mode); | ||||
|         this._startActionEdition(key, Meta.PadActionType.RING, ring, dir, mode); | ||||
|     }, | ||||
|  | ||||
|     _startStripActionEdition: function (strip, dir, mode) { | ||||
|         let ch = String.fromCharCode('A'.charCodeAt() + strip); | ||||
|         let key = 'strip%s-%s-mode-%d'.format(ch, dir == UP ? 'up' : 'down', mode); | ||||
|         this._startActionEdition(key, Meta.PadActionType.STRIP, strip, dir, mode); | ||||
|         let settingsPath = this._settings.path + "button" + ch + '/'; | ||||
|         this._editedButtonSettings = Gio.Settings.new_with_path('org.gnome.desktop.peripherals.tablet.pad-button', | ||||
|                                                                 settingsPath); | ||||
|         this._actionEditor.setSettings(this._editedButtonSettings); | ||||
|         this._padDiagram.startEdition(Meta.PadActionType.BUTTON, button); | ||||
|     }, | ||||
|  | ||||
|     setEditionMode: function (editionMode) { | ||||
|   | ||||
| @@ -801,9 +801,11 @@ const Panel = new Lang.Class({ | ||||
|  | ||||
|         Main.overview.connect('showing', Lang.bind(this, function () { | ||||
|             this.actor.add_style_pseudo_class('overview'); | ||||
|             this._updateSolidStyle(); | ||||
|         })); | ||||
|         Main.overview.connect('hiding', Lang.bind(this, function () { | ||||
|             this.actor.remove_style_pseudo_class('overview'); | ||||
|             this._updateSolidStyle(); | ||||
|         })); | ||||
|  | ||||
|         Main.layoutManager.panelBox.add(this.actor); | ||||
| @@ -811,9 +813,26 @@ const Panel = new Lang.Class({ | ||||
|                                         { sortGroup: CtrlAltTab.SortGroup.TOP }); | ||||
|  | ||||
|         Main.sessionMode.connect('updated', Lang.bind(this, this._updatePanel)); | ||||
|  | ||||
|         this._trackedWindows = new Map(); | ||||
|         global.window_group.connect('actor-added', Lang.bind(this, this._onWindowActorAdded)); | ||||
|         global.window_group.connect('actor-removed', Lang.bind(this, this._onWindowActorRemoved)); | ||||
|         global.window_manager.connect('switch-workspace', Lang.bind(this, this._updateSolidStyle)); | ||||
|  | ||||
|         this._updatePanel(); | ||||
|     }, | ||||
|  | ||||
|     _onWindowActorAdded: function(container, metaWindowActor) { | ||||
|         let signalId = metaWindowActor.connect('allocation-changed', Lang.bind(this, this._updateSolidStyle)); | ||||
|         this._trackedWindows.set(metaWindowActor, signalId); | ||||
|     }, | ||||
|  | ||||
|     _onWindowActorRemoved: function(container, metaWindowActor) { | ||||
|         metaWindowActor.disconnect(this._trackedWindows.get(metaWindowActor)); | ||||
|         this._trackedWindows.delete(metaWindowActor); | ||||
|         this._updateSolidStyle(); | ||||
|     }, | ||||
|  | ||||
|     _getPreferredWidth: function(actor, forHeight, alloc) { | ||||
|         alloc.min_size = -1; | ||||
|         alloc.natural_size = Main.layoutManager.primaryMonitor.width; | ||||
| @@ -996,6 +1015,8 @@ const Panel = new Lang.Class({ | ||||
|         else | ||||
|             Main.messageTray.bannerAlignment = Clutter.ActorAlign.CENTER; | ||||
|  | ||||
|         this._updateSolidStyle(); | ||||
|  | ||||
|         if (this._sessionStyle) | ||||
|             this._removeStyleClassName(this._sessionStyle); | ||||
|  | ||||
| @@ -1012,6 +1033,36 @@ const Panel = new Lang.Class({ | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     _updateSolidStyle: function() { | ||||
|         if (this.actor.has_style_pseudo_class('overview') || !Main.sessionMode.hasWindows) { | ||||
|             this._removeStyleClassName('solid'); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         /* Get all the windows in the active workspace that are in the primary monitor and visible */ | ||||
|         let activeWorkspace = global.screen.get_active_workspace(); | ||||
|         let windows = activeWorkspace.list_windows().filter(function(metaWindow) { | ||||
|             return metaWindow.is_on_primary_monitor() && | ||||
|                    metaWindow.showing_on_its_workspace() && | ||||
|                    metaWindow.get_window_type() != Meta.WindowType.DESKTOP; | ||||
|         }); | ||||
|  | ||||
|         /* Check if at least one window is near enough to the panel */ | ||||
|         let [, panelTop] = this.actor.get_transformed_position(); | ||||
|         let panelBottom = panelTop + this.actor.get_height(); | ||||
|         let scale = St.ThemeContext.get_for_stage(global.stage).scale_factor; | ||||
|         let isNearEnough = windows.some(Lang.bind(this, function(metaWindow) { | ||||
|             let verticalPosition = metaWindow.get_frame_rect().y; | ||||
|             return verticalPosition < panelBottom + 5 * scale; | ||||
|         })); | ||||
|  | ||||
|         if (isNearEnough) | ||||
|             this._addStyleClassName('solid'); | ||||
|         else | ||||
|             this._removeStyleClassName('solid'); | ||||
|  | ||||
|     }, | ||||
|  | ||||
|     _hideIndicators: function() { | ||||
|         for (let role in PANEL_ITEM_IMPLEMENTATIONS) { | ||||
|             let indicator = this.statusArea[role]; | ||||
| @@ -1104,7 +1155,7 @@ const Panel = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     _onMenuSet: function(indicator) { | ||||
|         if (!indicator.menu || indicator.menu.hasOwnProperty('_openChangedId')) | ||||
|         if (!indicator.menu || indicator.menu._openChangedId > 0) | ||||
|             return; | ||||
|  | ||||
|         indicator.menu._openChangedId = indicator.menu.connect('open-state-changed', | ||||
|   | ||||
| @@ -2,6 +2,8 @@ | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Gtk = imports.gi.Gtk; | ||||
| const Gio = imports.gi.Gio; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Lang = imports.lang; | ||||
| const Shell = imports.gi.Shell; | ||||
| const Signals = imports.signals; | ||||
| @@ -389,20 +391,24 @@ const PopupImageMenuItem = new Lang.Class({ | ||||
|     Name: 'PopupImageMenuItem', | ||||
|     Extends: PopupBaseMenuItem, | ||||
|  | ||||
|     _init: function (text, iconName, params) { | ||||
|     _init: function (text, icon, params) { | ||||
|         this.parent(params); | ||||
|  | ||||
|         this.label = new St.Label({ text: text }); | ||||
|         this.actor.add_child(this.label); | ||||
|         this._icon = new St.Icon({ style_class: 'popup-menu-icon' }); | ||||
|         this.actor.add_child(this._icon, { align: St.Align.END }); | ||||
|         this.label = new St.Label({ text: text }); | ||||
|         this.actor.add_child(this.label); | ||||
|         this.actor.label_actor = this.label; | ||||
|  | ||||
|         this.setIcon(iconName); | ||||
|         this.setIcon(icon); | ||||
|     }, | ||||
|  | ||||
|     setIcon: function(name) { | ||||
|         this._icon.icon_name = name; | ||||
|     setIcon: function(icon) { | ||||
|         // The 'icon' parameter can be either a Gio.Icon or a string. | ||||
|         if (GObject.type_is_a(icon, Gio.Icon)) | ||||
|             this._icon.gicon = icon; | ||||
|         else | ||||
|             this._icon.icon_name = icon; | ||||
|     } | ||||
| }); | ||||
|  | ||||
| @@ -461,8 +467,13 @@ const PopupMenuBase = new Lang.Class({ | ||||
|         this._setSettingsVisibility(Main.sessionMode.allowSettings); | ||||
|     }, | ||||
|  | ||||
|     addAction: function(title, callback) { | ||||
|         let menuItem = new PopupMenuItem(title); | ||||
|     addAction: function(title, callback, icon) { | ||||
|         let menuItem; | ||||
|         if (icon != undefined) | ||||
|             menuItem = new PopupImageMenuItem(title, icon); | ||||
|         else | ||||
|             menuItem = new PopupMenuItem(title); | ||||
|  | ||||
|         this.addMenuItem(menuItem); | ||||
|         menuItem.connect('activate', Lang.bind(this, function (menuItem, event) { | ||||
|             callback(event); | ||||
|   | ||||
| @@ -192,10 +192,6 @@ const RemoteMenu = new Lang.Class({ | ||||
|                                               _removeItem.bind(null, this)); | ||||
|     }, | ||||
|  | ||||
|     get actionGroup() { | ||||
|         return this._actionGroup; | ||||
|     }, | ||||
|  | ||||
|     destroy: function() { | ||||
|         this._tracker.destroy(); | ||||
|         this.parent(); | ||||
|   | ||||
| @@ -200,7 +200,6 @@ const RemoteSearchProvider = new Lang.Class({ | ||||
|         this.appInfo = appInfo; | ||||
|         this.id = appInfo.get_id(); | ||||
|         this.isRemoteProvider = true; | ||||
|         this.canLaunchSearch = false; | ||||
|     }, | ||||
|  | ||||
|     createIcon: function(size, meta) { | ||||
|   | ||||
							
								
								
									
										175
									
								
								js/ui/search.js
									
									
									
									
									
								
							
							
						
						
									
										175
									
								
								js/ui/search.js
									
									
									
									
									
								
							| @@ -22,7 +22,7 @@ const Util = imports.misc.util; | ||||
|  | ||||
| const SEARCH_PROVIDERS_SCHEMA = 'org.gnome.desktop.search-providers'; | ||||
|  | ||||
| const MAX_LIST_SEARCH_RESULTS_ROWS = 3; | ||||
| const MAX_LIST_SEARCH_RESULTS_ROWS = 5; | ||||
| const MAX_GRID_SEARCH_RESULTS_ROWS = 1; | ||||
|  | ||||
| const MaxWidthBin = new Lang.Class({ | ||||
| @@ -48,9 +48,10 @@ const MaxWidthBin = new Lang.Class({ | ||||
| const SearchResult = new Lang.Class({ | ||||
|     Name: 'SearchResult', | ||||
|  | ||||
|     _init: function(provider, metaInfo) { | ||||
|     _init: function(provider, metaInfo, searchResultsView) { | ||||
|         this.provider = provider; | ||||
|         this.metaInfo = metaInfo; | ||||
|         this._searchResultsView = searchResultsView; | ||||
|  | ||||
|         this.actor = new St.Button({ reactive: true, | ||||
|                                      can_focus: true, | ||||
| @@ -72,10 +73,10 @@ const ListSearchResult = new Lang.Class({ | ||||
|     Name: 'ListSearchResult', | ||||
|     Extends: SearchResult, | ||||
|  | ||||
|     ICON_SIZE: 64, | ||||
|     ICON_SIZE: 24, | ||||
|  | ||||
|     _init: function(provider, metaInfo) { | ||||
|         this.parent(provider, metaInfo); | ||||
|     _init: function(provider, metaInfo, searchResultsView) { | ||||
|         this.parent(provider, metaInfo, searchResultsView); | ||||
|  | ||||
|         this.actor.style_class = 'list-search-result'; | ||||
|         this.actor.x_fill = true; | ||||
| @@ -90,7 +91,7 @@ const ListSearchResult = new Lang.Class({ | ||||
|             content.add(icon); | ||||
|         } | ||||
|  | ||||
|         let details = new St.BoxLayout({ vertical: true }); | ||||
|         let details = new St.BoxLayout({ vertical: false }); | ||||
|         content.add(details, { x_fill: true, | ||||
|                                y_fill: false, | ||||
|                                x_align: St.Align.START, | ||||
| @@ -101,17 +102,38 @@ const ListSearchResult = new Lang.Class({ | ||||
|         details.add(title, { x_fill: false, | ||||
|                              y_fill: false, | ||||
|                              x_align: St.Align.START, | ||||
|                              y_align: St.Align.START }); | ||||
|                              y_align: St.Align.MIDDLE }); | ||||
|         this.actor.label_actor = title; | ||||
|  | ||||
|         this._descriptionLabel = | ||||
|                         new St.Label({ | ||||
|                               style_class: 'list-search-result-description' }); | ||||
|  | ||||
|         if (this.metaInfo['description']) { | ||||
|             let description = new St.Label({ style_class: 'list-search-result-description' }); | ||||
|             description.clutter_text.set_markup(this.metaInfo['description']); | ||||
|             details.add(description, { x_fill: false, | ||||
|                                        y_fill: false, | ||||
|                                        x_align: St.Align.START, | ||||
|                                        y_align: St.Align.END }); | ||||
|             this._highlightTerms(); | ||||
|  | ||||
|             details.add(this._descriptionLabel, { x_fill: false, | ||||
|                                                   y_fill: false, | ||||
|                                                   x_align: St.Align.START, | ||||
|                                                   y_align: St.Align.MIDDLE }); | ||||
|         } | ||||
|  | ||||
|         this._termsChangedSignal = | ||||
|                     this._searchResultsView.connect( | ||||
|                                         'terms-changed', | ||||
|                                         Lang.bind(this, this._highlightTerms)); | ||||
|         this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); | ||||
|     }, | ||||
|  | ||||
|     _highlightTerms: function() { | ||||
|         if (!this.metaInfo['description'] || !this._descriptionLabel || !this._searchResultsView) | ||||
|             return; | ||||
|  | ||||
|         this._descriptionLabel.clutter_text.set_markup(this._searchResultsView.highlightTerms(this.metaInfo['description'])); | ||||
|     }, | ||||
|  | ||||
|     _onDestroy: function() { | ||||
|         this._searchResultsView.disconnect(this._termsChangedSignal); | ||||
|     } | ||||
| }); | ||||
|  | ||||
| @@ -119,8 +141,8 @@ const GridSearchResult = new Lang.Class({ | ||||
|     Name: 'GridSearchResult', | ||||
|     Extends: SearchResult, | ||||
|  | ||||
|     _init: function(provider, metaInfo) { | ||||
|         this.parent(provider, metaInfo); | ||||
|     _init: function(provider, metaInfo, searchResultsView) { | ||||
|         this.parent(provider, metaInfo, searchResultsView); | ||||
|  | ||||
|         this.actor.style_class = 'grid-search-result'; | ||||
|  | ||||
| @@ -135,8 +157,9 @@ const GridSearchResult = new Lang.Class({ | ||||
| const SearchResultsBase = new Lang.Class({ | ||||
|     Name: 'SearchResultsBase', | ||||
|  | ||||
|     _init: function(provider) { | ||||
|     _init: function(provider, searchResultsView) { | ||||
|         this.provider = provider; | ||||
|         this._searchResultsView = searchResultsView; | ||||
|  | ||||
|         this._terms = []; | ||||
|  | ||||
| @@ -147,8 +170,8 @@ const SearchResultsBase = new Lang.Class({ | ||||
|                                               y_fill: true }); | ||||
|         this.actor.add(this._resultDisplayBin, { expand: true }); | ||||
|  | ||||
|         let separator = new Separator.HorizontalSeparator({ style_class: 'search-section-separator' }); | ||||
|         this.actor.add(separator.actor); | ||||
|         let separator = new St.DrawingArea({ style_class: 'search-section-separator' }); | ||||
|         this.actor.add(separator); | ||||
|  | ||||
|         this._resultDisplays = {}; | ||||
|  | ||||
| @@ -164,7 +187,8 @@ const SearchResultsBase = new Lang.Class({ | ||||
|  | ||||
|     _createResultDisplay: function(meta) { | ||||
|         if (this.provider.createResultObject) | ||||
|             return this.provider.createResultObject(meta); | ||||
|             return this.provider.createResultObject(meta, | ||||
|                                                     this._searchResultsView); | ||||
|  | ||||
|         return null; | ||||
|     }, | ||||
| @@ -188,7 +212,7 @@ const SearchResultsBase = new Lang.Class({ | ||||
|         Main.overview.toggle(); | ||||
|     }, | ||||
|  | ||||
|     _setMoreIconVisible: function(visible) { | ||||
|     _setMoreLabelVisible: function(visible, moreNumber) { | ||||
|     }, | ||||
|  | ||||
|     _ensureResultActors: function(results, callback) { | ||||
| @@ -231,7 +255,6 @@ const SearchResultsBase = new Lang.Class({ | ||||
|  | ||||
|     updateSearch: function(providerResults, terms, callback) { | ||||
|         this._terms = terms; | ||||
|  | ||||
|         if (providerResults.length == 0) { | ||||
|             this._clearResultDisplay(); | ||||
|             this.actor.hide(); | ||||
| @@ -256,7 +279,8 @@ const SearchResultsBase = new Lang.Class({ | ||||
|                 results.forEach(Lang.bind(this, function(resultId) { | ||||
|                     this._addItem(this._resultDisplays[resultId]); | ||||
|                 })); | ||||
|                 this._setMoreIconVisible(hasMoreResults && this.provider.canLaunchSearch); | ||||
|                 this._setMoreLabelVisible(hasMoreResults && this.provider.canLaunchSearch, | ||||
|                                           providerResults.length - results.length); | ||||
|                 this.actor.show(); | ||||
|                 callback(); | ||||
|             })); | ||||
| @@ -268,20 +292,20 @@ const ListSearchResults = new Lang.Class({ | ||||
|     Name: 'ListSearchResults', | ||||
|     Extends: SearchResultsBase, | ||||
|  | ||||
|     _init: function(provider) { | ||||
|         this.parent(provider); | ||||
|     _init: function(provider, searchResultsView) { | ||||
|         this.parent(provider, searchResultsView); | ||||
|  | ||||
|         this._container = new St.BoxLayout({ style_class: 'search-section-content' }); | ||||
|         this.providerIcon = new ProviderIcon(provider); | ||||
|         this.providerIcon.connect('key-focus-in', Lang.bind(this, this._keyFocusIn)); | ||||
|         this.providerIcon.connect('clicked', Lang.bind(this, | ||||
|         this.providerInfo = new ProviderInfo(provider); | ||||
|         this.providerInfo.connect('key-focus-in', Lang.bind(this, this._keyFocusIn)); | ||||
|         this.providerInfo.connect('clicked', Lang.bind(this, | ||||
|             function() { | ||||
|                 this.providerIcon.animateLaunch(); | ||||
|                 this.providerInfo.animateLaunch(); | ||||
|                 provider.launchSearch(this._terms); | ||||
|                 Main.overview.toggle(); | ||||
|             })); | ||||
|  | ||||
|         this._container.add(this.providerIcon, { x_fill: false, | ||||
|         this._container.add(this.providerInfo, { x_fill: false, | ||||
|                                                  y_fill: false, | ||||
|                                                  x_align: St.Align.START, | ||||
|                                                  y_align: St.Align.START }); | ||||
| @@ -293,8 +317,8 @@ const ListSearchResults = new Lang.Class({ | ||||
|         this._resultDisplayBin.set_child(this._container); | ||||
|     }, | ||||
|  | ||||
|     _setMoreIconVisible: function(visible) { | ||||
|         this.providerIcon.moreIcon.visible = visible; | ||||
|     _setMoreLabelVisible: function(visible, moreNumber) { | ||||
|         this.providerInfo.setMoreVisible(visible, moreNumber); | ||||
|     }, | ||||
|  | ||||
|     _getMaxDisplayedResults: function() { | ||||
| @@ -306,7 +330,8 @@ const ListSearchResults = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     _createResultDisplay: function(meta) { | ||||
|         return this.parent(meta) || new ListSearchResult(this.provider, meta); | ||||
|         return this.parent(meta, this._searchResultsView) || | ||||
|             new ListSearchResult(this.provider, meta, this._searchResultsView); | ||||
|     }, | ||||
|  | ||||
|     _addItem: function(display) { | ||||
| @@ -326,14 +351,14 @@ const GridSearchResults = new Lang.Class({ | ||||
|     Name: 'GridSearchResults', | ||||
|     Extends: SearchResultsBase, | ||||
|  | ||||
|     _init: function(provider, parentContainer) { | ||||
|         this.parent(provider); | ||||
|     _init: function(provider, searchResultsView) { | ||||
|         this.parent(provider, searchResultsView); | ||||
|         // We need to use the parent container to know how much results we can show. | ||||
|         // None of the actors in this class can be used for that, since the main actor | ||||
|         // goes hidden when no results are displayed, and then it lost its allocation. | ||||
|         // Then on the next use of _getMaxDisplayedResults allocation is 0, en therefore | ||||
|         // it doesn't show any result although we have some. | ||||
|         this._parentContainer = parentContainer; | ||||
|         this._parentContainer = searchResultsView.actor; | ||||
|  | ||||
|         this._grid = new IconGrid.IconGrid({ rowLimit: MAX_GRID_SEARCH_RESULTS_ROWS, | ||||
|                                              xAlign: St.Align.START }); | ||||
| @@ -354,7 +379,8 @@ const GridSearchResults = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     _createResultDisplay: function(meta) { | ||||
|         return this.parent(meta) || new GridSearchResult(this.provider, meta); | ||||
|         return this.parent(meta, this._searchResultsView) || | ||||
|             new GridSearchResult(this.provider, meta, this._searchResultsView); | ||||
|     }, | ||||
|  | ||||
|     _addItem: function(display) { | ||||
| @@ -418,6 +444,8 @@ const SearchResults = new Lang.Class({ | ||||
|  | ||||
|         this._providers = []; | ||||
|  | ||||
|         this._searchTermRegex = null; | ||||
|  | ||||
|         this._searchSettings = new Gio.Settings({ schema_id: SEARCH_PROVIDERS_SCHEMA }); | ||||
|         this._searchSettings.connect('changed::disabled', Lang.bind(this, this._reloadRemoteProviders)); | ||||
|         this._searchSettings.connect('changed::enabled', Lang.bind(this, this._reloadRemoteProviders)); | ||||
| @@ -537,6 +565,14 @@ const SearchResults = new Lang.Class({ | ||||
|  | ||||
|         if (this._searchTimeoutId == 0) | ||||
|             this._searchTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 150, Lang.bind(this, this._onSearchTimeout)); | ||||
|  | ||||
|         let escapedSearchTerms = this._terms.map( | ||||
|                     (currentTerm, index, array) => | ||||
|                             { return Shell.util_regex_escape(currentTerm) }); | ||||
|  | ||||
|         this._searchTermRegex = | ||||
|                         new RegExp(`(${escapedSearchTerms.join('|')})`, 'gi'); | ||||
|         this.emit('terms-changed'); | ||||
|     }, | ||||
|  | ||||
|     _onPan: function(action) { | ||||
| @@ -556,9 +592,9 @@ const SearchResults = new Lang.Class({ | ||||
|  | ||||
|         let providerDisplay; | ||||
|         if (provider.appInfo) | ||||
|             providerDisplay = new ListSearchResults(provider); | ||||
|             providerDisplay = new ListSearchResults(provider, this); | ||||
|         else | ||||
|             providerDisplay = new GridSearchResults(provider, this.actor); | ||||
|             providerDisplay = new GridSearchResults(provider, this); | ||||
|  | ||||
|         providerDisplay.connect('key-focus-in', Lang.bind(this, this._keyFocusIn)); | ||||
|         providerDisplay.actor.hide(); | ||||
| @@ -675,14 +711,22 @@ const SearchResults = new Lang.Class({ | ||||
|         } else { | ||||
|             result.actor.remove_style_pseudo_class('selected'); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     highlightTerms: function(description) { | ||||
|         if (!description) | ||||
|             return ''; | ||||
|  | ||||
|         return description.replace(this._searchTermRegex, '<b>$1</b>'); | ||||
|     } | ||||
| }); | ||||
| Signals.addSignalMethods(SearchResults.prototype); | ||||
|  | ||||
| const ProviderIcon = new Lang.Class({ | ||||
|     Name: 'ProviderIcon', | ||||
| const ProviderInfo = new Lang.Class({ | ||||
|     Name: 'ProviderInfo', | ||||
|     Extends: St.Button, | ||||
|  | ||||
|     PROVIDER_ICON_SIZE: 48, | ||||
|     PROVIDER_ICON_SIZE: 32, | ||||
|  | ||||
|     _init: function(provider) { | ||||
|         this.provider = provider; | ||||
| @@ -692,22 +736,45 @@ const ProviderIcon = new Lang.Class({ | ||||
|                       accessible_name: provider.appInfo.get_name(), | ||||
|                       track_hover: true }); | ||||
|  | ||||
|         this._content = new St.Widget({ layout_manager: new Clutter.BinLayout() }); | ||||
|         this._content = new St.BoxLayout({ vertical: false }); | ||||
|         this.set_child(this._content); | ||||
|  | ||||
|         let rtl = (this.get_text_direction() == Clutter.TextDirection.RTL); | ||||
|  | ||||
|         this.moreIcon = new St.Widget({ style_class: 'search-provider-icon-more', | ||||
|                                         visible: false, | ||||
|                                         x_align: rtl ? Clutter.ActorAlign.START : Clutter.ActorAlign.END, | ||||
|                                         y_align: Clutter.ActorAlign.END, | ||||
|                                         x_expand: true, | ||||
|                                         y_expand: true }); | ||||
|  | ||||
|         let icon = new St.Icon({ icon_size: this.PROVIDER_ICON_SIZE, | ||||
|                                  gicon: provider.appInfo.get_icon() }); | ||||
|         this._content.add_actor(icon); | ||||
|         this._content.add_actor(this.moreIcon); | ||||
|  | ||||
|         this._providerDetails = new St.BoxLayout({ | ||||
|                                     style_class: 'list-search-provider-details', | ||||
|                                     vertical: true }); | ||||
|  | ||||
|         let providerNameLabel = new St.Label({ | ||||
|                                     style_class: 'list-search-result-provider', | ||||
|                                     text: provider.appInfo.get_name() }); | ||||
|  | ||||
|         this._remainingResultsLabel = new St.Label({ | ||||
|                                     style_class: 'list-search-result-title' }); | ||||
|  | ||||
|         this._providerDetails.add(providerNameLabel, | ||||
|                                   { x_fill: false, | ||||
|                                     y_fill: false, | ||||
|                                     x_align: St.Align.START, | ||||
|                                     y_align: St.Align.START }); | ||||
|         this._providerDetails.add(this._remainingResultsLabel, | ||||
|                                   { x_fill: false, | ||||
|                                     y_fill: false, | ||||
|                                     x_align: St.Align.START, | ||||
|                                     y_align: St.Align.START }); | ||||
|  | ||||
|  | ||||
|         this._content.add(icon, { x_fill: false, | ||||
|                                   y_fill: false, | ||||
|                                   x_align: St.Align.START, | ||||
|                                   y_align: St.Align.MIDDLE }); | ||||
|         this._content.add(this._providerDetails, { x_fill: false, | ||||
|                                                    y_fill: false, | ||||
|                                                    x_align: St.Align.START, | ||||
|                                                    y_align: St.Align.START }); | ||||
|     }, | ||||
|  | ||||
|     animateLaunch: function() { | ||||
| @@ -715,5 +782,11 @@ const ProviderIcon = new Lang.Class({ | ||||
|         let app = appSys.lookup_app(this.provider.appInfo.get_id()); | ||||
|         if (app.state == Shell.AppState.STOPPED) | ||||
|             IconGrid.zoomOutActor(this._content); | ||||
|     }, | ||||
|  | ||||
|     setMoreVisible: function(visible, resultsCount) { | ||||
|         this._remainingResultsLabel.visible = visible; | ||||
|         this._remainingResultsLabel.clutter_text.set_markup( | ||||
|                                             _("%d more").format(resultsCount)); | ||||
|     } | ||||
| }); | ||||
|   | ||||
| @@ -7,7 +7,6 @@ const Mainloop = imports.mainloop; | ||||
| const Signals = imports.signals; | ||||
|  | ||||
| const FileUtils = imports.misc.fileUtils; | ||||
| const Main = imports.ui.main; | ||||
| const Params = imports.misc.params; | ||||
|  | ||||
| const Config = imports.misc.config; | ||||
|   | ||||
| @@ -28,6 +28,9 @@ const GnomeShellIface = '<node> \ | ||||
| <method name="ShowMonitorLabels"> \ | ||||
|     <arg type="a{uv}" direction="in" name="params" /> \ | ||||
| </method> \ | ||||
| <method name="ShowMonitorLabels2"> \ | ||||
|     <arg type="a{sv}" direction="in" name="params" /> \ | ||||
| </method> \ | ||||
| <method name="HideMonitorLabels" /> \ | ||||
| <method name="FocusApp"> \ | ||||
|     <arg type="s" direction="in" name="id"/> \ | ||||
| @@ -142,15 +145,15 @@ const GnomeShell = new Lang.Class({ | ||||
|         for (let param in params) | ||||
|             params[param] = params[param].deep_unpack(); | ||||
|  | ||||
|         let monitorIndex = params['monitor'] || -1; | ||||
|         let label = params['label'] || undefined; | ||||
|         let level = params['level'] || undefined; | ||||
|         let monitorIndex = -1; | ||||
|         if (params['monitor'] >= 0) | ||||
|             monitorIndex = params['monitor']; | ||||
|  | ||||
|         let icon = null; | ||||
|         if (params['icon']) | ||||
|             icon = Gio.Icon.new_for_string(params['icon']); | ||||
|  | ||||
|         Main.osdWindowManager.show(monitorIndex, icon, label, level); | ||||
|         Main.osdWindowManager.show(monitorIndex, icon, params['label'], params['level']); | ||||
|     }, | ||||
|  | ||||
|     FocusApp: function(id) { | ||||
| @@ -250,6 +253,12 @@ const GnomeShell = new Lang.Class({ | ||||
|         Main.osdMonitorLabeler.show(sender, dict); | ||||
|     }, | ||||
|  | ||||
|     ShowMonitorLabels2Async: function(params, invocation) { | ||||
|         let sender = invocation.get_sender(); | ||||
|         let [dict] = params; | ||||
|         Main.osdMonitorLabeler.show2(sender, dict); | ||||
|     }, | ||||
|  | ||||
|     HideMonitorLabelsAsync: function(params, invocation) { | ||||
|         let sender = invocation.get_sender(); | ||||
|         Main.osdMonitorLabeler.hide(sender); | ||||
|   | ||||
| @@ -1709,7 +1709,6 @@ const NMApplet = new Lang.Class({ | ||||
|  | ||||
|         this._mainConnection = null; | ||||
|         this._mainConnectionIconChangedId = 0; | ||||
|         this._mainConnectionStateChangedId = 0; | ||||
|  | ||||
|         this._notification = null; | ||||
|  | ||||
|   | ||||
| @@ -42,15 +42,9 @@ const AltSwitcher = new Lang.Class({ | ||||
|     _init: function(standard, alternate) { | ||||
|         this._standard = standard; | ||||
|         this._standard.connect('notify::visible', Lang.bind(this, this._sync)); | ||||
|         if (this._standard instanceof St.Button) | ||||
|             this._standard.connect('clicked', | ||||
|                                    () => { this._clickAction.release(); }); | ||||
|  | ||||
|         this._alternate = alternate; | ||||
|         this._alternate.connect('notify::visible', Lang.bind(this, this._sync)); | ||||
|         if (this._alternate instanceof St.Button) | ||||
|             this._alternate.connect('clicked', | ||||
|                                     () => { this._clickAction.release(); }); | ||||
|  | ||||
|         this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent)); | ||||
|  | ||||
|   | ||||
| @@ -385,7 +385,7 @@ const SwitcherList = new Lang.Class({ | ||||
|  | ||||
|         let n = this._items.length; | ||||
|         bbox.connect('clicked', Lang.bind(this, function() { this._onItemClicked(n); })); | ||||
|         bbox.connect('enter-event', Lang.bind(this, function() { this._onItemEnter(n); })); | ||||
|         bbox.connect('motion-event', Lang.bind(this, function() { return this._onItemEnter(n); })); | ||||
|  | ||||
|         bbox.label_actor = label; | ||||
|  | ||||
| @@ -399,7 +399,11 @@ const SwitcherList = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     _onItemEnter: function (index) { | ||||
|         this._itemEntered(index); | ||||
|         // Avoid reentrancy | ||||
|         if (index != this._currentItemEntered) { | ||||
|             this._currentItemEntered = index; | ||||
|             this._itemEntered(index); | ||||
|         } | ||||
|         return Clutter.EVENT_PROPAGATE; | ||||
|     }, | ||||
|  | ||||
|   | ||||
| @@ -1313,15 +1313,13 @@ const WindowManager = new Lang.Class({ | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if ((whichChange == Meta.SizeChange.FULLSCREEN || | ||||
|              whichChange == Meta.SizeChange.UNFULLSCREEN) && | ||||
|             oldFrameRect.width > 0 && oldFrameRect.height > 0) | ||||
|             this._fullscreenAnimation(shellwm, actor, oldFrameRect, whichChange); | ||||
|         if (oldFrameRect.width > 0 && oldFrameRect.height > 0) | ||||
|             this._prepareAnimationInfo(shellwm, actor, oldFrameRect, whichChange); | ||||
|         else | ||||
|             shellwm.completed_size_change(actor); | ||||
|     }, | ||||
|  | ||||
|     _fullscreenAnimation: function(shellwm, actor, oldFrameRect, change) { | ||||
|     _prepareAnimationInfo: function(shellwm, actor, oldFrameRect, change) { | ||||
|         // Position a clone of the window on top of the old position, | ||||
|         // while actor updates are frozen. | ||||
|         let actorContent = Shell.util_get_content_for_window_actor(actor, oldFrameRect); | ||||
| @@ -1331,26 +1329,25 @@ const WindowManager = new Lang.Class({ | ||||
|         actorClone.set_size(oldFrameRect.width, oldFrameRect.height); | ||||
|         Main.uiGroup.add_actor(actorClone); | ||||
|  | ||||
|         let rect = change == Meta.SizeChange.FULLSCREEN ? oldFrameRect : null; | ||||
|  | ||||
|         if (this._clearFullscreenInfo(actor)) | ||||
|         if (this._clearAnimationInfo(actor)) | ||||
|             this._shellwm.completed_size_change(actor); | ||||
|  | ||||
|         actor.__fullscreenInfo = { clone: actorClone, | ||||
|                                    oldRect: rect }; | ||||
|         actor.__animationInfo = { clone: actorClone, | ||||
|                                   oldRect: oldFrameRect }; | ||||
|     }, | ||||
|  | ||||
|     _sizeChangedWindow: function(shellwm, actor) { | ||||
|         if (!actor.__fullscreenInfo) | ||||
|         if (!actor.__animationInfo) | ||||
|             return; | ||||
|         if (this._resizing.indexOf(actor) != -1) | ||||
|             return; | ||||
|  | ||||
|         let actorClone = actor.__fullscreenInfo.clone; | ||||
|         let actorClone = actor.__animationInfo.clone; | ||||
|         let targetRect = actor.meta_window.get_frame_rect(); | ||||
|         let sourceRect = actor.__animationInfo.oldRect; | ||||
|  | ||||
|         let scaleX = targetRect.width / actorClone.width; | ||||
|         let scaleY = targetRect.height / actorClone.height; | ||||
|         let scaleX = targetRect.width / sourceRect.width; | ||||
|         let scaleY = targetRect.height / sourceRect.height; | ||||
|  | ||||
|         this._resizing.push(actor); | ||||
|  | ||||
| @@ -1365,15 +1362,8 @@ const WindowManager = new Lang.Class({ | ||||
|                            transition: 'easeOutQuad' | ||||
|                          }); | ||||
|  | ||||
|         let monitor = Main.layoutManager.monitors[actor.meta_window.get_monitor()]; | ||||
|         let oldRect = actor.__fullscreenInfo.oldRect; | ||||
|         if (oldRect) { | ||||
|             actor.translation_x = oldRect.x - monitor.x; | ||||
|             actor.translation_y = oldRect.y - monitor.y; | ||||
|         } else { | ||||
|             actor.translation_x = -(targetRect.x - monitor.x); | ||||
|             actor.translation_y = -(targetRect.y - monitor.y); | ||||
|         } | ||||
|         actor.translation_x = -targetRect.x + sourceRect.x; | ||||
|         actor.translation_y = -targetRect.y + sourceRect.y; | ||||
|  | ||||
|         // Now set scale the actor to size it as the clone. | ||||
|         actor.scale_x = 1 / scaleX; | ||||
| @@ -1401,10 +1391,10 @@ const WindowManager = new Lang.Class({ | ||||
|         shellwm.completed_size_change(actor); | ||||
|     }, | ||||
|  | ||||
|     _clearFullscreenInfo: function(actor) { | ||||
|         if (actor.__fullscreenInfo) { | ||||
|             actor.__fullscreenInfo.clone.destroy(); | ||||
|             delete actor.__fullscreenInfo; | ||||
|     _clearAnimationInfo: function(actor) { | ||||
|         if (actor.__animationInfo) { | ||||
|             actor.__animationInfo.clone.destroy(); | ||||
|             delete actor.__animationInfo; | ||||
|             return true; | ||||
|         } | ||||
|         return false; | ||||
| @@ -1417,13 +1407,13 @@ const WindowManager = new Lang.Class({ | ||||
|             actor.scale_y = 1.0; | ||||
|             actor.translation_x = 0; | ||||
|             actor.translation_y = 0; | ||||
|             this._clearFullscreenInfo(actor); | ||||
|             this._clearAnimationInfo(actor); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     _sizeChangeWindowOverwritten: function(shellwm, actor) { | ||||
|         if (this._removeEffect(this._resizing, actor)) | ||||
|             this._clearFullscreenInfo(actor); | ||||
|             this._clearAnimationInfo(actor); | ||||
|     }, | ||||
|  | ||||
|     _hasAttachedDialogs: function(window, ignoreWindow) { | ||||
| @@ -1614,7 +1604,7 @@ const WindowManager = new Lang.Class({ | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         switch (actor.meta_window.window_type) { | ||||
|         switch (actor._windowType) { | ||||
|         case Meta.WindowType.NORMAL: | ||||
|             actor.set_pivot_point(0.5, 0.5); | ||||
|             this._destroying.push(actor); | ||||
|   | ||||
| @@ -1100,7 +1100,6 @@ const Workspace = new Lang.Class({ | ||||
|     _init : function(metaWorkspace, monitorIndex) { | ||||
|         // When dragging a window, we use this slot for reserve space. | ||||
|         this._reservedSlot = null; | ||||
|         this._reservedSlotWindow = null; | ||||
|         this.metaWorkspace = metaWorkspace; | ||||
|  | ||||
|         // The full geometry is the geometry we should try and position | ||||
| @@ -1794,14 +1793,20 @@ const Workspace = new Lang.Class({ | ||||
|         global.screen.disconnect(this._windowEnteredMonitorId); | ||||
|         global.screen.disconnect(this._windowLeftMonitorId); | ||||
|  | ||||
|         if (this._repositionWindowsId > 0) | ||||
|         if (this._repositionWindowsId > 0) { | ||||
|             Mainloop.source_remove(this._repositionWindowsId); | ||||
|             this._repositionWindowsId = 0; | ||||
|         } | ||||
|  | ||||
|         if (this._positionWindowsId > 0) | ||||
|         if (this._positionWindowsId > 0) { | ||||
|             Meta.later_remove(this._positionWindowsId); | ||||
|             this._positionWindowsId = 0; | ||||
|         } | ||||
|  | ||||
|         if (this._actualGeometryLater > 0) | ||||
|         if (this._actualGeometryLater > 0) { | ||||
|             Meta.later_remove(this._actualGeometryLater); | ||||
|             this._actualGeometryLater = 0; | ||||
|         } | ||||
|  | ||||
|         this._windows = []; | ||||
|     }, | ||||
|   | ||||
							
								
								
									
										220
									
								
								po/da.po
									
									
									
									
									
								
							
							
						
						
									
										220
									
								
								po/da.po
									
									
									
									
									
								
							| @@ -21,8 +21,8 @@ msgstr "" | ||||
| "Project-Id-Version: gnome-shell\n" | ||||
| "Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" | ||||
| "shell&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2017-04-07 12:28+0000\n" | ||||
| "PO-Revision-Date: 2017-04-08 16:17+0200\n" | ||||
| "POT-Creation-Date: 2017-03-03 11:37+0000\n" | ||||
| "PO-Revision-Date: 2017-03-07 20:04+0200\n" | ||||
| "Last-Translator: Kris Thomsen\n" | ||||
| "Language-Team: Danish <dansk@dansk-gruppen.dk>\n" | ||||
| "Language: da\n" | ||||
| @@ -347,7 +347,7 @@ msgstr "Der opstod in fejl ved indlæsning af indstillingsdialogen for %s:" | ||||
| #: js/gdm/authPrompt.js:149 js/ui/audioDeviceSelection.js:71 | ||||
| #: js/ui/components/networkAgent.js:145 js/ui/components/polkitAgent.js:179 | ||||
| #: js/ui/endSessionDialog.js:482 js/ui/extensionDownloader.js:195 | ||||
| #: js/ui/shellMountOperation.js:399 js/ui/status/network.js:947 | ||||
| #: js/ui/shellMountOperation.js:399 js/ui/status/network.js:939 | ||||
| msgid "Cancel" | ||||
| msgstr "Annullér" | ||||
|  | ||||
| @@ -395,7 +395,7 @@ msgstr "Brugernavn: " | ||||
| msgid "Login Window" | ||||
| msgstr "Indlogningsvindue" | ||||
|  | ||||
| #: js/gdm/util.js:342 | ||||
| #: js/gdm/util.js:341 | ||||
| msgid "Authentication error" | ||||
| msgstr "Godkendelsesfejl" | ||||
|  | ||||
| @@ -404,7 +404,7 @@ msgstr "Godkendelsesfejl" | ||||
| #. as a cue to display our own message. | ||||
| #. Translators: this message is shown below the password entry field | ||||
| #. to indicate the user can swipe their finger instead | ||||
| #: js/gdm/util.js:474 | ||||
| #: js/gdm/util.js:473 | ||||
| msgid "(or swipe finger)" | ||||
| msgstr "(eller indlæs fingeraftryk)" | ||||
|  | ||||
| @@ -442,6 +442,7 @@ msgstr[0] "%d time siden" | ||||
| msgstr[1] "%d timer siden" | ||||
|  | ||||
| #: js/misc/util.js:188 | ||||
| #| msgid "Yesterday, %H∶%M" | ||||
| msgid "Yesterday" | ||||
| msgstr "I går" | ||||
|  | ||||
| @@ -461,6 +462,8 @@ msgstr[1] "%d uger siden" | ||||
|  | ||||
| #: js/misc/util.js:196 | ||||
| #, javascript-format | ||||
| #| msgid "%d minute ago" | ||||
| #| msgid_plural "%d minutes ago" | ||||
| msgid "%d month ago" | ||||
| msgid_plural "%d months ago" | ||||
| msgstr[0] "%d måned siden" | ||||
| @@ -468,6 +471,8 @@ msgstr[1] "%d måneder siden" | ||||
|  | ||||
| #: js/misc/util.js:198 | ||||
| #, javascript-format | ||||
| #| msgid "%d day ago" | ||||
| #| msgid_plural "%d days ago" | ||||
| msgid "%d year ago" | ||||
| msgid_plural "%d years ago" | ||||
| msgstr[0] "%d år siden" | ||||
| @@ -544,11 +549,11 @@ msgid "%B %d %Y, %l∶%M %p" | ||||
| msgstr "%d. %B %Y, %l∶%M %p" | ||||
|  | ||||
| #. TRANSLATORS: this is the title of the wifi captive portal login window | ||||
| #: js/portalHelper/main.js:66 | ||||
| #: js/portalHelper/main.js:67 | ||||
| msgid "Hotspot Login" | ||||
| msgstr "Hotspot-login" | ||||
|  | ||||
| #: js/portalHelper/main.js:112 | ||||
| #: js/portalHelper/main.js:113 | ||||
| msgid "" | ||||
| "Your connection to this hotspot login is not secure. Passwords or other " | ||||
| "information you enter on this page can be viewed by people nearby." | ||||
| @@ -558,11 +563,11 @@ msgstr "" | ||||
|  | ||||
| #. No support for non-modal system dialogs, so ignore the option | ||||
| #. let modal = options['modal'] || true; | ||||
| #: js/ui/accessDialog.js:62 js/ui/status/location.js:405 | ||||
| #: js/ui/accessDialog.js:62 js/ui/status/location.js:427 | ||||
| msgid "Deny Access" | ||||
| msgstr "Forbyd adgang" | ||||
|  | ||||
| #: js/ui/accessDialog.js:63 js/ui/status/location.js:408 | ||||
| #: js/ui/accessDialog.js:63 js/ui/status/location.js:430 | ||||
| msgid "Grant Access" | ||||
| msgstr "Giv adgang" | ||||
|  | ||||
| @@ -762,7 +767,7 @@ msgid "Type again:" | ||||
| msgstr "Indtast igen:" | ||||
|  | ||||
| #: js/ui/components/networkAgent.js:140 js/ui/status/network.js:272 | ||||
| #: js/ui/status/network.js:366 js/ui/status/network.js:950 | ||||
| #: js/ui/status/network.js:366 js/ui/status/network.js:942 | ||||
| msgid "Connect" | ||||
| msgstr "Forbind" | ||||
|  | ||||
| @@ -837,7 +842,7 @@ msgstr "Adgangskode til mobilt bredbåndsnetværk" | ||||
| msgid "A password is required to connect to “%s”." | ||||
| msgstr "Der kræves en adgangskode for at forbinde til “%s”." | ||||
|  | ||||
| #: js/ui/components/networkAgent.js:655 js/ui/status/network.js:1759 | ||||
| #: js/ui/components/networkAgent.js:655 js/ui/status/network.js:1747 | ||||
| msgid "Network Manager" | ||||
| msgstr "Netværkshåndtering" | ||||
|  | ||||
| @@ -863,12 +868,12 @@ msgstr "Beklager, det fungerede ikke. Prøv igen." | ||||
|  | ||||
| #. Translators: this is the other person changing their old IM name to their new | ||||
| #. IM name. | ||||
| #: js/ui/components/telepathyClient.js:799 | ||||
| #: js/ui/components/telepathyClient.js:767 | ||||
| #, javascript-format | ||||
| msgid "%s is now known as %s" | ||||
| msgstr "%s kalder sig nu %s" | ||||
|  | ||||
| #: js/ui/ctrlAltTab.js:29 js/ui/viewSelector.js:179 | ||||
| #: js/ui/ctrlAltTab.js:29 js/ui/viewSelector.js:178 | ||||
| msgid "Windows" | ||||
| msgstr "Vinduer" | ||||
|  | ||||
| @@ -937,24 +942,21 @@ msgid "%s, then %s, followed by %s later." | ||||
| msgstr "%s, derefter %s, efterfulgt af %s." | ||||
|  | ||||
| #: js/ui/dateMenu.js:300 | ||||
| msgid "Select a location…" | ||||
| msgstr "Vælg en placering …" | ||||
|  | ||||
| #: js/ui/dateMenu.js:303 | ||||
| #| msgid "Searching…" | ||||
| msgid "Loading…" | ||||
| msgstr "Indlæser …" | ||||
|  | ||||
| #. Translators: %s is a temperature with unit, e.g. "23℃" | ||||
| #: js/ui/dateMenu.js:309 | ||||
| #: js/ui/dateMenu.js:306 | ||||
| #, javascript-format | ||||
| msgid "Feels like %s." | ||||
| msgstr "Føles som %s." | ||||
|  | ||||
| #: js/ui/dateMenu.js:312 | ||||
| #: js/ui/dateMenu.js:309 | ||||
| msgid "Go online for weather information" | ||||
| msgstr "Gå online for at se information om vejret" | ||||
|  | ||||
| #: js/ui/dateMenu.js:314 | ||||
| #: js/ui/dateMenu.js:311 | ||||
| msgid "Weather information is currently unavailable" | ||||
| msgstr "Vejrinformation er ikke tilgængelig i øjeblikket" | ||||
|  | ||||
| @@ -1127,51 +1129,51 @@ msgstr "Skjul statusfelt" | ||||
| msgid "Status Icons" | ||||
| msgstr "Statusikoner" | ||||
|  | ||||
| #: js/ui/lookingGlass.js:642 | ||||
| #: js/ui/lookingGlass.js:643 | ||||
| msgid "No extensions installed" | ||||
| msgstr "Ingen udvidelser er installeret" | ||||
|  | ||||
| #. Translators: argument is an extension UUID. | ||||
| #: js/ui/lookingGlass.js:696 | ||||
| #: js/ui/lookingGlass.js:697 | ||||
| #, javascript-format | ||||
| msgid "%s has not emitted any errors." | ||||
| msgstr "%s er ikke kommet med nogen fejl." | ||||
|  | ||||
| #: js/ui/lookingGlass.js:702 | ||||
| #: js/ui/lookingGlass.js:703 | ||||
| msgid "Hide Errors" | ||||
| msgstr "Skjul fejl" | ||||
|  | ||||
| #: js/ui/lookingGlass.js:706 js/ui/lookingGlass.js:766 | ||||
| #: js/ui/lookingGlass.js:707 js/ui/lookingGlass.js:767 | ||||
| msgid "Show Errors" | ||||
| msgstr "Vis fejl" | ||||
|  | ||||
| #: js/ui/lookingGlass.js:715 | ||||
| #: js/ui/lookingGlass.js:716 | ||||
| msgid "Enabled" | ||||
| msgstr "Aktiveret" | ||||
|  | ||||
| #. translators: | ||||
| #. * The device has been disabled | ||||
| #: js/ui/lookingGlass.js:718 src/gvc/gvc-mixer-control.c:1866 | ||||
| #: js/ui/lookingGlass.js:719 src/gvc/gvc-mixer-control.c:1866 | ||||
| msgid "Disabled" | ||||
| msgstr "Deaktiveret" | ||||
|  | ||||
| #: js/ui/lookingGlass.js:720 | ||||
| #: js/ui/lookingGlass.js:721 | ||||
| msgid "Error" | ||||
| msgstr "Fejl" | ||||
|  | ||||
| #: js/ui/lookingGlass.js:722 | ||||
| #: js/ui/lookingGlass.js:723 | ||||
| msgid "Out of date" | ||||
| msgstr "Udløbet" | ||||
|  | ||||
| #: js/ui/lookingGlass.js:724 | ||||
| #: js/ui/lookingGlass.js:725 | ||||
| msgid "Downloading" | ||||
| msgstr "Henter" | ||||
|  | ||||
| #: js/ui/lookingGlass.js:748 | ||||
| #: js/ui/lookingGlass.js:749 | ||||
| msgid "View Source" | ||||
| msgstr "Vis kilde" | ||||
|  | ||||
| #: js/ui/lookingGlass.js:757 | ||||
| #: js/ui/lookingGlass.js:758 | ||||
| msgid "Web Page" | ||||
| msgstr "Webside" | ||||
|  | ||||
| @@ -1205,47 +1207,47 @@ msgstr "Oversigt" | ||||
| msgid "Type to search…" | ||||
| msgstr "Skriv for at søge …" | ||||
|  | ||||
| #: js/ui/padOsd.js:103 | ||||
| #: js/ui/padOsd.js:37 | ||||
| msgid "New shortcut…" | ||||
| msgstr "Ny genvej …" | ||||
|  | ||||
| #: js/ui/padOsd.js:152 | ||||
| #: js/ui/padOsd.js:86 | ||||
| msgid "Application defined" | ||||
| msgstr "Program defineret" | ||||
|  | ||||
| #: js/ui/padOsd.js:153 | ||||
| #: js/ui/padOsd.js:87 | ||||
| msgid "Show on-screen help" | ||||
| msgstr "Vis hjælp på skærmen" | ||||
|  | ||||
| #: js/ui/padOsd.js:154 | ||||
| #: js/ui/padOsd.js:88 | ||||
| msgid "Switch monitor" | ||||
| msgstr "Skift skærm" | ||||
|  | ||||
| #: js/ui/padOsd.js:155 | ||||
| #: js/ui/padOsd.js:89 | ||||
| msgid "Assign keystroke" | ||||
| msgstr "Tildel tastekombination" | ||||
|  | ||||
| #: js/ui/padOsd.js:209 | ||||
| #: js/ui/padOsd.js:143 | ||||
| msgid "Done" | ||||
| msgstr "Færdig" | ||||
|  | ||||
| #: js/ui/padOsd.js:698 | ||||
| #: js/ui/padOsd.js:597 | ||||
| msgid "Edit…" | ||||
| msgstr "Redigér …" | ||||
|  | ||||
| #: js/ui/padOsd.js:738 js/ui/padOsd.js:800 | ||||
| #: js/ui/padOsd.js:610 js/ui/padOsd.js:665 | ||||
| msgid "None" | ||||
| msgstr "Ingen" | ||||
|  | ||||
| #: js/ui/padOsd.js:783 | ||||
| #: js/ui/padOsd.js:648 | ||||
| msgid "Press a button to configure" | ||||
| msgstr "Tryk på en knap for at konfigurere" | ||||
|  | ||||
| #: js/ui/padOsd.js:784 | ||||
| #: js/ui/padOsd.js:649 | ||||
| msgid "Press Esc to exit" | ||||
| msgstr "Tryk Esc for at afslutte" | ||||
|  | ||||
| #: js/ui/padOsd.js:787 | ||||
| #: js/ui/padOsd.js:652 | ||||
| msgid "Press any key to exit" | ||||
| msgstr "Tryk en vilkårlig tast for at afslutte" | ||||
|  | ||||
| @@ -1281,7 +1283,7 @@ msgstr "toggle-switch-intl" | ||||
| msgid "Enter a Command" | ||||
| msgstr "Indtast en kommando" | ||||
|  | ||||
| #: js/ui/runDialog.js:111 js/ui/windowMenu.js:160 | ||||
| #: js/ui/runDialog.js:111 js/ui/windowMenu.js:162 | ||||
| msgid "Close" | ||||
| msgstr "Luk" | ||||
|  | ||||
| @@ -1295,29 +1297,29 @@ msgstr "Genstarter …" | ||||
|  | ||||
| #. Translators: This is a time format for a date in | ||||
| #. long format | ||||
| #: js/ui/screenShield.js:88 | ||||
| #: js/ui/screenShield.js:85 | ||||
| msgid "%A, %B %d" | ||||
| msgstr "%A, %d. %B" | ||||
|  | ||||
| #: js/ui/screenShield.js:147 | ||||
| #: js/ui/screenShield.js:144 | ||||
| #, javascript-format | ||||
| msgid "%d new message" | ||||
| msgid_plural "%d new messages" | ||||
| msgstr[0] "%d ny besked" | ||||
| msgstr[1] "%d nye beskeder" | ||||
|  | ||||
| #: js/ui/screenShield.js:149 | ||||
| #: js/ui/screenShield.js:146 | ||||
| #, javascript-format | ||||
| msgid "%d new notification" | ||||
| msgid_plural "%d new notifications" | ||||
| msgstr[0] "%d ny påmindelse" | ||||
| msgstr[1] "%d nye påmindelser" | ||||
|  | ||||
| #: js/ui/screenShield.js:452 js/ui/status/system.js:409 | ||||
| #: js/ui/screenShield.js:449 js/ui/status/system.js:409 | ||||
| msgid "Lock" | ||||
| msgstr "Lås" | ||||
|  | ||||
| #: js/ui/screenShield.js:715 | ||||
| #: js/ui/screenShield.js:707 | ||||
| msgid "GNOME needs to lock the screen" | ||||
| msgstr "GNOME er nødt til at låse skærmen" | ||||
|  | ||||
| @@ -1328,11 +1330,11 @@ msgstr "GNOME er nødt til at låse skærmen" | ||||
| #. | ||||
| #. XXX: another option is to kick the user into the gdm login | ||||
| #. screen, where we're not affected by grabs | ||||
| #: js/ui/screenShield.js:836 js/ui/screenShield.js:1308 | ||||
| #: js/ui/screenShield.js:828 js/ui/screenShield.js:1295 | ||||
| msgid "Unable to lock" | ||||
| msgstr "Kunne ikke låse" | ||||
|  | ||||
| #: js/ui/screenShield.js:837 js/ui/screenShield.js:1309 | ||||
| #: js/ui/screenShield.js:829 js/ui/screenShield.js:1296 | ||||
| msgid "Lock was blocked by an application" | ||||
| msgstr "Lås blev blokeret af et program" | ||||
|  | ||||
| @@ -1436,13 +1438,13 @@ msgstr "Slukket" | ||||
| msgid "On" | ||||
| msgstr "Tændt" | ||||
|  | ||||
| #: js/ui/status/bluetooth.js:142 js/ui/status/network.js:1310 | ||||
| #: js/ui/status/bluetooth.js:142 js/ui/status/network.js:1302 | ||||
| msgid "Turn On" | ||||
| msgstr "Tænd" | ||||
|  | ||||
| #: js/ui/status/bluetooth.js:142 js/ui/status/network.js:181 | ||||
| #: js/ui/status/network.js:367 js/ui/status/network.js:1310 | ||||
| #: js/ui/status/network.js:1429 js/ui/status/nightLight.js:47 | ||||
| #: js/ui/status/network.js:367 js/ui/status/network.js:1302 | ||||
| #: js/ui/status/network.js:1417 js/ui/status/nightLight.js:47 | ||||
| #: js/ui/status/rfkill.js:90 js/ui/status/rfkill.js:117 | ||||
| msgid "Turn Off" | ||||
| msgstr "Sluk" | ||||
| @@ -1455,37 +1457,37 @@ msgstr "Lysstyrke" | ||||
| msgid "Show Keyboard Layout" | ||||
| msgstr "Vis tastaturlayout" | ||||
|  | ||||
| #: js/ui/status/location.js:88 js/ui/status/location.js:196 | ||||
| #: js/ui/status/location.js:107 js/ui/status/location.js:215 | ||||
| msgid "Location Enabled" | ||||
| msgstr "Placering aktiveret" | ||||
|  | ||||
| #: js/ui/status/location.js:89 js/ui/status/location.js:197 | ||||
| #: js/ui/status/location.js:108 js/ui/status/location.js:216 | ||||
| msgid "Disable" | ||||
| msgstr "Slå fra" | ||||
|  | ||||
| #: js/ui/status/location.js:90 | ||||
| #: js/ui/status/location.js:109 | ||||
| msgid "Privacy Settings" | ||||
| msgstr "Indstillinger for privatliv" | ||||
|  | ||||
| #: js/ui/status/location.js:195 | ||||
| #: js/ui/status/location.js:214 | ||||
| msgid "Location In Use" | ||||
| msgstr "Placering i brug" | ||||
|  | ||||
| #: js/ui/status/location.js:199 | ||||
| #: js/ui/status/location.js:218 | ||||
| msgid "Location Disabled" | ||||
| msgstr "Placering deaktiveret" | ||||
|  | ||||
| #: js/ui/status/location.js:200 | ||||
| #: js/ui/status/location.js:219 | ||||
| msgid "Enable" | ||||
| msgstr "Slå til" | ||||
|  | ||||
| #. Translators: %s is an application name | ||||
| #: js/ui/status/location.js:414 | ||||
| #: js/ui/status/location.js:436 | ||||
| #, javascript-format | ||||
| msgid "Give %s access to your location?" | ||||
| msgstr "Giv %s adgang til din placering?" | ||||
|  | ||||
| #: js/ui/status/location.js:416 | ||||
| #: js/ui/status/location.js:438 | ||||
| msgid "Location access can be changed at any time from the privacy settings." | ||||
| msgstr "" | ||||
| "Placeringsadgang kan ændres når som helst via privatlivsindstillingerne." | ||||
| @@ -1495,7 +1497,7 @@ msgid "<unknown>" | ||||
| msgstr "<ukendt>" | ||||
|  | ||||
| #. Translators: %s is a network identifier | ||||
| #: js/ui/status/network.js:465 js/ui/status/network.js:1339 | ||||
| #: js/ui/status/network.js:465 js/ui/status/network.js:1331 | ||||
| #, javascript-format | ||||
| msgid "%s Off" | ||||
| msgstr "%s er slukket" | ||||
| @@ -1521,7 +1523,7 @@ msgid "%s Disconnecting" | ||||
| msgstr "%s frakobler" | ||||
|  | ||||
| #. Translators: %s is a network identifier | ||||
| #: js/ui/status/network.js:483 js/ui/status/network.js:1331 | ||||
| #: js/ui/status/network.js:483 js/ui/status/network.js:1323 | ||||
| #, javascript-format | ||||
| msgid "%s Connecting" | ||||
| msgstr "%s forbinder" | ||||
| @@ -1561,7 +1563,7 @@ msgid "Mobile Broadband Settings" | ||||
| msgstr "Indstillinger for mobilbredbånd" | ||||
|  | ||||
| #. Translators: %s is a network identifier | ||||
| #: js/ui/status/network.js:602 js/ui/status/network.js:1336 | ||||
| #: js/ui/status/network.js:602 js/ui/status/network.js:1328 | ||||
| #, javascript-format | ||||
| msgid "%s Hardware Disabled" | ||||
| msgstr "Hardwaren %s er deaktiveret" | ||||
| @@ -1577,122 +1579,122 @@ msgstr "%s er deaktiveret" | ||||
| msgid "Connect to Internet" | ||||
| msgstr "Forbind til internet" | ||||
|  | ||||
| #: js/ui/status/network.js:844 | ||||
| #: js/ui/status/network.js:836 | ||||
| msgid "Airplane Mode is On" | ||||
| msgstr "Flytilstand er slået til" | ||||
|  | ||||
| #: js/ui/status/network.js:845 | ||||
| #: js/ui/status/network.js:837 | ||||
| msgid "Wi-Fi is disabled when airplane mode is on." | ||||
| msgstr "Trådløs er deaktiveret når flytilstand er slået til." | ||||
|  | ||||
| #: js/ui/status/network.js:846 | ||||
| #: js/ui/status/network.js:838 | ||||
| msgid "Turn Off Airplane Mode" | ||||
| msgstr "Slå flytilstand fra" | ||||
|  | ||||
| #: js/ui/status/network.js:855 | ||||
| #: js/ui/status/network.js:847 | ||||
| msgid "Wi-Fi is Off" | ||||
| msgstr "Trådløs er slået fra" | ||||
|  | ||||
| #: js/ui/status/network.js:856 | ||||
| #: js/ui/status/network.js:848 | ||||
| msgid "Wi-Fi needs to be turned on in order to connect to a network." | ||||
| msgstr "Trådløs skal tændes for at kunne forbinde til et netværk." | ||||
|  | ||||
| #: js/ui/status/network.js:857 | ||||
| #: js/ui/status/network.js:849 | ||||
| msgid "Turn On Wi-Fi" | ||||
| msgstr "Slå trådløs til" | ||||
|  | ||||
| #: js/ui/status/network.js:882 | ||||
| #: js/ui/status/network.js:874 | ||||
| msgid "Wi-Fi Networks" | ||||
| msgstr "Trådløse netværk" | ||||
|  | ||||
| #: js/ui/status/network.js:884 | ||||
| #: js/ui/status/network.js:876 | ||||
| msgid "Select a network" | ||||
| msgstr "Vælg et netværk" | ||||
|  | ||||
| #: js/ui/status/network.js:914 | ||||
| #: js/ui/status/network.js:906 | ||||
| msgid "No Networks" | ||||
| msgstr "Ingen netværk" | ||||
|  | ||||
| #: js/ui/status/network.js:935 js/ui/status/rfkill.js:115 | ||||
| #: js/ui/status/network.js:927 js/ui/status/rfkill.js:115 | ||||
| msgid "Use hardware switch to turn off" | ||||
| msgstr "Brug hardwareknap til at slukke" | ||||
|  | ||||
| #: js/ui/status/network.js:1202 | ||||
| #: js/ui/status/network.js:1194 | ||||
| msgid "Select Network" | ||||
| msgstr "Vælg netværk" | ||||
|  | ||||
| #: js/ui/status/network.js:1208 | ||||
| #: js/ui/status/network.js:1200 | ||||
| msgid "Wi-Fi Settings" | ||||
| msgstr "Indstillinger for trådløs" | ||||
|  | ||||
| #. Translators: %s is a network identifier | ||||
| #: js/ui/status/network.js:1327 | ||||
| #: js/ui/status/network.js:1319 | ||||
| #, javascript-format | ||||
| msgid "%s Hotspot Active" | ||||
| msgstr "Hotspottet %s er aktivt" | ||||
|  | ||||
| #. Translators: %s is a network identifier | ||||
| #: js/ui/status/network.js:1342 | ||||
| #: js/ui/status/network.js:1334 | ||||
| #, javascript-format | ||||
| msgid "%s Not Connected" | ||||
| msgstr "%s er ikke forbundet" | ||||
|  | ||||
| #: js/ui/status/network.js:1446 | ||||
| #: js/ui/status/network.js:1434 | ||||
| msgid "connecting…" | ||||
| msgstr "forbinder …" | ||||
|  | ||||
| #. Translators: this is for network connections that require some kind of key or password | ||||
| #: js/ui/status/network.js:1449 | ||||
| #: js/ui/status/network.js:1437 | ||||
| msgid "authentication required" | ||||
| msgstr "godkendelse påkrævet" | ||||
|  | ||||
| #: js/ui/status/network.js:1451 | ||||
| #: js/ui/status/network.js:1439 | ||||
| msgid "connection failed" | ||||
| msgstr "forbindelse mislykkedes" | ||||
|  | ||||
| #: js/ui/status/network.js:1517 js/ui/status/network.js:1612 | ||||
| #: js/ui/status/network.js:1505 js/ui/status/network.js:1600 | ||||
| #: js/ui/status/rfkill.js:93 | ||||
| msgid "Network Settings" | ||||
| msgstr "Netværksindstillinger" | ||||
|  | ||||
| #: js/ui/status/network.js:1519 | ||||
| #: js/ui/status/network.js:1507 | ||||
| msgid "VPN Settings" | ||||
| msgstr "Indstillinger for VPN" | ||||
|  | ||||
| #: js/ui/status/network.js:1538 | ||||
| #: js/ui/status/network.js:1526 | ||||
| msgid "VPN" | ||||
| msgstr "VPN" | ||||
|  | ||||
| #: js/ui/status/network.js:1548 | ||||
| #: js/ui/status/network.js:1536 | ||||
| msgid "VPN Off" | ||||
| msgstr "VPN slukket" | ||||
|  | ||||
| #: js/ui/status/network.js:1643 | ||||
| #: js/ui/status/network.js:1631 | ||||
| #, javascript-format | ||||
| msgid "%s Wired Connection" | ||||
| msgid_plural "%s Wired Connections" | ||||
| msgstr[0] "%s kablet forbindelse" | ||||
| msgstr[1] "%s kablede forbindelser" | ||||
|  | ||||
| #: js/ui/status/network.js:1647 | ||||
| #: js/ui/status/network.js:1635 | ||||
| #, javascript-format | ||||
| msgid "%s Wi-Fi Connection" | ||||
| msgid_plural "%s Wi-Fi Connections" | ||||
| msgstr[0] "%s trådløs forbindelse" | ||||
| msgstr[1] "%s trådløse forbindelser" | ||||
|  | ||||
| #: js/ui/status/network.js:1651 | ||||
| #: js/ui/status/network.js:1639 | ||||
| #, javascript-format | ||||
| msgid "%s Modem Connection" | ||||
| msgid_plural "%s Modem Connections" | ||||
| msgstr[0] "%s modem-forbindelse" | ||||
| msgstr[1] "%s modem-forbindelser" | ||||
|  | ||||
| #: js/ui/status/network.js:1798 | ||||
| #: js/ui/status/network.js:1786 | ||||
| msgid "Connection failed" | ||||
| msgstr "Forbindelse mislykkedes" | ||||
|  | ||||
| #: js/ui/status/network.js:1799 | ||||
| #: js/ui/status/network.js:1787 | ||||
| msgid "Activation of network connection failed" | ||||
| msgstr "Aktivering af netværksforbindelse mislykkedes" | ||||
|  | ||||
| @@ -1790,11 +1792,11 @@ msgstr "Log ind som en anden bruger" | ||||
| msgid "Unlock Window" | ||||
| msgstr "Lås vindue op" | ||||
|  | ||||
| #: js/ui/viewSelector.js:183 | ||||
| #: js/ui/viewSelector.js:182 | ||||
| msgid "Applications" | ||||
| msgstr "Programmer" | ||||
|  | ||||
| #: js/ui/viewSelector.js:187 | ||||
| #: js/ui/viewSelector.js:186 | ||||
| msgid "Search" | ||||
| msgstr "Søg" | ||||
|  | ||||
| @@ -1803,22 +1805,22 @@ msgstr "Søg" | ||||
| msgid "“%s” is ready" | ||||
| msgstr "“%s” er klar" | ||||
|  | ||||
| #: js/ui/windowManager.js:84 | ||||
| #: js/ui/windowManager.js:83 | ||||
| msgid "Do you want to keep these display settings?" | ||||
| msgstr "Vil du beholde disse skærmindstillinger?" | ||||
|  | ||||
| #. Translators: this and the following message should be limited in lenght, | ||||
| #. to avoid ellipsizing the labels. | ||||
| #. | ||||
| #: js/ui/windowManager.js:103 | ||||
| #: js/ui/windowManager.js:102 | ||||
| msgid "Revert Settings" | ||||
| msgstr "Forkast indstillinger" | ||||
|  | ||||
| #: js/ui/windowManager.js:106 | ||||
| #: js/ui/windowManager.js:105 | ||||
| msgid "Keep Changes" | ||||
| msgstr "Behold ændringer" | ||||
|  | ||||
| #: js/ui/windowManager.js:124 | ||||
| #: js/ui/windowManager.js:123 | ||||
| #, javascript-format | ||||
| msgid "Settings changes will revert in %d second" | ||||
| msgid_plural "Settings changes will revert in %d seconds" | ||||
| @@ -1827,7 +1829,7 @@ msgstr[1] "Indstillingsændringer vil forkastes om %d sekunder" | ||||
|  | ||||
| #. Translators: This represents the size of a window. The first number is | ||||
| #. * the width of the window and the second is the height. | ||||
| #: js/ui/windowManager.js:679 | ||||
| #: js/ui/windowManager.js:678 | ||||
| #, javascript-format | ||||
| msgid "%d × %d" | ||||
| msgstr "%d × %d" | ||||
| @@ -1864,35 +1866,35 @@ msgstr "Altid øverst" | ||||
| msgid "Always on Visible Workspace" | ||||
| msgstr "Altid på synligt arbejdsområde" | ||||
|  | ||||
| #: js/ui/windowMenu.js:103 | ||||
| #: js/ui/windowMenu.js:105 | ||||
| msgid "Move to Workspace Left" | ||||
| msgstr "Flyt til venste arbejdsområde" | ||||
|  | ||||
| #: js/ui/windowMenu.js:108 | ||||
| #: js/ui/windowMenu.js:110 | ||||
| msgid "Move to Workspace Right" | ||||
| msgstr "Flyt til højre arbejdsområde" | ||||
|  | ||||
| #: js/ui/windowMenu.js:113 | ||||
| #: js/ui/windowMenu.js:115 | ||||
| msgid "Move to Workspace Up" | ||||
| msgstr "Flyt til arbejdsområdet ovenover" | ||||
|  | ||||
| #: js/ui/windowMenu.js:118 | ||||
| #: js/ui/windowMenu.js:120 | ||||
| msgid "Move to Workspace Down" | ||||
| msgstr "Flyt til arbejdsområdet nedenunder" | ||||
|  | ||||
| #: js/ui/windowMenu.js:134 | ||||
| #: js/ui/windowMenu.js:136 | ||||
| msgid "Move to Monitor Up" | ||||
| msgstr "Flyt til skærmen ovenover" | ||||
|  | ||||
| #: js/ui/windowMenu.js:140 | ||||
| #: js/ui/windowMenu.js:142 | ||||
| msgid "Move to Monitor Down" | ||||
| msgstr "Flyt til skærmen nedenunder" | ||||
|  | ||||
| #: js/ui/windowMenu.js:146 | ||||
| #: js/ui/windowMenu.js:148 | ||||
| msgid "Move to Monitor Left" | ||||
| msgstr "Flyt til venstre skærm" | ||||
|  | ||||
| #: js/ui/windowMenu.js:152 | ||||
| #: js/ui/windowMenu.js:154 | ||||
| msgid "Move to Monitor Right" | ||||
| msgstr "Flyt til højre skærm" | ||||
|  | ||||
| @@ -1927,19 +1929,19 @@ msgstr[1] "%u inputs" | ||||
| msgid "System Sounds" | ||||
| msgstr "Systemlyde" | ||||
|  | ||||
| #: src/main.c:372 | ||||
| #: src/main.c:381 | ||||
| msgid "Print version" | ||||
| msgstr "Udskriv version" | ||||
|  | ||||
| #: src/main.c:378 | ||||
| #: src/main.c:387 | ||||
| msgid "Mode used by GDM for login screen" | ||||
| msgstr "Tilstand brugt af GDM til indlogningskærm" | ||||
|  | ||||
| #: src/main.c:384 | ||||
| #: src/main.c:393 | ||||
| msgid "Use a specific mode, e.g. “gdm” for login screen" | ||||
| msgstr "Brug en specifik tilstand, f.eks. “gdm” til logind-skærm" | ||||
|  | ||||
| #: src/main.c:390 | ||||
| #: src/main.c:399 | ||||
| msgid "List possible modes" | ||||
| msgstr "Vis mulige tilstande" | ||||
|  | ||||
|   | ||||
							
								
								
									
										14
									
								
								po/es.po
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								po/es.po
									
									
									
									
									
								
							| @@ -1,10 +1,10 @@ | ||||
| # Spanish translation of gnome-shell. | ||||
| # Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER | ||||
| # This file is distributed under the same license as the gnome-shell package. | ||||
| # Jorge González <jorgegonz@svn.gnome.org>, 2009, 2010, 2011. | ||||
| # Benjamín Valero Espinosa <benjavalero@gmail.com>, 2011. | ||||
| #  | ||||
| # Daniel Mustieles <daniel.mustieles@gmail.com>, 2010-2017. | ||||
| # Spanish translation of gnome-shell. | ||||
| # Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER | ||||
| # This file is distributed under the same license as the gnome-shell package. | ||||
| # Jorge González <jorgegonz@svn.gnome.org>, 2009, 2010, 2011. | ||||
| # Benjamín Valero Espinosa <benjavalero@gmail.com>, 2011. | ||||
| #  | ||||
| # Daniel Mustieles <daniel.mustieles@gmail.com>, 2010, 2011, 2012, 2013, 2014, 2015. | ||||
| , 2016, 2017. | ||||
| # | ||||
| msgid "" | ||||
|   | ||||
							
								
								
									
										24
									
								
								po/he.po
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								po/he.po
									
									
									
									
									
								
							| @@ -1,10 +1,10 @@ | ||||
| # Hebrew translation for gnome-shell. | ||||
| # Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER | ||||
| # This file is distributed under the same license as the gnome-shell package. | ||||
| # liel <lielft@gmail.com>, 2009. | ||||
| # Yaron Shahrabani <sh.yaron@gmail.com>, 2010. | ||||
| #  | ||||
| # Yosef Or Boczko <yoseforb@gnome.org>, 2013, 2014. | ||||
| # Hebrew translation for gnome-shell. | ||||
| # Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER | ||||
| # This file is distributed under the same license as the gnome-shell package. | ||||
| # liel <lielft@gmail.com>, 2009. | ||||
| # Yaron Shahrabani <sh.yaron@gmail.com>, 2010. | ||||
| #  | ||||
| # Yosef Or Boczko <yoseforb@gnome.org>, 2013, 2014. | ||||
| , 2014. | ||||
| # | ||||
| msgid "" | ||||
| @@ -1095,7 +1095,7 @@ msgstr "מופעל מחדש…" | ||||
| #: js/ui/screenShield.js:85 | ||||
| msgid "%A, %B %d" | ||||
| msgstr "%A, ה־%d ב%B" | ||||
| # javascript-format | ||||
|  | ||||
| # javascript-format | ||||
| #: js/ui/screenShield.js:144 | ||||
| #, javascript-format | ||||
| @@ -1103,7 +1103,7 @@ msgid_plural "%d new messages" | ||||
| msgid_plural "%d new messages" | ||||
| msgstr[0] "הודעה חדשה אחת" | ||||
| msgstr[1] "%d הודעות חדשות" | ||||
| # javascript-format | ||||
|  | ||||
| # javascript-format | ||||
| #: js/ui/screenShield.js:146 | ||||
| #, javascript-format | ||||
| @@ -1577,7 +1577,7 @@ msgstr "שחזור הגדרות" | ||||
| #: js/ui/windowManager.js:85 | ||||
| msgid "Keep Changes" | ||||
| msgstr "שמירת שינויים" | ||||
| # javascript-format | ||||
|  | ||||
| # javascript-format | ||||
| #: js/ui/windowManager.js:103 | ||||
| #, javascript-format | ||||
| @@ -1728,7 +1728,7 @@ msgstr "המשתמש בחר להתעלם מתיבת דו־שיח האימות" | ||||
|  | ||||
| #~ msgid "System" | ||||
| #~ msgstr "מערכת" | ||||
| # javascript-format | ||||
|  | ||||
| # javascript-format | ||||
| #~ msgid "Show the notification list" | ||||
| #~ msgstr "הצגת רשימת ההתרעות" | ||||
| @@ -1759,7 +1759,7 @@ msgstr "המשתמש בחר להתעלם מתיבת דו־שיח האימות" | ||||
|  | ||||
| #~ msgid "GNOME Shell (wayland compositor)" | ||||
| #~ msgstr "GNOME Shell (מסדר wayland)" | ||||
| # javascript-format | ||||
|  | ||||
| # javascript-format | ||||
| #~ msgid "%d Connected Device" | ||||
| #~ msgid_plural "%d Connected Devices" | ||||
|   | ||||
| @@ -42,8 +42,7 @@ generated_script_substitutions = \ | ||||
| 	    -e "s|@pkgdatadir[@]|$(pkgdatadir)|g" \ | ||||
| 	    -e "s|@PYTHON[@]|$(PYTHON)|g" \ | ||||
| 	    -e "s|@VERSION[@]|$(VERSION)|g" \ | ||||
| 	    -e "s|@sysconfdir[@]|$(sysconfdir)|g" \ | ||||
| 	    -e "s|@GJS_CONSOLE[@]|$(GJS_CONSOLE)|g" | ||||
| 	    -e "s|@sysconfdir[@]|$(sysconfdir)|g" | ||||
|  | ||||
| gnome-shell-extension-tool: gnome-shell-extension-tool.in Makefile | ||||
| 	$(AM_V_GEN) sed $(generated_script_substitutions) $< > $@.tmp && mv $@.tmp $@ && chmod a+x $@ | ||||
| @@ -79,7 +78,6 @@ gnome_shell_cflags =				\ | ||||
|  | ||||
| privlibdir = $(pkglibdir) | ||||
| privlib_LTLIBRARIES = libgnome-shell-menu.la libgnome-shell.la | ||||
| noinst_LTLIBRARIES += libgnome-shell-base.la | ||||
|  | ||||
| shell_built_sources = \ | ||||
| 	org-gtk-application.h \ | ||||
| @@ -128,13 +126,22 @@ libgnome_shell_menu_la_SOURCES = 	\ | ||||
| 	gtkmenutracker.h		\ | ||||
| 	$(NULL) | ||||
|  | ||||
| libgnome_shell_base_la_SOURCES = 	\ | ||||
| libgnome_shell_sources =		\ | ||||
| 	$(shell_public_headers_h)	\ | ||||
| 	$(shell_private_sources)	\ | ||||
| 	gnome-shell-plugin.c		\ | ||||
| 	shell-app.c			\ | ||||
| 	shell-app-private.h		\ | ||||
| 	shell-app-system.c		\ | ||||
| 	shell-app-system-private.h	\ | ||||
| 	shell-app-usage.c		\ | ||||
| 	shell-embedded-window-private.h	\ | ||||
| 	shell-embedded-window.c		\ | ||||
| 	shell-generic-container.c	\ | ||||
| 	shell-global.c			\ | ||||
| 	shell-global-private.h		\ | ||||
| 	shell-glsl-quad.c		\ | ||||
| 	shell-gtk-embed.c		\ | ||||
| 	shell-invert-lightness-effect.c	\ | ||||
| 	shell-keyring-prompt.h		\ | ||||
| 	shell-keyring-prompt.c		\ | ||||
| @@ -144,36 +151,24 @@ libgnome_shell_base_la_SOURCES = 	\ | ||||
| 	shell-perf-log.c		\ | ||||
| 	shell-polkit-authentication-agent.h	\ | ||||
| 	shell-polkit-authentication-agent.c	\ | ||||
| 	shell-screenshot.c		\ | ||||
| 	shell-secure-text-buffer.c	\ | ||||
| 	shell-secure-text-buffer.h	\ | ||||
| 	shell-stack.c			\ | ||||
| 	$(NULL) | ||||
|  | ||||
| if HAVE_NETWORKMANAGER | ||||
| libgnome_shell_base_la_SOURCES +=  shell-network-agent.c | ||||
| endif | ||||
|  | ||||
| libgnome_shell_sources =		\ | ||||
| 	$(shell_public_headers_h)	\ | ||||
| 	shell-app-private.h		\ | ||||
| 	shell-app-system-private.h	\ | ||||
| 	shell-global-private.h		\ | ||||
| 	shell-window-tracker-private.h	\ | ||||
| 	shell-wm-private.h		\ | ||||
| 	gnome-shell-plugin.c		\ | ||||
| 	shell-app.c			\ | ||||
| 	shell-app-system.c		\ | ||||
| 	shell-app-usage.c		\ | ||||
| 	shell-global.c			\ | ||||
| 	shell-gtk-embed.c		\ | ||||
| 	shell-screenshot.c		\ | ||||
| 	shell-tray-icon.c		\ | ||||
| 	shell-tray-manager.c		\ | ||||
| 	shell-util.c			\ | ||||
| 	shell-window-tracker.c		\ | ||||
| 	shell-window-tracker-private.h	\ | ||||
| 	shell-wm.c			\ | ||||
| 	shell-wm-private.h		\ | ||||
| 	$(NULL) | ||||
|  | ||||
| if HAVE_NETWORKMANAGER | ||||
| libgnome_shell_sources +=  shell-network-agent.c | ||||
| endif | ||||
|  | ||||
|  | ||||
| libgnome_shell_built_sources =		\ | ||||
| 	$(shell_built_sources)		\ | ||||
| 	$(top_builddir)/js/js-resources.c		\ | ||||
| @@ -188,7 +183,7 @@ shell_no_gir_sources = \ | ||||
| 	org-gtk-application.c | ||||
|  | ||||
| libgnome_shell_la_gir_sources = \ | ||||
| 	$(filter-out %-private.h $(shell_private_sources) $(shell_no_gir_sources), $(shell_public_headers_h) $(libgnome_shell_base_la_SOURCES) $(libgnome_shell_sources) $(libgnome_shell_built_sources)) | ||||
| 	$(filter-out %-private.h $(shell_private_sources) $(shell_no_gir_sources), $(shell_public_headers_h) $(libgnome_shell_sources) $(libgnome_shell_built_sources)) | ||||
|  | ||||
| gnome_shell_SOURCES = main.c | ||||
| gnome_shell_CPPFLAGS = \ | ||||
| @@ -306,11 +301,8 @@ libgnome_shell_menu_la_LDFLAGS = $(libgnome_shell_ldflags) | ||||
| libgnome_shell_menu_la_LIBADD = $(GNOME_SHELL_LIBS) | ||||
| libgnome_shell_menu_la_CPPFLAGS = $(GNOME_SHELL_CFLAGS) | ||||
|  | ||||
| libgnome_shell_base_la_LIBADD = $(libgnome_shell_libadd) | ||||
| libgnome_shell_base_la_CPPFLAGS = $(gnome_shell_cflags) | ||||
|  | ||||
| libgnome_shell_la_LDFLAGS = $(libgnome_shell_ldflags) | ||||
| libgnome_shell_la_LIBADD = $(GNOME_SHELL_LIBS) $(MUTTER_LIBS) libgnome-shell-base.la | ||||
| libgnome_shell_la_LIBADD = $(GNOME_SHELL_LIBS) $(MUTTER_LIBS) $(libgnome_shell_libadd) | ||||
| libgnome_shell_la_CPPFLAGS = $(MUTTER_CFLAGS) $(gnome_shell_cflags) | ||||
|  | ||||
| ShellMenu-0.1.gir: libgnome-shell-menu.la | ||||
|   | ||||
| @@ -573,6 +573,7 @@ app_load_events (App *app) | ||||
|   gchar *since_iso8601; | ||||
|   gchar *until_iso8601; | ||||
|   gchar *query; | ||||
|   const char *tz_location; | ||||
|  | ||||
|   /* out with the old */ | ||||
|   g_hash_table_remove_all (app->appointments); | ||||
| @@ -594,15 +595,17 @@ app_load_events (App *app) | ||||
|  | ||||
|   since_iso8601 = isodate_from_time_t (app->since); | ||||
|   until_iso8601 = isodate_from_time_t (app->until); | ||||
|   tz_location = icaltimezone_get_location (app->zone); | ||||
|  | ||||
|   print_debug ("Loading events since %s until %s", | ||||
|                since_iso8601, | ||||
|                until_iso8601); | ||||
|  | ||||
|   query = g_strdup_printf ("occur-in-time-range? (make-time \"%s\") " | ||||
|                            "(make-time \"%s\")", | ||||
|                            "(make-time \"%s\") \"%s\"", | ||||
|                            since_iso8601, | ||||
|                            until_iso8601); | ||||
|                            until_iso8601, | ||||
|                            tz_location); | ||||
|  | ||||
|   clients = calendar_sources_get_appointment_clients (app->sources); | ||||
|   for (l = clients; l != NULL; l = l->next) | ||||
|   | ||||
| @@ -68,7 +68,6 @@ main(int argc, char **argv) | ||||
|   if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) | ||||
|     return 1; | ||||
|  | ||||
|   g_object_set (clutter_settings_get_default (), "window-scaling-factor", 1, NULL); | ||||
|   gdk_x11_display_set_window_scale (gdk_display_get_default (), 1); | ||||
|  | ||||
|   context = g_option_context_new (NULL); | ||||
|   | ||||
| @@ -22,10 +22,12 @@ | ||||
| #include <gdk/gdkx.h> | ||||
| #include <gio/gio.h> | ||||
| #include <girepository.h> | ||||
| #include <meta/meta-backend.h> | ||||
| #include <meta/display.h> | ||||
| #include <meta/util.h> | ||||
| #include <meta/meta-shaped-texture.h> | ||||
| #include <meta/meta-cursor-tracker.h> | ||||
| #include <meta/meta-settings.h> | ||||
|  | ||||
| #ifdef HAVE_SYSTEMD | ||||
| #include <systemd/sd-journal.h> | ||||
| @@ -833,35 +835,37 @@ global_stage_after_swap (gpointer data) | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void | ||||
| update_scale_factor (GtkSettings *settings, | ||||
|                      GParamSpec *pspec, | ||||
|                      gpointer data) | ||||
| update_scaling_factor (ShellGlobal  *global, | ||||
|                        MetaSettings *settings) | ||||
| { | ||||
|   ShellGlobal *global = SHELL_GLOBAL (data); | ||||
|   ClutterStage *stage = CLUTTER_STAGE (global->stage); | ||||
|   StThemeContext *context = st_theme_context_get_for_stage (stage); | ||||
|   GValue value = G_VALUE_INIT; | ||||
|   int scaling_factor; | ||||
|  | ||||
|   g_value_init (&value, G_TYPE_INT); | ||||
|   if (gdk_screen_get_setting (global->gdk_screen, "gdk-window-scaling-factor", &value)) | ||||
|   scaling_factor = meta_settings_get_ui_scaling_factor (settings); | ||||
|  | ||||
|   g_object_set (context, "scale-factor", scaling_factor, NULL); | ||||
|   if (meta_is_wayland_compositor ()) | ||||
|     { | ||||
|       g_object_set (context, "scale-factor", g_value_get_int (&value), NULL); | ||||
|       if (meta_is_wayland_compositor ()) | ||||
|         { | ||||
|           int xft_dpi; | ||||
|           g_object_get (settings, "gtk-xft-dpi", &xft_dpi, NULL); | ||||
|       GtkSettings *gtk_settings = gtk_settings_get_default (); | ||||
|       int xft_dpi; | ||||
|  | ||||
|           g_object_set (clutter_settings_get_default (), "font-dpi", xft_dpi, NULL); | ||||
|         } | ||||
|       g_object_get (gtk_settings, "gtk-xft-dpi", &xft_dpi, NULL); | ||||
|       g_object_set (clutter_settings_get_default (), "font-dpi", xft_dpi, NULL); | ||||
|     } | ||||
|  | ||||
|   /* Make sure clutter and gdk scaling stays disabled */ | ||||
|   g_object_set (clutter_settings_get_default (), "window-scaling-factor", 1, NULL); | ||||
|   gdk_x11_display_set_window_scale (gdk_display_get_default (), 1); | ||||
| } | ||||
|  | ||||
| static void | ||||
| ui_scaling_factor_changed (MetaSettings *settings, | ||||
|                            ShellGlobal  *global) | ||||
| { | ||||
|   update_scaling_factor (global, settings); | ||||
| } | ||||
|  | ||||
| /* This is an IBus workaround. The flow of events with IBus is that every time | ||||
|  * it gets gets a key event, it: | ||||
|  * | ||||
| @@ -965,6 +969,9 @@ void | ||||
| _shell_global_set_plugin (ShellGlobal *global, | ||||
|                           MetaPlugin  *plugin) | ||||
| { | ||||
|   MetaBackend *backend; | ||||
|   MetaSettings *settings; | ||||
|  | ||||
|   g_return_if_fail (SHELL_IS_GLOBAL (global)); | ||||
|   g_return_if_fail (global->plugin == NULL); | ||||
|  | ||||
| @@ -1045,18 +1052,16 @@ _shell_global_set_plugin (ShellGlobal *global, | ||||
|   g_signal_connect (global->meta_display, "notify::focus-window", | ||||
|                     G_CALLBACK (focus_window_changed), global); | ||||
|  | ||||
|   /* gdk-window-scaling-factor is not exported to gtk-settings | ||||
|    * because it is handled inside gdk, so we use gtk-xft-dpi instead | ||||
|    * which also changes when the scale factor changes. | ||||
|    */ | ||||
|   g_signal_connect (gtk_settings_get_default (), "notify::gtk-xft-dpi", | ||||
|                     G_CALLBACK (update_scale_factor), global); | ||||
|   backend = meta_get_backend (); | ||||
|   settings = meta_backend_get_settings (backend); | ||||
|   g_signal_connect (settings, "ui-scaling-factor-changed", | ||||
|                     G_CALLBACK (ui_scaling_factor_changed), global); | ||||
|  | ||||
|   gdk_event_handler_set (gnome_shell_gdk_event_handler, global, NULL); | ||||
|  | ||||
|   global->focus_manager = st_focus_manager_get_for_stage (global->stage); | ||||
|  | ||||
|   update_scale_factor (gtk_settings_get_default (), NULL, global); | ||||
|   update_scaling_factor (global, settings); | ||||
| } | ||||
|  | ||||
| GjsContext * | ||||
|   | ||||
| @@ -23,8 +23,6 @@ | ||||
| #include <string.h> | ||||
| #include <dbus/dbus-glib.h> | ||||
|  | ||||
| /* For use of unstable features in libsecret, until they stabilize */ | ||||
| #define SECRET_API_SUBJECT_TO_CHANGE | ||||
| #include <libsecret/secret.h> | ||||
|  | ||||
| #include "shell-network-agent.h" | ||||
|   | ||||
| @@ -240,6 +240,21 @@ shell_util_translate_time_string (const char *str) | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * shell_util_regex_escape: | ||||
|  * @str: a UTF-8 string to escape | ||||
|  * | ||||
|  * A wrapper around g_regex_escape_string() that takes its argument as | ||||
|  * \0-terminated string rather than a byte-array the confuses gjs. | ||||
|  * | ||||
|  * Returns: @str with all regex-special characters escaped | ||||
|  */ | ||||
| char * | ||||
| shell_util_regex_escape (const char *str) | ||||
| { | ||||
|   return g_regex_escape_string (str, -1); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * shell_write_string_to_stream: | ||||
|  * @stream: a #GOutputStream | ||||
|   | ||||
| @@ -24,6 +24,8 @@ char    *shell_util_format_date                (const char       *format, | ||||
|                                                 gint64            time_ms); | ||||
| const char *shell_util_translate_time_string   (const char *str); | ||||
|  | ||||
| char    *shell_util_regex_escape               (const char *str); | ||||
|  | ||||
| gboolean shell_write_string_to_stream          (GOutputStream    *stream, | ||||
|                                                 const char       *str, | ||||
|                                                 GError          **error); | ||||
|   | ||||
| @@ -34,7 +34,7 @@ | ||||
|  *   <para>focus: the widget has focus</para> | ||||
|  *  </listitem> | ||||
|  *  <listitem> | ||||
|  *   <para>indeterminate: the widget is showing the hint text</para> | ||||
|  *   <para>indeterminate: the widget is showing the hint text or actor</para> | ||||
|  *  </listitem> | ||||
|  * </itemizedlist> | ||||
|  */ | ||||
| @@ -56,6 +56,7 @@ | ||||
|  | ||||
| #include "st-im-text.h" | ||||
| #include "st-icon.h" | ||||
| #include "st-label.h" | ||||
| #include "st-widget.h" | ||||
| #include "st-texture-cache.h" | ||||
| #include "st-clipboard.h" | ||||
| @@ -72,7 +73,10 @@ enum | ||||
|   PROP_0, | ||||
|  | ||||
|   PROP_CLUTTER_TEXT, | ||||
|   PROP_PRIMARY_ICON, | ||||
|   PROP_SECONDARY_ICON, | ||||
|   PROP_HINT_TEXT, | ||||
|   PROP_HINT_ACTOR, | ||||
|   PROP_TEXT, | ||||
|   PROP_INPUT_PURPOSE, | ||||
|   PROP_INPUT_HINTS, | ||||
| @@ -94,16 +98,20 @@ typedef struct _StEntryPrivate StEntryPrivate; | ||||
| struct _StEntryPrivate | ||||
| { | ||||
|   ClutterActor *entry; | ||||
|   gchar        *hint; | ||||
|  | ||||
|   ClutterActor *primary_icon; | ||||
|   ClutterActor *secondary_icon; | ||||
|  | ||||
|   ClutterActor *hint_actor; | ||||
|  | ||||
|   gfloat        spacing; | ||||
|  | ||||
|   gboolean      hint_visible; | ||||
|   gboolean      capslock_warning_shown; | ||||
|   gboolean      has_ibeam; | ||||
|  | ||||
|   CoglHandle    text_shadow_material; | ||||
|   gfloat        shadow_width; | ||||
|   gfloat        shadow_height; | ||||
| }; | ||||
|  | ||||
| static guint entry_signals[LAST_SIGNAL] = { 0, }; | ||||
| @@ -122,10 +130,22 @@ st_entry_set_property (GObject      *gobject, | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_PRIMARY_ICON: | ||||
|       st_entry_set_primary_icon (entry, g_value_get_object (value)); | ||||
|       break; | ||||
|  | ||||
|     case PROP_SECONDARY_ICON: | ||||
|       st_entry_set_secondary_icon (entry, g_value_get_object (value)); | ||||
|       break; | ||||
|  | ||||
|     case PROP_HINT_TEXT: | ||||
|       st_entry_set_hint_text (entry, g_value_get_string (value)); | ||||
|       break; | ||||
|  | ||||
|     case PROP_HINT_ACTOR: | ||||
|       st_entry_set_hint_actor (entry, g_value_get_object (value)); | ||||
|       break; | ||||
|  | ||||
|     case PROP_TEXT: | ||||
|       st_entry_set_text (entry, g_value_get_string (value)); | ||||
|       break; | ||||
| @@ -158,8 +178,20 @@ st_entry_get_property (GObject    *gobject, | ||||
|       g_value_set_object (value, priv->entry); | ||||
|       break; | ||||
|  | ||||
|     case PROP_PRIMARY_ICON: | ||||
|       g_value_set_object (value, priv->primary_icon); | ||||
|       break; | ||||
|  | ||||
|     case PROP_SECONDARY_ICON: | ||||
|       g_value_set_object (value, priv->secondary_icon); | ||||
|       break; | ||||
|  | ||||
|     case PROP_HINT_TEXT: | ||||
|       g_value_set_string (value, priv->hint); | ||||
|       g_value_set_string (value, st_entry_get_hint_text (ST_ENTRY (gobject))); | ||||
|       break; | ||||
|  | ||||
|     case PROP_HINT_ACTOR: | ||||
|       g_value_set_object (value, priv->hint_actor); | ||||
|       break; | ||||
|  | ||||
|     case PROP_TEXT: | ||||
| @@ -230,10 +262,10 @@ st_entry_dispose (GObject *object) | ||||
|   StEntryPrivate *priv = ST_ENTRY_PRIV (entry); | ||||
|   GdkKeymap *keymap; | ||||
|  | ||||
|   if (priv->entry) | ||||
|   if (priv->text_shadow_material != COGL_INVALID_HANDLE) | ||||
|     { | ||||
|       clutter_actor_destroy (priv->entry); | ||||
|       priv->entry = NULL; | ||||
|       cogl_handle_unref (priv->text_shadow_material); | ||||
|       priv->text_shadow_material = COGL_INVALID_HANDLE; | ||||
|     } | ||||
|  | ||||
|   keymap = gdk_keymap_get_for_display (gdk_display_get_default ()); | ||||
| @@ -243,14 +275,21 @@ st_entry_dispose (GObject *object) | ||||
| } | ||||
|  | ||||
| static void | ||||
| st_entry_finalize (GObject *object) | ||||
| st_entry_update_hint_visibility (StEntry *self) | ||||
| { | ||||
|   StEntryPrivate *priv = ST_ENTRY_PRIV (object); | ||||
|   StEntryPrivate *priv = ST_ENTRY_PRIV (self); | ||||
|   gboolean hint_visible = | ||||
|     priv->hint_actor != NULL && | ||||
|     strcmp (clutter_text_get_text (CLUTTER_TEXT (priv->entry)), "") == 0 && | ||||
|     !HAS_FOCUS (priv->entry); | ||||
|  | ||||
|   g_free (priv->hint); | ||||
|   priv->hint = NULL; | ||||
|   if (priv->hint_actor) | ||||
|     g_object_set (priv->hint_actor, "visible", hint_visible, NULL); | ||||
|  | ||||
|   G_OBJECT_CLASS (st_entry_parent_class)->finalize (object); | ||||
|   if (hint_visible) | ||||
|     st_widget_add_style_pseudo_class (ST_WIDGET (self), "indeterminate"); | ||||
|   else | ||||
|     st_widget_remove_style_pseudo_class (ST_WIDGET (self), "indeterminate"); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -263,6 +302,12 @@ st_entry_style_changed (StWidget *self) | ||||
|   gchar *font_string, *font_name; | ||||
|   gdouble size; | ||||
|  | ||||
|   if (priv->text_shadow_material != COGL_INVALID_HANDLE) | ||||
|     { | ||||
|       cogl_handle_unref (priv->text_shadow_material); | ||||
|       priv->text_shadow_material = COGL_INVALID_HANDLE; | ||||
|     } | ||||
|  | ||||
|   theme_node = st_widget_get_theme_node (self); | ||||
|   | ||||
|   st_theme_node_get_foreground_color (theme_node, &color); | ||||
| @@ -324,7 +369,7 @@ st_entry_get_preferred_width (ClutterActor *actor, | ||||
| { | ||||
|   StEntryPrivate *priv = ST_ENTRY_PRIV (actor); | ||||
|   StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor)); | ||||
|   gfloat icon_w; | ||||
|   gfloat hint_w, icon_w; | ||||
|  | ||||
|   st_theme_node_adjust_for_height (theme_node, &for_height); | ||||
|  | ||||
| @@ -332,6 +377,17 @@ st_entry_get_preferred_width (ClutterActor *actor, | ||||
|                                      min_width_p, | ||||
|                                      natural_width_p); | ||||
|  | ||||
|   if (priv->hint_actor) | ||||
|     { | ||||
|       clutter_actor_get_preferred_width (priv->hint_actor, -1, NULL, &hint_w); | ||||
|  | ||||
|       if (min_width_p && hint_w > *min_width_p) | ||||
|         *min_width_p = hint_w; | ||||
|  | ||||
|       if (natural_width_p && hint_w > *natural_width_p) | ||||
|         *natural_width_p = hint_w; | ||||
|     } | ||||
|  | ||||
|   if (priv->primary_icon) | ||||
|     { | ||||
|       clutter_actor_get_preferred_width (priv->primary_icon, -1, NULL, &icon_w); | ||||
| @@ -366,7 +422,7 @@ st_entry_get_preferred_height (ClutterActor *actor, | ||||
| { | ||||
|   StEntryPrivate *priv = ST_ENTRY_PRIV (actor); | ||||
|   StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor)); | ||||
|   gfloat icon_h; | ||||
|   gfloat hint_h, icon_h; | ||||
|  | ||||
|   st_theme_node_adjust_for_width (theme_node, &for_width); | ||||
|  | ||||
| @@ -374,6 +430,17 @@ st_entry_get_preferred_height (ClutterActor *actor, | ||||
|                                       min_height_p, | ||||
|                                       natural_height_p); | ||||
|  | ||||
|   if (priv->hint_actor) | ||||
|     { | ||||
|       clutter_actor_get_preferred_height (priv->hint_actor, -1, NULL, &hint_h); | ||||
|  | ||||
|       if (min_height_p && hint_h > *min_height_p) | ||||
|         *min_height_p = hint_h; | ||||
|  | ||||
|       if (natural_height_p && hint_h > *natural_height_p) | ||||
|         *natural_height_p = hint_h; | ||||
|     } | ||||
|  | ||||
|   if (priv->primary_icon) | ||||
|     { | ||||
|       clutter_actor_get_preferred_height (priv->primary_icon, | ||||
| @@ -408,12 +475,16 @@ st_entry_allocate (ClutterActor          *actor, | ||||
| { | ||||
|   StEntryPrivate *priv = ST_ENTRY_PRIV (actor); | ||||
|   StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor)); | ||||
|   ClutterActorBox content_box, child_box, icon_box; | ||||
|   ClutterActorBox content_box, child_box, icon_box, hint_box; | ||||
|   gfloat icon_w, icon_h; | ||||
|   gfloat hint_w, hint_h; | ||||
|   gfloat entry_h, min_h, pref_h, avail_h; | ||||
|   ClutterActor *left_icon, *right_icon; | ||||
|   gboolean is_rtl; | ||||
|  | ||||
|   if (clutter_actor_get_text_direction (actor) == CLUTTER_TEXT_DIRECTION_RTL) | ||||
|   is_rtl = clutter_actor_get_text_direction (actor) == CLUTTER_TEXT_DIRECTION_RTL; | ||||
|  | ||||
|   if (is_rtl) | ||||
|     { | ||||
|       right_icon = priv->primary_icon; | ||||
|       left_icon = priv->secondary_icon; | ||||
| @@ -447,7 +518,7 @@ st_entry_allocate (ClutterActor          *actor, | ||||
|       clutter_actor_allocate (left_icon, &icon_box, flags); | ||||
|  | ||||
|       /* reduce the size for the entry */ | ||||
|       child_box.x1 += icon_w + priv->spacing; | ||||
|       child_box.x1 = MIN (child_box.x2, child_box.x1 + icon_w + priv->spacing); | ||||
|     } | ||||
|  | ||||
|   if (right_icon) | ||||
| @@ -464,7 +535,26 @@ st_entry_allocate (ClutterActor          *actor, | ||||
|       clutter_actor_allocate (right_icon, &icon_box, flags); | ||||
|  | ||||
|       /* reduce the size for the entry */ | ||||
|       child_box.x2 -= icon_w + priv->spacing; | ||||
|       child_box.x2 = MAX (child_box.x1, child_box.x2 - icon_w - priv->spacing); | ||||
|     } | ||||
|  | ||||
|   if (priv->hint_actor) | ||||
|     { | ||||
|       /* now allocate the hint actor */ | ||||
|       hint_box = child_box; | ||||
|  | ||||
|       clutter_actor_get_preferred_width (priv->hint_actor, -1, NULL, &hint_w); | ||||
|       clutter_actor_get_preferred_height (priv->hint_actor, -1, NULL, &hint_h); | ||||
|  | ||||
|       if (is_rtl) | ||||
|         hint_box.x1 = hint_box.x2 - hint_w; | ||||
|       else | ||||
|         hint_box.x2 = hint_box.x1 + hint_w; | ||||
|  | ||||
|       hint_box.y1 = ceil (content_box.y1 + avail_h / 2 - hint_h / 2); | ||||
|       hint_box.y2 = hint_box.y1 + hint_h; | ||||
|  | ||||
|       clutter_actor_allocate (priv->hint_actor, &hint_box, flags); | ||||
|     } | ||||
|  | ||||
|   clutter_actor_get_preferred_height (priv->entry, child_box.x2 - child_box.x1, | ||||
| @@ -483,23 +573,15 @@ clutter_text_focus_in_cb (ClutterText  *text, | ||||
|                           ClutterActor *actor) | ||||
| { | ||||
|   StEntry *entry = ST_ENTRY (actor); | ||||
|   StEntryPrivate *priv = ST_ENTRY_PRIV (entry); | ||||
|   GdkKeymap *keymap; | ||||
|  | ||||
|   /* remove the hint if visible */ | ||||
|   if (priv->hint && priv->hint_visible) | ||||
|     { | ||||
|       priv->hint_visible = FALSE; | ||||
|  | ||||
|       clutter_text_set_text (text, ""); | ||||
|     } | ||||
|   st_entry_update_hint_visibility (entry); | ||||
|  | ||||
|   keymap = gdk_keymap_get_for_display (gdk_display_get_default ()); | ||||
|   keymap_state_changed (keymap, entry); | ||||
|   g_signal_connect (keymap, "state-changed", | ||||
|                     G_CALLBACK (keymap_state_changed), entry); | ||||
|  | ||||
|   st_widget_remove_style_pseudo_class (ST_WIDGET (actor), "indeterminate"); | ||||
|   st_widget_add_style_pseudo_class (ST_WIDGET (actor), "focus"); | ||||
|   clutter_text_set_cursor_visible (text, TRUE); | ||||
| } | ||||
| @@ -509,19 +591,12 @@ clutter_text_focus_out_cb (ClutterText  *text, | ||||
|                            ClutterActor *actor) | ||||
| { | ||||
|   StEntry *entry = ST_ENTRY (actor); | ||||
|   StEntryPrivate *priv = ST_ENTRY_PRIV (entry); | ||||
|   GdkKeymap *keymap; | ||||
|  | ||||
|   st_widget_remove_style_pseudo_class (ST_WIDGET (actor), "focus"); | ||||
|  | ||||
|   /* add a hint if the entry is empty */ | ||||
|   if (priv->hint && !strcmp (clutter_text_get_text (text), "")) | ||||
|     { | ||||
|       priv->hint_visible = TRUE; | ||||
|   st_entry_update_hint_visibility (entry); | ||||
|  | ||||
|       clutter_text_set_text (text, priv->hint); | ||||
|       st_widget_add_style_pseudo_class (ST_WIDGET (actor), "indeterminate"); | ||||
|     } | ||||
|   clutter_text_set_cursor_visible (text, FALSE); | ||||
|   remove_capslock_feedback (entry); | ||||
|  | ||||
| @@ -541,6 +616,22 @@ clutter_text_password_char_cb (GObject    *object, | ||||
|     remove_capslock_feedback (entry); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_text_changed_cb (GObject    *object, | ||||
|                          GParamSpec *pspec, | ||||
|                          gpointer    user_data) | ||||
| { | ||||
|   StEntry *entry = ST_ENTRY (user_data); | ||||
|   StEntryPrivate *priv = ST_ENTRY_PRIV (entry); | ||||
|  | ||||
|   /* Since the text changed, force a regen of the shadow texture */ | ||||
|   if (priv->text_shadow_material != COGL_INVALID_HANDLE) | ||||
|     { | ||||
|       cogl_handle_unref (priv->text_shadow_material); | ||||
|       priv->text_shadow_material = COGL_INVALID_HANDLE; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| st_entry_clipboard_callback (StClipboard *clipboard, | ||||
|                              const gchar *text, | ||||
| @@ -707,8 +798,8 @@ st_entry_key_focus_in (ClutterActor *actor) | ||||
|   clutter_actor_grab_key_focus (priv->entry); | ||||
| } | ||||
|  | ||||
| static StEntryCursorFunc cursor_func; | ||||
| static gpointer          cursor_func_data; | ||||
| static StEntryCursorFunc cursor_func = NULL; | ||||
| static gpointer          cursor_func_data = NULL; | ||||
|  | ||||
| /** | ||||
|  * st_entry_set_cursor_func: (skip) | ||||
| @@ -728,7 +819,8 @@ static void | ||||
| st_entry_set_cursor (StEntry  *entry, | ||||
|                      gboolean  use_ibeam) | ||||
| { | ||||
|   cursor_func (entry, use_ibeam, cursor_func_data); | ||||
|   if (cursor_func) | ||||
|     cursor_func (entry, use_ibeam, cursor_func_data); | ||||
|  | ||||
|   ((StEntryPrivate *)ST_ENTRY_PRIV (entry))->has_ibeam = use_ibeam; | ||||
| } | ||||
| @@ -755,6 +847,56 @@ st_entry_leave_event (ClutterActor         *actor, | ||||
|   return CLUTTER_ACTOR_CLASS (st_entry_parent_class)->leave_event (actor, event); | ||||
| } | ||||
|  | ||||
| static void | ||||
| st_entry_paint (ClutterActor *actor) | ||||
| { | ||||
|   StEntryPrivate *priv = ST_ENTRY_PRIV (actor); | ||||
|   StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor)); | ||||
|   StShadow *shadow_spec = st_theme_node_get_text_shadow (theme_node); | ||||
|   ClutterActorClass *parent_class; | ||||
|  | ||||
|   st_widget_paint_background (ST_WIDGET (actor)); | ||||
|  | ||||
|   if (shadow_spec) | ||||
|     { | ||||
|       ClutterActorBox allocation; | ||||
|       float width, height; | ||||
|  | ||||
|       clutter_actor_get_allocation_box (priv->entry, &allocation); | ||||
|       clutter_actor_box_get_size (&allocation, &width, &height); | ||||
|  | ||||
|       if (priv->text_shadow_material == COGL_INVALID_HANDLE || | ||||
|           width != priv->shadow_width || | ||||
|           height != priv->shadow_height) | ||||
|         { | ||||
|           CoglHandle material; | ||||
|  | ||||
|           if (priv->text_shadow_material != COGL_INVALID_HANDLE) | ||||
|             cogl_handle_unref (priv->text_shadow_material); | ||||
|  | ||||
|           material = _st_create_shadow_pipeline_from_actor (shadow_spec, | ||||
|                                                             priv->entry); | ||||
|  | ||||
|           priv->shadow_width = width; | ||||
|           priv->shadow_height = height; | ||||
|           priv->text_shadow_material = material; | ||||
|         } | ||||
|  | ||||
|       if (priv->text_shadow_material != COGL_INVALID_HANDLE) | ||||
|         _st_paint_shadow_with_opacity (shadow_spec, | ||||
|                                        priv->text_shadow_material, | ||||
|                                        &allocation, | ||||
|                                        clutter_actor_get_paint_opacity (priv->entry)); | ||||
|     } | ||||
|  | ||||
|   /* Since we paint the background ourselves, chain to the parent class | ||||
|    * of StWidget, to avoid painting it twice. | ||||
|    * This is needed as we still want to paint children. | ||||
|    */ | ||||
|   parent_class = g_type_class_peek_parent (st_entry_parent_class); | ||||
|   parent_class->paint (actor); | ||||
| } | ||||
|  | ||||
| static void | ||||
| st_entry_unmap (ClutterActor *actor) | ||||
| { | ||||
| @@ -775,12 +917,12 @@ st_entry_class_init (StEntryClass *klass) | ||||
|  | ||||
|   gobject_class->set_property = st_entry_set_property; | ||||
|   gobject_class->get_property = st_entry_get_property; | ||||
|   gobject_class->finalize = st_entry_finalize; | ||||
|   gobject_class->dispose = st_entry_dispose; | ||||
|  | ||||
|   actor_class->get_preferred_width = st_entry_get_preferred_width; | ||||
|   actor_class->get_preferred_height = st_entry_get_preferred_height; | ||||
|   actor_class->allocate = st_entry_allocate; | ||||
|   actor_class->paint = st_entry_paint; | ||||
|   actor_class->unmap = st_entry_unmap; | ||||
|  | ||||
|   actor_class->key_press_event = st_entry_key_press_event; | ||||
| @@ -800,6 +942,20 @@ st_entry_class_init (StEntryClass *klass) | ||||
| 			       G_PARAM_READABLE); | ||||
|   g_object_class_install_property (gobject_class, PROP_CLUTTER_TEXT, pspec); | ||||
|  | ||||
|   pspec = g_param_spec_object ("primary-icon", | ||||
| 			       "Primary Icon", | ||||
| 			       "Primary Icon actor", | ||||
| 			       CLUTTER_TYPE_ACTOR, | ||||
| 			       G_PARAM_READWRITE); | ||||
|   g_object_class_install_property (gobject_class, PROP_PRIMARY_ICON, pspec); | ||||
|  | ||||
|   pspec = g_param_spec_object ("secondary-icon", | ||||
| 			       "Secondary Icon", | ||||
| 			       "Secondary Icon actor", | ||||
| 			       CLUTTER_TYPE_ACTOR, | ||||
| 			       G_PARAM_READWRITE); | ||||
|   g_object_class_install_property (gobject_class, PROP_SECONDARY_ICON, pspec); | ||||
|  | ||||
|   pspec = g_param_spec_string ("hint-text", | ||||
|                                "Hint Text", | ||||
|                                "Text to display when the entry is not focused " | ||||
| @@ -807,6 +963,14 @@ st_entry_class_init (StEntryClass *klass) | ||||
|                                NULL, G_PARAM_READWRITE); | ||||
|   g_object_class_install_property (gobject_class, PROP_HINT_TEXT, pspec); | ||||
|  | ||||
|   pspec = g_param_spec_object ("hint-actor", | ||||
|                                "Hint Actor", | ||||
|                                "An actor to display when the entry is not focused " | ||||
|                                "and the text property is empty", | ||||
|                                CLUTTER_TYPE_ACTOR, | ||||
|                                G_PARAM_READWRITE); | ||||
|   g_object_class_install_property (gobject_class, PROP_HINT_ACTOR, pspec); | ||||
|  | ||||
|   pspec = g_param_spec_string ("text", | ||||
|                                "Text", | ||||
|                                "Text of the entry", | ||||
| @@ -889,8 +1053,15 @@ st_entry_init (StEntry *entry) | ||||
|   g_signal_connect (priv->entry, "button-press-event", | ||||
|                     G_CALLBACK (clutter_text_button_press_event), entry); | ||||
|  | ||||
|   g_signal_connect (priv->entry, "notify::text", | ||||
|                     G_CALLBACK (clutter_text_changed_cb), entry); | ||||
|  | ||||
|   priv->spacing = 6.0f; | ||||
|  | ||||
|   priv->text_shadow_material = COGL_INVALID_HANDLE; | ||||
|   priv->shadow_width = -1.; | ||||
|   priv->shadow_height = -1.; | ||||
|  | ||||
|   clutter_actor_add_child (CLUTTER_ACTOR (entry), priv->entry); | ||||
|   clutter_actor_set_reactive ((ClutterActor *) entry, TRUE); | ||||
|  | ||||
| @@ -935,7 +1106,7 @@ st_entry_get_text (StEntry *entry) | ||||
|   g_return_val_if_fail (ST_IS_ENTRY (entry), NULL); | ||||
|  | ||||
|   priv = st_entry_get_instance_private (entry); | ||||
|   if (priv->hint_visible) | ||||
|   if (clutter_actor_is_visible (priv->hint_actor)) | ||||
|     return ""; | ||||
|   else | ||||
|     return clutter_text_get_text (CLUTTER_TEXT (priv->entry)); | ||||
| @@ -958,24 +1129,10 @@ st_entry_set_text (StEntry     *entry, | ||||
|  | ||||
|   priv = st_entry_get_instance_private (entry); | ||||
|  | ||||
|   /* set a hint if we are blanking the entry */ | ||||
|   if (priv->hint | ||||
|       && text && !strcmp ("", text) | ||||
|       && !HAS_FOCUS (priv->entry)) | ||||
|     { | ||||
|       text = priv->hint; | ||||
|       priv->hint_visible = TRUE; | ||||
|       st_widget_add_style_pseudo_class (ST_WIDGET (entry), "indeterminate"); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       st_widget_remove_style_pseudo_class (ST_WIDGET (entry), "indeterminate"); | ||||
|  | ||||
|       priv->hint_visible = FALSE; | ||||
|     } | ||||
|  | ||||
|   clutter_text_set_text (CLUTTER_TEXT (priv->entry), text); | ||||
|  | ||||
|   st_entry_update_hint_visibility (entry); | ||||
|  | ||||
|   g_object_notify (G_OBJECT (entry), "text"); | ||||
| } | ||||
|  | ||||
| @@ -1009,24 +1166,12 @@ void | ||||
| st_entry_set_hint_text (StEntry     *entry, | ||||
|                         const gchar *text) | ||||
| { | ||||
|   StEntryPrivate *priv; | ||||
|   StWidget *label; | ||||
|  | ||||
|   g_return_if_fail (ST_IS_ENTRY (entry)); | ||||
|  | ||||
|   priv = st_entry_get_instance_private (entry); | ||||
|  | ||||
|   g_free (priv->hint); | ||||
|  | ||||
|   priv->hint = g_strdup (text); | ||||
|  | ||||
|   if (!strcmp (clutter_text_get_text (CLUTTER_TEXT (priv->entry)), "") | ||||
|       && !HAS_FOCUS (priv->entry)) | ||||
|     { | ||||
|       priv->hint_visible = TRUE; | ||||
|  | ||||
|       clutter_text_set_text (CLUTTER_TEXT (priv->entry), priv->hint); | ||||
|       st_widget_add_style_pseudo_class (ST_WIDGET (entry), "indeterminate"); | ||||
|     } | ||||
|   label = st_label_new (text); | ||||
|   st_entry_set_hint_actor (ST_ENTRY (entry), CLUTTER_ACTOR (label)); | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -1041,9 +1186,16 @@ st_entry_set_hint_text (StEntry     *entry, | ||||
| const gchar * | ||||
| st_entry_get_hint_text (StEntry *entry) | ||||
| { | ||||
|   StEntryPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (ST_IS_ENTRY (entry), NULL); | ||||
|  | ||||
|   return ((StEntryPrivate *)ST_ENTRY_PRIV (entry))->hint; | ||||
|   priv = ST_ENTRY_PRIV (entry); | ||||
|  | ||||
|   if (priv->hint_actor != NULL && ST_IS_LABEL (priv->hint_actor)) | ||||
|     return st_label_get_text (ST_LABEL (priv->hint_actor)); | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -1199,6 +1351,23 @@ st_entry_set_primary_icon (StEntry      *entry, | ||||
|   _st_entry_set_icon (entry, &priv->primary_icon, icon); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * st_entry_get_primary_icon: | ||||
|  * @entry: a #StEntry | ||||
|  * | ||||
|  * Returns: (transfer none): a #ClutterActor | ||||
|  */ | ||||
| ClutterActor * | ||||
| st_entry_get_primary_icon (StEntry *entry) | ||||
| { | ||||
|   StEntryPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (ST_IS_ENTRY (entry), NULL); | ||||
|  | ||||
|   priv = ST_ENTRY_PRIV (entry); | ||||
|   return priv->primary_icon; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * st_entry_set_secondary_icon: | ||||
|  * @entry: a #StEntry | ||||
| @@ -1219,6 +1388,74 @@ st_entry_set_secondary_icon (StEntry      *entry, | ||||
|   _st_entry_set_icon (entry, &priv->secondary_icon, icon); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * st_entry_get_secondary_icon: | ||||
|  * @entry: a #StEntry | ||||
|  * | ||||
|  * Returns: (transfer none): a #ClutterActor | ||||
|  */ | ||||
| ClutterActor * | ||||
| st_entry_get_secondary_icon (StEntry *entry) | ||||
| { | ||||
|   StEntryPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (ST_IS_ENTRY (entry), NULL); | ||||
|  | ||||
|   priv = ST_ENTRY_PRIV (entry); | ||||
|   return priv->secondary_icon; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * st_entry_set_hint_actor: | ||||
|  * @entry: a #StEntry | ||||
|  * @hint_actor: (allow-none): a #ClutterActor | ||||
|  * | ||||
|  * Set the hint actor of the entry to @hint_actor | ||||
|  */ | ||||
| void | ||||
| st_entry_set_hint_actor (StEntry      *entry, | ||||
|                          ClutterActor *hint_actor) | ||||
| { | ||||
|   StEntryPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (ST_IS_ENTRY (entry)); | ||||
|  | ||||
|   priv = ST_ENTRY_PRIV (entry); | ||||
|  | ||||
|   if (priv->hint_actor != NULL) | ||||
|     { | ||||
|       clutter_actor_remove_child (CLUTTER_ACTOR (entry), priv->hint_actor); | ||||
|       priv->hint_actor = NULL; | ||||
|     } | ||||
|  | ||||
|   if (hint_actor != NULL) | ||||
|     { | ||||
|       priv->hint_actor = hint_actor; | ||||
|       clutter_actor_add_child (CLUTTER_ACTOR (entry), priv->hint_actor); | ||||
|     } | ||||
|  | ||||
|   st_entry_update_hint_visibility (entry); | ||||
|  | ||||
|   clutter_actor_queue_relayout (CLUTTER_ACTOR (entry)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * st_entry_get_hint_actor: | ||||
|  * @entry: a #StEntry | ||||
|  * | ||||
|  * Returns: (transfer none): a #ClutterActor | ||||
|  */ | ||||
| ClutterActor * | ||||
| st_entry_get_hint_actor (StEntry *entry) | ||||
| { | ||||
|   StEntryPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (ST_IS_ENTRY (entry), NULL); | ||||
|  | ||||
|   priv = ST_ENTRY_PRIV (entry); | ||||
|   return priv->hint_actor; | ||||
| } | ||||
|  | ||||
| /******************************************************************************/ | ||||
| /*************************** ACCESSIBILITY SUPPORT ****************************/ | ||||
| /******************************************************************************/ | ||||
|   | ||||
| @@ -57,10 +57,17 @@ void            st_entry_set_input_hints    (StEntry        *entry, | ||||
|                                              GtkInputHints   hints); | ||||
| GtkInputHints   st_entry_get_input_hints    (StEntry        *entry); | ||||
|  | ||||
| void            st_entry_set_primary_icon   (StEntry        *entry, | ||||
|                                              ClutterActor   *icon); | ||||
| void            st_entry_set_secondary_icon (StEntry        *entry, | ||||
|                                              ClutterActor   *icon); | ||||
| void            st_entry_set_primary_icon  (StEntry      *entry, | ||||
|                                             ClutterActor *icon); | ||||
| ClutterActor *  st_entry_get_primary_icon  (StEntry      *entry); | ||||
|  | ||||
| void            st_entry_set_secondary_icon (StEntry      *entry, | ||||
|                                              ClutterActor *icon); | ||||
| ClutterActor *  st_entry_get_secondary_icon (StEntry      *entry); | ||||
|  | ||||
| void            st_entry_set_hint_actor    (StEntry      *entry, | ||||
|                                             ClutterActor *hint_actor); | ||||
| ClutterActor *  st_entry_get_hint_actor    (StEntry      *entry); | ||||
|  | ||||
| typedef void (*StEntryCursorFunc) (StEntry *entry, gboolean use_ibeam, gpointer data); | ||||
| void            st_entry_set_cursor_func    (StEntryCursorFunc func, | ||||
|   | ||||
| @@ -202,7 +202,7 @@ st_im_text_get_paint_volume (ClutterActor       *self, | ||||
|   return clutter_paint_volume_set_from_allocation (volume, self); | ||||
| } | ||||
|  | ||||
| static GdkWindow *event_window; | ||||
| static GdkWindow *event_window = NULL; | ||||
|  | ||||
| void | ||||
| st_im_text_set_event_window (GdkWindow *window) | ||||
| @@ -217,9 +217,11 @@ st_im_text_realize (ClutterActor *actor) | ||||
| { | ||||
|   StIMTextPrivate *priv = ST_IM_TEXT (actor)->priv; | ||||
|  | ||||
|   g_assert (event_window != NULL); | ||||
|   priv->window = g_object_ref (event_window); | ||||
|   gtk_im_context_set_client_window (priv->im_context, priv->window); | ||||
|   if (event_window != NULL) | ||||
|     { | ||||
|       priv->window = g_object_ref (event_window); | ||||
|       gtk_im_context_set_client_window (priv->im_context, priv->window); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -230,8 +232,12 @@ st_im_text_unrealize (ClutterActor *actor) | ||||
|  | ||||
|   reset_im_context (self); | ||||
|   gtk_im_context_set_client_window (priv->im_context, NULL); | ||||
|   g_object_unref (priv->window); | ||||
|   priv->window = NULL; | ||||
|  | ||||
|   if (priv->window != NULL) | ||||
|     { | ||||
|       g_object_unref (priv->window); | ||||
|       priv->window = NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| @@ -277,10 +283,12 @@ static GdkEventKey * | ||||
| key_event_to_gdk (ClutterKeyEvent *event_clutter) | ||||
| { | ||||
|   GdkEventKey *event_gdk; | ||||
|  | ||||
|   if (event_window == NULL) | ||||
|     return NULL; | ||||
|  | ||||
|   event_gdk = (GdkEventKey *)gdk_event_new ((event_clutter->type == CLUTTER_KEY_PRESS) ? | ||||
|                                             GDK_KEY_PRESS : GDK_KEY_RELEASE); | ||||
|  | ||||
|   g_assert (event_window != NULL); | ||||
|   event_gdk->window = g_object_ref (event_window); | ||||
|   event_gdk->send_event = FALSE; | ||||
|   event_gdk->time = event_clutter->time; | ||||
| @@ -348,13 +356,14 @@ st_im_text_captured_event (ClutterActor *actor, | ||||
|     { | ||||
|       GdkEventKey *event_gdk = key_event_to_gdk ((ClutterKeyEvent *)event); | ||||
|  | ||||
|       if (gtk_im_context_filter_keypress (priv->im_context, event_gdk)) | ||||
|       if (event_gdk && gtk_im_context_filter_keypress (priv->im_context, event_gdk)) | ||||
|         { | ||||
|           priv->need_im_reset = TRUE; | ||||
|           result = TRUE; | ||||
|         } | ||||
|  | ||||
|       gdk_event_free ((GdkEvent *)event_gdk); | ||||
|       if (event_gdk) | ||||
|         gdk_event_free ((GdkEvent *)event_gdk); | ||||
|     } | ||||
|  | ||||
|   old_position = clutter_text_get_cursor_position (clutter_text); | ||||
|   | ||||
| @@ -180,12 +180,6 @@ st_label_dispose (GObject   *object) | ||||
| { | ||||
|   StLabelPrivate *priv = ST_LABEL (object)->priv; | ||||
|  | ||||
|   if (priv->label) | ||||
|     { | ||||
|       clutter_actor_destroy (priv->label); | ||||
|       priv->label = NULL; | ||||
|     } | ||||
|  | ||||
|   g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref); | ||||
|  | ||||
|   G_OBJECT_CLASS (st_label_parent_class)->dispose (object); | ||||
|   | ||||
| @@ -420,8 +420,7 @@ _st_create_shadow_pipeline_from_actor (StShadow     *shadow_spec, | ||||
|       CoglTexture *texture; | ||||
|  | ||||
|       texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (actor)); | ||||
|       if (texture) | ||||
|         shadow_pipeline = _st_create_shadow_pipeline (shadow_spec, texture); | ||||
|       shadow_pipeline = _st_create_shadow_pipeline (shadow_spec, texture); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|   | ||||
| @@ -180,7 +180,7 @@ st_shadow_get_box (StShadow              *shadow, | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * SECTION:st-shadow-helper: | ||||
|  * SECTION: st-shadow-helper | ||||
|  * | ||||
|  * An helper for implementing a drop shadow on a actor. | ||||
|  * The actor is expected to recreate the helper whenever its contents | ||||
|   | ||||
| @@ -3198,11 +3198,13 @@ parse_shadow_property (StThemeNode       *node, | ||||
|                        gdouble           *yoffset, | ||||
|                        gdouble           *blur, | ||||
|                        gdouble           *spread, | ||||
|                        gboolean          *inset) | ||||
|                        gboolean          *inset, | ||||
|                        gboolean          *is_none) | ||||
| { | ||||
|   GetFromTermResult result; | ||||
|   CRTerm *term; | ||||
|   int n_offsets = 0; | ||||
|   *is_none = FALSE; | ||||
|  | ||||
|   /* default values */ | ||||
|   color->red = 0x0; color->green = 0x0; color->blue = 0x0; color->alpha = 0xff; | ||||
| @@ -3224,8 +3226,10 @@ parse_shadow_property (StThemeNode       *node, | ||||
|   for (term = decl->value; term; term = term->next) | ||||
|     { | ||||
|       /* if we found "none", we're all set with the default values */ | ||||
|       if (term_is_none (term)) | ||||
|       if (term_is_none (term)) { | ||||
|         *is_none = TRUE; | ||||
|         return VALUE_FOUND; | ||||
|       } | ||||
|  | ||||
|       if (term->type == TERM_NUMBER) | ||||
|         { | ||||
| @@ -3324,7 +3328,8 @@ parse_shadow_property (StThemeNode       *node, | ||||
|  * See also st_theme_node_get_shadow(), which provides a simpler API. | ||||
|  * | ||||
|  * Return value: %TRUE if the property was found in the properties for this | ||||
|  *  theme node (or in the properties of parent nodes when inheriting.) | ||||
|  * theme node (or in the properties of parent nodes when inheriting.), %FALSE | ||||
|  * if the property was not found, or was explicitly set to 'none'. | ||||
|  */ | ||||
| gboolean | ||||
| st_theme_node_lookup_shadow (StThemeNode  *node, | ||||
| @@ -3338,6 +3343,7 @@ st_theme_node_lookup_shadow (StThemeNode  *node, | ||||
|   gdouble blur = 0.; | ||||
|   gdouble spread = 0.; | ||||
|   gboolean inset = FALSE; | ||||
|   gboolean is_none = FALSE; | ||||
|  | ||||
|   int i; | ||||
|  | ||||
| @@ -3356,9 +3362,13 @@ st_theme_node_lookup_shadow (StThemeNode  *node, | ||||
|                                                             &yoffset, | ||||
|                                                             &blur, | ||||
|                                                             &spread, | ||||
|                                                             &inset); | ||||
|                                                             &inset, | ||||
|                                                             &is_none); | ||||
|           if (result == VALUE_FOUND) | ||||
|             { | ||||
|               if (is_none) | ||||
|                 return FALSE; | ||||
|  | ||||
|               *shadow = st_shadow_new (&color, | ||||
|                                        xoffset, yoffset, | ||||
|                                        blur, spread, | ||||
|   | ||||
| @@ -4,10 +4,9 @@ const UI = imports.testcommon.ui; | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const Lang = imports.lang; | ||||
| const Mainloop = imports.mainloop; | ||||
| const St = imports.gi.St; | ||||
|  | ||||
| const Calendar = imports.ui.calendar; | ||||
|  | ||||
| function test() { | ||||
|     let stage = new Clutter.Stage({ width: 400, height: 400 }); | ||||
|     UI.init(stage); | ||||
| @@ -15,15 +14,47 @@ function test() { | ||||
|     let vbox = new St.BoxLayout({ vertical: true, | ||||
|                                   width: stage.width, | ||||
|                                   height: stage.height, | ||||
|                                   style: 'padding: 10px; spacing: 10px; font: 15px sans-serif;' }); | ||||
|                                   style: 'padding: 10px; spacing: 10px; font: 32px sans-serif;' }); | ||||
|     stage.add_actor(vbox); | ||||
|  | ||||
|     let entry = new St.Entry({ style: 'border: 1px solid black;' }); | ||||
|     let entry = new St.Entry({ style: 'border: 1px solid black; text-shadow: 0 2px red;', | ||||
|                                text: 'Example text' }); | ||||
|     vbox.add(entry, | ||||
|              { expand: true, | ||||
|                y_fill: false, y_align: St.Align.MIDDLE }); | ||||
|     entry.grab_key_focus(); | ||||
|  | ||||
|     let entryTextHint = new St.Entry({ style: 'border: 1px solid black; text-shadow: 0 2px red;', | ||||
|                                        hint_text: 'Hint text' }); | ||||
|     vbox.add(entryTextHint, | ||||
|              { expand: true, | ||||
|                y_fill: false, y_align: St.Align.MIDDLE }); | ||||
|  | ||||
|     let hintActor = new St.Label({ text: 'Hint actor' }); | ||||
|     let entryHintActor = new St.Entry({ style: 'border: 1px solid black; text-shadow: 0 2px red;', | ||||
|                                         hint_actor: hintActor }); | ||||
|     vbox.add(entryHintActor, | ||||
|              { expand: true, | ||||
|                y_fill: false, y_align: St.Align.MIDDLE }); | ||||
|  | ||||
|     let hintActor2 = new St.Label({ text: 'Hint both (actor)' }); | ||||
|     let entryHintBoth = new St.Entry({ style: 'border: 1px solid black; text-shadow: 0 2px red;', | ||||
|                                        hint_actor: hintActor2 }); | ||||
|     let idx = 0; | ||||
|     Mainloop.timeout_add_seconds(1, function() { | ||||
|         idx++; | ||||
|  | ||||
|         if (idx % 2 == 0) | ||||
|             entryHintBoth.hint_actor = hintActor2; | ||||
|         else | ||||
|             entryHintBoth.hint_text = 'Hint both (text)'; | ||||
|  | ||||
|         return true; | ||||
|     }); | ||||
|     vbox.add(entryHintBoth, | ||||
|              { expand: true, | ||||
|                y_fill: false, y_align: St.Align.MIDDLE }); | ||||
|  | ||||
|     UI.main(stage); | ||||
| } | ||||
| test(); | ||||
|   | ||||
| @@ -27,11 +27,11 @@ done | ||||
|  | ||||
| builddir=`dirname $0` | ||||
| builddir=`cd $builddir && pwd` | ||||
| srcdir=$builddir/@srcdir@ | ||||
| srcdir=@srcdir@ | ||||
| srcdir=`cd $srcdir && pwd` | ||||
|  | ||||
| GI_TYPELIB_PATH="$GI_TYPELIB_PATH${GI_TYPELIB_PATH:+:}@MUTTER_TYPELIB_DIR@:$builddir/../src:$builddir/../src/gvc" | ||||
| GJS_PATH="$srcdir:$srcdir/../js" | ||||
| GJS_PATH="$srcdir:$srcdir/../js:$builddir/../js" | ||||
| GJS_DEBUG_OUTPUT=stderr | ||||
| $verbose || GJS_DEBUG_TOPICS="JS ERROR;JS LOG" | ||||
| GNOME_SHELL_TESTSDIR="$srcdir/" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user