Compare commits
	
		
			341 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					07c39959d9 | ||
| 
						 | 
					23d1d18619 | ||
| 
						 | 
					23bf5db80c | ||
| 
						 | 
					f81af32963 | ||
| 
						 | 
					8f5198821e | ||
| 
						 | 
					96c2b5ef32 | ||
| 
						 | 
					c5eb324cf0 | ||
| 
						 | 
					f117d9bfd3 | ||
| 
						 | 
					b470736246 | ||
| 
						 | 
					b2a2a00cd8 | ||
| 
						 | 
					659130856c | ||
| 
						 | 
					9a21008177 | ||
| 
						 | 
					550e9973b7 | ||
| 
						 | 
					8f58bc5b19 | ||
| 
						 | 
					3a0220a875 | ||
| 
						 | 
					9f438d0ec6 | ||
| 
						 | 
					22c22e0d7a | ||
| 
						 | 
					bc48bd5f4a | ||
| 
						 | 
					905c4bb4a5 | ||
| 
						 | 
					94bfaf6896 | ||
| 
						 | 
					25b743b03c | ||
| 
						 | 
					8da4e6ce5e | ||
| 
						 | 
					cedd297ba6 | ||
| 
						 | 
					b6e0c5e0ea | ||
| 
						 | 
					bf3f7d0dc4 | ||
| 
						 | 
					7b42a84422 | ||
| 
						 | 
					8b7c065706 | ||
| 
						 | 
					c6a4b3d9b0 | ||
| 
						 | 
					0ef32f2b8d | ||
| 
						 | 
					f7fdcb7bf1 | ||
| 
						 | 
					848d36ff39 | ||
| 
						 | 
					07ce3e7cdf | ||
| 
						 | 
					cfec145ae2 | ||
| 
						 | 
					641d7a4ea4 | ||
| 
						 | 
					da0650fda6 | ||
| 
						 | 
					6724133927 | ||
| 
						 | 
					c0ded8ef5f | ||
| 
						 | 
					7382de51dc | ||
| 
						 | 
					96a1121e6b | ||
| 
						 | 
					323bbb0692 | ||
| 
						 | 
					59e235623a | ||
| 
						 | 
					40dc85d975 | ||
| 
						 | 
					6006a42cbb | ||
| 
						 | 
					c2e0278bd9 | ||
| 
						 | 
					c1ba920c86 | ||
| 
						 | 
					7b997e9374 | ||
| 
						 | 
					dfb97c1ed7 | ||
| 
						 | 
					fc49fb2f4f | ||
| 
						 | 
					63078fba5b | ||
| 
						 | 
					b0176546c2 | ||
| 
						 | 
					a234ba91a4 | ||
| 
						 | 
					526d11809f | ||
| 
						 | 
					3bbdecc6b3 | ||
| 
						 | 
					00fc4a2eb7 | ||
| 
						 | 
					924b31233b | ||
| 
						 | 
					475161f716 | ||
| 
						 | 
					31b12635d1 | ||
| 
						 | 
					d2de0865bf | ||
| 
						 | 
					e4e6b26e15 | ||
| 
						 | 
					9b4dbd0e83 | ||
| 
						 | 
					4577cd7497 | ||
| 
						 | 
					4ebf07c725 | ||
| 
						 | 
					da852a94bd | ||
| 
						 | 
					9b51ff7241 | ||
| 
						 | 
					aa0137e7ce | ||
| 
						 | 
					3889ae7627 | ||
| 
						 | 
					c97a8602a1 | ||
| 
						 | 
					affc9f9058 | ||
| 
						 | 
					1582819259 | ||
| 
						 | 
					05e8ae33dc | ||
| 
						 | 
					219d5fb66b | ||
| 
						 | 
					92ff57c0ea | ||
| 
						 | 
					5233429b6f | ||
| 
						 | 
					475cf7179e | ||
| 
						 | 
					f608c65962 | ||
| 
						 | 
					6cf0a35b4c | ||
| 
						 | 
					bac006ebc1 | ||
| 
						 | 
					be5f74e37f | ||
| 
						 | 
					5c29bff23d | ||
| 
						 | 
					68968d2b40 | ||
| 
						 | 
					038f4e8bde | ||
| 
						 | 
					f8874fec0f | ||
| 
						 | 
					ee6693e6e3 | ||
| 
						 | 
					bfba97647e | ||
| 
						 | 
					82d5194afe | ||
| 
						 | 
					bf449b9f61 | ||
| 
						 | 
					9530048867 | ||
| 
						 | 
					090d54516e | ||
| 
						 | 
					c91b716a63 | ||
| 
						 | 
					80cdb0dc4e | ||
| 
						 | 
					aaa6b54673 | ||
| 
						 | 
					a3b61ec8c8 | ||
| 
						 | 
					6c41d6b66a | ||
| 
						 | 
					1838ab1412 | ||
| 
						 | 
					72e8d38586 | ||
| 
						 | 
					9259e2221d | ||
| 
						 | 
					42ea979b06 | ||
| 
						 | 
					46824adb97 | ||
| 
						 | 
					3758f4952e | ||
| 
						 | 
					8fdbbe78f4 | ||
| 
						 | 
					5a86b0f9e3 | ||
| 
						 | 
					604722b775 | ||
| 
						 | 
					812812d817 | ||
| 
						 | 
					f07fe0a8e7 | ||
| 
						 | 
					1d7cef5bfe | ||
| 
						 | 
					34b12e6a6a | ||
| 
						 | 
					eb6ba563bd | ||
| 
						 | 
					281b2e9b0e | ||
| 
						 | 
					5437629e89 | ||
| 
						 | 
					e1df2f8ff5 | ||
| 
						 | 
					12fad6f05f | ||
| 
						 | 
					4208078750 | ||
| 
						 | 
					dba02f8f08 | ||
| 
						 | 
					35e410fe96 | ||
| 
						 | 
					7dcd2313d8 | ||
| 
						 | 
					40750f2dc6 | ||
| 
						 | 
					85c007431b | ||
| 
						 | 
					cbd187369e | ||
| 
						 | 
					d20d89a0b9 | ||
| 
						 | 
					80eb37ef60 | ||
| 
						 | 
					d19cdc206b | ||
| 
						 | 
					02078255ea | ||
| 
						 | 
					bea2d40f79 | ||
| 
						 | 
					a5d3259cfe | ||
| 
						 | 
					4a93ce703e | ||
| 
						 | 
					661ea906d9 | ||
| 
						 | 
					b382b4cb94 | ||
| 
						 | 
					087e86fb32 | ||
| 
						 | 
					afffa76c17 | ||
| 
						 | 
					69ca18f36b | ||
| 
						 | 
					f84c62f0be | ||
| 
						 | 
					90c554ad42 | ||
| 
						 | 
					e2cb6cc4da | ||
| 
						 | 
					02da366cc2 | ||
| 
						 | 
					54e3a54489 | ||
| 
						 | 
					8798ec653d | ||
| 
						 | 
					d1ffd3cf35 | ||
| 
						 | 
					133b854f1b | ||
| 
						 | 
					33125e78c8 | ||
| 
						 | 
					4118bf1a5e | ||
| 
						 | 
					8282db456b | ||
| 
						 | 
					7b5eacf671 | ||
| 
						 | 
					12bd374477 | ||
| 
						 | 
					9ef4cc0ab9 | ||
| 
						 | 
					528fc9bc47 | ||
| 
						 | 
					c58b8498b3 | ||
| 
						 | 
					c81c564941 | ||
| 
						 | 
					b16de0e374 | ||
| 
						 | 
					d38f41a459 | ||
| 
						 | 
					30346884fe | ||
| 
						 | 
					1518dc9b60 | ||
| 
						 | 
					fd3f2289c3 | ||
| 
						 | 
					22bfd4f7c3 | ||
| 
						 | 
					2782011ce8 | ||
| 
						 | 
					7f17fcfafc | ||
| 
						 | 
					a40daa3c22 | ||
| 
						 | 
					1e366aa56e | ||
| 
						 | 
					bad8dbc2d2 | ||
| 
						 | 
					d0dd37fe94 | ||
| 
						 | 
					b2df3fcd1d | ||
| 
						 | 
					96f89ce4ae | ||
| 
						 | 
					e886a3d891 | ||
| 
						 | 
					0eaf141ae4 | ||
| 
						 | 
					291ef07cf3 | ||
| 
						 | 
					b9066ac997 | ||
| 
						 | 
					206f4604a4 | ||
| 
						 | 
					adbc1d97a0 | ||
| 
						 | 
					70ae700461 | ||
| 
						 | 
					b81ad3ed39 | ||
| 
						 | 
					77cdb17cee | ||
| 
						 | 
					d4e329b76d | ||
| 
						 | 
					fb24585dd8 | ||
| 
						 | 
					bd5efd5968 | ||
| 
						 | 
					650f35c1f3 | ||
| 
						 | 
					14e65168c9 | ||
| 
						 | 
					f00c47c21a | ||
| 
						 | 
					547d105b2e | ||
| 
						 | 
					de671103ca | ||
| 
						 | 
					2c48efa3fd | ||
| 
						 | 
					7f35b2dc43 | ||
| 
						 | 
					6ae914da2f | ||
| 
						 | 
					06ea78af1b | ||
| 
						 | 
					2ea12a7699 | ||
| 
						 | 
					8ab25de6c6 | ||
| 
						 | 
					e0424a7017 | ||
| 
						 | 
					f259162d64 | ||
| 
						 | 
					6bb5cdeb2f | ||
| 
						 | 
					384c30b6fd | ||
| 
						 | 
					67a75d4439 | ||
| 
						 | 
					0d963df7b3 | ||
| 
						 | 
					99efde5673 | ||
| 
						 | 
					c8ff699c4b | ||
| 
						 | 
					0718a888d0 | ||
| 
						 | 
					b7be4df603 | ||
| 
						 | 
					8bece0b49e | ||
| 
						 | 
					47d6edc3c8 | ||
| 
						 | 
					26bb56396d | ||
| 
						 | 
					dd99ed73a9 | ||
| 
						 | 
					36ce460a39 | ||
| 
						 | 
					e92c845dfd | ||
| 
						 | 
					492263c2e9 | ||
| 
						 | 
					0c99f66547 | ||
| 
						 | 
					df440496ee | ||
| 
						 | 
					09f2028d6a | ||
| 
						 | 
					05736ba0a1 | ||
| 
						 | 
					e5f05bc9d8 | ||
| 
						 | 
					cdd1209b55 | ||
| 
						 | 
					0e6458a630 | ||
| 
						 | 
					a1a068a377 | ||
| 
						 | 
					2c5657e8a9 | ||
| 
						 | 
					87fbd715a3 | ||
| 
						 | 
					fc8cba9598 | ||
| 
						 | 
					147725bf7a | ||
| 
						 | 
					06d2c0af35 | ||
| 
						 | 
					708f1a97dd | ||
| 
						 | 
					d8bd9f5a66 | ||
| 
						 | 
					079953c3ee | ||
| 
						 | 
					fea8b6da2f | ||
| 
						 | 
					4bf1df0894 | ||
| 
						 | 
					b4f16c4df8 | ||
| 
						 | 
					61282737c5 | ||
| 
						 | 
					d8c2290099 | ||
| 
						 | 
					830ab599df | ||
| 
						 | 
					0de5c5e8a3 | ||
| 
						 | 
					c6170ed751 | ||
| 
						 | 
					2ea762cfc9 | ||
| 
						 | 
					2646741297 | ||
| 
						 | 
					f5df5faf71 | ||
| 
						 | 
					cab9a580e8 | ||
| 
						 | 
					c8ac3fd4f5 | ||
| 
						 | 
					7f67c34b39 | ||
| 
						 | 
					e27293edbc | ||
| 
						 | 
					8d57c5052c | ||
| 
						 | 
					1314559833 | ||
| 
						 | 
					735397aa89 | ||
| 
						 | 
					c0d0c792e1 | ||
| 
						 | 
					43020b20b7 | ||
| 
						 | 
					0a3d80b86e | ||
| 
						 | 
					a9505d0426 | ||
| 
						 | 
					4d804c2a29 | ||
| 
						 | 
					e8eec2d357 | ||
| 
						 | 
					971e3f679f | ||
| 
						 | 
					7c90f078e7 | ||
| 
						 | 
					5957bd1abb | ||
| 
						 | 
					b16380e7e5 | ||
| 
						 | 
					b72a32c70d | ||
| 
						 | 
					90f15b3c5a | ||
| 
						 | 
					44bbf26cb2 | ||
| 
						 | 
					fcfd17e973 | ||
| 
						 | 
					73853cf147 | ||
| 
						 | 
					ddbc263da2 | ||
| 
						 | 
					982d8a0dc0 | ||
| 
						 | 
					5a269db9d5 | ||
| 
						 | 
					525da01a62 | ||
| 
						 | 
					12df10b2d0 | ||
| 
						 | 
					e6aee5d7ea | ||
| 
						 | 
					6ff69da0de | ||
| 
						 | 
					ebcb87c163 | ||
| 
						 | 
					79d9df9bb1 | ||
| 
						 | 
					8c40c2086a | ||
| 
						 | 
					f4a000cb59 | ||
| 
						 | 
					4029202635 | ||
| 
						 | 
					9551e1c2f5 | ||
| 
						 | 
					29d473f2fa | ||
| 
						 | 
					7ad89dc46b | ||
| 
						 | 
					4b2d6f8a99 | ||
| 
						 | 
					9b55de1c6b | ||
| 
						 | 
					8b45211a8f | ||
| 
						 | 
					f079501cff | ||
| 
						 | 
					e375e1789b | ||
| 
						 | 
					30d2cfdf56 | ||
| 
						 | 
					44d61e6857 | ||
| 
						 | 
					3466829766 | ||
| 
						 | 
					d3703516d9 | ||
| 
						 | 
					bdebaa986b | ||
| 
						 | 
					c2d400846b | ||
| 
						 | 
					034e147910 | ||
| 
						 | 
					25015c9c3a | ||
| 
						 | 
					43cf60f563 | ||
| 
						 | 
					057348763b | ||
| 
						 | 
					7230452e23 | ||
| 
						 | 
					438317c1e9 | ||
| 
						 | 
					cfe719c962 | ||
| 
						 | 
					44e2d88628 | ||
| 
						 | 
					6e50e77709 | ||
| 
						 | 
					02ed28d68d | ||
| 
						 | 
					73274e201b | ||
| 
						 | 
					f6fc88cc2d | ||
| 
						 | 
					d16acc43d9 | ||
| 
						 | 
					239aa7b8d5 | ||
| 
						 | 
					44a1bc5396 | ||
| 
						 | 
					821583acae | ||
| 
						 | 
					c6a2814881 | ||
| 
						 | 
					1954a02352 | ||
| 
						 | 
					8a28022a6b | ||
| 
						 | 
					43a243b24a | ||
| 
						 | 
					7c937c8704 | ||
| 
						 | 
					bdd1f82777 | ||
| 
						 | 
					cbb8876815 | ||
| 
						 | 
					f8cdaaae30 | ||
| 
						 | 
					74314bacd7 | ||
| 
						 | 
					04473f607b | ||
| 
						 | 
					88958270cb | ||
| 
						 | 
					856f7ecee9 | ||
| 
						 | 
					9f5584a157 | ||
| 
						 | 
					eda8a94d5b | ||
| 
						 | 
					5956b13588 | ||
| 
						 | 
					a70ea12be8 | ||
| 
						 | 
					162d029c81 | ||
| 
						 | 
					7f3920dbb7 | ||
| 
						 | 
					6d07c3a1df | ||
| 
						 | 
					a0a83428cf | ||
| 
						 | 
					dc2cae07b2 | ||
| 
						 | 
					f8b44cd30e | ||
| 
						 | 
					c3eca3d754 | ||
| 
						 | 
					1ea005f6a6 | ||
| 
						 | 
					16a675b7ce | ||
| 
						 | 
					df2f939f3a | ||
| 
						 | 
					5743224817 | ||
| 
						 | 
					a80e88e33e | ||
| 
						 | 
					0207f1f29b | ||
| 
						 | 
					72120bb87f | ||
| 
						 | 
					7eaca86bf1 | ||
| 
						 | 
					db5f72c868 | ||
| 
						 | 
					69d6ae4141 | ||
| 
						 | 
					edabafc0fc | ||
| 
						 | 
					e9f2aa6010 | ||
| 
						 | 
					e054dd7813 | ||
| 
						 | 
					76d788a186 | ||
| 
						 | 
					3944df1bd2 | ||
| 
						 | 
					49f6280645 | ||
| 
						 | 
					84eb66d5aa | ||
| 
						 | 
					026fc531ba | ||
| 
						 | 
					8d14df0ced | ||
| 
						 | 
					f27547dcff | ||
| 
						 | 
					fb5a3a53fa | ||
| 
						 | 
					30eac56691 | ||
| 
						 | 
					cb6f3a0836 | ||
| 
						 | 
					8e579024b1 | ||
| 
						 | 
					41c70293df | ||
| 
						 | 
					4b015903bc | 
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -44,8 +44,9 @@ src/calendar-server/org.gnome.Shell.CalendarServer.service
 | 
			
		||||
src/gnome-shell
 | 
			
		||||
src/gnome-shell-calendar-server
 | 
			
		||||
src/gnome-shell-extension-tool
 | 
			
		||||
src/gnome-shell-real
 | 
			
		||||
src/gnome-shell-jhbuild
 | 
			
		||||
src/gnome-shell-perf-helper
 | 
			
		||||
src/gnome-shell-real
 | 
			
		||||
src/run-js-test
 | 
			
		||||
src/test-recorder
 | 
			
		||||
src/test-recorder.ogg
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								configure.ac
									
									
									
									
									
								
							@@ -1,5 +1,5 @@
 | 
			
		||||
AC_PREREQ(2.63)
 | 
			
		||||
AC_INIT([gnome-shell],[2.91.91],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
 | 
			
		||||
AC_INIT([gnome-shell],[2.91.93],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
 | 
			
		||||
 | 
			
		||||
AC_CONFIG_HEADERS([config.h])
 | 
			
		||||
AC_CONFIG_SRCDIR([src/shell-global.c])
 | 
			
		||||
@@ -52,8 +52,8 @@ AC_MSG_CHECKING([for GStreamer (needed for recording functionality)])
 | 
			
		||||
if $PKG_CONFIG --exists gstreamer-0.10 '>=' $GSTREAMER_MIN_VERSION ; then
 | 
			
		||||
   AC_MSG_RESULT(yes)
 | 
			
		||||
   build_recorder=true
 | 
			
		||||
   recorder_modules="gstreamer-0.10 gstreamer-base-0.10 xfixes x11"
 | 
			
		||||
   PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0)
 | 
			
		||||
   recorder_modules="gstreamer-0.10 gstreamer-base-0.10 x11"
 | 
			
		||||
   PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0 xfixes)
 | 
			
		||||
else
 | 
			
		||||
   AC_MSG_RESULT(no)
 | 
			
		||||
fi
 | 
			
		||||
@@ -63,7 +63,7 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
 | 
			
		||||
CLUTTER_MIN_VERSION=1.5.15
 | 
			
		||||
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
 | 
			
		||||
GJS_MIN_VERSION=0.7.11
 | 
			
		||||
MUTTER_MIN_VERSION=2.91.91
 | 
			
		||||
MUTTER_MIN_VERSION=2.91.93
 | 
			
		||||
GTK_MIN_VERSION=3.0.0
 | 
			
		||||
GIO_MIN_VERSION=2.25.9
 | 
			
		||||
LIBECAL_MIN_VERSION=2.32.0
 | 
			
		||||
@@ -71,13 +71,14 @@ LIBEDATASERVER_MIN_VERSION=1.2.0
 | 
			
		||||
LIBEDATASERVERUI2_MIN_VERSION=1.2.0
 | 
			
		||||
LIBEDATASERVERUI3_MIN_VERSION=2.91.6
 | 
			
		||||
TELEPATHY_GLIB_MIN_VERSION=0.13.12
 | 
			
		||||
TELEPATHY_LOGGER_MIN_VERSION=0.2.4
 | 
			
		||||
POLKIT_MIN_VERSION=0.100
 | 
			
		||||
 | 
			
		||||
# Collect more than 20 libraries for a prize!
 | 
			
		||||
PKG_CHECK_MODULES(GNOME_SHELL, gio-2.0 >= $GIO_MIN_VERSION
 | 
			
		||||
                               gio-unix-2.0 dbus-glib-1 libxml-2.0
 | 
			
		||||
                               gtk+-3.0 >= $GTK_MIN_VERSION
 | 
			
		||||
                               libmutter-wm >= $MUTTER_MIN_VERSION
 | 
			
		||||
                               libmutter >= $MUTTER_MIN_VERSION
 | 
			
		||||
                               gjs-internals-1.0 >= $GJS_MIN_VERSION
 | 
			
		||||
			       libgnome-menu $recorder_modules gconf-2.0
 | 
			
		||||
                               gdk-x11-3.0
 | 
			
		||||
@@ -87,20 +88,31 @@ PKG_CHECK_MODULES(GNOME_SHELL, gio-2.0 >= $GIO_MIN_VERSION
 | 
			
		||||
                               gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
 | 
			
		||||
			       libcanberra
 | 
			
		||||
                               telepathy-glib >= $TELEPATHY_GLIB_MIN_VERSION
 | 
			
		||||
                               polkit-agent-1 >= $POLKIT_MIN_VERSION)
 | 
			
		||||
                               telepathy-logger-0.2 >= $TELEPATHY_LOGGER_MIN_VERSION
 | 
			
		||||
                               polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes)
 | 
			
		||||
 | 
			
		||||
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
 | 
			
		||||
 | 
			
		||||
GJS_VERSION=`$PKG_CONFIG --modversion gjs-internals-1.0`
 | 
			
		||||
AC_DEFINE_UNQUOTED([GJS_VERSION], ["$GJS_VERSION"], [The version of GJS we're linking to])
 | 
			
		||||
AC_SUBST([GJS_VERSION], ["$GJS_VERSION"])
 | 
			
		||||
 | 
			
		||||
GOBJECT_INTROSPECTION_CHECK([$GOBJECT_INTROSPECTION_MIN_VERSION])
 | 
			
		||||
JHBUILD_TYPELIBDIR="$INTROSPECTION_TYPELIBDIR"
 | 
			
		||||
# NM is the only typelib we use that we don't jhbuild
 | 
			
		||||
PKG_CHECK_EXISTS([libnm-glib >= 0.8.995],
 | 
			
		||||
        [NM_TYPELIBDIR=`$PKG_CONFIG --variable=libdir libnm-glib`/girepository-1.0
 | 
			
		||||
	 if test "$INTROSPECTION_TYPELIBDIR" != "$NM_TYPELIBDIR"; then
 | 
			
		||||
	     JHBUILD_TYPELIBDIR="$JHBUILD_TYPELIBDIR:$NM_TYPELIBDIR"
 | 
			
		||||
	 fi])
 | 
			
		||||
AC_SUBST(JHBUILD_TYPELIBDIR)
 | 
			
		||||
 | 
			
		||||
saved_CFLAGS=$CFLAGS
 | 
			
		||||
saved_LIBS=$LIBS
 | 
			
		||||
CFLAGS=$GNOME_SHELL_CFLAGS
 | 
			
		||||
LIBS=$GNOME_SHELL_LIBS
 | 
			
		||||
# sn_startup_sequence_get_application_id, we can replace with a version check later
 | 
			
		||||
AC_CHECK_FUNCS(JS_NewGlobalObject sn_startup_sequence_get_application_id)
 | 
			
		||||
AC_CHECK_FUNCS(JS_NewGlobalObject sn_startup_sequence_get_application_id XFixesCreatePointerBarrier)
 | 
			
		||||
CFLAGS=$saved_CFLAGS
 | 
			
		||||
LIBS=$saved_LIBS
 | 
			
		||||
 | 
			
		||||
@@ -134,8 +146,8 @@ PKG_CHECK_MODULES(CALENDAR_SERVER, libecal-1.2 >= $LIBECAL_MIN_VERSION libedatas
 | 
			
		||||
AC_SUBST(CALENDAR_SERVER_CFLAGS)
 | 
			
		||||
AC_SUBST(CALENDAR_SERVER_LIBS)
 | 
			
		||||
 | 
			
		||||
MUTTER_GIR_DIR=`$PKG_CONFIG --variable=girdir libmutter-wm`
 | 
			
		||||
MUTTER_TYPELIB_DIR=`$PKG_CONFIG --variable=typelibdir libmutter-wm`
 | 
			
		||||
MUTTER_GIR_DIR=`$PKG_CONFIG --variable=girdir libmutter`
 | 
			
		||||
MUTTER_TYPELIB_DIR=`$PKG_CONFIG --variable=typelibdir libmutter`
 | 
			
		||||
AC_SUBST(MUTTER_GIR_DIR)
 | 
			
		||||
AC_SUBST(MUTTER_TYPELIB_DIR)
 | 
			
		||||
 | 
			
		||||
@@ -190,20 +202,6 @@ AC_ARG_ENABLE(jhbuild-wrapper-script,
 | 
			
		||||
  AS_HELP_STRING([--jhbuild-wrapper-script=yes],[Make "gnome-shell" script work for jhbuild]),,enable_jhbuild_wrapper_script=no)
 | 
			
		||||
AM_CONDITIONAL(USE_JHBUILD_WRAPPER_SCRIPT, test "x$enable_jhbuild_wrapper_script" = xyes)
 | 
			
		||||
 | 
			
		||||
AC_MSG_CHECKING([for Ubuntu])
 | 
			
		||||
if test -f /etc/ubuntu_version; then
 | 
			
		||||
  enable_dynamic_mozjs_hack_default=yes
 | 
			
		||||
  AC_MSG_RESULT([yes])
 | 
			
		||||
else
 | 
			
		||||
  enable_dynamic_mozjs_hack_default=no
 | 
			
		||||
  AC_MSG_RESULT([no])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
AC_ARG_ENABLE(dynamic-mozjs-hack,
 | 
			
		||||
  AS_HELP_STRING([--dynamic-mozjs-hack=no],[Look for libmozjs.so using pkg-config]),,enable_dynamic_mozjs_hack=$enable_dynamic_mozjs_hack_default)
 | 
			
		||||
ENABLE_DYNAMIC_MOZJS_HACK=$enable_dynamic_mozjs_hack
 | 
			
		||||
AC_SUBST(ENABLE_DYNAMIC_MOZJS_HACK)
 | 
			
		||||
 | 
			
		||||
AC_CONFIG_FILES([
 | 
			
		||||
  Makefile
 | 
			
		||||
  data/Makefile
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,8 @@ dist_theme_DATA =				\
 | 
			
		||||
	theme/calendar-today.svg		\
 | 
			
		||||
	theme/close-window.svg			\
 | 
			
		||||
	theme/close.svg				\
 | 
			
		||||
	theme/corner-ripple.png			\
 | 
			
		||||
	theme/corner-ripple-ltr.png		\
 | 
			
		||||
	theme/corner-ripple-rtl.png		\
 | 
			
		||||
	theme/dash-placeholder.svg		\
 | 
			
		||||
	theme/filter-selected-ltr.svg		\
 | 
			
		||||
	theme/filter-selected-rtl.svg		\
 | 
			
		||||
@@ -49,6 +50,7 @@ dist_theme_DATA =				\
 | 
			
		||||
	theme/separator-white.png		\
 | 
			
		||||
	theme/single-view-active.svg		\
 | 
			
		||||
	theme/single-view.svg			\
 | 
			
		||||
	theme/source-button-border.svg		\
 | 
			
		||||
	theme/toggle-off-us.svg			\
 | 
			
		||||
	theme/toggle-off-intl.svg		\
 | 
			
		||||
	theme/toggle-on-us.svg			\
 | 
			
		||||
 
 | 
			
		||||
@@ -13,3 +13,4 @@ NoDisplay=true
 | 
			
		||||
X-GNOME-Autostart-Phase=WindowManager
 | 
			
		||||
X-GNOME-Provides=panel;windowmanager;
 | 
			
		||||
X-GNOME-Autostart-Notify=true
 | 
			
		||||
X-GNOME-AutoRestart=true
 | 
			
		||||
 
 | 
			
		||||
@@ -81,5 +81,20 @@
 | 
			
		||||
        </locale>
 | 
			
		||||
      </schema>
 | 
			
		||||
 | 
			
		||||
      <schema>
 | 
			
		||||
        <key>/schemas/desktop/gnome/shell/windows/workspaces_only_on_primary</key>
 | 
			
		||||
        <applyto>/desktop/gnome/shell/windows/workspaces_only_on_primary</applyto>
 | 
			
		||||
        <owner>gnome-shell</owner>
 | 
			
		||||
        <type>bool</type>
 | 
			
		||||
        <default>true</default>
 | 
			
		||||
        <locale name="C">
 | 
			
		||||
          <short>Workspaces only on primary monitor</short>
 | 
			
		||||
          <long>
 | 
			
		||||
             This key overrides /apps/mutter/general/workspaces_only_on_primary when
 | 
			
		||||
             running GNOME Shell.
 | 
			
		||||
          </long>
 | 
			
		||||
        </locale>
 | 
			
		||||
      </schema>
 | 
			
		||||
 | 
			
		||||
  </schemalist>
 | 
			
		||||
</gconfschemafile>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<schemalist>
 | 
			
		||||
  <schema id="org.gnome.shell" path="/apps/gnome-shell/"
 | 
			
		||||
  <schema id="org.gnome.shell" path="/org/gnome/shell/"
 | 
			
		||||
          gettext-domain="@GETTEXT_PACKAGE@">
 | 
			
		||||
    <key name="development-tools" type="b">
 | 
			
		||||
      <default>true</default>
 | 
			
		||||
@@ -54,7 +54,7 @@
 | 
			
		||||
    <child name="recorder" schema="org.gnome.shell.recorder"/>
 | 
			
		||||
  </schema>
 | 
			
		||||
 | 
			
		||||
  <schema id="org.gnome.shell.calendar" path="/apps/gnome-shell/calendar/"
 | 
			
		||||
  <schema id="org.gnome.shell.calendar" path="/org/gnome/shell/calendar/"
 | 
			
		||||
          gettext-domain="@GETTEXT_PACKAGE@">
 | 
			
		||||
    <key name="show-weekdate" type="b">
 | 
			
		||||
      <default>false</default>
 | 
			
		||||
@@ -65,7 +65,7 @@
 | 
			
		||||
      </key>
 | 
			
		||||
  </schema>
 | 
			
		||||
 | 
			
		||||
  <schema id="org.gnome.shell.clock" path="/apps/gnome-shell/clock/"
 | 
			
		||||
  <schema id="org.gnome.shell.clock" path="/org/gnome/shell/clock/"
 | 
			
		||||
          gettext-domain="@GETTEXT_PACKAGE@">
 | 
			
		||||
    <key name="show-seconds" type="b">
 | 
			
		||||
      <default>false</default>
 | 
			
		||||
@@ -83,7 +83,7 @@
 | 
			
		||||
    </key>
 | 
			
		||||
  </schema>
 | 
			
		||||
 | 
			
		||||
  <schema id="org.gnome.shell.recorder" path="/apps/gnome-shell/recorder/"
 | 
			
		||||
  <schema id="org.gnome.shell.recorder" path="/org/gnome/shell/recorder/"
 | 
			
		||||
          gettext-domain="@GETTEXT_PACKAGE@">
 | 
			
		||||
    <key name="framerate" type="i">
 | 
			
		||||
      <default>15</default>
 | 
			
		||||
 
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								data/theme/corner-ripple-rtl.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								data/theme/corner-ripple-rtl.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 2.3 KiB  | 
@@ -34,13 +34,6 @@ stage {
 | 
			
		||||
    color: rgba(0,0,0,0.5);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.label-real-shadow {
 | 
			
		||||
    background-gradient-direction: horizontal;
 | 
			
		||||
    background-gradient-start: rgba(0, 0, 0, 0);
 | 
			
		||||
    background-gradient-end: rgba(0, 0, 0, 255);
 | 
			
		||||
    width: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
StScrollBar
 | 
			
		||||
{
 | 
			
		||||
  padding: 0px;
 | 
			
		||||
@@ -82,10 +75,10 @@ StScrollBar StButton#vhandle:hover
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
StTooltip StLabel {
 | 
			
		||||
    border: 1px solid rgba(79,111,173,1);
 | 
			
		||||
    border: 1px solid rgba(255,255,255,0.6);
 | 
			
		||||
    border-radius: 5px;
 | 
			
		||||
    padding: 4px;
 | 
			
		||||
    background-color: rgba(79,111,173,0.9);
 | 
			
		||||
    padding: 2px 12px;
 | 
			
		||||
    background-color: rgba(0,0,0,0.9);
 | 
			
		||||
    color: #ffffff;
 | 
			
		||||
    font-size: 0.8em;
 | 
			
		||||
    font-weight: normal;
 | 
			
		||||
@@ -105,7 +98,7 @@ StTooltip StLabel {
 | 
			
		||||
 | 
			
		||||
.popup-menu {
 | 
			
		||||
    color: #ffffff;
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    font-size: 10.5pt;
 | 
			
		||||
    min-width: 200px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -150,6 +143,8 @@ StTooltip StLabel {
 | 
			
		||||
    -slider-height: 0.3em;
 | 
			
		||||
    -slider-background-color: #333333;
 | 
			
		||||
    -slider-border-color: #5f5f5f;
 | 
			
		||||
    -slider-active-background-color: #76b0ec;
 | 
			
		||||
    -slider-active-border-color: #1f6dbc;
 | 
			
		||||
    -slider-border-width: 1px;
 | 
			
		||||
    -slider-handle-radius: 0.5em;
 | 
			
		||||
}
 | 
			
		||||
@@ -158,14 +153,22 @@ StTooltip StLabel {
 | 
			
		||||
    spacing: .5em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.popup-inactive-menu-item {
 | 
			
		||||
    color: #999;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.popup-subtitle-menu-item {
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.popup-menu-icon {
 | 
			
		||||
    icon-size: 1.14em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Switches (to be used in menus) */
 | 
			
		||||
.toggle-switch {
 | 
			
		||||
    width: 4.5em;
 | 
			
		||||
    height: 1.5em;
 | 
			
		||||
    width: 65px;
 | 
			
		||||
    height: 22px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.toggle-switch-us {
 | 
			
		||||
@@ -182,12 +185,18 @@ StTooltip StLabel {
 | 
			
		||||
    background-image: url("toggle-on-intl.svg");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.nm-menu-item-icons {
 | 
			
		||||
    spacing: .5em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Panel */
 | 
			
		||||
 | 
			
		||||
#panel {
 | 
			
		||||
    color: #ffffff;
 | 
			
		||||
    background-color: black;
 | 
			
		||||
    border-image: url("panel-border.svg") 1;
 | 
			
		||||
    font-size: 10.5pt;
 | 
			
		||||
    height: 1.86em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#panelLeft, #panelCenter, #panelRight {
 | 
			
		||||
@@ -247,12 +256,16 @@ StTooltip StLabel {
 | 
			
		||||
 | 
			
		||||
.panel-button {
 | 
			
		||||
    padding: 0px 12px;
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    color: #ccc;
 | 
			
		||||
    transition-duration: 100;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.panel-button:hover {
 | 
			
		||||
    color: white;
 | 
			
		||||
    text-shadow: black 0px 2px 2px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.panel-button:active,
 | 
			
		||||
.panel-button:checked,
 | 
			
		||||
.panel-button:focus {
 | 
			
		||||
@@ -315,7 +328,7 @@ StTooltip StLabel {
 | 
			
		||||
    background-color: rgba(0,0,0,0.6);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.workspaces-view {
 | 
			
		||||
.window-caption {
 | 
			
		||||
    color: white;
 | 
			
		||||
    spacing: 25px;
 | 
			
		||||
}
 | 
			
		||||
@@ -344,13 +357,14 @@ StTooltip StLabel {
 | 
			
		||||
 | 
			
		||||
.workspace-thumbnail-indicator {
 | 
			
		||||
    outline: 2px solid white;
 | 
			
		||||
    border: 1px solid #888;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.window-caption {
 | 
			
		||||
    background: rgba(0,0,0,0.8);
 | 
			
		||||
    border: 1px solid rgba(128,128,128,0.40);
 | 
			
		||||
    border-radius: 10px;
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    font-size: 9pt;
 | 
			
		||||
    padding: 2px 8px;
 | 
			
		||||
    -shell-caption-spacing: 4px;
 | 
			
		||||
}
 | 
			
		||||
@@ -370,7 +384,7 @@ StTooltip StLabel {
 | 
			
		||||
 | 
			
		||||
#dash {
 | 
			
		||||
    color: #5f5f5f;
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    font-size: 9pt;
 | 
			
		||||
    padding: 4px 0px;
 | 
			
		||||
    background-color: rgba(0, 0, 0, 0.5);
 | 
			
		||||
    border: 1px solid rgba(128, 128, 128, 0.4);
 | 
			
		||||
@@ -396,12 +410,12 @@ StTooltip StLabel {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#viewSelector {
 | 
			
		||||
    spacing: 16px;
 | 
			
		||||
    font-size: 16px;
 | 
			
		||||
    spacing: 1em;
 | 
			
		||||
    font-size: 12pt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#viewSelectorTabBar {
 | 
			
		||||
    padding: 16px;
 | 
			
		||||
    padding: 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#searchArea {
 | 
			
		||||
@@ -449,8 +463,8 @@ StTooltip StLabel {
 | 
			
		||||
.view-tab-title {
 | 
			
		||||
    color: #888a85;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    padding: 0px 12px;
 | 
			
		||||
    height: 24px;
 | 
			
		||||
    padding: 0px 0.75em;
 | 
			
		||||
    height: 1.5em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.view-tab-title:hover {
 | 
			
		||||
@@ -460,17 +474,7 @@ StTooltip StLabel {
 | 
			
		||||
.view-tab-title:selected {
 | 
			
		||||
    color: #000000;
 | 
			
		||||
    background-color: #c2c7cd;
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    height: 24px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.view-tab-boxpointer {
 | 
			
		||||
    -arrow-border-radius: 9px;
 | 
			
		||||
    -arrow-background-color: rgba(0,0,0,0.5);
 | 
			
		||||
    -arrow-border-width: 2px;
 | 
			
		||||
    -arrow-border-color: rgba(255,255,255,0.5);
 | 
			
		||||
    -arrow-base: 30px;
 | 
			
		||||
    -arrow-rise: 15px;
 | 
			
		||||
    border-radius: 0.25em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#searchResults {
 | 
			
		||||
@@ -533,7 +537,7 @@ StTooltip StLabel {
 | 
			
		||||
 | 
			
		||||
.dash-search-button-label {
 | 
			
		||||
    color: #cccccc;
 | 
			
		||||
    font-size: 16px;
 | 
			
		||||
    font-size: 12pt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Apps */
 | 
			
		||||
@@ -558,9 +562,9 @@ StTooltip StLabel {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.app-filter {
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    font-size: 10.5pt;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    height: 40px;
 | 
			
		||||
    height: 2.85em;
 | 
			
		||||
    color: #aaa;
 | 
			
		||||
    width: 200px;
 | 
			
		||||
}
 | 
			
		||||
@@ -603,7 +607,7 @@ StTooltip StLabel {
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    padding: 3px;
 | 
			
		||||
    border: 1px rgba(0,0,0,0);
 | 
			
		||||
    font-size: 10px;
 | 
			
		||||
    font-size: 7.5pt;
 | 
			
		||||
    color: white;
 | 
			
		||||
    transition-duration: 100;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
@@ -633,7 +637,7 @@ StTooltip StLabel {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.app-well-menu {
 | 
			
		||||
    font-size: 12px
 | 
			
		||||
    font-size: 9pt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* LookingGlass */
 | 
			
		||||
@@ -789,7 +793,7 @@ StTooltip StLabel {
 | 
			
		||||
 | 
			
		||||
.calendar-month-label {
 | 
			
		||||
    color: #666666;
 | 
			
		||||
    font-size: 10px;
 | 
			
		||||
    font-size: 7.5pt;
 | 
			
		||||
    padding: 2px;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
@@ -832,16 +836,16 @@ StTooltip StLabel {
 | 
			
		||||
 | 
			
		||||
.datemenu-date-label {
 | 
			
		||||
    padding: .4em 1.75em;
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    font-size: 10.5pt;
 | 
			
		||||
    color: #cccccc;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.calendar-day-base {
 | 
			
		||||
    font-size: 10px;
 | 
			
		||||
    font-size: 7.5pt;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    width: 24px;
 | 
			
		||||
    height: 24px;
 | 
			
		||||
    width: 2.4em;
 | 
			
		||||
    height: 2.4em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.calendar-day-base:hover {
 | 
			
		||||
@@ -911,7 +915,7 @@ StTooltip StLabel {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.events-day-header {
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    font-size: 9pt;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    color: rgba(153, 153, 153, 1.0);
 | 
			
		||||
    padding-left: 0.3em;
 | 
			
		||||
@@ -923,7 +927,7 @@ StTooltip StLabel {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.events-day-dayname {
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    font-size: 9pt;
 | 
			
		||||
    color: rgba(153, 153, 153, 1.0);
 | 
			
		||||
    text-align: left;
 | 
			
		||||
}
 | 
			
		||||
@@ -933,7 +937,7 @@ StTooltip StLabel {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.events-day-time {
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    font-size: 9pt;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    text-align: right;
 | 
			
		||||
}
 | 
			
		||||
@@ -943,7 +947,7 @@ StTooltip StLabel {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.events-day-task {
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    font-size: 9pt;
 | 
			
		||||
    color: rgba(153, 153, 153, 1.0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -972,13 +976,13 @@ StTooltip StLabel {
 | 
			
		||||
#message-tray {
 | 
			
		||||
    background-gradient-direction: vertical;
 | 
			
		||||
    background-gradient-start: rgba(0,0,0,0.01);
 | 
			
		||||
    background-gradient-end: rgba(0,0,0,0.95);
 | 
			
		||||
    background-gradient-end: rgba(0,0,0,0.82);
 | 
			
		||||
    height: 36px;
 | 
			
		||||
    color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#notification {
 | 
			
		||||
    font-size: 16px;
 | 
			
		||||
    font-size: 12pt;
 | 
			
		||||
    border-radius: 5px 5px 0px 0px;
 | 
			
		||||
    background: rgba(0,0,0,0.9);
 | 
			
		||||
    padding: 8px 8px 4px 8px;
 | 
			
		||||
@@ -1007,11 +1011,29 @@ StTooltip StLabel {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-boxpointer #summary-right-click-menu {
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    font-size: 10.5pt;
 | 
			
		||||
    padding-top: 12px;
 | 
			
		||||
    padding-bottom: 12px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#summary-notification-stack-scrollview {
 | 
			
		||||
    max-height: 18em;
 | 
			
		||||
    padding-top: 6px;
 | 
			
		||||
    padding-bottom: 6px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#summary-notification-stack-scrollview > .top-shadow, #summary-notification-stack-scrollview > .bottom-shadow {
 | 
			
		||||
    height: 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#summary-notification-stack-scrollview:ltr {
 | 
			
		||||
    padding-right: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#summary-notification-stack-scrollview:rtl {
 | 
			
		||||
    padding-left: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#notification-scrollview {
 | 
			
		||||
    max-height: 10em;
 | 
			
		||||
}
 | 
			
		||||
@@ -1078,6 +1100,10 @@ StTooltip StLabel {
 | 
			
		||||
    icon-size: 36px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.chat-log-message {
 | 
			
		||||
    color: #888888;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.chat-received {
 | 
			
		||||
    background-gradient-direction: horizontal;
 | 
			
		||||
    background-gradient-start: rgba(255, 255, 255, 0.2);
 | 
			
		||||
@@ -1109,7 +1135,7 @@ StTooltip StLabel {
 | 
			
		||||
.chat-meta-message {
 | 
			
		||||
    padding-left: 4px;
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    font-size: 10.5pt;
 | 
			
		||||
    color: #bbbbbb;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1158,14 +1184,32 @@ StTooltip StLabel {
 | 
			
		||||
    padding: 2px 4px 0px 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-source-button {
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    text-shadow: black 0px 2px 2px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-source-button:ltr {
 | 
			
		||||
    padding-left: 4px;
 | 
			
		||||
    padding-right: 16px;
 | 
			
		||||
    padding-right: 12px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-source-button:selected .summary-source {
 | 
			
		||||
    background-image: url("panel-button-highlight-narrow.svg");
 | 
			
		||||
    border-image: url("source-button-border.svg") 10 10 0 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-source-button:expanded:selected .summary-source {
 | 
			
		||||
    background-image: none;
 | 
			
		||||
    border-image: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-source-button:expanded:selected {
 | 
			
		||||
    background-image: url("panel-button-highlight-wide.svg");
 | 
			
		||||
    border-image: url("source-button-border.svg") 10 10 0 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-source-button:rtl {
 | 
			
		||||
    padding-right: 4px;
 | 
			
		||||
    padding-left: 16px;
 | 
			
		||||
    padding-left: 12px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-source-button:last-child:ltr {
 | 
			
		||||
@@ -1176,8 +1220,13 @@ StTooltip StLabel {
 | 
			
		||||
    padding-left: 12px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-source {
 | 
			
		||||
    padding-right: 4px;
 | 
			
		||||
    padding-left: 4px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.source-title {
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    font-size: 9pt;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    padding-left: 4px;
 | 
			
		||||
}
 | 
			
		||||
@@ -1199,7 +1248,7 @@ StTooltip StLabel {
 | 
			
		||||
    border-radius: 24px;
 | 
			
		||||
    padding: 20px;
 | 
			
		||||
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    font-size: 9pt;
 | 
			
		||||
    color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1258,7 +1307,11 @@ StTooltip StLabel {
 | 
			
		||||
.ripple-box {
 | 
			
		||||
    width: 52px;
 | 
			
		||||
    height: 52px;
 | 
			
		||||
    background-image: url("corner-ripple.png");
 | 
			
		||||
    background-image: url("corner-ripple-ltr.png");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ripple-box:rtl {
 | 
			
		||||
    background-image: url("corner-ripple-rtl.png");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.switcher-arrow {
 | 
			
		||||
@@ -1328,10 +1381,14 @@ StTooltip StLabel {
 | 
			
		||||
    padding-top: 30px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.modal-dialog-button-box {
 | 
			
		||||
    spacing: 21px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.modal-dialog-button {
 | 
			
		||||
    border: 1px solid #8b8b8b;
 | 
			
		||||
    border-radius: 18px;
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    font-size: 10.5pt;
 | 
			
		||||
 | 
			
		||||
    margin-left: 10px;
 | 
			
		||||
    margin-right: 10px;
 | 
			
		||||
@@ -1364,12 +1421,12 @@ StTooltip StLabel {
 | 
			
		||||
 | 
			
		||||
/* Run Dialog */
 | 
			
		||||
.run-dialog-label {
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    font-size: 9pt;
 | 
			
		||||
    color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.run-dialog-error-label {
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    font-size: 9pt;
 | 
			
		||||
    color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1379,9 +1436,9 @@ StTooltip StLabel {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.run-dialog-entry {
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    font-size: 10.5pt;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    width: 320px;
 | 
			
		||||
    width: 23em;
 | 
			
		||||
    color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1399,6 +1456,10 @@ StTooltip StLabel {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* End Session Dialog */
 | 
			
		||||
.end-session-dialog {
 | 
			
		||||
    spacing: 42px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.end-session-dialog-subject {
 | 
			
		||||
    font-size: 12pt;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
@@ -1417,13 +1478,11 @@ StTooltip StLabel {
 | 
			
		||||
    font-size: 10pt;
 | 
			
		||||
    color: white;
 | 
			
		||||
    padding-left: 17px;
 | 
			
		||||
    padding-right: 40px;
 | 
			
		||||
    width: 16em;
 | 
			
		||||
    width: 28em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.end-session-dialog-description:rtl {
 | 
			
		||||
    padding-right: 17px;
 | 
			
		||||
    padding-left: 40px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.end-session-dialog-logout-icon {
 | 
			
		||||
@@ -1442,16 +1501,23 @@ StTooltip StLabel {
 | 
			
		||||
    font-size: 10pt;
 | 
			
		||||
    max-height: 200px;
 | 
			
		||||
    padding-top: 42px;
 | 
			
		||||
    padding-bottom: 42px;
 | 
			
		||||
    padding-left: 17px;
 | 
			
		||||
    padding-left: 49px;
 | 
			
		||||
    padding-right: 32px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.end-session-dialog-app-list:rtl {
 | 
			
		||||
    padding-right: 17px;
 | 
			
		||||
    padding-right: 49px;
 | 
			
		||||
    padding-left: 32px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.end-session-dialog-app-list-item {
 | 
			
		||||
    color: #ccc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.end-session-dialog-app-list-item:hover {
 | 
			
		||||
    color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.end-session-dialog-app-list-item:ltr {
 | 
			
		||||
    padding-right: 1em;
 | 
			
		||||
}
 | 
			
		||||
@@ -1484,12 +1550,12 @@ StTooltip StLabel {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.polkit-dialog-main-layout {
 | 
			
		||||
    spacing: 10px;
 | 
			
		||||
    spacing: 24px;
 | 
			
		||||
    padding: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.polkit-dialog-message-layout {
 | 
			
		||||
    spacing: 10px;
 | 
			
		||||
    spacing: 16px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.polkit-dialog-headline {
 | 
			
		||||
@@ -1513,6 +1579,10 @@ StTooltip StLabel {
 | 
			
		||||
    padding-right: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.polkit-dialog-user-root-label {
 | 
			
		||||
    color: #ff0000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.polkit-dialog-password-label:ltr {
 | 
			
		||||
    padding-right: 0.5em;
 | 
			
		||||
}
 | 
			
		||||
@@ -1528,33 +1598,21 @@ StTooltip StLabel {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.polkit-dialog-error-label {
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.polkit-dialog-error-box {
 | 
			
		||||
    padding-top: 15px;
 | 
			
		||||
    spacing: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.polkit-dialog-checking-label {
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.polkit-dialog-checking-box {
 | 
			
		||||
    padding-top: 15px;
 | 
			
		||||
    spacing: 5px;
 | 
			
		||||
    font-size: 10pt;
 | 
			
		||||
    color: #ffff00;
 | 
			
		||||
    padding-bottom: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.polkit-dialog-info-label {
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    color: white;
 | 
			
		||||
    font-size: 10pt;
 | 
			
		||||
    padding-bottom: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.polkit-dialog-info-box {
 | 
			
		||||
    padding-top: 15px;
 | 
			
		||||
    spacing: 5px;
 | 
			
		||||
/* intentionally left transparent to avoid dialog changing size */
 | 
			
		||||
.polkit-dialog-null-label {
 | 
			
		||||
    font-size: 10pt;
 | 
			
		||||
    color: rgba(0,0,0,0);
 | 
			
		||||
    padding-bottom: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										74
									
								
								data/theme/source-button-border.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								data/theme/source-button-border.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="21"
 | 
			
		||||
   height="10"
 | 
			
		||||
   id="svg2"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.48.0 r9654"
 | 
			
		||||
   sodipodi:docname="source-button-border.svg">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#000000"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="44.8"
 | 
			
		||||
     inkscape:cx="8.704132"
 | 
			
		||||
     inkscape:cy="5.7029946"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="true"
 | 
			
		||||
     showguides="true"
 | 
			
		||||
     inkscape:guide-bbox="true"
 | 
			
		||||
     inkscape:window-width="1600"
 | 
			
		||||
     inkscape:window-height="1145"
 | 
			
		||||
     inkscape:window-x="0"
 | 
			
		||||
     inkscape:window-y="26"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     guidetolerance="10000"
 | 
			
		||||
     objecttolerance="10000">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid3792"
 | 
			
		||||
       empspacing="10"
 | 
			
		||||
       visible="true"
 | 
			
		||||
       enabled="true"
 | 
			
		||||
       snapvisiblegridlinesonly="true" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata7">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1">
 | 
			
		||||
    <rect
 | 
			
		||||
       style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none"
 | 
			
		||||
       id="rect3796"
 | 
			
		||||
       width="19"
 | 
			
		||||
       height="2"
 | 
			
		||||
       x="1"
 | 
			
		||||
       y="8" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 2.0 KiB  | 
@@ -6,6 +6,22 @@
 | 
			
		||||
 | 
			
		||||
  <name xml:lang="en">GNOME Shell</name>
 | 
			
		||||
  <shortdesc xml:lang="en">Next generation GNOME desktop shell</shortdesc>
 | 
			
		||||
  <description>GNOME Shell provides core user interface functions for the GNOME 3
 | 
			
		||||
desktop, like switching to windows and launching applications.
 | 
			
		||||
GNOME Shell takes advantage of the capabilities of modern graphics
 | 
			
		||||
hardware and introduces innovative user interface concepts to
 | 
			
		||||
provide a visually attractive and easy to use experience.
 | 
			
		||||
 | 
			
		||||
Tarball releases are provided largely for distributions to build
 | 
			
		||||
packages. If you are interested in building GNOME Shell from source,
 | 
			
		||||
we would recommend building from version control using the build
 | 
			
		||||
script described at:
 | 
			
		||||
 | 
			
		||||
 http://live.gnome.org/GnomeShell
 | 
			
		||||
 | 
			
		||||
Not only will that give you the very latest version of this rapidly
 | 
			
		||||
changing project, it will be much easier than get GNOME Shell and
 | 
			
		||||
its dependencies to build from tarballs.</description>
 | 
			
		||||
  <!--
 | 
			
		||||
  <homepage rdf:resource="http://live.gnome.org/GnomeShell" />
 | 
			
		||||
  -->
 | 
			
		||||
 
 | 
			
		||||
@@ -8,8 +8,11 @@ nobase_dist_js_DATA = 	\
 | 
			
		||||
	misc/format.js		\
 | 
			
		||||
	misc/gnomeSession.js	\
 | 
			
		||||
	misc/history.js		\
 | 
			
		||||
	misc/modemManager.js	\
 | 
			
		||||
	misc/params.js		\
 | 
			
		||||
	misc/semantic.js	\
 | 
			
		||||
	misc/util.js		\
 | 
			
		||||
	misc/zeitgeist.js	\
 | 
			
		||||
	perf/core.js		\
 | 
			
		||||
	ui/altTab.js		\
 | 
			
		||||
	ui/appDisplay.js	\
 | 
			
		||||
@@ -21,7 +24,6 @@ nobase_dist_js_DATA = 	\
 | 
			
		||||
	ui/dash.js		\
 | 
			
		||||
	ui/dateMenu.js		\
 | 
			
		||||
	ui/dnd.js		\
 | 
			
		||||
	ui/docDisplay.js	\
 | 
			
		||||
	ui/endSessionDialog.js	\
 | 
			
		||||
	ui/environment.js	\
 | 
			
		||||
	ui/extensionSystem.js	\
 | 
			
		||||
@@ -50,6 +52,7 @@ nobase_dist_js_DATA = 	\
 | 
			
		||||
	ui/statusMenu.js	\
 | 
			
		||||
	ui/status/accessibility.js	\
 | 
			
		||||
	ui/status/keyboard.js	\
 | 
			
		||||
	ui/status/network.js	\
 | 
			
		||||
	ui/status/power.js	\
 | 
			
		||||
	ui/status/volume.js	\
 | 
			
		||||
	ui/status/bluetooth.js	\
 | 
			
		||||
@@ -62,4 +65,5 @@ nobase_dist_js_DATA = 	\
 | 
			
		||||
	ui/workspaceThumbnail.js	\
 | 
			
		||||
	ui/workspacesView.js	\
 | 
			
		||||
	ui/workspaceSwitcherPopup.js    \
 | 
			
		||||
	ui/xdndHandler.js
 | 
			
		||||
	ui/xdndHandler.js	\
 | 
			
		||||
	ui/zeitgeistSearch.js
 | 
			
		||||
 
 | 
			
		||||
@@ -1,36 +1,32 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 | 
			
		||||
 | 
			
		||||
const St = imports.gi.St;
 | 
			
		||||
const Shell = imports.gi.Shell;
 | 
			
		||||
const Lang = imports.lang;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
const Search = imports.ui.search;
 | 
			
		||||
 | 
			
		||||
const THUMBNAIL_ICON_MARGIN = 2;
 | 
			
		||||
 | 
			
		||||
function DocInfo(recentInfo) {
 | 
			
		||||
    this._init(recentInfo);
 | 
			
		||||
function ZeitgeistItemInfo(event) {
 | 
			
		||||
    this._init(event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DocInfo.prototype = {
 | 
			
		||||
    _init : function(recentInfo) {
 | 
			
		||||
        this.recentInfo = recentInfo;
 | 
			
		||||
        // We actually used get_modified() instead of get_visited()
 | 
			
		||||
        // here, as GtkRecentInfo doesn't updated get_visited()
 | 
			
		||||
        // correctly. See http://bugzilla.gnome.org/show_bug.cgi?id=567094
 | 
			
		||||
        this.timestamp = recentInfo.get_modified();
 | 
			
		||||
        this.name = recentInfo.get_display_name();
 | 
			
		||||
ZeitgeistItemInfo.prototype = {
 | 
			
		||||
    _init : function(event) {
 | 
			
		||||
        this.event = event;
 | 
			
		||||
        this.subject = event.subjects[0];
 | 
			
		||||
        this.timestamp = event.timestamp;
 | 
			
		||||
        this.name = this.subject.text;
 | 
			
		||||
        this._lowerName = this.name.toLowerCase();
 | 
			
		||||
        this.uri = recentInfo.get_uri();
 | 
			
		||||
        this.mimeType = recentInfo.get_mime_type();
 | 
			
		||||
        this.uri = this.subject.uri;
 | 
			
		||||
        this.mimeType = this.subject.mimetype;
 | 
			
		||||
        this.interpretation = this.subject.interpretation;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    createIcon : function(size) {
 | 
			
		||||
        return St.TextureCache.get_default().load_recent_thumbnail(size, this.recentInfo);
 | 
			
		||||
        return St.TextureCache.get_default().load_thumbnail(size, this.uri, this.subject.mimetype);
 | 
			
		||||
        // FIXME: We should consider caching icons
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    launch : function(workspaceIndex) {
 | 
			
		||||
        Shell.DocSystem.get_default().open(this.recentInfo, workspaceIndex);
 | 
			
		||||
    launch : function() {
 | 
			
		||||
        Gio.app_info_launch_default_for_uri(this.uri,
 | 
			
		||||
                                            global.create_app_launch_context());
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    matchTerms: function(terms) {
 | 
			
		||||
@@ -48,93 +44,5 @@ DocInfo.prototype = {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return mtype;
 | 
			
		||||
    }
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var docManagerInstance = null;
 | 
			
		||||
 | 
			
		||||
function getDocManager() {
 | 
			
		||||
    if (docManagerInstance == null)
 | 
			
		||||
        docManagerInstance = new DocManager();
 | 
			
		||||
    return docManagerInstance;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * DocManager wraps the DocSystem, primarily to expose DocInfo objects.
 | 
			
		||||
 */
 | 
			
		||||
function DocManager() {
 | 
			
		||||
    this._init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DocManager.prototype = {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._docSystem = Shell.DocSystem.get_default();
 | 
			
		||||
        this._infosByTimestamp = [];
 | 
			
		||||
        this._infosByUri = {};
 | 
			
		||||
        this._docSystem.connect('changed', Lang.bind(this, this._reload));
 | 
			
		||||
        this._reload();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _reload: function() {
 | 
			
		||||
        let docs = this._docSystem.get_all();
 | 
			
		||||
        this._infosByTimestamp = [];
 | 
			
		||||
        this._infosByUri = {};
 | 
			
		||||
        for (let i = 0; i < docs.length; i++) {
 | 
			
		||||
            let recentInfo = docs[i];
 | 
			
		||||
 | 
			
		||||
            let docInfo = new DocInfo(recentInfo);
 | 
			
		||||
            this._infosByTimestamp.push(docInfo);
 | 
			
		||||
            this._infosByUri[docInfo.uri] = docInfo;
 | 
			
		||||
        }
 | 
			
		||||
        this.emit('changed');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getTimestampOrderedInfos: function() {
 | 
			
		||||
        return this._infosByTimestamp;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getInfosByUri: function() {
 | 
			
		||||
        return this._infosByUri;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    lookupByUri: function(uri) {
 | 
			
		||||
        return this._infosByUri[uri];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    queueExistenceCheck: function(count) {
 | 
			
		||||
        return this._docSystem.queue_existence_check(count);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _searchDocs: function(items, terms) {
 | 
			
		||||
        let multiplePrefixMatches = [];
 | 
			
		||||
        let prefixMatches = [];
 | 
			
		||||
        let multipleSubtringMatches = [];
 | 
			
		||||
        let substringMatches = [];
 | 
			
		||||
        for (let i = 0; i < items.length; i++) {
 | 
			
		||||
            let item = items[i];
 | 
			
		||||
            let mtype = item.matchTerms(terms);
 | 
			
		||||
            if (mtype == Search.MatchType.MULTIPLE_PREFIX)
 | 
			
		||||
                multiplePrefixMatches.push(item.uri);
 | 
			
		||||
            else if (mtype == Search.MatchType.PREFIX)
 | 
			
		||||
                prefixMatches.push(item.uri);
 | 
			
		||||
            else if (mtype == Search.MatchType.MULTIPLE_SUBSTRING)
 | 
			
		||||
                multipleSubtringMatches.push(item.uri);
 | 
			
		||||
            else if (mtype == Search.MatchType.SUBSTRING)
 | 
			
		||||
                substringMatches.push(item.uri);
 | 
			
		||||
         }
 | 
			
		||||
        return multiplePrefixMatches.concat(prefixMatches.concat(multipleSubtringMatches.concat(substringMatches)));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    initialSearch: function(terms) {
 | 
			
		||||
        return this._searchDocs(this._infosByTimestamp, terms);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    subsearch: function(previousResults, terms) {
 | 
			
		||||
        return this._searchDocs(previousResults.map(Lang.bind(this,
 | 
			
		||||
            function(url) {
 | 
			
		||||
                return this._infosByUri[url];
 | 
			
		||||
            })), terms);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Signals.addSignalMethods(DocManager.prototype);
 | 
			
		||||
 
 | 
			
		||||
@@ -102,3 +102,24 @@ Inhibitor.prototype = {
 | 
			
		||||
};
 | 
			
		||||
DBus.proxifyPrototype(Inhibitor.prototype, InhibitorIface);
 | 
			
		||||
Signals.addSignalMethods(Inhibitor.prototype);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Not the full interface, only the methods we use
 | 
			
		||||
const SessionManagerIface = {
 | 
			
		||||
    name: 'org.gnome.SessionManager',
 | 
			
		||||
    methods: [
 | 
			
		||||
        { name: 'Logout', inSignature: 'u', outSignature: '' },
 | 
			
		||||
        { name: 'Shutdown', inSignature: '', outSignature: '' }
 | 
			
		||||
    ]
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function SessionManager() {
 | 
			
		||||
    this._init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SessionManager.prototype = {
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        DBus.session.proxifyObject(this, 'org.gnome.SessionManager', '/org/gnome/SessionManager');
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
DBus.proxifyPrototype(SessionManager.prototype, SessionManagerIface);
 | 
			
		||||
							
								
								
									
										225
									
								
								js/misc/modemManager.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								js/misc/modemManager.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,225 @@
 | 
			
		||||
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
 | 
			
		||||
 | 
			
		||||
const DBus = imports.dbus;
 | 
			
		||||
const Lang = imports.lang;
 | 
			
		||||
const Shell = imports.gi.Shell;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
 | 
			
		||||
// The following are not the complete interfaces, just the methods we need
 | 
			
		||||
// (or may need in the future)
 | 
			
		||||
 | 
			
		||||
const ModemGsmNetworkInterface = {
 | 
			
		||||
    name: 'org.freedesktop.ModemManager.Modem.Gsm.Network',
 | 
			
		||||
    methods: [
 | 
			
		||||
        { name: 'GetRegistrationInfo', inSignature: '', outSignature: 'uss' },
 | 
			
		||||
        { name: 'GetSignalQuality', inSignature: '', outSignature: 'u' }
 | 
			
		||||
    ],
 | 
			
		||||
    properties: [
 | 
			
		||||
        { name: 'AccessTechnology', signature: 'u', access: 'read' }
 | 
			
		||||
    ],
 | 
			
		||||
    signals: [
 | 
			
		||||
        { name: 'SignalQuality', inSignature: 'u' },
 | 
			
		||||
        { name: 'RegistrationInfo', inSignature: 'uss' }
 | 
			
		||||
    ]
 | 
			
		||||
};
 | 
			
		||||
const ModemGsmNetworkProxy = DBus.makeProxyClass(ModemGsmNetworkInterface);
 | 
			
		||||
 | 
			
		||||
const ModemCdmaInterface = {
 | 
			
		||||
    name: 'org.freedesktop.ModemManager.Modem.Cdma',
 | 
			
		||||
    methods: [
 | 
			
		||||
        { name: 'GetSignalQuality', inSignature: '', outSignature: 'u' },
 | 
			
		||||
        { name: 'GetServingSystem', inSignature: '', outSignature: 'usu' }
 | 
			
		||||
    ],
 | 
			
		||||
    signals: [
 | 
			
		||||
        { name: 'SignalQuality', inSignature: 'u' }
 | 
			
		||||
    ]
 | 
			
		||||
};
 | 
			
		||||
const ModemCdmaProxy = DBus.makeProxyClass(ModemCdmaInterface);
 | 
			
		||||
 | 
			
		||||
let _providersTable;
 | 
			
		||||
function _getProvidersTable() {
 | 
			
		||||
    if (_providersTable)
 | 
			
		||||
        return _providersTable;
 | 
			
		||||
    let [providers, countryCodes] = Shell.mobile_providers_parse();
 | 
			
		||||
    return _providersTable = providers;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function ModemGsm() {
 | 
			
		||||
    this._init.apply(this, arguments);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemGsm.prototype = {
 | 
			
		||||
    _init: function(path) {
 | 
			
		||||
        this._proxy = new ModemGsmNetworkProxy(DBus.system, 'org.freedesktop.ModemManager', path);
 | 
			
		||||
 | 
			
		||||
        this.signal_quality = 0;
 | 
			
		||||
        this.operator_name = null;
 | 
			
		||||
 | 
			
		||||
        // Code is duplicated because the function have different signatures
 | 
			
		||||
        this._proxy.connect('SignalQuality', Lang.bind(this, function(proxy, quality) {
 | 
			
		||||
            this.signal_quality = quality;
 | 
			
		||||
            this.emit('notify::signal-quality');
 | 
			
		||||
        }));
 | 
			
		||||
        this._proxy.connect('RegistrationInfo', Lang.bind(this, function(proxy, status, code, name) {
 | 
			
		||||
            this.operator_name = this._findOperatorName(name, code);
 | 
			
		||||
            this.emit('notify::operator-name');
 | 
			
		||||
        }));
 | 
			
		||||
        this._proxy.GetRegistrationInfoRemote(Lang.bind(this, function(result, err) {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                log(err);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let [status, code, name] = result;
 | 
			
		||||
            this.operator_name = this._findOperatorName(name, code);
 | 
			
		||||
            this.emit('notify::operator-name');
 | 
			
		||||
        }));
 | 
			
		||||
        this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                // it will return an error if the device is not connected
 | 
			
		||||
                this.signal_quality = 0;
 | 
			
		||||
            } else {
 | 
			
		||||
                let [quality] = result;
 | 
			
		||||
                this.signal_quality = quality;
 | 
			
		||||
            }
 | 
			
		||||
            this.emit('notify::signal-quality');
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _findOperatorName: function(name, opCode) {
 | 
			
		||||
        if (name.length != 0 && (name.length > 6 || name.length < 5)) {
 | 
			
		||||
            // this looks like a valid name, i.e. not an MCCMNC (that some
 | 
			
		||||
            // devices return when not yet connected
 | 
			
		||||
            return name;
 | 
			
		||||
        }
 | 
			
		||||
        if (isNaN(parseInt(name))) {
 | 
			
		||||
            // name is definitely not a MCCMNC, so it may be a name
 | 
			
		||||
            // after all; return that
 | 
			
		||||
            return name;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let needle;
 | 
			
		||||
        if (name.length == 0 && opCode)
 | 
			
		||||
            needle = opCode;
 | 
			
		||||
        else if (name.length == 6 || name.length == 5)
 | 
			
		||||
            needle = name;
 | 
			
		||||
        else // nothing to search
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
        return this._findProviderForMCCMNC(needle);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _findProviderForMCCMNC: function(needle) {
 | 
			
		||||
        let table = _getProvidersTable();
 | 
			
		||||
        let needlemcc = needle.substring(0, 3);
 | 
			
		||||
        let needlemnc = needle.substring(3, needle.length);
 | 
			
		||||
 | 
			
		||||
        let name2, name3;
 | 
			
		||||
        for (let iter in table) {
 | 
			
		||||
            let providers = table[iter];
 | 
			
		||||
 | 
			
		||||
            // Search through each country's providers
 | 
			
		||||
            for (let i = 0; i < providers.length; i++) {
 | 
			
		||||
                let provider = providers[i];
 | 
			
		||||
 | 
			
		||||
                // Search through MCC/MNC list
 | 
			
		||||
                let list = provider.get_gsm_mcc_mnc();
 | 
			
		||||
                for (let j = 0; j < list.length; j++) {
 | 
			
		||||
                    let mccmnc = list[j];
 | 
			
		||||
 | 
			
		||||
                    // Match both 2-digit and 3-digit MNC; prefer a
 | 
			
		||||
                    // 3-digit match if found, otherwise a 2-digit one.
 | 
			
		||||
                    if (mccmnc.mcc != needlemcc)
 | 
			
		||||
                        continue;  // MCC was wrong
 | 
			
		||||
 | 
			
		||||
                    if (!name3 && needle.length == 6 && needlemnc == mccmnc.mnc)
 | 
			
		||||
                        name3 = provider.name;
 | 
			
		||||
 | 
			
		||||
                    if (!name2 && needlemnc.substring(0, 2) == mccmnc.mnc.substring(0, 2))
 | 
			
		||||
                        name2 = provider.name;
 | 
			
		||||
 | 
			
		||||
                    if (name2 && name3)
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return name3 || name2 || null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
Signals.addSignalMethods(ModemGsm.prototype);
 | 
			
		||||
 | 
			
		||||
function ModemCdma() {
 | 
			
		||||
    this._init.apply(this, arguments);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModemCdma.prototype = {
 | 
			
		||||
    _init: function(path) {
 | 
			
		||||
        this._proxy = new ModemCdmaProxy(DBus.system, 'org.freedesktop.ModemManager', path);
 | 
			
		||||
 | 
			
		||||
        this.signal_quality = 0;
 | 
			
		||||
        this.operator_name = null;
 | 
			
		||||
        this._proxy.connect('SignalQuality', Lang.bind(this, function(proxy, quality) {
 | 
			
		||||
            this.signal_quality = quality;
 | 
			
		||||
            this.emit('notify::signal-quality');
 | 
			
		||||
 | 
			
		||||
            // receiving this signal means the device got activated
 | 
			
		||||
            // and we can finally call GetServingSystem
 | 
			
		||||
            if (this.operator_name == null)
 | 
			
		||||
                this._refreshServingSystem();
 | 
			
		||||
        }));
 | 
			
		||||
        this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                // it will return an error if the device is not connected
 | 
			
		||||
                this.signal_quality = 0;
 | 
			
		||||
            } else {
 | 
			
		||||
                let [quality] = result;
 | 
			
		||||
                this.signal_quality = quality;
 | 
			
		||||
            }
 | 
			
		||||
            this.emit('notify::signal-quality');
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _refreshServingSystem: function() {
 | 
			
		||||
        this._proxy.GetServingSystemRemote(Lang.bind(this, function(result, err) {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                // it will return an error if the device is not connected
 | 
			
		||||
                this.operator_name = null;
 | 
			
		||||
            } else {
 | 
			
		||||
                let [bandClass, band, id] = result;
 | 
			
		||||
                if (name.length > 0)
 | 
			
		||||
                    this.operator_name = this._findProviderForSid(id);
 | 
			
		||||
                else
 | 
			
		||||
                    this.operator_name = null;
 | 
			
		||||
            }
 | 
			
		||||
            this.emit('notify::operator-name');
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _findProviderForSid: function(sid) {
 | 
			
		||||
        if (sid == 0)
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
        let table = _getProvidersTable();
 | 
			
		||||
 | 
			
		||||
        // Search through each country
 | 
			
		||||
        for (let iter in table) {
 | 
			
		||||
            let providers = table[iter];
 | 
			
		||||
 | 
			
		||||
            // Search through each country's providers
 | 
			
		||||
            for (let i = 0; i < providers.length; i++) {
 | 
			
		||||
                let provider = providers[i];
 | 
			
		||||
                let cdma_sid = provider.get_cdma_sid();
 | 
			
		||||
 | 
			
		||||
                // Search through CDMA SID list
 | 
			
		||||
                for (let j = 0; j < cdma_sid.length; j++) {
 | 
			
		||||
                    if (cdma_sid[j] == sid)
 | 
			
		||||
                        return provider.name;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(ModemCdma.prototype);
 | 
			
		||||
							
								
								
									
										43
									
								
								js/misc/semantic.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								js/misc/semantic.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
 *
 | 
			
		||||
 * Semantic-desktop interpretations for various data types
 | 
			
		||||
 *
 | 
			
		||||
 * Authors: Federico Mena Quintero <federico@gnome.org>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2, or (at your option)
 | 
			
		||||
 * any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
const NFO_AUDIO                   = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Audio";
 | 
			
		||||
const NFO_DOCUMENT                = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Document";
 | 
			
		||||
const NFO_HTML_DOCUMENT           = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#HtmlDocument";
 | 
			
		||||
const NFO_IMAGE                   = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Image";
 | 
			
		||||
const NFO_MEDIA                   = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Media";
 | 
			
		||||
const NFO_MIND_MAP                = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#MindMap";
 | 
			
		||||
const NFO_PAGINATED_TEXT_DOCUMENT = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#PaginatedTextDocument";
 | 
			
		||||
const NFO_PLAIN_TEXT_DOCUMENT     = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#PlainTextDocument";
 | 
			
		||||
const NFO_PRESENTATION            = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Presentation";
 | 
			
		||||
const NFO_RASTER_IMAGE            = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#RasterImage";
 | 
			
		||||
const NFO_SOURCE_CODE             = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#SourceCode";
 | 
			
		||||
const NFO_SPREADSHEET             = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Spreadsheet";
 | 
			
		||||
const NFO_TEXT_DOCUMENT           = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#TextDocument";
 | 
			
		||||
const NFO_VECTOR_IMAGE            = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#VectorImage";
 | 
			
		||||
const NFO_VIDEO                   = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Video";
 | 
			
		||||
 | 
			
		||||
const NMM_CURSOR                  = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#Cursor";
 | 
			
		||||
const NMM_ICON                    = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#Icon";
 | 
			
		||||
const NMM_MOVIE                   = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#Movie";
 | 
			
		||||
const NMM_MUSIC_PIECE             = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#MusicPiece";
 | 
			
		||||
const NMM_TV_SHOW                 = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#TVShow";
 | 
			
		||||
							
								
								
									
										129
									
								
								js/misc/util.js
									
									
									
									
									
								
							
							
						
						
									
										129
									
								
								js/misc/util.js
									
									
									
									
									
								
							@@ -6,7 +6,6 @@ const GLib = imports.gi.GLib;
 | 
			
		||||
const Shell = imports.gi.Shell;
 | 
			
		||||
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const MessageTray = imports.ui.messageTray;
 | 
			
		||||
 | 
			
		||||
const Gettext = imports.gettext.domain('gnome-shell');
 | 
			
		||||
const _ = Gettext.gettext;
 | 
			
		||||
@@ -56,20 +55,6 @@ function spawnCommandLine(command_line) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// spawnDesktop:
 | 
			
		||||
// @id: a desktop file ID
 | 
			
		||||
//
 | 
			
		||||
// Spawns the desktop file identified by @id using startup notification,
 | 
			
		||||
// etc, handling any errors that occur when trying to find or start
 | 
			
		||||
// the program.
 | 
			
		||||
function spawnDesktop(id) {
 | 
			
		||||
    try {
 | 
			
		||||
        trySpawnDesktop(id);
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
        _handleSpawnError(id, err);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// trySpawn:
 | 
			
		||||
// @argv: an argv array
 | 
			
		||||
//
 | 
			
		||||
@@ -117,41 +102,9 @@ function trySpawnCommandLine(command_line) {
 | 
			
		||||
    trySpawn(argv);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// trySpawnDesktop:
 | 
			
		||||
// @id: a desktop file ID
 | 
			
		||||
//
 | 
			
		||||
// Spawns the desktop file identified by @id using startup notification.
 | 
			
		||||
// On error, throws an exception.
 | 
			
		||||
function trySpawnDesktop(id) {
 | 
			
		||||
    let app;
 | 
			
		||||
 | 
			
		||||
    // shell_app_system_load_from_desktop_file() will end up returning
 | 
			
		||||
    // a stupid error message if the desktop file doesn't exist, but
 | 
			
		||||
    // that's the only case it returns an error for, so we just
 | 
			
		||||
    // substitute our own error in instead
 | 
			
		||||
    try {
 | 
			
		||||
        app = Shell.AppSystem.get_default().load_from_desktop_file(id + '.desktop');
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
        throw new Error(_("No such application"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        app.launch();
 | 
			
		||||
    } catch(err) {
 | 
			
		||||
        // see trySpawn
 | 
			
		||||
        err.message = err.message.replace(/.*\((.+)\)/, '$1');
 | 
			
		||||
        throw err;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _handleSpawnError(command, err) {
 | 
			
		||||
    let title = _("Execution of '%s' failed:").format(command);
 | 
			
		||||
 | 
			
		||||
    let source = new MessageTray.SystemNotificationSource();
 | 
			
		||||
    Main.messageTray.add(source);
 | 
			
		||||
    let notification = new MessageTray.Notification(source, title, err.message);
 | 
			
		||||
    notification.setTransient(true);
 | 
			
		||||
    source.notify(notification);
 | 
			
		||||
    Main.notifyError(title, err.message);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// killall:
 | 
			
		||||
@@ -178,3 +131,83 @@ function killall(processName) {
 | 
			
		||||
        logError(e, 'Failed to kill ' + processName);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This was ported from network-manager-applet
 | 
			
		||||
// Copyright 2007 - 2011 Red Hat, Inc.
 | 
			
		||||
// Author: Dan Williams <dcbw@redhat.com>
 | 
			
		||||
 | 
			
		||||
const _IGNORED_WORDS = [
 | 
			
		||||
        'Semiconductor',
 | 
			
		||||
        'Components',
 | 
			
		||||
        'Corporation',
 | 
			
		||||
        'Communications',
 | 
			
		||||
        'Company',
 | 
			
		||||
        'Corp.',
 | 
			
		||||
        'Corp',
 | 
			
		||||
        'Co.',
 | 
			
		||||
        'Inc.',
 | 
			
		||||
        'Inc',
 | 
			
		||||
        'Incorporated',
 | 
			
		||||
        'Ltd.',
 | 
			
		||||
        'Limited.',
 | 
			
		||||
        'Intel?',
 | 
			
		||||
        'chipset',
 | 
			
		||||
        'adapter',
 | 
			
		||||
        '[hex]',
 | 
			
		||||
        'NDIS',
 | 
			
		||||
        'Module'
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
const _IGNORED_PHRASES = [
 | 
			
		||||
        'Multiprotocol MAC/baseband processor',
 | 
			
		||||
        'Wireless LAN Controller',
 | 
			
		||||
        'Wireless LAN Adapter',
 | 
			
		||||
        'Wireless Adapter',
 | 
			
		||||
        'Network Connection',
 | 
			
		||||
        'Wireless Cardbus Adapter',
 | 
			
		||||
        'Wireless CardBus Adapter',
 | 
			
		||||
        '54 Mbps Wireless PC Card',
 | 
			
		||||
        'Wireless PC Card',
 | 
			
		||||
        'Wireless PC',
 | 
			
		||||
        'PC Card with XJACK(r) Antenna',
 | 
			
		||||
        'Wireless cardbus',
 | 
			
		||||
        'Wireless LAN PC Card',
 | 
			
		||||
        'Technology Group Ltd.',
 | 
			
		||||
        'Communication S.p.A.',
 | 
			
		||||
        'Business Mobile Networks BV',
 | 
			
		||||
        'Mobile Broadband Minicard Composite Device',
 | 
			
		||||
        'Mobile Communications AB',
 | 
			
		||||
        '(PC-Suite Mode)'
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
function fixupPCIDescription(desc) {
 | 
			
		||||
    desc.replace(/[_,]/, ' ');
 | 
			
		||||
 | 
			
		||||
    /* Attempt to shorten ID by ignoring certain phrases */
 | 
			
		||||
    for (let i = 0; i < _IGNORED_PHRASES.length; i++) {
 | 
			
		||||
        let item = _IGNORED_PHRASES[i];
 | 
			
		||||
        let pos = desc.indexOf(item);
 | 
			
		||||
        if (pos != -1) {
 | 
			
		||||
            let before = desc.substring(0, pos);
 | 
			
		||||
            let after = desc.substring(pos + item.length, desc.length);
 | 
			
		||||
            desc = before + after;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Attmept to shorten ID by ignoring certain individual words */
 | 
			
		||||
    let words = desc.split(' ');
 | 
			
		||||
    let out = [ ];
 | 
			
		||||
    for (let i = 0; i < words; i++) {
 | 
			
		||||
        let item = words[i];
 | 
			
		||||
 | 
			
		||||
        // skip empty items (that come out from consecutive spaces)
 | 
			
		||||
        if (item.length == 0)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        if (_IGNORED_WORDS.indexOf(item) == -1) {
 | 
			
		||||
            out.push(item);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return out.join(' ');
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										264
									
								
								js/misc/zeitgeist.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										264
									
								
								js/misc/zeitgeist.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,264 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010 Seif Lotfy <seif@lotfy.com>
 | 
			
		||||
 * Copyright (C) 2011 Siegfried-Angel Gevatter Pujals <siegfried@gevatter.com>
 | 
			
		||||
 * Copyright (C) 2010-2011 Collabora Ltd.
 | 
			
		||||
 *     Authored by: Seif Lotfy <seif@lotfy.com>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2, or (at your option)
 | 
			
		||||
 * any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
const DBus = imports.dbus;
 | 
			
		||||
 | 
			
		||||
const SIG_EVENT = '(asaasay)';
 | 
			
		||||
const MAX_TIMESTAMP = 9999999999999;
 | 
			
		||||
 | 
			
		||||
// Number of results given by fullTextSearch; 100 is probably enough.
 | 
			
		||||
// Note: We can't currently increase this number to anything above 132, due to
 | 
			
		||||
// https://bugs.launchpad.net/zeitgeist-extensions/+bug/716503
 | 
			
		||||
const MAX_RESULTS = 100;
 | 
			
		||||
 | 
			
		||||
const ResultType = {
 | 
			
		||||
    // http://zeitgeist-project.com/docs/0.6/datamodel.html#resulttype
 | 
			
		||||
    // It's unfortunate to have to define these by hand; maybe if D-Bus had a way to introspect enums...
 | 
			
		||||
    MOST_RECENT_EVENTS                   : 0,
 | 
			
		||||
    LEAST_RECENT_EVENTS                  : 1,
 | 
			
		||||
    MOST_RECENT_SUBJECTS                 : 2,
 | 
			
		||||
    LEAST_RECENT_SUBJECTS                : 3,
 | 
			
		||||
    MOST_POPULAR_SUBJECTS                : 4,
 | 
			
		||||
    LEAST_POPULAR_SUBJECTS               : 5,
 | 
			
		||||
    MOST_POPULAR_ACTOR                   : 6,
 | 
			
		||||
    LEAST_POPULAR_ACTOR                  : 7,
 | 
			
		||||
    MOST_RECENT_ACTOR                    : 8,
 | 
			
		||||
    LEAST_RECENT_ACTOR                   : 9,
 | 
			
		||||
    MOST_RECENT_ORIGIN                   : 10,
 | 
			
		||||
    LEAST_RECENT_ORIGIN                  : 11,
 | 
			
		||||
    MOST_POPULAR_ORIGIN                  : 12,
 | 
			
		||||
    LEAST_POPULAR_ORIGIN                 : 13,
 | 
			
		||||
    OLDEST_ACTOR                         : 14,
 | 
			
		||||
    MOST_RECENT_SUBJECT_INTERPRETATION   : 15,
 | 
			
		||||
    LEAST_RECENT_SUBJECT_INTERPRETATION  : 16,
 | 
			
		||||
    MOST_POPULAR_SUBJECT_INTERPRETATION  : 17,
 | 
			
		||||
    LEAST_POPULAR_SUBJECT_INTERPRETATION : 18,
 | 
			
		||||
    MOST_RECENT_MIME_TYPE                : 19,
 | 
			
		||||
    LEAST_RECENT_MIME_TYPE               : 20,
 | 
			
		||||
    MOST_POPULAR_MIME_TYPE               : 21,
 | 
			
		||||
    LEAST_POPULAR_MIME_TYPE              : 22
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const StorageState = {
 | 
			
		||||
    // http://zeitgeist-project.com/docs/0.6/datamodel.html#storagestate
 | 
			
		||||
    // As with ResultType, it would be nice if we could introspect enums through D-Bus
 | 
			
		||||
    NOT_AVAILABLE : 0,
 | 
			
		||||
    AVAILABLE     : 1,
 | 
			
		||||
    ANY           : 2
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Zeitgeist Subjects (files, people, etc.) */
 | 
			
		||||
 | 
			
		||||
function Subject(uri, interpretation, manifestation, origin, mimetype, text, storage) {
 | 
			
		||||
    this._init(uri, interpretation, manifestation, origin, mimetype, text, storage);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Subject.prototype = {
 | 
			
		||||
    _init: function(uri, interpretation, manifestation, origin, mimetype, text, storage) {
 | 
			
		||||
        this.uri = uri;
 | 
			
		||||
        this.interpretation = interpretation;
 | 
			
		||||
        this.manifestation = manifestation;
 | 
			
		||||
        this.origin = origin;
 | 
			
		||||
        this.mimetype = mimetype;
 | 
			
		||||
        this.text = text;
 | 
			
		||||
        this.storage = storage;
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Subject.fromPlain = function(rawSubject) {
 | 
			
		||||
    return new Subject(rawSubject[0], // uri
 | 
			
		||||
                       rawSubject[1], // interpretation
 | 
			
		||||
                       rawSubject[2], // manifestation
 | 
			
		||||
                       rawSubject[3], // origin
 | 
			
		||||
                       rawSubject[4], // mimetype
 | 
			
		||||
                       rawSubject[5], // text
 | 
			
		||||
                       rawSubject[6]); // storage
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Subject.toPlain = function(subject) {
 | 
			
		||||
    let rawSubject = [];
 | 
			
		||||
    rawSubject[0] = subject.uri;
 | 
			
		||||
    rawSubject[1] = subject.interpretation;
 | 
			
		||||
    rawSubject[2] = subject.manifestation
 | 
			
		||||
    rawSubject[3] = subject.origin;
 | 
			
		||||
    rawSubject[4] = subject.mimetype;
 | 
			
		||||
    rawSubject[5] = subject.text;
 | 
			
		||||
    rawSubject[6] = subject.storage;
 | 
			
		||||
    return rawSubject;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Zeitgeist Events */
 | 
			
		||||
 | 
			
		||||
function Event(interpretation, manifestation, actor, subjects, payload) {
 | 
			
		||||
    this._init(interpretation, manifestation, actor, subjects, payload);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Event.prototype = {
 | 
			
		||||
    _init: function(interpretation, manifestation, actor, subjects, payload) {
 | 
			
		||||
        this.id = 0;
 | 
			
		||||
        this.timestamp = 0;
 | 
			
		||||
        this.actor = actor;
 | 
			
		||||
        this.interpretation = interpretation;
 | 
			
		||||
        this.manifestation = manifestation;
 | 
			
		||||
        this.actor = actor;
 | 
			
		||||
        this.payload = payload;
 | 
			
		||||
        this.subjects = subjects;
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Event.fromPlain = function(rawEvent) {
 | 
			
		||||
    let subjects = rawEvent[1].map(Subject.fromPlain);
 | 
			
		||||
    let event = new Event(rawEvent[0][2], // interpretation
 | 
			
		||||
                          rawEvent[0][3], // manifestation
 | 
			
		||||
                          rawEvent[0][4], // actor
 | 
			
		||||
                          subjects, // subjects
 | 
			
		||||
                          rawEvent[2]);// payload
 | 
			
		||||
    event.id = rawEvent[0][0]; // id
 | 
			
		||||
    event.timestamp = parseInt(rawEvent[0][1], 10); // timestamp - it comes as a string over d-bus (yuck)
 | 
			
		||||
    return event;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Event.toPlain = function(event) {
 | 
			
		||||
    let rawEvent = [];
 | 
			
		||||
    rawEvent[0] = [];
 | 
			
		||||
    rawEvent[0][0] = event.id.toString();
 | 
			
		||||
    rawEvent[0][1] = event.timestamp.toString();
 | 
			
		||||
    rawEvent[0][2] = event.interpretation;
 | 
			
		||||
    rawEvent[0][3] = event.manifestation;
 | 
			
		||||
    rawEvent[0][4] = event.actor;
 | 
			
		||||
    rawEvent[1] = event.subjects.map(Subject.toPlain);
 | 
			
		||||
    rawEvent[2] = event.payload;
 | 
			
		||||
    return rawEvent;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Zeitgeist D-Bus interface definitions. Note that most of these are
 | 
			
		||||
// incomplete, and only cover the methods/properties/signals that
 | 
			
		||||
// we're currently using.
 | 
			
		||||
 | 
			
		||||
/* Zeitgeist D-Bus Interface */
 | 
			
		||||
 | 
			
		||||
const LOG_NAME = 'org.gnome.zeitgeist.Engine';
 | 
			
		||||
const LOG_PATH = '/org/gnome/zeitgeist/log/activity';
 | 
			
		||||
const LogIface = {
 | 
			
		||||
    name: 'org.gnome.zeitgeist.Log',
 | 
			
		||||
    methods: [
 | 
			
		||||
        { name: 'GetEvents',
 | 
			
		||||
          inSignature: 'au',
 | 
			
		||||
          outSignature: 'a'+SIG_EVENT },
 | 
			
		||||
        { name: 'FindRelatedUris',
 | 
			
		||||
          inSignature: 'au',
 | 
			
		||||
          outSignature: '(xx)a(' + SIG_EVENT + ')a'+ SIG_EVENT + 'uuu' },
 | 
			
		||||
        { name: 'FindEventIds',
 | 
			
		||||
          inSignature: '(xx)a' + SIG_EVENT + 'uuu',
 | 
			
		||||
          outSignature: 'au' },
 | 
			
		||||
        { name: 'FindEvents',
 | 
			
		||||
          inSignature: '(xx)a' + SIG_EVENT + 'uuu',
 | 
			
		||||
          outSignature: 'a' + SIG_EVENT },
 | 
			
		||||
        { name: 'InsertEvents',
 | 
			
		||||
          inSignature: 'a' + SIG_EVENT,
 | 
			
		||||
          outSignature: 'au' },
 | 
			
		||||
        { name: 'DeleteEvents',
 | 
			
		||||
          inSignature: 'au',
 | 
			
		||||
          outSignature: '(xx)' },
 | 
			
		||||
        { name: 'DeleteLog',
 | 
			
		||||
          inSignature: '',
 | 
			
		||||
          outSignature: '' },
 | 
			
		||||
        { name: 'Quit',
 | 
			
		||||
          inSignature: '',
 | 
			
		||||
          outSignature: '' },
 | 
			
		||||
        // FIXME: Add missing DBus Methods
 | 
			
		||||
        // - InstallMonitor
 | 
			
		||||
        // - RemoveMonitor
 | 
			
		||||
    ],
 | 
			
		||||
    properties: [
 | 
			
		||||
        { name: 'Get',
 | 
			
		||||
          inSignature: 'ss',
 | 
			
		||||
          outSignature: 'v',
 | 
			
		||||
          access: 'read' },
 | 
			
		||||
        { name: 'Set',
 | 
			
		||||
          inSignature: 'ssv',
 | 
			
		||||
          outSignature: '',
 | 
			
		||||
          access: 'read' },
 | 
			
		||||
        { name: 'GetAll',
 | 
			
		||||
          inSignature: 's',
 | 
			
		||||
          outSignature: 'a{sv}',
 | 
			
		||||
          access: 'read' },
 | 
			
		||||
    ]
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const Log = DBus.makeProxyClass(LogIface);
 | 
			
		||||
const _log = new Log(DBus.session, LOG_NAME, LOG_PATH);
 | 
			
		||||
 | 
			
		||||
function findEvents(timeRange, eventTemplates, storageState, numEvents, resultType, callback) {
 | 
			
		||||
    function handler(results, error) {
 | 
			
		||||
        if (error != null)
 | 
			
		||||
            log("Error querying Zeitgeist for events: "+error);
 | 
			
		||||
        else
 | 
			
		||||
            callback(results.map(Event.fromPlain));
 | 
			
		||||
    }
 | 
			
		||||
    _log.FindEventsRemote(timeRange, eventTemplates.map(Event.toPlain),
 | 
			
		||||
                          storageState, numEvents, resultType, handler);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Zeitgeist Full-Text-Search Interface */
 | 
			
		||||
 | 
			
		||||
const INDEX_NAME = 'org.gnome.zeitgeist.Engine';
 | 
			
		||||
const INDEX_PATH = '/org/gnome/zeitgeist/index/activity';
 | 
			
		||||
const IndexIface = {
 | 
			
		||||
    name: 'org.gnome.zeitgeist.Index',
 | 
			
		||||
    methods: [
 | 
			
		||||
        { name: 'Search',
 | 
			
		||||
          inSignature: 's(xx)a'+SIG_EVENT+'uuu',
 | 
			
		||||
          outSignature: 'a'+SIG_EVENT+'u' },
 | 
			
		||||
    ],
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const Index = DBus.makeProxyClass(IndexIface);
 | 
			
		||||
const _index = new Index(DBus.session, INDEX_NAME, INDEX_PATH);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * fullTextSearch:
 | 
			
		||||
 *
 | 
			
		||||
 * Asynchronously search Zeitgeist's index for events relating to the query.
 | 
			
		||||
 *
 | 
			
		||||
 * @param query The query string, using asterisks for wildcards. Wildcards must
 | 
			
		||||
 *        be used at the start and/or end of a string to get relevant information.
 | 
			
		||||
 * @param eventTemplates Zeitgeist event templates, see
 | 
			
		||||
 *        http://zeitgeist-project.com/docs/0.6/datamodel.html#event for more
 | 
			
		||||
 *        information
 | 
			
		||||
 * @param callback The callback, takes a list containing Zeitgeist.Event
 | 
			
		||||
 *        objects
 | 
			
		||||
 */
 | 
			
		||||
function fullTextSearch(query, eventTemplates, callback) {
 | 
			
		||||
    function handler(results, error) {
 | 
			
		||||
        if (error != null)
 | 
			
		||||
            log("Error searching with Zeitgeist FTS: "+error);
 | 
			
		||||
        else
 | 
			
		||||
            callback(results[0].map(Event.fromPlain));
 | 
			
		||||
    }
 | 
			
		||||
    _index.SearchRemote(query, [0, MAX_TIMESTAMP],
 | 
			
		||||
                        eventTemplates.map(Event.toPlain),
 | 
			
		||||
                        0, // offset into the search results
 | 
			
		||||
                        MAX_RESULTS,
 | 
			
		||||
                        ResultType.MOST_POPULAR_SUBJECTS, handler);
 | 
			
		||||
}
 | 
			
		||||
@@ -21,26 +21,77 @@ let METRICS = {
 | 
			
		||||
    overviewFpsSubsequent:
 | 
			
		||||
    { description: "Frames rate when going to the overview, second time",
 | 
			
		||||
      units: "frames / s" },
 | 
			
		||||
    overviewFps5Windows:
 | 
			
		||||
    { description: "Frames rate when going to the overview, 5 windows open",
 | 
			
		||||
      units: "frames / s" },
 | 
			
		||||
    overviewFps10Windows:
 | 
			
		||||
    { description: "Frames rate when going to the overview, 10 windows open",
 | 
			
		||||
      units: "frames / s" },
 | 
			
		||||
    overviewFps5Maximized:
 | 
			
		||||
    { description: "Frames rate when going to the overview, 5 maximized windows open",
 | 
			
		||||
      units: "frames / s" },
 | 
			
		||||
    overviewFps10Maximized:
 | 
			
		||||
    { description: "Frames rate when going to the overview, 10 maximized windows open",
 | 
			
		||||
      units: "frames / s" },
 | 
			
		||||
    overviewFps5Alpha:
 | 
			
		||||
    { description: "Frames rate when going to the overview, 5 alpha-transparent windows open",
 | 
			
		||||
      units: "frames / s" },
 | 
			
		||||
    overviewFps10Alpha:
 | 
			
		||||
    { description: "Frames rate when going to the overview, 10 alpha-transparent windows open",
 | 
			
		||||
      units: "frames / s" },
 | 
			
		||||
    usedAfterOverview:
 | 
			
		||||
    { description: "Malloc'ed bytes after the overview is shown once",
 | 
			
		||||
      units: "B" },
 | 
			
		||||
    leakedAfterOverview:
 | 
			
		||||
    { description: "Additional malloc'ed bytes the second time the overview is shown",
 | 
			
		||||
      units: "B" }
 | 
			
		||||
      units: "B" },
 | 
			
		||||
    applicationsShowTimeFirst:
 | 
			
		||||
    { description: "Time to switch to applications view, first time",
 | 
			
		||||
      units: "us" },
 | 
			
		||||
    applicationsShowTimeSubsequent:
 | 
			
		||||
    { description: "Time to switch to applications view, second time",
 | 
			
		||||
      units: "us"}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
let WINDOW_CONFIGS = [
 | 
			
		||||
    { width: 640, height: 480, alpha: false, maximized: false, count: 1,  metric: 'overviewFpsSubsequent' },
 | 
			
		||||
    { width: 640, height: 480, alpha: false, maximized: false, count: 5,  metric: 'overviewFps5Windows'  },
 | 
			
		||||
    { width: 640, height: 480, alpha: false, maximized: false, count: 10, metric: 'overviewFps10Windows'  },
 | 
			
		||||
    { width: 640, height: 480, alpha: false, maximized: true,  count: 5,  metric: 'overviewFps5Maximized' },
 | 
			
		||||
    { width: 640, height: 480, alpha: false, maximized: true,  count: 10, metric: 'overviewFps10Maximized' },
 | 
			
		||||
    { width: 640, height: 480, alpha: true,  maximized: false, count: 5,  metric: 'overviewFps5Alpha' },
 | 
			
		||||
    { width: 640, height: 480, alpha: true,  maximized: false, count: 10, metric: 'overviewFps10Alpha' }
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
function run() {
 | 
			
		||||
    Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
 | 
			
		||||
    Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
 | 
			
		||||
    Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview");
 | 
			
		||||
    Scripting.defineScriptEvent("applicationsShowStart", "Starting to switch to applications view");
 | 
			
		||||
    Scripting.defineScriptEvent("applicationsShowDone", "Done switching to applications view");
 | 
			
		||||
 | 
			
		||||
    Main.overview.connect('shown', function() {
 | 
			
		||||
                              Scripting.scriptEvent('overviewShowDone');
 | 
			
		||||
                          });
 | 
			
		||||
 | 
			
		||||
    yield Scripting.sleep(1000);
 | 
			
		||||
    yield Scripting.waitLeisure();
 | 
			
		||||
    for (let i = 0; i < 2; i++) {
 | 
			
		||||
 | 
			
		||||
    for (let i = 0; i < 2 * WINDOW_CONFIGS.length; i++) {
 | 
			
		||||
        // We go to the overview twice for each configuration; the first time
 | 
			
		||||
        // to calculate the mipmaps for the windows, the second time to get
 | 
			
		||||
        // a clean set of numbers.
 | 
			
		||||
        if ((i % 2) == 0) {
 | 
			
		||||
            let config = WINDOW_CONFIGS[i / 2];
 | 
			
		||||
            yield Scripting.destroyTestWindows();
 | 
			
		||||
 | 
			
		||||
            for (let k = 0; k < config.count; k++)
 | 
			
		||||
                yield Scripting.createTestWindow(config.width, config.height, config.alpha, config.maximized);
 | 
			
		||||
 | 
			
		||||
            yield Scripting.waitTestWindows();
 | 
			
		||||
            yield Scripting.sleep(1000);
 | 
			
		||||
            yield Scripting.waitLeisure();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Scripting.scriptEvent('overviewShowStart');
 | 
			
		||||
        Main.overview.show();
 | 
			
		||||
 | 
			
		||||
@@ -53,6 +104,21 @@ function run() {
 | 
			
		||||
        Scripting.collectStatistics();
 | 
			
		||||
        Scripting.scriptEvent('afterShowHide');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    yield Scripting.destroyTestWindows();
 | 
			
		||||
    yield Scripting.sleep(1000);
 | 
			
		||||
 | 
			
		||||
    Main.overview.show();
 | 
			
		||||
    yield Scripting.waitLeisure();
 | 
			
		||||
 | 
			
		||||
    for (let i = 0; i < 2; i++) {
 | 
			
		||||
        Scripting.scriptEvent('applicationsShowStart');
 | 
			
		||||
        Main.overview.viewSelector.switchTab('applications');
 | 
			
		||||
        yield Scripting.waitLeisure();
 | 
			
		||||
        Scripting.scriptEvent('applicationsShowDone');
 | 
			
		||||
        Main.overview.viewSelector.switchTab('windows');
 | 
			
		||||
        yield Scripting.waitLeisure();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let showingOverview = false;
 | 
			
		||||
@@ -64,6 +130,8 @@ let mallocUsedSize = 0;
 | 
			
		||||
let overviewShowCount = 0;
 | 
			
		||||
let firstOverviewUsedSize;
 | 
			
		||||
let haveSwapComplete = false;
 | 
			
		||||
let applicationsShowStart;
 | 
			
		||||
let applicationsShowCount = 0;
 | 
			
		||||
 | 
			
		||||
function script_overviewShowStart(time) {
 | 
			
		||||
    showingOverview = true;
 | 
			
		||||
@@ -79,6 +147,18 @@ function script_overviewShowDone(time) {
 | 
			
		||||
    finishedShowingOverview = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function script_applicationsShowStart(time) {
 | 
			
		||||
    applicationsShowStart = time;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function script_applicationsShowDone(time) {
 | 
			
		||||
    applicationsShowCount++;
 | 
			
		||||
    if (applicationsShowCount == 1)
 | 
			
		||||
        METRICS.applicationsShowTimeFirst.value = time - applicationsShowStart;
 | 
			
		||||
    else
 | 
			
		||||
        METRICS.applicationsShowTimeSubsequent.value = time - applicationsShowStart;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function script_afterShowHide(time) {
 | 
			
		||||
    if (overviewShowCount == 1) {
 | 
			
		||||
        METRICS.usedAfterOverview.value = mallocUsedSize;
 | 
			
		||||
@@ -113,9 +193,15 @@ function _frameDone(time) {
 | 
			
		||||
        if (overviewShowCount == 1) {
 | 
			
		||||
            METRICS.overviewLatencyFirst.value = overviewLatency;
 | 
			
		||||
            METRICS.overviewFpsFirst.value = fps;
 | 
			
		||||
        } else {
 | 
			
		||||
        } else if (overviewShowCount == 2) {
 | 
			
		||||
            METRICS.overviewLatencySubsequent.value = overviewLatency;
 | 
			
		||||
            METRICS.overviewFpsSubsequent.value = fps;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Other than overviewFpsFirst, we collect FPS metrics the second
 | 
			
		||||
        // we show each window configuration. overviewShowCount is 1,2,3...
 | 
			
		||||
        if (overviewShowCount % 2 == 0) {
 | 
			
		||||
            let config = WINDOW_CONFIGS[(overviewShowCount / 2) - 1];
 | 
			
		||||
            METRICS[config.metric].value = fps;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -87,7 +87,7 @@ AltTabPopup.prototype = {
 | 
			
		||||
        let [childMinHeight, childNaturalHeight] = this._appSwitcher.actor.get_preferred_height(primary.width - hPadding);
 | 
			
		||||
        let [childMinWidth, childNaturalWidth] = this._appSwitcher.actor.get_preferred_width(childNaturalHeight);
 | 
			
		||||
        childBox.x1 = Math.max(primary.x + leftPadding, primary.x + Math.floor((primary.width - childNaturalWidth) / 2));
 | 
			
		||||
        childBox.x2 = Math.min(primary.width - hPadding, childBox.x1 + childNaturalWidth);
 | 
			
		||||
        childBox.x2 = Math.min(primary.x + primary.width - hPadding, childBox.x1 + childNaturalWidth);
 | 
			
		||||
        childBox.y1 = primary.y + Math.floor((primary.height - childNaturalHeight) / 2);
 | 
			
		||||
        childBox.y2 = childBox.y1 + childNaturalHeight;
 | 
			
		||||
        this._appSwitcher.actor.allocate(childBox, flags);
 | 
			
		||||
@@ -376,7 +376,15 @@ AltTabPopup.prototype = {
 | 
			
		||||
        this.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _popModal: function() {
 | 
			
		||||
        if (this._haveModal) {
 | 
			
		||||
            Main.popModal(this.actor);
 | 
			
		||||
            this._haveModal = false;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy : function() {
 | 
			
		||||
        this._popModal();
 | 
			
		||||
        if (this.actor.visible) {
 | 
			
		||||
            Tweener.addTween(this.actor,
 | 
			
		||||
                             { opacity: 0,
 | 
			
		||||
@@ -392,8 +400,7 @@ AltTabPopup.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy : function() {
 | 
			
		||||
        if (this._haveModal)
 | 
			
		||||
            Main.popModal(this.actor);
 | 
			
		||||
        this._popModal();
 | 
			
		||||
 | 
			
		||||
        if (this._thumbnails)
 | 
			
		||||
            this._destroyThumbnails();
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
const GLib = imports.gi.GLib;
 | 
			
		||||
const Gio = imports.gi.Gio;
 | 
			
		||||
const Gtk = imports.gi.Gtk;
 | 
			
		||||
const Shell = imports.gi.Shell;
 | 
			
		||||
const Lang = imports.lang;
 | 
			
		||||
@@ -13,6 +14,7 @@ const _ = Gettext.gettext;
 | 
			
		||||
 | 
			
		||||
const AppFavorites = imports.ui.appFavorites;
 | 
			
		||||
const DND = imports.ui.dnd;
 | 
			
		||||
const DocInfo = imports.misc.docInfo;
 | 
			
		||||
const IconGrid = imports.ui.iconGrid;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const Overview = imports.ui.overview;
 | 
			
		||||
@@ -21,6 +23,7 @@ const Search = imports.ui.search;
 | 
			
		||||
const Tweener = imports.ui.tweener;
 | 
			
		||||
const Workspace = imports.ui.workspace;
 | 
			
		||||
const Params = imports.misc.params;
 | 
			
		||||
const Zeitgeist = imports.misc.zeitgeist;
 | 
			
		||||
 | 
			
		||||
const MENU_POPUP_TIMEOUT = 600;
 | 
			
		||||
const SCROLL_TIME = 0.1;
 | 
			
		||||
@@ -86,10 +89,14 @@ AlphabeticalView.prototype = {
 | 
			
		||||
        if (vfade)
 | 
			
		||||
            offset = vfade.fade_offset;
 | 
			
		||||
 | 
			
		||||
        if (icon.y < value + offset)
 | 
			
		||||
            value = Math.max(0, icon.y - offset);
 | 
			
		||||
        else if (icon.y + icon.height > value + pageSize - offset)
 | 
			
		||||
            value = Math.min(upper, icon.y + icon.height + offset - pageSize);
 | 
			
		||||
        // If this gets called as part of a right-click, the actor
 | 
			
		||||
        // will be needs_allocation, and so "icon.y" would return 0
 | 
			
		||||
        let box = icon.get_allocation_box();
 | 
			
		||||
 | 
			
		||||
        if (box.y1 < value + offset)
 | 
			
		||||
            value = Math.max(0, box.y1 - offset);
 | 
			
		||||
        else if (box.y2 > value + pageSize - offset)
 | 
			
		||||
            value = Math.min(upper, box.y2 + offset - pageSize);
 | 
			
		||||
        else
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -412,6 +419,10 @@ AppWellIcon.prototype = {
 | 
			
		||||
                this._removeMenuTimeout();
 | 
			
		||||
                Main.overview.beginItemDrag(this);
 | 
			
		||||
            }));
 | 
			
		||||
        this._draggable.connect('drag-cancelled', Lang.bind(this,
 | 
			
		||||
            function () {
 | 
			
		||||
                Main.overview.cancelledItemDrag(this);
 | 
			
		||||
            }));
 | 
			
		||||
        this._draggable.connect('drag-end', Lang.bind(this,
 | 
			
		||||
            function () {
 | 
			
		||||
               Main.overview.endItemDrag(this);
 | 
			
		||||
@@ -505,6 +516,8 @@ AppWellIcon.prototype = {
 | 
			
		||||
            this._menuManager.addMenu(this._menu);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.actor.set_hover(true);
 | 
			
		||||
        this.actor.show_tooltip();
 | 
			
		||||
        this._menu.popup();
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
@@ -568,7 +581,11 @@ AppIconMenu.prototype = {
 | 
			
		||||
 | 
			
		||||
        PopupMenu.PopupMenu.prototype._init.call(this, source.actor, 0.5, side, 0);
 | 
			
		||||
 | 
			
		||||
        // We want to keep the item hovered while the menu is up
 | 
			
		||||
        this.blockSourceEvents = true;
 | 
			
		||||
 | 
			
		||||
        this._source = source;
 | 
			
		||||
        this._eventTemplate = new Zeitgeist.Event('', '', "application://" + this._source.app.get_id(), [], []);
 | 
			
		||||
 | 
			
		||||
        this.connect('activate', Lang.bind(this, this._onActivate));
 | 
			
		||||
        this.connect('open-state-changed', Lang.bind(this, this._onOpenStateChanged));
 | 
			
		||||
@@ -615,6 +632,63 @@ AppIconMenu.prototype = {
 | 
			
		||||
        this._toggleFavoriteMenuItem = this._appendMenuItem(isFavorite ? _("Remove from Favorites")
 | 
			
		||||
                                                                    : _("Add to Favorites"));
 | 
			
		||||
 | 
			
		||||
        Zeitgeist.findEvents([new Date().getTime() - 86400000*90, Zeitgeist.MAX_TIMESTAMP],
 | 
			
		||||
                             [this._eventTemplate],
 | 
			
		||||
                             Zeitgeist.StorageState.ANY,
 | 
			
		||||
                             100,
 | 
			
		||||
                             Zeitgeist.ResultType.MOST_RECENT_SUBJECTS,
 | 
			
		||||
                             Lang.bind(this, this._appendJumplist));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _appendJumplist: function (events) {
 | 
			
		||||
        let fetchedUris = [];
 | 
			
		||||
        let hasJumplist = false;
 | 
			
		||||
 | 
			
		||||
        function appendEvents(events2, count, type) {
 | 
			
		||||
            if (count == null) {
 | 
			
		||||
                count = 3;
 | 
			
		||||
            }
 | 
			
		||||
            if (type == null) {
 | 
			
		||||
                type = "emblem-favorite";
 | 
			
		||||
            }
 | 
			
		||||
            let j = 0;
 | 
			
		||||
            if (events.length > 0) {
 | 
			
		||||
                for (let i in events) {
 | 
			
		||||
                    let uri = events[i].subjects[0].uri.replace('file://', '');
 | 
			
		||||
                    uri = uri.replace(/\%20/g, ' '); // FIXME: properly unescape, or get the display name otherwise
 | 
			
		||||
                    if (fetchedUris.indexOf(uri) == -1 &&
 | 
			
		||||
                        (GLib.file_test(uri, GLib.FileTest.EXISTS) || this._source.app.get_id() == "tomboy.desktop")) {
 | 
			
		||||
                        if (!hasJumplist) {
 | 
			
		||||
                            this._appendSeparator();
 | 
			
		||||
                            hasJumplist = true;
 | 
			
		||||
                        }
 | 
			
		||||
                        this._appendJumplistItem(events[i], type);
 | 
			
		||||
                        fetchedUris.push(uri);
 | 
			
		||||
                        j++;
 | 
			
		||||
                        if (j >= count)
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        appendEvents.call(this, events, 4, "document-open-recent");
 | 
			
		||||
        Zeitgeist.findEvents([new Date().getTime() - 86400000*90, Zeitgeist.MAX_TIMESTAMP],
 | 
			
		||||
                             [this._eventTemplate],
 | 
			
		||||
                             Zeitgeist.StorageState.ANY,
 | 
			
		||||
                             100,
 | 
			
		||||
                             Zeitgeist.ResultType.MOST_POPULAR_SUBJECTS,
 | 
			
		||||
                             Lang.bind(this, appendEvents));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _appendJumplistItem: function (event, type) {
 | 
			
		||||
        let info = new DocInfo.ZeitgeistItemInfo(event);
 | 
			
		||||
        let item = new PopupMenu.PopupImageMenuItem(info.name, type);
 | 
			
		||||
        this.addMenuItem(item);
 | 
			
		||||
        item.connect('activate', Lang.bind(this, function () {
 | 
			
		||||
            let app = new Gio.DesktopAppInfo.new(this._source.app.get_id());
 | 
			
		||||
            app.launch_uris([info.uri], null);
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _appendSeparator: function () {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
const Lang = imports.lang;
 | 
			
		||||
const Meta = imports.gi.Meta;
 | 
			
		||||
const St = imports.gi.St;
 | 
			
		||||
const Shell = imports.gi.Shell;
 | 
			
		||||
 | 
			
		||||
@@ -40,80 +41,80 @@ BoxPointer.prototype = {
 | 
			
		||||
        this._border.connect('repaint', Lang.bind(this, this._drawBorder));
 | 
			
		||||
        this._container.add_actor(this._border);
 | 
			
		||||
        this.bin.raise(this._border);
 | 
			
		||||
        this._xOffset = 0;
 | 
			
		||||
        this._yOffset = 0;
 | 
			
		||||
        this._xPosition = 0;
 | 
			
		||||
        this._yPosition = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    show: function(animate, onComplete) {
 | 
			
		||||
        let x = this.actor.x;
 | 
			
		||||
        let y = this.actor.y;
 | 
			
		||||
        let themeNode = this.actor.get_theme_node();
 | 
			
		||||
        let rise = themeNode.get_length('-arrow-rise');
 | 
			
		||||
 | 
			
		||||
        this.actor.opacity = 0;
 | 
			
		||||
        this.opacity = 0;
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
 | 
			
		||||
        if (animate) {
 | 
			
		||||
            switch (this._arrowSide) {
 | 
			
		||||
                case St.Side.TOP:
 | 
			
		||||
                    this.actor.y -= rise;
 | 
			
		||||
                    this.yOffset = -rise;
 | 
			
		||||
                    break;
 | 
			
		||||
                case St.Side.BOTTOM:
 | 
			
		||||
                    this.actor.y += rise;
 | 
			
		||||
                    this.yOffset = rise;
 | 
			
		||||
                    break;
 | 
			
		||||
                case St.Side.LEFT:
 | 
			
		||||
                    this.actor.x -= rise;
 | 
			
		||||
                    this.xOffset = -rise;
 | 
			
		||||
                    break;
 | 
			
		||||
                case St.Side.RIGHT:
 | 
			
		||||
                    this.actor.x += rise;
 | 
			
		||||
                    this.xOffset = rise;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Tweener.addTween(this.actor, { opacity: 255,
 | 
			
		||||
                                       x: x,
 | 
			
		||||
                                       y: y,
 | 
			
		||||
                                       transition: "linear",
 | 
			
		||||
                                       onComplete: onComplete,
 | 
			
		||||
                                       time: POPUP_ANIMATION_TIME });
 | 
			
		||||
        Tweener.addTween(this, { opacity: 255,
 | 
			
		||||
                                 xOffset: 0,
 | 
			
		||||
                                 yOffset: 0,
 | 
			
		||||
                                 transition: "linear",
 | 
			
		||||
                                 onComplete: onComplete,
 | 
			
		||||
                                 time: POPUP_ANIMATION_TIME });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hide: function(animate, onComplete) {
 | 
			
		||||
        let x = this.actor.x;
 | 
			
		||||
        let y = this.actor.y;
 | 
			
		||||
        let originalX = this.actor.x;
 | 
			
		||||
        let originalY = this.actor.y;
 | 
			
		||||
        let xOffset = 0;
 | 
			
		||||
        let yOffset = 0;
 | 
			
		||||
        let themeNode = this.actor.get_theme_node();
 | 
			
		||||
        let rise = themeNode.get_length('-arrow-rise');
 | 
			
		||||
 | 
			
		||||
        if (animate) {
 | 
			
		||||
            switch (this._arrowSide) {
 | 
			
		||||
                case St.Side.TOP:
 | 
			
		||||
                    y += rise;
 | 
			
		||||
                    yOffset = rise;
 | 
			
		||||
                    break;
 | 
			
		||||
                case St.Side.BOTTOM:
 | 
			
		||||
                    y -= rise;
 | 
			
		||||
                    yOffset = -rise;
 | 
			
		||||
                    break;
 | 
			
		||||
                case St.Side.LEFT:
 | 
			
		||||
                    x += rise;
 | 
			
		||||
                    xOffset = rise;
 | 
			
		||||
                    break;
 | 
			
		||||
                case St.Side.RIGHT:
 | 
			
		||||
                    x -= rise;
 | 
			
		||||
                    xOffset = -rise;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Tweener.addTween(this.actor, { opacity: 0,
 | 
			
		||||
                                       x: x,
 | 
			
		||||
                                       y: y,
 | 
			
		||||
                                       transition: "linear",
 | 
			
		||||
                                       time: POPUP_ANIMATION_TIME,
 | 
			
		||||
                                       onComplete: Lang.bind(this, function () {
 | 
			
		||||
                                           this.actor.hide();
 | 
			
		||||
                                           this.actor.x = originalX;
 | 
			
		||||
                                           this.actor.y = originalY;
 | 
			
		||||
                                           if (onComplete)
 | 
			
		||||
                                               onComplete();
 | 
			
		||||
                                       })
 | 
			
		||||
                                     });
 | 
			
		||||
        Tweener.addTween(this, { opacity: 0,
 | 
			
		||||
                                 xOffset: xOffset,
 | 
			
		||||
                                 yOffset: yOffset,
 | 
			
		||||
                                 transition: "linear",
 | 
			
		||||
                                 time: POPUP_ANIMATION_TIME,
 | 
			
		||||
                                 onComplete: Lang.bind(this, function () {
 | 
			
		||||
                                     this.actor.hide();
 | 
			
		||||
                                     this.xOffset = 0;
 | 
			
		||||
                                     this.yOffset = 0;
 | 
			
		||||
                                     if (onComplete)
 | 
			
		||||
                                         onComplete();
 | 
			
		||||
                                 })
 | 
			
		||||
                               });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _adjustAllocationForArrow: function(isWidth, alloc) {
 | 
			
		||||
@@ -176,6 +177,9 @@ BoxPointer.prototype = {
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        this.bin.allocate(childBox, flags);
 | 
			
		||||
 | 
			
		||||
        if (this._sourceActor && this._sourceActor.mapped)
 | 
			
		||||
            this._reposition(this._sourceActor, this._gap, this._alignment);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _drawBorder: function(area) {
 | 
			
		||||
@@ -306,13 +310,20 @@ BoxPointer.prototype = {
 | 
			
		||||
        // so that we can query the correct size.
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
 | 
			
		||||
        this._sourceActor = sourceActor;
 | 
			
		||||
        this._gap = gap;
 | 
			
		||||
        this._alignment = alignment;
 | 
			
		||||
 | 
			
		||||
        this._reposition(sourceActor, gap, alignment);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _reposition: function(sourceActor, gap, alignment) {
 | 
			
		||||
        // Position correctly relative to the sourceActor
 | 
			
		||||
        let sourceNode = sourceActor.get_theme_node();
 | 
			
		||||
        let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box());
 | 
			
		||||
        let [sourceX, sourceY] = sourceActor.get_transformed_position();
 | 
			
		||||
        let [sourceWidth, sourceHeight] = sourceActor.get_transformed_size();
 | 
			
		||||
        let sourceCenterX = sourceX + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) / 2;
 | 
			
		||||
        let sourceCenterY = sourceY + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) / 2;
 | 
			
		||||
        let sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
 | 
			
		||||
        let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) / 2;
 | 
			
		||||
        let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) / 2;
 | 
			
		||||
        let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
 | 
			
		||||
 | 
			
		||||
        // We also want to keep it onscreen, and separated from the
 | 
			
		||||
@@ -330,16 +341,16 @@ BoxPointer.prototype = {
 | 
			
		||||
 | 
			
		||||
        switch (this._arrowSide) {
 | 
			
		||||
        case St.Side.TOP:
 | 
			
		||||
            resY = sourceY + sourceHeight + gap;
 | 
			
		||||
            resY = sourceAllocation.y2 + gap;
 | 
			
		||||
            break;
 | 
			
		||||
        case St.Side.BOTTOM:
 | 
			
		||||
            resY = sourceY - natHeight - gap;
 | 
			
		||||
            resY = sourceAllocation.y1 - natHeight - gap;
 | 
			
		||||
            break;
 | 
			
		||||
        case St.Side.LEFT:
 | 
			
		||||
            resX = sourceX + sourceWidth + gap;
 | 
			
		||||
            resX = sourceAllocation.x2 + gap;
 | 
			
		||||
            break;
 | 
			
		||||
        case St.Side.RIGHT:
 | 
			
		||||
            resX = sourceX - natWidth - gap;
 | 
			
		||||
            resX = sourceAllocation.x1 - natWidth - gap;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -373,9 +384,9 @@ BoxPointer.prototype = {
 | 
			
		||||
            parent = parent.get_parent();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Actually set the position
 | 
			
		||||
        this.actor.x = Math.floor(x);
 | 
			
		||||
        this.actor.y = Math.floor(y);
 | 
			
		||||
        this._xPosition = Math.floor(x);
 | 
			
		||||
        this._yPosition = Math.floor(y);
 | 
			
		||||
        this._shiftActor();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // @origin: Coordinate specifying middle of the arrow, along
 | 
			
		||||
@@ -386,5 +397,42 @@ BoxPointer.prototype = {
 | 
			
		||||
            this._arrowOrigin = origin;
 | 
			
		||||
            this._border.queue_repaint();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _shiftActor : function() {
 | 
			
		||||
        // Since the position of the BoxPointer depends on the allocated size
 | 
			
		||||
        // of the BoxPointer and the position of the source actor, trying
 | 
			
		||||
        // to position the BoxPoiner via the x/y properties will result in
 | 
			
		||||
        // allocation loops and warnings. Instead we do the positioning via
 | 
			
		||||
        // the anchor point, which is independent of allocation, and leave
 | 
			
		||||
        // x == y == 0.
 | 
			
		||||
        this.actor.set_anchor_point(-(this._xPosition + this._xOffset),
 | 
			
		||||
                                    -(this._yPosition + this._yOffset));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    set xOffset(offset) {
 | 
			
		||||
        this._xOffset = offset;
 | 
			
		||||
        this._shiftActor();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get xOffset() {
 | 
			
		||||
        return this._xOffset;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    set yOffset(offset) {
 | 
			
		||||
        this._yOffset = offset;
 | 
			
		||||
        this._shiftActor();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get yOffset() {
 | 
			
		||||
        return this._yOffset;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    set opacity(opacity) {
 | 
			
		||||
        this.actor.opacity = opacity;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get opacity() {
 | 
			
		||||
        return this.actor.opacity;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -36,8 +36,8 @@ Chrome.prototype = {
 | 
			
		||||
 | 
			
		||||
        this._trackedActors = [];
 | 
			
		||||
 | 
			
		||||
        global.gdk_screen.connect('monitors-changed',
 | 
			
		||||
                                  Lang.bind(this, this._monitorsChanged));
 | 
			
		||||
        global.screen.connect('monitors-changed',
 | 
			
		||||
                              Lang.bind(this, this._monitorsChanged));
 | 
			
		||||
        global.screen.connect('restacked',
 | 
			
		||||
                              Lang.bind(this, this._windowsRestacked));
 | 
			
		||||
 | 
			
		||||
@@ -335,6 +335,11 @@ Chrome.prototype = {
 | 
			
		||||
            this._updateVisibility();
 | 
			
		||||
            this._queueUpdateRegions();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Figure out where the pointer is in case we lost track of
 | 
			
		||||
        // it during a grab. (In particular, if a trayicon popup menu
 | 
			
		||||
        // is dismissed, see if we need to close the message tray.)
 | 
			
		||||
        global.sync_pointer();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateRegions: function() {
 | 
			
		||||
 
 | 
			
		||||
@@ -281,6 +281,7 @@ CtrlAltTabPopup.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy : function() {
 | 
			
		||||
        this._popModal();
 | 
			
		||||
        if (this._keyPressEventId)
 | 
			
		||||
            this.actor.disconnect(this._keyPressEventId);
 | 
			
		||||
        if (this._keyReleaseEventId)
 | 
			
		||||
 
 | 
			
		||||
@@ -283,20 +283,37 @@ Dash.prototype = {
 | 
			
		||||
                              Lang.bind(this, this._onDragBegin));
 | 
			
		||||
        Main.overview.connect('item-drag-end',
 | 
			
		||||
                              Lang.bind(this, this._onDragEnd));
 | 
			
		||||
        Main.overview.connect('item-drag-cancelled',
 | 
			
		||||
                              Lang.bind(this, this._onDragCancelled));
 | 
			
		||||
        Main.overview.connect('window-drag-begin',
 | 
			
		||||
                              Lang.bind(this, this._onDragBegin));
 | 
			
		||||
        Main.overview.connect('window-drag-cancelled',
 | 
			
		||||
                              Lang.bind(this, this._onDragCancelled));
 | 
			
		||||
        Main.overview.connect('window-drag-end',
 | 
			
		||||
                              Lang.bind(this, this._onDragEnd));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragBegin: function() {
 | 
			
		||||
        this._dragCancelled = false;
 | 
			
		||||
        this._dragMonitor = {
 | 
			
		||||
            dragMotion: Lang.bind(this, this._onDragMotion)
 | 
			
		||||
        };
 | 
			
		||||
        DND.addDragMonitor(this._dragMonitor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragCancelled: function() {
 | 
			
		||||
        this._dragCancelled = true;
 | 
			
		||||
        this._endDrag();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragEnd: function() {
 | 
			
		||||
        if (this._dragCancelled)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._endDrag();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _endDrag: function() {
 | 
			
		||||
        this._clearDragPlaceholder();
 | 
			
		||||
        if (this._favRemoveTarget) {
 | 
			
		||||
            this._favRemoveTarget.actor.hide();
 | 
			
		||||
@@ -372,6 +389,8 @@ Dash.prototype = {
 | 
			
		||||
                                   Lang.bind(this, function() {
 | 
			
		||||
                                       display.actor.opacity = 255;
 | 
			
		||||
                                   }));
 | 
			
		||||
        display.actor.set_tooltip_text(app.get_name());
 | 
			
		||||
 | 
			
		||||
        let item = new DashItemContainer();
 | 
			
		||||
        item.setChild(display.actor);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -185,21 +185,6 @@ DateMenuButton.prototype = {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let displayDate = new Date();
 | 
			
		||||
        let msecRemaining;
 | 
			
		||||
        if (showSeconds) {
 | 
			
		||||
            msecRemaining = 1000 - displayDate.getMilliseconds();
 | 
			
		||||
            if (msecRemaining < 50) {
 | 
			
		||||
                displayDate.setSeconds(displayDate.getSeconds() + 1);
 | 
			
		||||
                msecRemaining += 1000;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            msecRemaining = 60000 - (1000 * displayDate.getSeconds() +
 | 
			
		||||
                                     displayDate.getMilliseconds());
 | 
			
		||||
            if (msecRemaining < 500) {
 | 
			
		||||
                displayDate.setMinutes(displayDate.getMinutes() + 1);
 | 
			
		||||
                msecRemaining += 60000;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._clock.set_text(displayDate.toLocaleFormat(clockFormat));
 | 
			
		||||
 | 
			
		||||
@@ -209,19 +194,19 @@ DateMenuButton.prototype = {
 | 
			
		||||
        dateFormat = _("%A %B %e, %Y");
 | 
			
		||||
        this._date.set_text(displayDate.toLocaleFormat(dateFormat));
 | 
			
		||||
 | 
			
		||||
        Mainloop.timeout_add(msecRemaining, Lang.bind(this, this._updateClockAndDate));
 | 
			
		||||
        Mainloop.timeout_add_seconds(1, Lang.bind(this, this._updateClockAndDate));
 | 
			
		||||
        return false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onPreferencesActivate: function() {
 | 
			
		||||
        this.menu.close();
 | 
			
		||||
        Util.spawnDesktop('gnome-datetime-panel');
 | 
			
		||||
        let app = Shell.AppSystem.get_default().get_app('gnome-datetime-panel.desktop');
 | 
			
		||||
        app.activate(-1);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onOpenCalendarActivate: function() {
 | 
			
		||||
        this.menu.close();
 | 
			
		||||
        // TODO: pass '-c calendar' (to force the calendar at startup)
 | 
			
		||||
        // TODO: pass the selected day
 | 
			
		||||
        Util.spawnDesktop('evolution');
 | 
			
		||||
    },
 | 
			
		||||
        Util.spawn(['evolution', '-c', 'calendar']);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -480,7 +480,9 @@ _Draggable.prototype = {
 | 
			
		||||
            let [parentX, parentY] = this._dragOrigParent.get_transformed_position();
 | 
			
		||||
            let [parentWidth, parentHeight] = this._dragOrigParent.get_size();
 | 
			
		||||
            let [parentScaledWidth, parentScaledHeight] = this._dragOrigParent.get_transformed_size();
 | 
			
		||||
            let parentScale = parentScaledWidth / parentWidth;
 | 
			
		||||
            let parentScale = 1.0;
 | 
			
		||||
            if (parentWidth != 0)
 | 
			
		||||
                parentScale = parentScaledWidth / parentWidth;
 | 
			
		||||
 | 
			
		||||
            x = parentX + parentScale * this._dragOrigX;
 | 
			
		||||
            y = parentY + parentScale * this._dragOrigY;
 | 
			
		||||
@@ -496,6 +498,7 @@ _Draggable.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _cancelDrag: function(eventTime) {
 | 
			
		||||
        this.emit('drag-cancelled', eventTime);
 | 
			
		||||
        this._dragInProgress = false;
 | 
			
		||||
        let [snapBackX, snapBackY, snapBackScale] = this._getRestoreLocation();
 | 
			
		||||
 | 
			
		||||
@@ -504,6 +507,9 @@ _Draggable.prototype = {
 | 
			
		||||
            if (!this._buttonDown)
 | 
			
		||||
                this._dragComplete();
 | 
			
		||||
            this.emit('drag-end', eventTime, false);
 | 
			
		||||
            if (!this._dragOrigParent)
 | 
			
		||||
                this._dragActor.destroy();
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,50 +0,0 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 | 
			
		||||
 | 
			
		||||
const Gettext = imports.gettext.domain('gnome-shell');
 | 
			
		||||
const _ = Gettext.gettext;
 | 
			
		||||
 | 
			
		||||
const DocInfo = imports.misc.docInfo;
 | 
			
		||||
const Params = imports.misc.params;
 | 
			
		||||
const Search = imports.ui.search;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function DocSearchProvider() {
 | 
			
		||||
    this._init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DocSearchProvider.prototype = {
 | 
			
		||||
    __proto__: Search.SearchProvider.prototype,
 | 
			
		||||
 | 
			
		||||
    _init: function(name) {
 | 
			
		||||
        Search.SearchProvider.prototype._init.call(this, _("RECENT ITEMS"));
 | 
			
		||||
        this._docManager = DocInfo.getDocManager();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getResultMeta: function(resultId) {
 | 
			
		||||
        let docInfo = this._docManager.lookupByUri(resultId);
 | 
			
		||||
        if (!docInfo)
 | 
			
		||||
            return null;
 | 
			
		||||
        return { 'id': resultId,
 | 
			
		||||
                 'name': docInfo.name,
 | 
			
		||||
                 'createIcon': function(size) {
 | 
			
		||||
                                   return docInfo.createIcon(size);
 | 
			
		||||
                               }
 | 
			
		||||
               };
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateResult: function(id, params) {
 | 
			
		||||
        params = Params.parse(params, { workspace: null,
 | 
			
		||||
                                        timestamp: null });
 | 
			
		||||
 | 
			
		||||
        let docInfo = this._docManager.lookupByUri(id);
 | 
			
		||||
        docInfo.launch(params.workspace ? params.workspace.index() : -1);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getInitialResultSet: function(terms) {
 | 
			
		||||
        return this._docManager.initialSearch(terms);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getSubsearchResultSet: function(previousResults, terms) {
 | 
			
		||||
        return this._docManager.subsearch(previousResults, terms);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
@@ -66,16 +66,20 @@ const logoutDialogContent = {
 | 
			
		||||
    uninhibitedDescriptionWithUser: _("%s will be logged out automatically in %d seconds."),
 | 
			
		||||
    uninhibitedDescription: _("You will be logged out automatically in %d seconds."),
 | 
			
		||||
    endDescription: _("Logging out of the system."),
 | 
			
		||||
    confirmButtonText: _("Log Out"),
 | 
			
		||||
    confirmButtons: [{ signal: 'ConfirmedLogout',
 | 
			
		||||
                       label:  _("Log Out") }],
 | 
			
		||||
    iconStyleClass: 'end-session-dialog-logout-icon'
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const shutdownDialogContent = {
 | 
			
		||||
    subject: _("Shut Down"),
 | 
			
		||||
    inhibitedDescription: _("Click Shut Down to quit these applications and shut down the system."),
 | 
			
		||||
    uninhibitedDescription: _("The system will shut down automatically in %d seconds."),
 | 
			
		||||
    endDescription: _("Shutting down the system."),
 | 
			
		||||
    confirmButtonText: _("Shut Down"),
 | 
			
		||||
    subject: _("Power Off"),
 | 
			
		||||
    inhibitedDescription: _("Click Power Off to quit these applications and power off the system."),
 | 
			
		||||
    uninhibitedDescription: _("The system will power off automatically in %d seconds."),
 | 
			
		||||
    endDescription: _("Powering off the system."),
 | 
			
		||||
    confirmButtons: [{ signal: 'ConfirmedReboot',
 | 
			
		||||
                       label:  _("Restart") },
 | 
			
		||||
                     { signal: 'ConfirmedShutdown',
 | 
			
		||||
                       label:  _("Power Off") }],
 | 
			
		||||
    iconName: 'system-shutdown',
 | 
			
		||||
    iconStyleClass: 'end-session-dialog-shutdown-icon'
 | 
			
		||||
};
 | 
			
		||||
@@ -85,7 +89,8 @@ const restartDialogContent = {
 | 
			
		||||
    inhibitedDescription: _("Click Restart to quit these applications and restart the system."),
 | 
			
		||||
    uninhibitedDescription: _("The system will restart automatically in %d seconds."),
 | 
			
		||||
    endDescription: _("Restarting the system."),
 | 
			
		||||
    confirmButtonText: _("Restart"),
 | 
			
		||||
    confirmButtons: [{ signal: 'ConfirmedReboot',
 | 
			
		||||
                       label:  _("Restart") }],
 | 
			
		||||
    iconName: 'system-shutdown',
 | 
			
		||||
    iconStyleClass: 'end-session-dialog-shutdown-icon'
 | 
			
		||||
};
 | 
			
		||||
@@ -233,7 +238,7 @@ EndSessionDialog.prototype = {
 | 
			
		||||
    __proto__: ModalDialog.ModalDialog.prototype,
 | 
			
		||||
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        ModalDialog.ModalDialog.prototype._init.call(this);
 | 
			
		||||
        ModalDialog.ModalDialog.prototype._init.call(this, { styleClass: 'end-session-dialog' });
 | 
			
		||||
 | 
			
		||||
        this._user = Gdm.UserManager.ref_default().get_user(GLib.get_user_name());
 | 
			
		||||
 | 
			
		||||
@@ -288,12 +293,26 @@ EndSessionDialog.prototype = {
 | 
			
		||||
        this.contentLayout.add(scrollView,
 | 
			
		||||
                               { x_fill: true,
 | 
			
		||||
                                 y_fill: true });
 | 
			
		||||
        scrollView.hide();
 | 
			
		||||
 | 
			
		||||
        this._applicationList = new St.BoxLayout({ vertical: true });
 | 
			
		||||
        scrollView.add_actor(this._applicationList,
 | 
			
		||||
                             { x_fill:  true,
 | 
			
		||||
                               y_fill:  true,
 | 
			
		||||
                               x_align: St.Align.START,
 | 
			
		||||
                               y_align: St.Align.MIDDLE });
 | 
			
		||||
 | 
			
		||||
        this._applicationList.connect('actor-added',
 | 
			
		||||
                                      Lang.bind(this, function() {
 | 
			
		||||
                                          if (this._applicationList.get_children().length == 1)
 | 
			
		||||
                                              scrollView.show();
 | 
			
		||||
                                      }));
 | 
			
		||||
 | 
			
		||||
        this._applicationList.connect('actor-removed',
 | 
			
		||||
                                      Lang.bind(this, function() {
 | 
			
		||||
                                          if (this._applicationList.get_children().length == 0)
 | 
			
		||||
                                              scrollView.hide();
 | 
			
		||||
                                      }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
@@ -392,18 +411,27 @@ EndSessionDialog.prototype = {
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let dialogContent = DialogContent[this._type];
 | 
			
		||||
        let confirmButtonText = _("Confirm");
 | 
			
		||||
        let buttons = [{ action: Lang.bind(this, this.cancel),
 | 
			
		||||
                         label:  _("Cancel"),
 | 
			
		||||
                         key:    Clutter.Escape }];
 | 
			
		||||
 | 
			
		||||
        if (dialogContent.confirmButtonText)
 | 
			
		||||
            confirmButtonText = dialogContent.confirmButtonText;
 | 
			
		||||
        for (let i = 0; i < dialogContent.confirmButtons.length; i++) {
 | 
			
		||||
            let signal = dialogContent.confirmButtons[i].signal;
 | 
			
		||||
            let label = dialogContent.confirmButtons[i].label;
 | 
			
		||||
            buttons.push({ action: Lang.bind(this, function() {
 | 
			
		||||
                                       this._confirm(signal);
 | 
			
		||||
                                   }),
 | 
			
		||||
                           label: label });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.setButtons([{ label: _("Cancel"),
 | 
			
		||||
                           action: Lang.bind(this, this.cancel),
 | 
			
		||||
                           key:    Clutter.Escape
 | 
			
		||||
                         },
 | 
			
		||||
                         { label:  confirmButtonText,
 | 
			
		||||
                           action: Lang.bind(this, this._confirm)
 | 
			
		||||
                         }]);
 | 
			
		||||
        this.setButtons(buttons);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    close: function() {
 | 
			
		||||
        ModalDialog.ModalDialog.prototype.close.call(this);
 | 
			
		||||
        DBus.session.emit_signal('/org/gnome/SessionManager/EndSessionDialog',
 | 
			
		||||
                                 'org.gnome.SessionManager.EndSessionDialog',
 | 
			
		||||
                                 'Closed', '', []);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    cancel: function() {
 | 
			
		||||
@@ -414,12 +442,12 @@ EndSessionDialog.prototype = {
 | 
			
		||||
        this.close(global.get_current_time());
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _confirm: function() {
 | 
			
		||||
    _confirm: function(signal) {
 | 
			
		||||
        this._fadeOutDialog();
 | 
			
		||||
        this._stopTimer();
 | 
			
		||||
        DBus.session.emit_signal('/org/gnome/SessionManager/EndSessionDialog',
 | 
			
		||||
                                 'org.gnome.SessionManager.EndSessionDialog',
 | 
			
		||||
                                 'Confirmed', '', []);
 | 
			
		||||
                                 signal, '', []);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onOpened: function() {
 | 
			
		||||
@@ -434,7 +462,11 @@ EndSessionDialog.prototype = {
 | 
			
		||||
                           time: this._secondsLeft,
 | 
			
		||||
                           transition: 'linear',
 | 
			
		||||
                           onUpdate: Lang.bind(this, this._updateContent),
 | 
			
		||||
                           onComplete: Lang.bind(this, this._confirm),
 | 
			
		||||
                           onComplete: Lang.bind(this, function() {
 | 
			
		||||
                                           let dialogContent = DialogContent[this._type];
 | 
			
		||||
                                           let button = dialogContent.confirmButtons[dialogContent.confirmButtons.length - 1];
 | 
			
		||||
                                           this._confirm(button.signal);
 | 
			
		||||
                                       }),
 | 
			
		||||
                         });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -64,6 +64,11 @@ function init() {
 | 
			
		||||
    Tweener.init();
 | 
			
		||||
    String.prototype.format = Format.format;
 | 
			
		||||
 | 
			
		||||
    // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=508783
 | 
			
		||||
    Date.prototype.toLocaleFormat = function(format) {
 | 
			
		||||
        return Shell.util_format_date(format, this.getTime());
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Set the default direction for St widgets (this needs to be done before any use of St)
 | 
			
		||||
    if (Gettext_gtk30.gettext('default:LTR') == 'default:RTL') {
 | 
			
		||||
        St.Widget.set_default_direction(St.TextDirection.RTL);
 | 
			
		||||
 
 | 
			
		||||
@@ -281,8 +281,11 @@ IconGrid.prototype = {
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    childrenInRow: function(rowWidth) {
 | 
			
		||||
        return this._computeLayout(rowWidth)[0];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _computeLayout: function (forWidth) {
 | 
			
		||||
        let children = this._grid.get_children();
 | 
			
		||||
        let nColumns = 0;
 | 
			
		||||
        let usedWidth = 0;
 | 
			
		||||
        while ((this._colLimit == null || nColumns < this._colLimit) &&
 | 
			
		||||
 
 | 
			
		||||
@@ -26,11 +26,13 @@ var commandHeader = 'const Clutter = imports.gi.Clutter; ' +
 | 
			
		||||
                    'const Gtk = imports.gi.Gtk; ' +
 | 
			
		||||
                    'const Mainloop = imports.mainloop; ' +
 | 
			
		||||
                    'const Meta = imports.gi.Meta; ' +
 | 
			
		||||
                    'const Semantic = imports.misc.semantic' +
 | 
			
		||||
                    'const Shell = imports.gi.Shell; ' +
 | 
			
		||||
                    'const Tp = imports.gi.TelepathyGLib; ' +
 | 
			
		||||
                    'const Main = imports.ui.main; ' +
 | 
			
		||||
                    'const Lang = imports.lang; ' +
 | 
			
		||||
                    'const Tweener = imports.ui.tweener; ' +
 | 
			
		||||
                    'const Zeitgeist = imports.misc.zeitgeist; ' +
 | 
			
		||||
                    /* Utility functions...we should probably be able to use these
 | 
			
		||||
                     * in the shell core code too. */
 | 
			
		||||
                    'const stage = global.stage; ' +
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										128
									
								
								js/ui/main.js
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								js/ui/main.js
									
									
									
									
									
								
							@@ -86,6 +86,9 @@ function start() {
 | 
			
		||||
    global.logError = _logError;
 | 
			
		||||
    global.log = _logDebug;
 | 
			
		||||
 | 
			
		||||
    // Chain up async errors reported from C
 | 
			
		||||
    global.connect('notify-error', function (global, msg, detail) { notifyError(msg, detail); });
 | 
			
		||||
 | 
			
		||||
    Gio.DesktopAppInfo.set_desktop_env('GNOME');
 | 
			
		||||
 | 
			
		||||
    shellDBusService = new ShellDBus.GnomeShell();
 | 
			
		||||
@@ -133,6 +136,7 @@ function start() {
 | 
			
		||||
 | 
			
		||||
    // Set up stage hierarchy to group all UI actors under one container.
 | 
			
		||||
    uiGroup = new Clutter.Group();
 | 
			
		||||
    St.set_ui_root(global.stage, uiGroup);
 | 
			
		||||
    global.window_group.reparent(uiGroup);
 | 
			
		||||
    global.overlay_group.reparent(uiGroup);
 | 
			
		||||
    global.stage.add_actor(uiGroup);
 | 
			
		||||
@@ -189,7 +193,7 @@ function start() {
 | 
			
		||||
    // Attempt to become a PolicyKit authentication agent
 | 
			
		||||
    PolkitAuthenticationAgent.init()
 | 
			
		||||
 | 
			
		||||
    global.gdk_screen.connect('monitors-changed', _relayout);
 | 
			
		||||
    global.screen.connect('monitors-changed', _relayout);
 | 
			
		||||
 | 
			
		||||
    ExtensionSystem.init();
 | 
			
		||||
    ExtensionSystem.loadExtensions();
 | 
			
		||||
@@ -216,7 +220,11 @@ function start() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    global.screen.connect('notify::n-workspaces', _nWorkspacesChanged);
 | 
			
		||||
    Mainloop.idle_add(_nWorkspacesChanged);
 | 
			
		||||
 | 
			
		||||
    global.screen.connect('window-entered-monitor', _windowEnteredMonitor);
 | 
			
		||||
    global.screen.connect('window-left-monitor', _windowLeftMonitor);
 | 
			
		||||
 | 
			
		||||
    _nWorkspacesChanged();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let _workspaces = [];
 | 
			
		||||
@@ -262,12 +270,32 @@ function _checkWorkspaces() {
 | 
			
		||||
        emptyWorkspaces.push(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let activeWorkspaceIndex = global.screen.get_active_workspace_index();
 | 
			
		||||
    let removingCurrentWorkspace = (emptyWorkspaces[activeWorkspaceIndex] &&
 | 
			
		||||
                                    activeWorkspaceIndex < emptyWorkspaces.length - 1);
 | 
			
		||||
    // Don't enter the overview when removing multiple empty workspaces at startup
 | 
			
		||||
    let showOverview  = (removingCurrentWorkspace &&
 | 
			
		||||
                         !emptyWorkspaces.every(function(x) { return x; }));
 | 
			
		||||
 | 
			
		||||
    if (removingCurrentWorkspace) {
 | 
			
		||||
        // "Merge" the empty workspace we are removing with the one at the end
 | 
			
		||||
        wm.blockAnimations();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Delete other empty workspaces; do it from the end to avoid index changes
 | 
			
		||||
    for (i = emptyWorkspaces.length - 2; i >= 0; i--) {
 | 
			
		||||
        if (emptyWorkspaces[i])
 | 
			
		||||
            global.screen.remove_workspace(_workspaces[i], global.get_current_time());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (removingCurrentWorkspace) {
 | 
			
		||||
        global.screen.get_workspace_by_index(global.screen.n_workspaces - 1).activate(global.get_current_time());
 | 
			
		||||
        wm.unblockAnimations();
 | 
			
		||||
 | 
			
		||||
        if (!overview.visible && showOverview)
 | 
			
		||||
            overview.show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _checkWorkspacesId = 0;
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
@@ -283,6 +311,20 @@ function _windowRemoved(workspace, window) {
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _windowLeftMonitor(metaScreen, monitorIndex, metaWin) {
 | 
			
		||||
    // If the window left the primary monitor, that
 | 
			
		||||
    // might make that workspace empty
 | 
			
		||||
    if (monitorIndex == global.get_primary_monitor_index())
 | 
			
		||||
        _queueCheckWorkspaces();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _windowEnteredMonitor(metaScreen, monitorIndex, metaWin) {
 | 
			
		||||
    // If the window entered the primary monitor, that
 | 
			
		||||
    // might make that workspace non-empty
 | 
			
		||||
    if (monitorIndex == global.get_primary_monitor_index())
 | 
			
		||||
        _queueCheckWorkspaces();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _queueCheckWorkspaces() {
 | 
			
		||||
    if (_checkWorkspacesId == 0)
 | 
			
		||||
        _checkWorkspacesId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, _checkWorkspaces);
 | 
			
		||||
@@ -375,6 +417,27 @@ function loadTheme() {
 | 
			
		||||
    themeContext.set_theme (theme);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * notifyError:
 | 
			
		||||
 * @msg: An error message
 | 
			
		||||
 * @details: Additional information
 | 
			
		||||
 *
 | 
			
		||||
 * See shell_global_notify_problem().
 | 
			
		||||
 */
 | 
			
		||||
function notifyError(msg, details) {
 | 
			
		||||
    // Also print to stderr so it's logged somewhere
 | 
			
		||||
    if (details)
 | 
			
		||||
        log("error: " + msg + ": " + details);
 | 
			
		||||
    else
 | 
			
		||||
        log("error: " + msg)
 | 
			
		||||
 | 
			
		||||
    let source = new MessageTray.SystemNotificationSource();
 | 
			
		||||
    messageTray.add(source);
 | 
			
		||||
    let notification = new MessageTray.Notification(source, msg, details);
 | 
			
		||||
    notification.setTransient(true);
 | 
			
		||||
    source.notify(notification);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * _log:
 | 
			
		||||
 * @category: string message type ('info', 'error')
 | 
			
		||||
@@ -418,28 +481,67 @@ function _getAndClearErrorStack() {
 | 
			
		||||
 | 
			
		||||
function _relayout() {
 | 
			
		||||
    let monitors = global.get_monitors();
 | 
			
		||||
    if (monitors.length != hotCorners.length) {
 | 
			
		||||
        // destroy old corners
 | 
			
		||||
        for (let i = 0; i < hotCorners.length; i++)
 | 
			
		||||
            hotCorners[i].destroy();
 | 
			
		||||
        hotCorners = [];
 | 
			
		||||
        for (let i = 0; i < monitors.length; i++)
 | 
			
		||||
            hotCorners[i] = new Panel.HotCorner();
 | 
			
		||||
    }
 | 
			
		||||
    // destroy old corners
 | 
			
		||||
    for (let i = 0; i < hotCorners.length; i++)
 | 
			
		||||
        hotCorners[i].destroy();
 | 
			
		||||
    hotCorners = [];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    let primary = global.get_primary_monitor();
 | 
			
		||||
    for (let i = 0; i < monitors.length; i++) {
 | 
			
		||||
        let monitor = monitors[i];
 | 
			
		||||
        let corner = hotCorners[i];
 | 
			
		||||
        let isPrimary = (monitor.x == primary.x &&
 | 
			
		||||
                         monitor.y == primary.y &&
 | 
			
		||||
                         monitor.width == primary.width &&
 | 
			
		||||
                         monitor.height == primary.height);
 | 
			
		||||
 | 
			
		||||
        let cornerX = monitor.x;
 | 
			
		||||
        let cornerY = monitor.y;
 | 
			
		||||
        if (St.Widget.get_default_direction() == St.TextDirection.RTL)
 | 
			
		||||
            corner.actor.set_position(monitor.x + monitor.width, monitor.y);
 | 
			
		||||
            cornerX += monitor.width;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        let haveTopLeftCorner = true;
 | 
			
		||||
 | 
			
		||||
        /* Check if we have a top left (right for RTL) corner.
 | 
			
		||||
         * I.e. if there is no monitor directly above or to the left(right) */
 | 
			
		||||
        let besideX;
 | 
			
		||||
        if (St.Widget.get_default_direction() == St.TextDirection.RTL)
 | 
			
		||||
            besideX = monitor.x + 1;
 | 
			
		||||
        else
 | 
			
		||||
            corner.actor.set_position(monitor.x, monitor.y);
 | 
			
		||||
            besideX = cornerX - 1;
 | 
			
		||||
        let besideY = cornerY;
 | 
			
		||||
        let aboveX = cornerX;
 | 
			
		||||
        let aboveY = cornerY - 1;
 | 
			
		||||
 | 
			
		||||
        for (let j = 0; j < monitors.length; j++) {
 | 
			
		||||
            if (i == j)
 | 
			
		||||
                continue;
 | 
			
		||||
            let otherMonitor = monitors[j];
 | 
			
		||||
            if (besideX >= otherMonitor.x &&
 | 
			
		||||
                besideX < otherMonitor.x + otherMonitor.width &&
 | 
			
		||||
                besideY >= otherMonitor.y &&
 | 
			
		||||
                besideY < otherMonitor.y + otherMonitor.height) {
 | 
			
		||||
                haveTopLeftCorner = false;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            if (aboveX >= otherMonitor.x &&
 | 
			
		||||
                aboveX < otherMonitor.x + otherMonitor.width &&
 | 
			
		||||
                aboveY >= otherMonitor.y &&
 | 
			
		||||
                aboveY < otherMonitor.y + otherMonitor.height) {
 | 
			
		||||
                haveTopLeftCorner = false;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* We only want hot corners where there is a natural top-left
 | 
			
		||||
         * corner, and on the primary monitor */
 | 
			
		||||
        if (!isPrimary && !haveTopLeftCorner)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        let corner = new Panel.HotCorner(isPrimary ? panel.button : null);
 | 
			
		||||
        hotCorners.push(corner);
 | 
			
		||||
        corner.actor.set_position(cornerX, cornerY);
 | 
			
		||||
        if (isPrimary)
 | 
			
		||||
            panel.setHotCorner(corner);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -108,6 +108,12 @@ URLHighlighter.prototype = {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.setMarkup(text, allowMarkup);
 | 
			
		||||
        this.actor.connect('button-press-event', Lang.bind(this, function(actor, event) {
 | 
			
		||||
            // Keep Notification.actor from seeing this and taking
 | 
			
		||||
            // a pointer grab, which would block our button-release-event
 | 
			
		||||
            // handler, if an URL is clicked
 | 
			
		||||
            return this._findUrlAtPos(event) != -1;
 | 
			
		||||
        }));
 | 
			
		||||
        this.actor.connect('button-release-event', Lang.bind(this, function (actor, event) {
 | 
			
		||||
            let urlId = this._findUrlAtPos(event);
 | 
			
		||||
            if (urlId != -1) {
 | 
			
		||||
@@ -406,24 +412,23 @@ Notification.prototype = {
 | 
			
		||||
        this._bannerBodyMarkup = false;
 | 
			
		||||
        this._titleFitsInBannerMode = true;
 | 
			
		||||
        this._spacing = 0;
 | 
			
		||||
        this._scrollPolicy = Gtk.PolicyType.AUTOMATIC;
 | 
			
		||||
 | 
			
		||||
        source.connect('destroy', Lang.bind(this,
 | 
			
		||||
            // Avoid passing 'source' as an argument to this.destroy()
 | 
			
		||||
            function () {
 | 
			
		||||
                this.destroy();
 | 
			
		||||
            function (source, reason) {
 | 
			
		||||
                this.destroy(reason);
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Table({ name: 'notification',
 | 
			
		||||
                                    reactive: true });
 | 
			
		||||
        this.actor.connect('style-changed', Lang.bind(this, this._styleChanged));
 | 
			
		||||
        this.actor.connect('button-release-event', Lang.bind(this,
 | 
			
		||||
            function (actor, event) {
 | 
			
		||||
                if (!this._actionArea ||
 | 
			
		||||
                    !this._actionArea.contains(event.get_source()))
 | 
			
		||||
                    this._onClicked();
 | 
			
		||||
            }));
 | 
			
		||||
        this.actor = new St.Button();
 | 
			
		||||
        this.actor._delegate = this;
 | 
			
		||||
        this.actor.connect('clicked', Lang.bind(this, this._onClicked));
 | 
			
		||||
        this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
 | 
			
		||||
 | 
			
		||||
        this._table = new St.Table({ name: 'notification',
 | 
			
		||||
                                     reactive: true });
 | 
			
		||||
        this._table.connect('style-changed', Lang.bind(this, this._styleChanged));
 | 
			
		||||
        this.actor.set_child(this._table);
 | 
			
		||||
 | 
			
		||||
        this._buttonFocusManager = St.FocusManager.get_for_stage(global.stage);
 | 
			
		||||
 | 
			
		||||
        // The first line should have the title, followed by the
 | 
			
		||||
@@ -435,10 +440,10 @@ Notification.prototype = {
 | 
			
		||||
        this._bannerBox.connect('get-preferred-width', Lang.bind(this, this._bannerBoxGetPreferredWidth));
 | 
			
		||||
        this._bannerBox.connect('get-preferred-height', Lang.bind(this, this._bannerBoxGetPreferredHeight));
 | 
			
		||||
        this._bannerBox.connect('allocate', Lang.bind(this, this._bannerBoxAllocate));
 | 
			
		||||
        this.actor.add(this._bannerBox, { row: 0,
 | 
			
		||||
                                          col: 1,
 | 
			
		||||
                                          y_expand: false,
 | 
			
		||||
                                          y_fill: false });
 | 
			
		||||
        this._table.add(this._bannerBox, { row: 0,
 | 
			
		||||
                                           col: 1,
 | 
			
		||||
                                           y_expand: false,
 | 
			
		||||
                                           y_fill: false });
 | 
			
		||||
 | 
			
		||||
        this._titleLabel = new St.Label();
 | 
			
		||||
        this._bannerBox.add_actor(this._titleLabel);
 | 
			
		||||
@@ -468,31 +473,39 @@ Notification.prototype = {
 | 
			
		||||
 | 
			
		||||
        this._customContent = params.customContent;
 | 
			
		||||
 | 
			
		||||
        let oldFocus = global.stage.key_focus;
 | 
			
		||||
 | 
			
		||||
        if (this._icon)
 | 
			
		||||
            this._icon.destroy();
 | 
			
		||||
        // We always clear the content area if we don't have custom
 | 
			
		||||
        // content because it might contain the @banner that didn't
 | 
			
		||||
        // fit in the banner mode.
 | 
			
		||||
        if (this._scrollArea && (!this._customContent || params.clear)) {
 | 
			
		||||
            if (oldFocus && this._scrollArea.contains(oldFocus))
 | 
			
		||||
                this.actor.grab_key_focus();
 | 
			
		||||
 | 
			
		||||
            this._scrollArea.destroy();
 | 
			
		||||
            this._scrollArea = null;
 | 
			
		||||
            this._contentArea = null;
 | 
			
		||||
        }
 | 
			
		||||
        if (this._actionArea && params.clear) {
 | 
			
		||||
            if (oldFocus && this._actionArea.contains(oldFocus))
 | 
			
		||||
                this.actor.grab_key_focus();
 | 
			
		||||
 | 
			
		||||
            this._actionArea.destroy();
 | 
			
		||||
            this._actionArea = null;
 | 
			
		||||
            this._buttonBox = null;
 | 
			
		||||
        }
 | 
			
		||||
        if (!this._scrollArea && !this._actionArea)
 | 
			
		||||
            this.actor.remove_style_class_name('multi-line-notification');
 | 
			
		||||
            this._table.remove_style_class_name('multi-line-notification');
 | 
			
		||||
 | 
			
		||||
        this._icon = params.icon || this.source.createNotificationIcon();
 | 
			
		||||
        this.actor.add(this._icon, { row: 0,
 | 
			
		||||
                                     col: 0,
 | 
			
		||||
                                     x_expand: false,
 | 
			
		||||
                                     y_expand: false,
 | 
			
		||||
                                     y_fill: false,
 | 
			
		||||
                                     y_align: St.Align.START });
 | 
			
		||||
        this._table.add(this._icon, { row: 0,
 | 
			
		||||
                                      col: 0,
 | 
			
		||||
                                      x_expand: false,
 | 
			
		||||
                                      y_expand: false,
 | 
			
		||||
                                      y_fill: false,
 | 
			
		||||
                                      y_align: St.Align.START });
 | 
			
		||||
 | 
			
		||||
        title = title ? _fixMarkup(title.replace(/\n/g, ' '), params.titleMarkup) : '';
 | 
			
		||||
        this._titleLabel.clutter_text.set_markup('<b>' + title + '</b>');
 | 
			
		||||
@@ -518,25 +531,38 @@ Notification.prototype = {
 | 
			
		||||
        this._updated();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setIconVisible: function(visible) {
 | 
			
		||||
        this._icon.visible = visible;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    enableScrolling: function(enableScrolling) {
 | 
			
		||||
        this._scrollPolicy = enableScrolling ? Gtk.PolicyType.AUTOMATIC : Gtk.PolicyType.NEVER;
 | 
			
		||||
        if (this._scrollArea)
 | 
			
		||||
            this._scrollArea.vscrollbar_policy = this._scrollPolicy;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createScrollArea: function() {
 | 
			
		||||
        this._table.add_style_class_name('multi-line-notification');
 | 
			
		||||
        this._scrollArea = new St.ScrollView({ name: 'notification-scrollview',
 | 
			
		||||
                                               vscrollbar_policy: this._scrollPolicy,
 | 
			
		||||
                                               hscrollbar_policy: Gtk.PolicyType.NEVER,
 | 
			
		||||
                                               vfade: true });
 | 
			
		||||
        this._table.add(this._scrollArea, { row: 1, col: 1 });
 | 
			
		||||
        this._contentArea = new St.BoxLayout({ name: 'notification-body',
 | 
			
		||||
                                               vertical: true });
 | 
			
		||||
        this._scrollArea.add_actor(this._contentArea);
 | 
			
		||||
        // If we know the notification will be expandable, we need to add
 | 
			
		||||
        // the banner text to the body as the first element.
 | 
			
		||||
        this._addBannerBody();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // addActor:
 | 
			
		||||
    // @actor: actor to add to the body of the notification
 | 
			
		||||
    //
 | 
			
		||||
    // Appends @actor to the notification's body
 | 
			
		||||
    addActor: function(actor, style) {
 | 
			
		||||
        if (!this._scrollArea) {
 | 
			
		||||
            this.actor.add_style_class_name('multi-line-notification');
 | 
			
		||||
            this._scrollArea = new St.ScrollView({ name: 'notification-scrollview',
 | 
			
		||||
                                                   vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
 | 
			
		||||
                                                   hscrollbar_policy: Gtk.PolicyType.NEVER,
 | 
			
		||||
                                                   vfade: true });
 | 
			
		||||
            this.actor.add(this._scrollArea, { row: 1,
 | 
			
		||||
                                               col: 1 });
 | 
			
		||||
            this._contentArea = new St.BoxLayout({ name: 'notification-body',
 | 
			
		||||
                                                   vertical: true });
 | 
			
		||||
            this._scrollArea.add_actor(this._contentArea);
 | 
			
		||||
            // If we know the notification will be expandable, we need to add
 | 
			
		||||
            // the banner text to the body as the first element.
 | 
			
		||||
            this._addBannerBody();
 | 
			
		||||
            this._createScrollArea();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._contentArea.add(actor, style ? style : {});
 | 
			
		||||
@@ -571,11 +597,6 @@ Notification.prototype = {
 | 
			
		||||
    //
 | 
			
		||||
    // Scrolls the content area (if scrollable) to the indicated edge
 | 
			
		||||
    scrollTo: function(side) {
 | 
			
		||||
        // Hack to force a relayout, since the caller probably
 | 
			
		||||
        // just added or removed something to scrollArea, and
 | 
			
		||||
        // the adjustment needs to reflect that.
 | 
			
		||||
        global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, 0, 0);
 | 
			
		||||
 | 
			
		||||
        let adjustment = this._scrollArea.vscroll.adjustment;
 | 
			
		||||
        if (side == St.Side.TOP)
 | 
			
		||||
            adjustment.value = adjustment.lower;
 | 
			
		||||
@@ -605,8 +626,8 @@ Notification.prototype = {
 | 
			
		||||
        props.row = 2;
 | 
			
		||||
        props.col = 1;
 | 
			
		||||
 | 
			
		||||
        this.actor.add_style_class_name('multi-line-notification');
 | 
			
		||||
        this.actor.add(this._actionArea, props);
 | 
			
		||||
        this._table.add_style_class_name('multi-line-notification');
 | 
			
		||||
        this._table.add(this._actionArea, props);
 | 
			
		||||
        this._updated();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -667,7 +688,7 @@ Notification.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _styleChanged: function() {
 | 
			
		||||
        this._spacing = this.actor.get_theme_node().get_length('spacing-columns');
 | 
			
		||||
        this._spacing = this._table.get_theme_node().get_length('spacing-columns');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _bannerBoxGetPreferredWidth: function(actor, forHeight, alloc) {
 | 
			
		||||
@@ -712,22 +733,29 @@ Notification.prototype = {
 | 
			
		||||
            // Make _bannerLabel visible if the entire notification
 | 
			
		||||
            // fits on one line, or if the notification is currently
 | 
			
		||||
            // unexpanded and only showing one line anyway.
 | 
			
		||||
            if (!this.expanded || (bannerFits && this.actor.row_count == 1))
 | 
			
		||||
            if (!this.expanded || (bannerFits && this._table.row_count == 1))
 | 
			
		||||
                this._bannerLabel.opacity = 255;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If the banner doesn't fully fit in the banner box, we possibly need to add the
 | 
			
		||||
        // banner to the body. We can't do that from here though since that will force a
 | 
			
		||||
        // relayout, so we add it to the main loop.
 | 
			
		||||
        if (!bannerFits)
 | 
			
		||||
            Mainloop.idle_add(Lang.bind(this,
 | 
			
		||||
                                        function() {
 | 
			
		||||
        if (!bannerFits && this._canExpandContent())
 | 
			
		||||
            Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
 | 
			
		||||
                           Lang.bind(this,
 | 
			
		||||
                                     function() {
 | 
			
		||||
                                        if (this._canExpandContent()) {
 | 
			
		||||
                                            this._addBannerBody();
 | 
			
		||||
                                            if (!this._titleFitsInBannerMode)
 | 
			
		||||
                                                this.actor.add_style_class_name('multi-line-notification');
 | 
			
		||||
                                            this._table.add_style_class_name('multi-line-notification');
 | 
			
		||||
                                            this._updated();
 | 
			
		||||
                                            return false;
 | 
			
		||||
                                        }));
 | 
			
		||||
                                        }
 | 
			
		||||
                                        return false;
 | 
			
		||||
                                     }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _canExpandContent: function() {
 | 
			
		||||
        return this._bannerBodyText ||
 | 
			
		||||
               (!this._titleFitsInBannerMode && !this._table.has_style_class_name('multi-line-notification'));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updated: function() {
 | 
			
		||||
@@ -745,7 +773,7 @@ Notification.prototype = {
 | 
			
		||||
            this._titleLabel.clutter_text.line_wrap = true;
 | 
			
		||||
            this._titleLabel.clutter_text.line_wrap_mode = Pango.WrapMode.WORD_CHAR;
 | 
			
		||||
            this._titleLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
 | 
			
		||||
        } else if (this.actor.row_count > 1 && this._bannerLabel.opacity != 0) {
 | 
			
		||||
        } else if (this._table.row_count > 1 && this._bannerLabel.opacity != 0) {
 | 
			
		||||
            // We always hide the banner if the notification has additional content.
 | 
			
		||||
            //
 | 
			
		||||
            // We don't need to wrap the banner that doesn't fit the way we wrap the
 | 
			
		||||
@@ -810,6 +838,7 @@ Notification.prototype = {
 | 
			
		||||
    destroy: function(reason) {
 | 
			
		||||
        this._destroyedReason = reason;
 | 
			
		||||
        this.actor.destroy();
 | 
			
		||||
        this.actor._delegate = null;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(Notification.prototype);
 | 
			
		||||
@@ -824,9 +853,13 @@ Source.prototype = {
 | 
			
		||||
    _init: function(title) {
 | 
			
		||||
        this.title = title;
 | 
			
		||||
        this._iconBin = new St.Bin({ width: this.ICON_SIZE,
 | 
			
		||||
                                     height: this.ICON_SIZE });
 | 
			
		||||
                                     height: this.ICON_SIZE,
 | 
			
		||||
                                     x_fill: true,
 | 
			
		||||
                                     y_fill: true });
 | 
			
		||||
        this.isTransient = false;
 | 
			
		||||
        this.isChat = false;
 | 
			
		||||
 | 
			
		||||
        this.notifications = [];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setTransient: function(isTransient) {
 | 
			
		||||
@@ -846,30 +879,40 @@ Source.prototype = {
 | 
			
		||||
        return this._iconBin;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    notify: function(notification) {
 | 
			
		||||
        if (this.notification) {
 | 
			
		||||
            this.notification.disconnect(this._notificationClickedId);
 | 
			
		||||
            this.notification.disconnect(this._notificationDestroyedId);
 | 
			
		||||
    pushNotification: function(notification) {
 | 
			
		||||
        if (this.notifications.indexOf(notification) < 0) {
 | 
			
		||||
            this.notifications.push(notification);
 | 
			
		||||
            this.emit('notification-added', notification);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.notification = notification;
 | 
			
		||||
 | 
			
		||||
        this._notificationClickedId = notification.connect('clicked', Lang.bind(this, this.open));
 | 
			
		||||
        this._notificationDestroyedId = notification.connect('destroy', Lang.bind(this,
 | 
			
		||||
        notification.connect('clicked', Lang.bind(this, this.open));
 | 
			
		||||
        notification.connect('destroy', Lang.bind(this,
 | 
			
		||||
            function () {
 | 
			
		||||
                if (this.notification == notification) {
 | 
			
		||||
                    this.notification = null;
 | 
			
		||||
                    this._notificationDestroyedId = 0;
 | 
			
		||||
                    this._notificationClickedId = 0;
 | 
			
		||||
                    this._notificationRemoved();
 | 
			
		||||
                }
 | 
			
		||||
            }));
 | 
			
		||||
                let index = this.notifications.indexOf(notification);
 | 
			
		||||
                if (index < 0)
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                this.notifications.splice(index, 1);
 | 
			
		||||
                if (this.notifications.length == 0)
 | 
			
		||||
                    this._lastNotificationRemoved();
 | 
			
		||||
            }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    notify: function(notification) {
 | 
			
		||||
        this.pushNotification(notification);
 | 
			
		||||
        this.emit('notify', notification);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy: function() {
 | 
			
		||||
        this.emit('destroy');
 | 
			
		||||
    destroy: function(reason) {
 | 
			
		||||
        this.emit('destroy', reason);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // A subclass can redefine this to "steal" clicks from the
 | 
			
		||||
    // summaryitem; Use Clutter.get_current_event() to get the
 | 
			
		||||
    // details, return true to prevent the default handling from
 | 
			
		||||
    // ocurring.
 | 
			
		||||
    handleSummaryClick: function() {
 | 
			
		||||
        return false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    //// Protected methods ////
 | 
			
		||||
@@ -885,8 +928,14 @@ Source.prototype = {
 | 
			
		||||
    open: function(notification) {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroyNonResidentNotifications: function() {
 | 
			
		||||
        for (let i = this.notifications.length - 1; i >= 0; i--)
 | 
			
		||||
            if (!this.notifications[i].resident)
 | 
			
		||||
                this.notifications[i].destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Default implementation is to destroy this source, but subclasses can override
 | 
			
		||||
    _notificationRemoved: function() {
 | 
			
		||||
    _lastNotificationRemoved: function() {
 | 
			
		||||
        this.destroy();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
@@ -899,8 +948,12 @@ function SummaryItem(source) {
 | 
			
		||||
SummaryItem.prototype = {
 | 
			
		||||
    _init: function(source) {
 | 
			
		||||
        this.source = source;
 | 
			
		||||
        this.source.connect('notification-added', Lang.bind(this, this._notificationAddedToSource));
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Button({ style_class: 'summary-source-button',
 | 
			
		||||
                                     y_fill: true,
 | 
			
		||||
                                     reactive: true,
 | 
			
		||||
                                     button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO | St.ButtonMask.THREE,
 | 
			
		||||
                                     track_hover: true });
 | 
			
		||||
 | 
			
		||||
        this._sourceBox = new St.BoxLayout({ style_class: 'summary-source' });
 | 
			
		||||
@@ -915,9 +968,30 @@ SummaryItem.prototype = {
 | 
			
		||||
        this._sourceTitleBin.child = this._sourceTitle;
 | 
			
		||||
        this._sourceTitleBin.width = 0;
 | 
			
		||||
 | 
			
		||||
        this._sourceBox.add_actor(this._sourceIcon);
 | 
			
		||||
        this._sourceBox.add_actor(this._sourceTitleBin, { expand: true });
 | 
			
		||||
        this._sourceBox.add(this._sourceIcon, { y_fill: false });
 | 
			
		||||
        this._sourceBox.add(this._sourceTitleBin, { expand: true, y_fill: false });
 | 
			
		||||
        this.actor.child = this._sourceBox;
 | 
			
		||||
 | 
			
		||||
        this.notificationStackView = new St.ScrollView({ name: source.isChat ? '' : 'summary-notification-stack-scrollview',
 | 
			
		||||
                                                         vscrollbar_policy: source.isChat ? Gtk.PolicyType.NEVER : Gtk.PolicyType.AUTOMATIC,
 | 
			
		||||
                                                         hscrollbar_policy: Gtk.PolicyType.NEVER,
 | 
			
		||||
                                                         vfade: true });
 | 
			
		||||
        this.notificationStack = new St.BoxLayout({ name: 'summary-notification-stack',
 | 
			
		||||
                                                     vertical: true });
 | 
			
		||||
        this.notificationStackView.add_actor(this.notificationStack);
 | 
			
		||||
        this._notificationExpandedIds = [];
 | 
			
		||||
        this._notificationDoneDisplayingIds = [];
 | 
			
		||||
        this._notificationDestroyedIds = [];
 | 
			
		||||
 | 
			
		||||
        this._oldMaxScrollAdjustment = 0;
 | 
			
		||||
 | 
			
		||||
        this.notificationStackView.vscroll.adjustment.connect('changed', Lang.bind(this, function(adjustment) {
 | 
			
		||||
            let currentValue = adjustment.value + adjustment.page_size;
 | 
			
		||||
            if (currentValue == this._oldMaxScrollAdjustment)
 | 
			
		||||
                this.scrollTo(St.Side.BOTTOM);
 | 
			
		||||
            this._oldMaxScrollAdjustment = adjustment.upper;
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this.rightClickMenu = new St.BoxLayout({ name: 'summary-right-click-menu',
 | 
			
		||||
                                                 vertical: true });
 | 
			
		||||
 | 
			
		||||
@@ -926,14 +1000,14 @@ SummaryItem.prototype = {
 | 
			
		||||
        item = new PopupMenu.PopupMenuItem(_("Open"));
 | 
			
		||||
        item.connect('activate', Lang.bind(this, function() {
 | 
			
		||||
            source.open();
 | 
			
		||||
            this.emit('right-click-menu-done-displaying');
 | 
			
		||||
            this.emit('done-displaying-content');
 | 
			
		||||
        }));
 | 
			
		||||
        this.rightClickMenu.add(item.actor);
 | 
			
		||||
 | 
			
		||||
        item = new PopupMenu.PopupMenuItem(_("Remove"));
 | 
			
		||||
        item.connect('activate', Lang.bind(this, function() {
 | 
			
		||||
            source.destroy();
 | 
			
		||||
            this.emit('right-click-menu-done-displaying');
 | 
			
		||||
            this.emit('done-displaying-content');
 | 
			
		||||
        }));
 | 
			
		||||
        this.rightClickMenu.add(item.actor);
 | 
			
		||||
 | 
			
		||||
@@ -963,6 +1037,87 @@ SummaryItem.prototype = {
 | 
			
		||||
 | 
			
		||||
    setEllipsization: function(mode) {
 | 
			
		||||
        this._sourceTitle.clutter_text.ellipsize = mode;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    prepareNotificationStackForShowing: function() {
 | 
			
		||||
        if (this.notificationStack.get_children().length > 0)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < this.source.notifications.length; i++) {
 | 
			
		||||
            this._appendNotificationToStack(this.source.notifications[i]);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    doneShowingNotificationStack: function() {
 | 
			
		||||
        let notificationActors = this.notificationStack.get_children();
 | 
			
		||||
        for (let i = 0; i < notificationActors.length; i++) {
 | 
			
		||||
            notificationActors[i]._delegate.collapseCompleted();
 | 
			
		||||
            notificationActors[i]._delegate.disconnect(this._notificationExpandedIds[i]);
 | 
			
		||||
            notificationActors[i]._delegate.disconnect(this._notificationDoneDisplayingIds[i]);
 | 
			
		||||
            notificationActors[i]._delegate.disconnect(this._notificationDestroyedIds[i]);
 | 
			
		||||
            this.notificationStack.remove_actor(notificationActors[i]);
 | 
			
		||||
            notificationActors[i]._delegate.setIconVisible(true);
 | 
			
		||||
            notificationActors[i]._delegate.enableScrolling(true);
 | 
			
		||||
        }
 | 
			
		||||
        this._notificationExpandedIds = [];
 | 
			
		||||
        this._notificationDoneDisplayingIds = [];
 | 
			
		||||
        this._notificationDestroyedIds = [];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _notificationAddedToSource: function(source, notification) {
 | 
			
		||||
        if (this.notificationStack.mapped)
 | 
			
		||||
            this._appendNotificationToStack(notification);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _appendNotificationToStack: function(notification) {
 | 
			
		||||
        let notificationExpandedId = notification.connect('expanded', Lang.bind(this, this._contentUpdated));
 | 
			
		||||
        this._notificationExpandedIds.push(notificationExpandedId);
 | 
			
		||||
        let notificationDoneDisplayingId = notification.connect('done-displaying', Lang.bind(this, this._notificationDoneDisplaying));
 | 
			
		||||
        this._notificationDoneDisplayingIds.push(notificationDoneDisplayingId);
 | 
			
		||||
        let notificationDestroyedId = notification.connect('destroy', Lang.bind(this, this._notificationDestroyed));
 | 
			
		||||
        this._notificationDestroyedIds.push(notificationDestroyedId);
 | 
			
		||||
        if (!this.source.isChat)
 | 
			
		||||
            notification.enableScrolling(false);
 | 
			
		||||
        if (this.notificationStack.get_children().length > 0)
 | 
			
		||||
            notification.setIconVisible(false);
 | 
			
		||||
        this.notificationStack.add(notification.actor);
 | 
			
		||||
        notification.expand(false);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // scrollTo:
 | 
			
		||||
    // @side: St.Side.TOP or St.Side.BOTTOM
 | 
			
		||||
    //
 | 
			
		||||
    // Scrolls the notifiction stack to the indicated edge
 | 
			
		||||
    scrollTo: function(side) {
 | 
			
		||||
        let adjustment = this.notificationStackView.vscroll.adjustment;
 | 
			
		||||
        if (side == St.Side.TOP)
 | 
			
		||||
            adjustment.value = adjustment.lower;
 | 
			
		||||
        else if (side == St.Side.BOTTOM)
 | 
			
		||||
            adjustment.value = adjustment.upper;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _contentUpdated: function() {
 | 
			
		||||
        this.emit('content-updated');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _notificationDoneDisplaying: function() {
 | 
			
		||||
        this.emit('done-displaying-content');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _notificationDestroyed: function(notification) {
 | 
			
		||||
        let index = this.notificationStack.get_children().indexOf(notification.actor);
 | 
			
		||||
        if (index >= 0) {
 | 
			
		||||
            notification.disconnect(this._notificationExpandedIds[index]);
 | 
			
		||||
            this._notificationExpandedIds.splice(index, 1);
 | 
			
		||||
            notification.disconnect(this._notificationDoneDisplayingIds[index]);
 | 
			
		||||
            this._notificationDoneDisplayingIds.splice(index, 1);
 | 
			
		||||
            notification.disconnect(this._notificationDestroyedIds[index]);
 | 
			
		||||
            this._notificationDestroyedIds.splice(index, 1);
 | 
			
		||||
            this.notificationStack.remove_actor(notification.actor);
 | 
			
		||||
            this._contentUpdated();
 | 
			
		||||
        }
 | 
			
		||||
        if (this.notificationStack.get_children().length > 0)
 | 
			
		||||
            this.notificationStack.get_children()[0]._delegate.setIconVisible(true);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(SummaryItem.prototype);
 | 
			
		||||
@@ -1011,14 +1166,15 @@ MessageTray.prototype = {
 | 
			
		||||
        this._summaryBoxPointer.actor.lower_bottom();
 | 
			
		||||
        this._summaryBoxPointer.actor.hide();
 | 
			
		||||
 | 
			
		||||
        this._summaryNotification = null;
 | 
			
		||||
        this._summaryNotificationClickedId = 0;
 | 
			
		||||
        this._summaryRightClickMenuClickedId = 0;
 | 
			
		||||
        this._summaryBoxPointerItem = null;
 | 
			
		||||
        this._summaryBoxPointerContentUpdatedId = 0;
 | 
			
		||||
        this._summaryBoxPointerDoneDisplayingId = 0;
 | 
			
		||||
        this._clickedSummaryItem = null;
 | 
			
		||||
        this._clickedSummaryItemMouseButton = -1;
 | 
			
		||||
        this._clickedSummaryItemAllocationChangedId = 0;
 | 
			
		||||
        this._expandedSummaryItem = null;
 | 
			
		||||
        this._summaryItemTitleWidth = 0;
 | 
			
		||||
        this._pointerBarrier = 0;
 | 
			
		||||
 | 
			
		||||
        // To simplify the summary item animation code, we pretend
 | 
			
		||||
        // that there's an invisible SummaryItem to the left of the
 | 
			
		||||
@@ -1053,18 +1209,17 @@ MessageTray.prototype = {
 | 
			
		||||
        this._notificationTimeoutId = 0;
 | 
			
		||||
        this._notificationExpandedId = 0;
 | 
			
		||||
        this._summaryBoxPointerState = State.HIDDEN;
 | 
			
		||||
        this._summaryNotificationTimeoutId = 0;
 | 
			
		||||
        this._summaryNotificationExpandedId = 0;
 | 
			
		||||
        this._summaryBoxPointerTimeoutId = 0;
 | 
			
		||||
        this._overviewVisible = Main.overview.visible;
 | 
			
		||||
        this._notificationRemoved = false;
 | 
			
		||||
        this._reNotifyWithSummaryNotificationAfterHide = false;
 | 
			
		||||
        this._reNotifyAfterHideNotification = null;
 | 
			
		||||
 | 
			
		||||
        Main.chrome.addActor(this.actor, { affectsStruts: false,
 | 
			
		||||
                                           visibleInOverview: true });
 | 
			
		||||
        Main.chrome.trackActor(this._notificationBin);
 | 
			
		||||
        Main.chrome.trackActor(this._summaryBoxPointer.actor);
 | 
			
		||||
 | 
			
		||||
        global.gdk_screen.connect('monitors-changed', Lang.bind(this, this._setSizePosition));
 | 
			
		||||
        global.screen.connect('monitors-changed', Lang.bind(this, this._setSizePosition));
 | 
			
		||||
 | 
			
		||||
        this._setSizePosition();
 | 
			
		||||
 | 
			
		||||
@@ -1108,6 +1263,15 @@ MessageTray.prototype = {
 | 
			
		||||
        this._notificationBin.width = primary.width;
 | 
			
		||||
        this._summaryBin.x = 0;
 | 
			
		||||
        this._summaryBin.width = primary.width;
 | 
			
		||||
 | 
			
		||||
        if (this._pointerBarrier)
 | 
			
		||||
            global.destroy_pointer_barrier(this._pointerBarrier);
 | 
			
		||||
        this._pointerBarrier =
 | 
			
		||||
            global.create_pointer_barrier(primary.x + primary.width, primary.y + primary.height - this.actor.height,
 | 
			
		||||
                                          primary.x + primary.width, primary.y + primary.height,
 | 
			
		||||
                                          4 /* BarrierNegativeX */);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    contains: function(source) {
 | 
			
		||||
@@ -1163,9 +1327,9 @@ MessageTray.prototype = {
 | 
			
		||||
                this._onSummaryItemHoverChanged(summaryItem);
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        summaryItem.actor.connect('button-press-event', Lang.bind(this,
 | 
			
		||||
            function (actor, event) {
 | 
			
		||||
                this._onSummaryItemClicked(summaryItem, event);
 | 
			
		||||
        summaryItem.actor.connect('clicked', Lang.bind(this,
 | 
			
		||||
            function (actor, button) {
 | 
			
		||||
                this._onSummaryItemClicked(summaryItem, button);
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        source.connect('destroy', Lang.bind(this, this._onSourceDestroy));
 | 
			
		||||
@@ -1229,13 +1393,6 @@ MessageTray.prototype = {
 | 
			
		||||
 | 
			
		||||
        if (needUpdate);
 | 
			
		||||
            this._updateState();
 | 
			
		||||
 | 
			
		||||
        // remove all notifications with this source from the queue
 | 
			
		||||
        let newNotificationQueue = [];
 | 
			
		||||
        for (let i = this._notificationQueue.length - 1; i >= 0; i--) {
 | 
			
		||||
            if (this._notificationQueue[i].source == source)
 | 
			
		||||
                this._notificationQueue[i].destroy();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onNotificationDestroy: function(notification) {
 | 
			
		||||
@@ -1260,18 +1417,23 @@ MessageTray.prototype = {
 | 
			
		||||
        if (!this._locked)
 | 
			
		||||
            return;
 | 
			
		||||
        this._locked = false;
 | 
			
		||||
        this._pointerInTray = this.actor.hover && !this._summaryBoxPointer.bin.hover;
 | 
			
		||||
        this._updateState();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onNotify: function(source, notification) {
 | 
			
		||||
        if (notification == this._summaryNotification) {
 | 
			
		||||
            if (!this._summaryNotificationExpandedId)
 | 
			
		||||
                // We must be in the process of hiding the summary notification.
 | 
			
		||||
                // If the summary notification is updated while it is being
 | 
			
		||||
                // hidden, we show the update as a new notification. However,
 | 
			
		||||
                // we must first wait till the hide is complete and the
 | 
			
		||||
                // notification actor is not part of the stage.
 | 
			
		||||
                this._reNotifyWithSummaryNotificationAfterHide = true;
 | 
			
		||||
        if (this._summaryBoxPointerItem && this._summaryBoxPointerItem.source == source) {
 | 
			
		||||
            if (this._summaryBoxPointerState == State.HIDING)
 | 
			
		||||
                // We are in the process of hiding the summary box pointer.
 | 
			
		||||
                // If there is an update for one of the notifications or
 | 
			
		||||
                // a new notification to be added to the notification stack
 | 
			
		||||
                // while it is in the process of being hidden, we show it as
 | 
			
		||||
                // a new notification. However, we first wait till the hide
 | 
			
		||||
                // is complete. This is especially important if one of the
 | 
			
		||||
                // notifications in the stack was updated because we will
 | 
			
		||||
                // need to be able to re-parent its actor to a different
 | 
			
		||||
                // part of the stage.
 | 
			
		||||
                this._reNotifyAfterHideNotification = notification;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -1310,12 +1472,18 @@ MessageTray.prototype = {
 | 
			
		||||
        // Turn off ellipsization for the previously expanded item that is
 | 
			
		||||
        // collapsing and for the item that is expanding because it looks
 | 
			
		||||
        // better that way.
 | 
			
		||||
        if (this._expandedSummaryItem)
 | 
			
		||||
        if (this._expandedSummaryItem) {
 | 
			
		||||
            // Ideally, we would remove 'expanded' pseudo class when the item
 | 
			
		||||
            // is done collapsing, but we don't track when that happens.
 | 
			
		||||
            this._expandedSummaryItem.actor.remove_style_pseudo_class('expanded');
 | 
			
		||||
            this._expandedSummaryItem.setEllipsization(Pango.EllipsizeMode.NONE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._expandedSummaryItem = summaryItem;
 | 
			
		||||
        if (this._expandedSummaryItem)
 | 
			
		||||
        if (this._expandedSummaryItem) {
 | 
			
		||||
            this._expandedSummaryItem.actor.add_style_pseudo_class('expanded');
 | 
			
		||||
            this._expandedSummaryItem.setEllipsization(Pango.EllipsizeMode.NONE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // We tween on a "_expandedSummaryItemTitleWidth" pseudo-property
 | 
			
		||||
        // that represents the current title width of the
 | 
			
		||||
@@ -1337,6 +1505,8 @@ MessageTray.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    set _expandedSummaryItemTitleWidth(expansion) {
 | 
			
		||||
        expansion = Math.round(expansion);
 | 
			
		||||
 | 
			
		||||
        // Expand the expanding item to its new width
 | 
			
		||||
        if (this._expandedSummaryItem)
 | 
			
		||||
            this._expandedSummaryItem.setTitleWidth(expansion);
 | 
			
		||||
@@ -1367,11 +1537,32 @@ MessageTray.prototype = {
 | 
			
		||||
            if (this._summaryItems[i] == this._expandedSummaryItem)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            let width = this._summaryItems[i].getTitleWidth();
 | 
			
		||||
            this._summaryItems[i].setTitleWidth(width * shrinkage);
 | 
			
		||||
            let oldWidth = this._summaryItems[i].getTitleWidth();
 | 
			
		||||
            let newWidth = Math.floor(oldWidth * shrinkage);
 | 
			
		||||
            excess -= newWidth;
 | 
			
		||||
            this._summaryItems[i].setTitleWidth(newWidth);
 | 
			
		||||
        }
 | 
			
		||||
        if (this._expandedSummaryItem) {
 | 
			
		||||
            let oldWidth = this._imaginarySummaryItemTitleWidth;
 | 
			
		||||
            let newWidth = Math.floor(oldWidth * shrinkage);
 | 
			
		||||
            excess -= newWidth;
 | 
			
		||||
            this._imaginarySummaryItemTitleWidth = newWidth;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If the tray as a whole is fully-expanded, make sure the
 | 
			
		||||
        // left edge doesn't wobble during animation due to rounding.
 | 
			
		||||
        if (this._imaginarySummaryItemTitleWidth == 0 && excess != 0) {
 | 
			
		||||
            for (let i = 0; i < this._summaryItems.length; i++) {
 | 
			
		||||
                if (this._summaryItems[i] == this._expandedSummaryItem)
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                let oldWidth = this._summaryItems[i].getTitleWidth();
 | 
			
		||||
                if (oldWidth != 0) {
 | 
			
		||||
                    this._summaryItems[i].setTitleWidth (oldWidth + excess);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (this._expandedSummaryItem)
 | 
			
		||||
            this._imaginarySummaryItemTitleWidth *= shrinkage;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _expandSummaryItemCompleted: function() {
 | 
			
		||||
@@ -1379,13 +1570,14 @@ MessageTray.prototype = {
 | 
			
		||||
            this._expandedSummaryItem.setEllipsization(Pango.EllipsizeMode.END);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSummaryItemClicked: function(summaryItem, event) {
 | 
			
		||||
        let clickedButton = event.get_button();
 | 
			
		||||
        if (!this._clickedSummaryItem ||
 | 
			
		||||
            this._clickedSummaryItem != summaryItem ||
 | 
			
		||||
            this._clickedSummaryItemMouseButton != clickedButton) {
 | 
			
		||||
    _onSummaryItemClicked: function(summaryItem, button) {
 | 
			
		||||
        if (summaryItem.source.handleSummaryClick())
 | 
			
		||||
            this._unsetClickedSummaryItem();
 | 
			
		||||
        else if (!this._clickedSummaryItem ||
 | 
			
		||||
                 this._clickedSummaryItem != summaryItem ||
 | 
			
		||||
                 this._clickedSummaryItemMouseButton != button) {
 | 
			
		||||
            this._clickedSummaryItem = summaryItem;
 | 
			
		||||
            this._clickedSummaryItemMouseButton = clickedButton;
 | 
			
		||||
            this._clickedSummaryItemMouseButton = button;
 | 
			
		||||
        } else {
 | 
			
		||||
            this._unsetClickedSummaryItem();
 | 
			
		||||
        }
 | 
			
		||||
@@ -1521,14 +1713,15 @@ MessageTray.prototype = {
 | 
			
		||||
    // at the present time.
 | 
			
		||||
    _updateState: function() {
 | 
			
		||||
        // Notifications
 | 
			
		||||
        let notificationsPending = this._notificationQueue.length > 0 &&
 | 
			
		||||
                                   (!this._busy || this._notificationQueue[0].urgency == Urgency.CRITICAL);
 | 
			
		||||
        let notificationUrgent = this._notificationQueue.length > 0 && this._notificationQueue[0].urgency == Urgency.CRITICAL;
 | 
			
		||||
        let notificationsPending = this._notificationQueue.length > 0 && (!this._busy || notificationUrgent);
 | 
			
		||||
        let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
 | 
			
		||||
        let notificationExpanded = this._notificationBin.y < 0;
 | 
			
		||||
        let notificationExpired = (this._notificationTimeoutId == 0 && !(this._notification && this._notification.urgency == Urgency.CRITICAL) && !this._pointerInTray && !this._locked) || this._notificationRemoved;
 | 
			
		||||
        let canShowNotification = notificationsPending && this._summaryState == State.HIDDEN;
 | 
			
		||||
 | 
			
		||||
        if (this._notificationState == State.HIDDEN) {
 | 
			
		||||
            if (notificationsPending)
 | 
			
		||||
            if (canShowNotification)
 | 
			
		||||
                this._showNotification();
 | 
			
		||||
        } else if (this._notificationState == State.SHOWN) {
 | 
			
		||||
            if (notificationExpired)
 | 
			
		||||
@@ -1550,7 +1743,11 @@ MessageTray.prototype = {
 | 
			
		||||
                                    this._notificationState == State.SHOWN);
 | 
			
		||||
        let notificationsDone = !notificationsVisible && !notificationsPending;
 | 
			
		||||
 | 
			
		||||
        if (this._summaryState == State.HIDDEN) {
 | 
			
		||||
        let summaryOptionalInOverview = this._overviewVisible && !this._locked && !summaryHovered;
 | 
			
		||||
        let mustHideSummary = (notificationsPending && (notificationUrgent || summaryOptionalInOverview))
 | 
			
		||||
                              || notificationsVisible;
 | 
			
		||||
 | 
			
		||||
        if (this._summaryState == State.HIDDEN && !mustHideSummary) {
 | 
			
		||||
            if (this._backFromAway) {
 | 
			
		||||
                // Immediately set this to false, so that we don't schedule a timeout later
 | 
			
		||||
                this._backFromAway = false;
 | 
			
		||||
@@ -1562,7 +1759,7 @@ MessageTray.prototype = {
 | 
			
		||||
                this._showSummary(0);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (this._summaryState == State.SHOWN) {
 | 
			
		||||
            if (!summaryPinned)
 | 
			
		||||
            if (!summaryPinned || mustHideSummary)
 | 
			
		||||
                this._hideSummary();
 | 
			
		||||
            else if (summaryVisibleWithNoHover && !summaryNotificationIsForExpandedSummaryItem)
 | 
			
		||||
                // If we are hiding the summary, we'll collapse the expanded summary item when we are done
 | 
			
		||||
@@ -1577,18 +1774,21 @@ MessageTray.prototype = {
 | 
			
		||||
        let summarySourceIsMainNotificationSource = (haveClickedSummaryItem && this._notification &&
 | 
			
		||||
                                                     this._clickedSummaryItem.source == this._notification.source);
 | 
			
		||||
        let canShowSummaryBoxPointer = this._summaryState == State.SHOWN;
 | 
			
		||||
        let wrongSummaryNotification = (this._clickedSummaryItemMouseButton == 1 &&
 | 
			
		||||
                                        this._summaryNotification != this._clickedSummaryItem.source.notification);
 | 
			
		||||
        // We only have sources with empty notification stacks for legacy tray icons. Currently, we never attempt
 | 
			
		||||
        // to show notifications for legacy tray icons, but this would be necessary if we did.
 | 
			
		||||
        let requestedNotificationStackIsEmpty = (this._clickedSummaryItemMouseButton == 1 && this._clickedSummaryItem.source.notifications.length == 0);
 | 
			
		||||
        let wrongSummaryNotificationStack = (this._clickedSummaryItemMouseButton == 1 &&
 | 
			
		||||
                                             this._summaryBoxPointer.bin.child != this._clickedSummaryItem.notificationStackView);
 | 
			
		||||
        let wrongSummaryRightClickMenu = (this._clickedSummaryItemMouseButton == 3 &&
 | 
			
		||||
                                          this._summaryBoxPointer.bin.child != this._clickedSummaryItem.rightClickMenu);
 | 
			
		||||
        let wrongSummaryBoxPointer = (haveClickedSummaryItem &&
 | 
			
		||||
                                      (wrongSummaryNotification || wrongSummaryRightClickMenu));
 | 
			
		||||
                                      (wrongSummaryNotificationStack || wrongSummaryRightClickMenu));
 | 
			
		||||
 | 
			
		||||
        if (this._summaryBoxPointerState == State.HIDDEN) {
 | 
			
		||||
            if (haveClickedSummaryItem && !summarySourceIsMainNotificationSource && canShowSummaryBoxPointer)
 | 
			
		||||
            if (haveClickedSummaryItem && !summarySourceIsMainNotificationSource && canShowSummaryBoxPointer && !requestedNotificationStackIsEmpty)
 | 
			
		||||
                this._showSummaryBoxPointer();
 | 
			
		||||
        } else if (this._summaryBoxPointerState == State.SHOWN) {
 | 
			
		||||
            if (!haveClickedSummaryItem || !canShowSummaryBoxPointer || wrongSummaryBoxPointer)
 | 
			
		||||
            if (!haveClickedSummaryItem || !canShowSummaryBoxPointer || wrongSummaryBoxPointer || mustHideSummary)
 | 
			
		||||
                this._hideSummaryBoxPointer();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -1843,38 +2043,33 @@ MessageTray.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _hideSummaryCompleted: function() {
 | 
			
		||||
        this._expandedSummaryItem = null;
 | 
			
		||||
        this._expandedSummaryItemTitleWidth = this._summaryItemTitleWidth;
 | 
			
		||||
        this._setExpandedSummaryItem(null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _showSummaryBoxPointer: function() {
 | 
			
		||||
        this._summaryBoxPointerItem = this._clickedSummaryItem;
 | 
			
		||||
        this._summaryBoxPointerContentUpdatedId = this._summaryBoxPointerItem.connect('content-updated',
 | 
			
		||||
                                                                                      Lang.bind(this, this._adjustSummaryBoxPointerPosition));
 | 
			
		||||
        this._summaryBoxPointerDoneDisplayingId = this._summaryBoxPointerItem.connect('done-displaying-content',
 | 
			
		||||
                                                                                      Lang.bind(this, this._escapeTray));
 | 
			
		||||
        if (this._clickedSummaryItemMouseButton == 1) {
 | 
			
		||||
            let clickedSummaryItemNotification = this._clickedSummaryItem.source.notification;
 | 
			
		||||
            let index = this._notificationQueue.indexOf(clickedSummaryItemNotification);
 | 
			
		||||
            if (index != -1)
 | 
			
		||||
                this._notificationQueue.splice(index, 1);
 | 
			
		||||
 | 
			
		||||
            this._summaryNotification = clickedSummaryItemNotification;
 | 
			
		||||
            this._summaryNotificationClickedId = this._summaryNotification.connect('done-displaying',
 | 
			
		||||
                                                                                   Lang.bind(this, this._escapeTray));
 | 
			
		||||
            this._summaryBoxPointer.bin.child = this._summaryNotification.actor;
 | 
			
		||||
            if (!this._summaryNotificationExpandedId)
 | 
			
		||||
                this._summaryNotificationExpandedId = this._summaryNotification.connect('expanded',
 | 
			
		||||
                                                                                        Lang.bind(this, this._onSummaryBoxPointerExpanded));
 | 
			
		||||
            this._summaryNotification.expand(false);
 | 
			
		||||
            this._notificationQueue = this._notificationQueue.filter( Lang.bind(this,
 | 
			
		||||
                function(notification) {
 | 
			
		||||
                    return this._summaryBoxPointerItem.source != notification.source;
 | 
			
		||||
                }));
 | 
			
		||||
            this._summaryBoxPointerItem.prepareNotificationStackForShowing();
 | 
			
		||||
            this._summaryBoxPointer.bin.child = this._summaryBoxPointerItem.notificationStackView;
 | 
			
		||||
            this._summaryBoxPointerItem.scrollTo(St.Side.BOTTOM);
 | 
			
		||||
        } else if (this._clickedSummaryItemMouseButton == 3) {
 | 
			
		||||
            this._summaryRightClickMenuClickedId = this._clickedSummaryItem.connect('right-click-menu-done-displaying',
 | 
			
		||||
                                                                                    Lang.bind(this, this._escapeTray));
 | 
			
		||||
            this._summaryBoxPointer.bin.child = this._clickedSummaryItem.rightClickMenu;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._focusGrabber.grabFocus(this._summaryBoxPointer.bin.child);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        this._clickedSummaryItemAllocationChangedId =
 | 
			
		||||
            this._clickedSummaryItem.actor.connect('allocation-changed',
 | 
			
		||||
                                                   Lang.bind(this, this._adjustSummaryBoxPointerPosition));
 | 
			
		||||
        // _clickedSummaryItem.actor can change absolute postiion without changing allocation
 | 
			
		||||
        // _clickedSummaryItem.actor can change absolute position without changing allocation
 | 
			
		||||
        this._summaryMotionId = this._summary.connect('allocation-changed',
 | 
			
		||||
                                                      Lang.bind(this, this._adjustSummaryBoxPointerPosition));
 | 
			
		||||
 | 
			
		||||
@@ -1883,6 +2078,7 @@ MessageTray.prototype = {
 | 
			
		||||
        this._adjustSummaryBoxPointerPosition();
 | 
			
		||||
 | 
			
		||||
        this._summaryBoxPointerState = State.SHOWING;
 | 
			
		||||
        this._clickedSummaryItem.actor.add_style_pseudo_class('selected');
 | 
			
		||||
        this._summaryBoxPointer.show(true, Lang.bind(this, function() {
 | 
			
		||||
            this._summaryBoxPointerState = State.SHOWN;
 | 
			
		||||
        }));
 | 
			
		||||
@@ -1904,49 +2100,54 @@ MessageTray.prototype = {
 | 
			
		||||
            this._summaryMotionId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._summaryRightClickMenuClickedId) {
 | 
			
		||||
            this._clickedSummaryItem.disconnect(this._summaryRightClickMenuClickedId);
 | 
			
		||||
            this._summaryRightClickMenuClickedId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._clickedSummaryItem)
 | 
			
		||||
            this._clickedSummaryItem.actor.remove_style_pseudo_class('selected');
 | 
			
		||||
        this._clickedSummaryItem = null;
 | 
			
		||||
        this._clickedSummaryItemMouseButton = -1;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSummaryBoxPointerExpanded: function() {
 | 
			
		||||
        this._adjustSummaryBoxPointerPosition();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _hideSummaryBoxPointer: function() {
 | 
			
		||||
        if (this._summaryNotificationExpandedId) {
 | 
			
		||||
            this._summaryNotification.disconnect(this._summaryNotificationExpandedId);
 | 
			
		||||
            this._summaryNotificationExpandedId = 0;
 | 
			
		||||
        }
 | 
			
		||||
        this._summaryBoxPointerState = State.HIDING;
 | 
			
		||||
        // Unset this._clickedSummaryItem if we are no longer showing the summary
 | 
			
		||||
        if (this._summaryState != State.SHOWN)
 | 
			
		||||
            this._unsetClickedSummaryItem();
 | 
			
		||||
 | 
			
		||||
        this._focusGrabber.ungrabFocus();
 | 
			
		||||
        this._summaryBoxPointerState = State.HIDING;
 | 
			
		||||
        this._summaryBoxPointer.hide(true, Lang.bind(this, this._hideSummaryBoxPointerCompleted));
 | 
			
		||||
        if (this._summaryBoxPointerItem.source.notifications.length == 0) {
 | 
			
		||||
            this._summaryBoxPointer.actor.hide();
 | 
			
		||||
            this._hideSummaryBoxPointerCompleted();
 | 
			
		||||
        } else {
 | 
			
		||||
            this._summaryBoxPointer.hide(true, Lang.bind(this, this._hideSummaryBoxPointerCompleted));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _hideSummaryBoxPointerCompleted: function() {
 | 
			
		||||
        let doneShowingNotificationStack = (this._summaryBoxPointer.bin.child == this._summaryBoxPointerItem.notificationStackView);
 | 
			
		||||
 | 
			
		||||
        this._summaryBoxPointerState = State.HIDDEN;
 | 
			
		||||
        this._summaryBoxPointer.bin.child = null;
 | 
			
		||||
        if (this._summaryNotification != null) {
 | 
			
		||||
            this._summaryNotification.collapseCompleted();
 | 
			
		||||
            this._summaryNotification.disconnect(this._summaryNotificationClickedId);
 | 
			
		||||
            this._summaryNotificationClickedId = 0;
 | 
			
		||||
            let summaryNotification = this._summaryNotification;
 | 
			
		||||
            this._summaryNotification = null;
 | 
			
		||||
            if (summaryNotification.isTransient && !this._reNotifyWithSummaryNotificationAfterHide)
 | 
			
		||||
                summaryNotification.destroy(NotificationDestroyedReason.EXPIRED);
 | 
			
		||||
            if (this._reNotifyWithSummaryNotificationAfterHide) {
 | 
			
		||||
                this._onNotify(summaryNotification.source, summaryNotification);
 | 
			
		||||
                this._reNotifyWithSummaryNotificationAfterHide = false;
 | 
			
		||||
        this._summaryBoxPointerItem.disconnect(this._summaryBoxPointerContentUpdatedId);
 | 
			
		||||
        this._summaryBoxPointerContentUpdatedId = 0;
 | 
			
		||||
        this._summaryBoxPointerItem.disconnect(this._summaryBoxPointerDoneDisplayingId);
 | 
			
		||||
        this._summaryBoxPointerDoneDisplayingId = 0;
 | 
			
		||||
 | 
			
		||||
        let sourceNotificationStackDoneShowing = null;
 | 
			
		||||
        if (doneShowingNotificationStack) {
 | 
			
		||||
            this._summaryBoxPointerItem.doneShowingNotificationStack();
 | 
			
		||||
            sourceNotificationStackDoneShowing = this._summaryBoxPointerItem.source;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._summaryBoxPointerItem = null;
 | 
			
		||||
 | 
			
		||||
        if (sourceNotificationStackDoneShowing) {
 | 
			
		||||
            if (sourceNotificationStackDoneShowing.isTransient && !this._reNotifyAfterHideNotification)
 | 
			
		||||
                sourceNotificationStackDoneShowing.destroy(NotificationDestroyedReason.EXPIRED);
 | 
			
		||||
            if (this._reNotifyAfterHideNotification) {
 | 
			
		||||
                this._onNotify(this._reNotifyAfterHideNotification.source, this._reNotifyAfterHideNotification);
 | 
			
		||||
                this._reNotifyAfterHideNotification = null;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._clickedSummaryItem)
 | 
			
		||||
            this._updateState();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -39,13 +39,20 @@ ModalDialog.prototype = {
 | 
			
		||||
        params = Params.parse(params, { styleClass: null });
 | 
			
		||||
 | 
			
		||||
        this.state = State.CLOSED;
 | 
			
		||||
        this._hasModal = false;
 | 
			
		||||
 | 
			
		||||
        this._group = new St.Group({ visible: false,
 | 
			
		||||
                                     x: 0,
 | 
			
		||||
                                     y: 0 });
 | 
			
		||||
        Main.uiGroup.add_actor(this._group);
 | 
			
		||||
 | 
			
		||||
        let constraint = new Clutter.BindConstraint({ source: global.stage,
 | 
			
		||||
                                                      coordinate: Clutter.BindCoordinate.POSITION | Clutter.BindCoordinate.SIZE });
 | 
			
		||||
        this._group.add_constraint(constraint);
 | 
			
		||||
 | 
			
		||||
        global.focus_manager.add_group(this._group);
 | 
			
		||||
        this._initialKeyFocus = this._group;
 | 
			
		||||
        this._savedKeyFocus = null;
 | 
			
		||||
 | 
			
		||||
        this._group.connect('destroy', Lang.bind(this, this._onGroupDestroy));
 | 
			
		||||
 | 
			
		||||
@@ -60,12 +67,18 @@ ModalDialog.prototype = {
 | 
			
		||||
        this._group.add_actor(this._backgroundBin);
 | 
			
		||||
        this._lightbox.highlight(this._backgroundBin);
 | 
			
		||||
 | 
			
		||||
        this._backgroundStack = new Shell.Stack();
 | 
			
		||||
        this._backgroundBin.child = this._backgroundStack;
 | 
			
		||||
 | 
			
		||||
        this._eventBlocker = new Clutter.Group({ reactive: true });
 | 
			
		||||
        this._backgroundStack.add_actor(this._eventBlocker);
 | 
			
		||||
 | 
			
		||||
        this._dialogLayout = new St.BoxLayout({ style_class: 'modal-dialog',
 | 
			
		||||
                                                vertical:    true });
 | 
			
		||||
        if (params.styleClass != null) {
 | 
			
		||||
            this._dialogLayout.add_style_class_name(params.styleClass);
 | 
			
		||||
        }
 | 
			
		||||
        this._backgroundBin.child = this._dialogLayout;
 | 
			
		||||
        this._backgroundStack.add_actor(this._dialogLayout);
 | 
			
		||||
 | 
			
		||||
        this.contentLayout = new St.BoxLayout({ vertical: true });
 | 
			
		||||
        this._dialogLayout.add(this.contentLayout,
 | 
			
		||||
@@ -74,8 +87,9 @@ ModalDialog.prototype = {
 | 
			
		||||
                                 x_align: St.Align.MIDDLE,
 | 
			
		||||
                                 y_align: St.Align.START });
 | 
			
		||||
 | 
			
		||||
        this._buttonLayout = new St.BoxLayout({ opacity:  220,
 | 
			
		||||
                                                vertical: false });
 | 
			
		||||
        this._buttonLayout = new St.BoxLayout({ style_class: 'modal-dialog-button-box',
 | 
			
		||||
                                                opacity:     220,
 | 
			
		||||
                                                vertical:    false });
 | 
			
		||||
        this._dialogLayout.add(this._buttonLayout,
 | 
			
		||||
                               { expand:  true,
 | 
			
		||||
                                 x_align: St.Align.MIDDLE,
 | 
			
		||||
@@ -154,22 +168,23 @@ ModalDialog.prototype = {
 | 
			
		||||
                           transition: 'easeOutQuad',
 | 
			
		||||
                           onComplete: Lang.bind(this,
 | 
			
		||||
                               function() {
 | 
			
		||||
                                   this._initialKeyFocus.grab_key_focus();
 | 
			
		||||
                                   this.state = State.OPENED;
 | 
			
		||||
                                   this.emit('opened');
 | 
			
		||||
                               }),
 | 
			
		||||
                               })
 | 
			
		||||
                         });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setInitialKeyFocus: function(actor) {
 | 
			
		||||
        this._initialKeyFocus = actor;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    open: function(timestamp) {
 | 
			
		||||
        if (this.state == State.OPENED || this.state == State.OPENING)
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        if (!Main.pushModal(this._group, timestamp))
 | 
			
		||||
        if (!this.pushModal(timestamp))
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        global.stage.set_key_focus(this._group);
 | 
			
		||||
 | 
			
		||||
        this._fadeOpen();
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
@@ -178,14 +193,8 @@ ModalDialog.prototype = {
 | 
			
		||||
        if (this.state == State.CLOSED || this.state == State.CLOSING)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let needsPopModal;
 | 
			
		||||
 | 
			
		||||
        if (this.state == State.OPENED || this.state == State.OPENING)
 | 
			
		||||
            needsPopModal = true;
 | 
			
		||||
        else
 | 
			
		||||
            needsPopModal = false;
 | 
			
		||||
 | 
			
		||||
        this.state = State.CLOSING;
 | 
			
		||||
        this.popModal(timestamp);
 | 
			
		||||
 | 
			
		||||
        Tweener.addTween(this._group,
 | 
			
		||||
                         { opacity: 0,
 | 
			
		||||
@@ -195,13 +204,46 @@ ModalDialog.prototype = {
 | 
			
		||||
                               function() {
 | 
			
		||||
                                   this.state = State.CLOSED;
 | 
			
		||||
                                   this._group.hide();
 | 
			
		||||
 | 
			
		||||
                                   if (needsPopModal)
 | 
			
		||||
                                       Main.popModal(this._group, timestamp);
 | 
			
		||||
                               })
 | 
			
		||||
                         });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Drop modal status without closing the dialog; this makes the
 | 
			
		||||
    // dialog insensitive as well, so it needs to be followed shortly
 | 
			
		||||
    // by either a close() or a pushModal()
 | 
			
		||||
    popModal: function(timestamp) {
 | 
			
		||||
        if (!this._hasModal)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let focus = global.stage.key_focus;
 | 
			
		||||
        if (focus && this._group.contains(focus))
 | 
			
		||||
            this._savedKeyFocus = focus;
 | 
			
		||||
        else
 | 
			
		||||
            this._savedKeyFocus = null;
 | 
			
		||||
        Main.popModal(this._group, timestamp);
 | 
			
		||||
        global.gdk_screen.get_display().sync();
 | 
			
		||||
        this._hasModal = false;
 | 
			
		||||
 | 
			
		||||
        this._eventBlocker.raise_top();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    pushModal: function (timestamp) {
 | 
			
		||||
        if (this._hasModal)
 | 
			
		||||
            return true;
 | 
			
		||||
        if (!Main.pushModal(this._group, timestamp))
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        this._hasModal = true;
 | 
			
		||||
        if (this._savedKeyFocus) {
 | 
			
		||||
            this._savedKeyFocus.grab_key_focus();
 | 
			
		||||
            this._savedKeyFocus = null;
 | 
			
		||||
        } else
 | 
			
		||||
            this._initialKeyFocus.grab_key_focus();
 | 
			
		||||
 | 
			
		||||
        this._eventBlocker.lower_bottom();
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // This method is like close, but fades the dialog out much slower,
 | 
			
		||||
    // and leaves the lightbox in place. Once in the faded out state,
 | 
			
		||||
    // the dialog can be brought back by an open call, or the lightbox
 | 
			
		||||
@@ -220,6 +262,7 @@ ModalDialog.prototype = {
 | 
			
		||||
        if (this.state == State.FADED_OUT)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this.popModal(timestamp);
 | 
			
		||||
        Tweener.addTween(this._dialogLayout,
 | 
			
		||||
                         { opacity: 0,
 | 
			
		||||
                           time:    FADE_OUT_DIALOG_TIME,
 | 
			
		||||
@@ -227,7 +270,6 @@ ModalDialog.prototype = {
 | 
			
		||||
                           onComplete: Lang.bind(this,
 | 
			
		||||
                               function() {
 | 
			
		||||
                                   this.state = State.FADED_OUT;
 | 
			
		||||
                                   Main.popModal(this._group, timestamp);
 | 
			
		||||
                               })
 | 
			
		||||
                         });
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 | 
			
		||||
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
const DBus = imports.dbus;
 | 
			
		||||
const GLib = imports.gi.GLib;
 | 
			
		||||
const Lang = imports.lang;
 | 
			
		||||
@@ -345,7 +346,7 @@ NotificationDaemon.prototype = {
 | 
			
		||||
        notification.setTransient(hints['transient'] == true);
 | 
			
		||||
 | 
			
		||||
        let sourceIconActor = source.useNotificationIcon ? this._iconForNotificationData(icon, hints, source.ICON_SIZE) : null;
 | 
			
		||||
        source.notify(notification, sourceIconActor);
 | 
			
		||||
        source.processNotification(notification, sourceIconActor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    CloseNotification: function(id) {
 | 
			
		||||
@@ -389,8 +390,7 @@ NotificationDaemon.prototype = {
 | 
			
		||||
        for (let id in this._sources) {
 | 
			
		||||
            let source = this._sources[id];
 | 
			
		||||
            if (source.app == tracker.focus_app) {
 | 
			
		||||
                if (source.notification && !source.notification.resident)
 | 
			
		||||
                    source.notification.destroy();
 | 
			
		||||
                source.destroyNonResidentNotifications();
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -441,15 +441,51 @@ Source.prototype = {
 | 
			
		||||
            this.title = this.app.get_name();
 | 
			
		||||
        else
 | 
			
		||||
            this.useNotificationIcon = true;
 | 
			
		||||
        this._isTrayIcon = false;
 | 
			
		||||
        this._trayIcon = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    notify: function(notification, icon) {
 | 
			
		||||
    processNotification: function(notification, icon) {
 | 
			
		||||
        if (!this.app)
 | 
			
		||||
            this._setApp();
 | 
			
		||||
        if (!this.app && icon)
 | 
			
		||||
            this._setSummaryIcon(icon);
 | 
			
		||||
        MessageTray.Source.prototype.notify.call(this, notification);
 | 
			
		||||
 | 
			
		||||
        let tracker = Shell.WindowTracker.get_default();
 | 
			
		||||
        if (notification.resident && this.app && tracker.focus_app == this.app)
 | 
			
		||||
            this.pushNotification(notification);
 | 
			
		||||
        else
 | 
			
		||||
            this.notify(notification);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    handleSummaryClick: function() {
 | 
			
		||||
        if (!this._trayIcon)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        let event = Clutter.get_current_event();
 | 
			
		||||
        if (event.type() != Clutter.EventType.BUTTON_RELEASE)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        // Left clicks are passed through only where there aren't unacknowledged
 | 
			
		||||
        // notifications, so it possible to open them in summary mode; right
 | 
			
		||||
        // clicks are always forwarded, as the right click menu is not useful for
 | 
			
		||||
        // tray icons
 | 
			
		||||
        if (event.get_button() == 1 &&
 | 
			
		||||
            this.notifications.length > 0)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        if (Main.overview.visible) {
 | 
			
		||||
            // We can't just connect to Main.overview's 'hidden' signal,
 | 
			
		||||
            // because it's emitted *before* it calls popModal()...
 | 
			
		||||
            let id = global.connect('notify::stage-input-mode', Lang.bind(this,
 | 
			
		||||
                function () {
 | 
			
		||||
                    global.disconnect(id);
 | 
			
		||||
                    this._trayIcon.click(event);
 | 
			
		||||
                }));
 | 
			
		||||
            Main.overview.hide();
 | 
			
		||||
        } else {
 | 
			
		||||
            this._trayIcon.click(event);
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setApp: function() {
 | 
			
		||||
@@ -466,7 +502,7 @@ Source.prototype = {
 | 
			
		||||
 | 
			
		||||
        // Only override the icon if we were previously using
 | 
			
		||||
        // notification-based icons (ie, not a trayicon) or if it was unset before
 | 
			
		||||
        if (!this._isTrayIcon) {
 | 
			
		||||
        if (!this._trayIcon) {
 | 
			
		||||
            this.useNotificationIcon = false;
 | 
			
		||||
            this._setSummaryIcon(this.app.create_icon_texture (this.ICON_SIZE));
 | 
			
		||||
        }
 | 
			
		||||
@@ -475,25 +511,29 @@ Source.prototype = {
 | 
			
		||||
    setTrayIcon: function(icon) {
 | 
			
		||||
        this._setSummaryIcon(icon);
 | 
			
		||||
        this.useNotificationIcon = false;
 | 
			
		||||
        this._isTrayIcon = true;
 | 
			
		||||
        this._trayIcon = icon;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    open: function(notification) {
 | 
			
		||||
        this.destroyNonResidentNotifications();
 | 
			
		||||
        this.openApp();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _notificationRemoved: function() {
 | 
			
		||||
        if (!this._isTrayIcon)
 | 
			
		||||
    _lastNotificationRemoved: function() {
 | 
			
		||||
        if (!this._trayIcon)
 | 
			
		||||
            this.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _appStateChanged: function() {
 | 
			
		||||
        // Destroy notification sources when their apps exit.
 | 
			
		||||
        // The app exiting would normally result in a tray icon being removed,
 | 
			
		||||
        // so it should be ok to destroy the source associated with a tray icon
 | 
			
		||||
        // here too, however we just let that happen through the code path
 | 
			
		||||
        // associated with the tray icon being removed.
 | 
			
		||||
        if (!this._isTrayIcon && this.app.get_state() == Shell.AppState.STOPPED)
 | 
			
		||||
        // so the associated source would be destroyed through the code path
 | 
			
		||||
        // that handles the tray icon being removed. We should not destroy
 | 
			
		||||
        // the source associated with a tray icon when the application state
 | 
			
		||||
        // is Shell.AppState.STOPPED because running applications that have
 | 
			
		||||
        // no open windows would also have that state. This is often the case
 | 
			
		||||
        // for applications that use tray icons.
 | 
			
		||||
        if (!this._trayIcon && this.app.get_state() == Shell.AppState.STOPPED)
 | 
			
		||||
            this.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,6 @@ const Gdk = imports.gi.Gdk;
 | 
			
		||||
const AppDisplay = imports.ui.appDisplay;
 | 
			
		||||
const Dash = imports.ui.dash;
 | 
			
		||||
const DND = imports.ui.dnd;
 | 
			
		||||
const DocDisplay = imports.ui.docDisplay;
 | 
			
		||||
const Lightbox = imports.ui.lightbox;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const MessageTray = imports.ui.messageTray;
 | 
			
		||||
@@ -24,6 +23,8 @@ const PlaceDisplay = imports.ui.placeDisplay;
 | 
			
		||||
const Tweener = imports.ui.tweener;
 | 
			
		||||
const ViewSelector = imports.ui.viewSelector;
 | 
			
		||||
const WorkspacesView = imports.ui.workspacesView;
 | 
			
		||||
const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
 | 
			
		||||
const ZeitgeistSearch = imports.ui.zeitgeistSearch;
 | 
			
		||||
 | 
			
		||||
// Time for initial animation going into Overview mode
 | 
			
		||||
const ANIMATION_TIME = 0.25;
 | 
			
		||||
@@ -74,11 +75,13 @@ ShellInfo.prototype = {
 | 
			
		||||
            Main.messageTray.add(this._source);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let notification = this._source.notification;
 | 
			
		||||
        if (notification == null)
 | 
			
		||||
        let notification = null;
 | 
			
		||||
        if (this._source.notifications.length == 0) {
 | 
			
		||||
            notification = new MessageTray.Notification(this._source, text, null);
 | 
			
		||||
        else
 | 
			
		||||
        } else {
 | 
			
		||||
            notification = this._source.notifications[0];
 | 
			
		||||
            notification.update(text, null, { clear: true });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        notification.setTransient(true);
 | 
			
		||||
 | 
			
		||||
@@ -180,16 +183,20 @@ Overview.prototype = {
 | 
			
		||||
        this._group.add_actor(this.viewSelector.actor);
 | 
			
		||||
 | 
			
		||||
        this._workspacesDisplay = new WorkspacesView.WorkspacesDisplay();
 | 
			
		||||
        this.viewSelector.addViewTab(_("Windows"), this._workspacesDisplay.actor, 'text-x-generic');
 | 
			
		||||
        this.viewSelector.addViewTab('windows', _("Windows"), this._workspacesDisplay.actor, 'text-x-generic');
 | 
			
		||||
 | 
			
		||||
        let appView = new AppDisplay.AllAppDisplay();
 | 
			
		||||
        this.viewSelector.addViewTab(_("Applications"), appView.actor, 'system-run');
 | 
			
		||||
        this.viewSelector.addViewTab('applications', _("Applications"), appView.actor, 'system-run');
 | 
			
		||||
 | 
			
		||||
        // Default search providers
 | 
			
		||||
        this.viewSelector.addSearchProvider(new AppDisplay.AppSearchProvider());
 | 
			
		||||
        this.viewSelector.addSearchProvider(new AppDisplay.PrefsSearchProvider());
 | 
			
		||||
        this.viewSelector.addSearchProvider(new PlaceDisplay.PlaceSearchProvider());
 | 
			
		||||
        this.viewSelector.addSearchProvider(new DocDisplay.DocSearchProvider());
 | 
			
		||||
        this.viewSelector.addSearchProvider(new ZeitgeistSearch.DocumentsAsyncSearchProvider());
 | 
			
		||||
        this.viewSelector.addSearchProvider(new ZeitgeistSearch.VideosAsyncSearchProvider());
 | 
			
		||||
        this.viewSelector.addSearchProvider(new ZeitgeistSearch.MusicAsyncSearchProvider());
 | 
			
		||||
        this.viewSelector.addSearchProvider(new ZeitgeistSearch.PicturesAsyncSearchProvider());
 | 
			
		||||
        this.viewSelector.addSearchProvider(new ZeitgeistSearch.OtherAsyncSearchProvider());
 | 
			
		||||
 | 
			
		||||
        // TODO - recalculate everything when desktop size changes
 | 
			
		||||
        this.dash = new Dash.Dash();
 | 
			
		||||
@@ -220,6 +227,7 @@ Overview.prototype = {
 | 
			
		||||
        this._resetWindowSwitchTimeout();
 | 
			
		||||
        this._lastHoveredWindow = null;
 | 
			
		||||
        DND.removeMonitor(this._dragMonitor);
 | 
			
		||||
        this.endItemDrag();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _resetWindowSwitchTimeout: function() {
 | 
			
		||||
@@ -242,7 +250,8 @@ Overview.prototype = {
 | 
			
		||||
    _onDragMotion: function(dragEvent) {
 | 
			
		||||
        let targetIsWindow = dragEvent.targetActor &&
 | 
			
		||||
                             dragEvent.targetActor._delegate &&
 | 
			
		||||
                             dragEvent.targetActor._delegate.metaWindow;
 | 
			
		||||
                             dragEvent.targetActor._delegate.metaWindow &&
 | 
			
		||||
                             !(dragEvent.targetActor._delegate instanceof WorkspaceThumbnail.WindowClone);
 | 
			
		||||
 | 
			
		||||
        this._windowSwitchTimestamp = global.get_current_time();
 | 
			
		||||
 | 
			
		||||
@@ -438,7 +447,7 @@ Overview.prototype = {
 | 
			
		||||
        let primary = global.get_primary_monitor();
 | 
			
		||||
        let rtl = (St.Widget.get_default_direction () == St.TextDirection.RTL);
 | 
			
		||||
 | 
			
		||||
        let contentY = Panel.PANEL_HEIGHT;
 | 
			
		||||
        let contentY = Main.panel.actor.height;
 | 
			
		||||
        let contentHeight = primary.height - contentY - Main.messageTray.actor.height;
 | 
			
		||||
 | 
			
		||||
        this._group.set_position(primary.x, primary.y);
 | 
			
		||||
@@ -473,6 +482,10 @@ Overview.prototype = {
 | 
			
		||||
        this.emit('item-drag-begin');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    cancelledItemDrag: function(source) {
 | 
			
		||||
        this.emit('item-drag-cancelled');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    endItemDrag: function(source) {
 | 
			
		||||
        this.emit('item-drag-end');
 | 
			
		||||
    },
 | 
			
		||||
@@ -481,35 +494,14 @@ Overview.prototype = {
 | 
			
		||||
        this.emit('window-drag-begin');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    cancelledWindowDrag: function(source) {
 | 
			
		||||
        this.emit('window-drag-cancelled');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    endWindowDrag: function(source) {
 | 
			
		||||
        this.emit('window-drag-end');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Returns the scale the Overview has when we just start zooming out
 | 
			
		||||
    // to overview mode. That is, when just the active workspace is showing.
 | 
			
		||||
    getZoomedInScale : function() {
 | 
			
		||||
        return 1 / this.workspaces.getScale();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Returns the position the Overview has when we just start zooming out
 | 
			
		||||
    // to overview mode. That is, when just the active workspace is showing.
 | 
			
		||||
    getZoomedInPosition : function() {
 | 
			
		||||
        let [posX, posY] = this.workspaces.getActiveWorkspacePosition();
 | 
			
		||||
        let scale = this.getZoomedInScale();
 | 
			
		||||
 | 
			
		||||
        return [- posX * scale, - posY * scale];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Returns the current scale of the Overview.
 | 
			
		||||
    getScale : function() {
 | 
			
		||||
        return this.workspaces.actor.scaleX;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Returns the current position of the Overview.
 | 
			
		||||
    getPosition : function() {
 | 
			
		||||
        return [this.workspaces.actor.x, this.workspaces.actor.y];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // show:
 | 
			
		||||
    //
 | 
			
		||||
    // Animates the overview visible and grabs mouse and keyboard input
 | 
			
		||||
@@ -563,30 +555,13 @@ Overview.prototype = {
 | 
			
		||||
                             });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Create a zoom out effect. First scale the workspaces view up and
 | 
			
		||||
        // position it so that the active workspace fills up the whole screen,
 | 
			
		||||
        // then transform it to its normal dimensions and position.
 | 
			
		||||
        // The opposite transition is used in hide().
 | 
			
		||||
        this.workspaces.actor.scaleX = this.workspaces.actor.scaleY = this.getZoomedInScale();
 | 
			
		||||
        [this.workspaces.actor.x, this.workspaces.actor.y] = this.getZoomedInPosition();
 | 
			
		||||
        let primary = global.get_primary_monitor();
 | 
			
		||||
        Tweener.addTween(this.workspaces.actor,
 | 
			
		||||
                         { x: primary.x - this._group.x,
 | 
			
		||||
                           y: primary.y - this._group.y,
 | 
			
		||||
                           scaleX: 1,
 | 
			
		||||
                           scaleY: 1,
 | 
			
		||||
                           transition: 'easeOutQuad',
 | 
			
		||||
                           time: ANIMATION_TIME,
 | 
			
		||||
                           onComplete: this._showDone,
 | 
			
		||||
                           onCompleteScope: this
 | 
			
		||||
                          });
 | 
			
		||||
 | 
			
		||||
        // Make the other elements fade in.
 | 
			
		||||
        this._group.opacity = 0;
 | 
			
		||||
        Tweener.addTween(this._group,
 | 
			
		||||
                         { opacity: 255,
 | 
			
		||||
                           transition: 'easeOutQuad',
 | 
			
		||||
                           time: ANIMATION_TIME
 | 
			
		||||
                           time: ANIMATION_TIME,
 | 
			
		||||
                           onComplete: this._showDone,
 | 
			
		||||
                           onCompleteScope: this
 | 
			
		||||
                         });
 | 
			
		||||
 | 
			
		||||
        this._coverPane.raise_top();
 | 
			
		||||
@@ -698,27 +673,13 @@ Overview.prototype = {
 | 
			
		||||
 | 
			
		||||
        this.workspaces.hide();
 | 
			
		||||
 | 
			
		||||
        // Create a zoom in effect by transforming the workspaces view so that
 | 
			
		||||
        // the active workspace fills up the whole screen. The opposite
 | 
			
		||||
        // transition is used in show().
 | 
			
		||||
        let scale = this.getZoomedInScale();
 | 
			
		||||
        let [posX, posY] = this.getZoomedInPosition();
 | 
			
		||||
        Tweener.addTween(this.workspaces.actor,
 | 
			
		||||
                         { x: posX,
 | 
			
		||||
                           y: posY,
 | 
			
		||||
                           scaleX: scale,
 | 
			
		||||
                           scaleY: scale,
 | 
			
		||||
                           transition: 'easeOutQuad',
 | 
			
		||||
                           time: ANIMATION_TIME,
 | 
			
		||||
                           onComplete: this._hideDone,
 | 
			
		||||
                           onCompleteScope: this
 | 
			
		||||
                          });
 | 
			
		||||
 | 
			
		||||
        // Make other elements fade out.
 | 
			
		||||
        Tweener.addTween(this._group,
 | 
			
		||||
                         { opacity: 0,
 | 
			
		||||
                           transition: 'easeOutQuad',
 | 
			
		||||
                           time: ANIMATION_TIME
 | 
			
		||||
                           time: ANIMATION_TIME,
 | 
			
		||||
                           onComplete: this._hideDone,
 | 
			
		||||
                           onCompleteScope: this
 | 
			
		||||
                         });
 | 
			
		||||
 | 
			
		||||
        this._coverPane.raise_top();
 | 
			
		||||
@@ -737,6 +698,7 @@ Overview.prototype = {
 | 
			
		||||
            this._animateNotVisible();
 | 
			
		||||
 | 
			
		||||
        this._syncInputMode();
 | 
			
		||||
        global.sync_pointer();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _hideDone: function() {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										207
									
								
								js/ui/panel.js
									
									
									
									
									
								
							
							
						
						
									
										207
									
								
								js/ui/panel.js
									
									
									
									
									
								
							@@ -22,8 +22,6 @@ const DateMenu = imports.ui.dateMenu;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const Tweener = imports.ui.tweener;
 | 
			
		||||
 | 
			
		||||
const PANEL_HEIGHT = 26;
 | 
			
		||||
 | 
			
		||||
const PANEL_ICON_SIZE = 24;
 | 
			
		||||
 | 
			
		||||
const STARTUP_ANIMATION_TIME = 0.2;
 | 
			
		||||
@@ -33,8 +31,7 @@ const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5;
 | 
			
		||||
const BUTTON_DND_ACTIVATION_TIMEOUT = 250;
 | 
			
		||||
 | 
			
		||||
const ANIMATED_ICON_UPDATE_TIMEOUT = 100;
 | 
			
		||||
const SPINNER_UPDATE_TIMEOUT = 130;
 | 
			
		||||
const SPINNER_SPEED = 0.02;
 | 
			
		||||
const SPINNER_ANIMATION_TIME = 0.2;
 | 
			
		||||
 | 
			
		||||
const STANDARD_TRAY_ICON_ORDER = ['a11y', 'display', 'keyboard', 'volume', 'bluetooth', 'network', 'battery'];
 | 
			
		||||
const STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION = {
 | 
			
		||||
@@ -47,6 +44,12 @@ const STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION = {
 | 
			
		||||
if (Config.HAVE_BLUETOOTH)
 | 
			
		||||
    STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['bluetooth'] = imports.ui.status.bluetooth.Indicator;
 | 
			
		||||
 | 
			
		||||
try {
 | 
			
		||||
    STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['network'] = imports.ui.status.network.NMApplet;
 | 
			
		||||
} catch(e) {
 | 
			
		||||
    log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// To make sure the panel corners blend nicely with the panel,
 | 
			
		||||
// we draw background and borders the same way, e.g. drawing
 | 
			
		||||
// them as filled shapes from the outside inwards instead of
 | 
			
		||||
@@ -244,6 +247,10 @@ AppMenuButton.prototype = {
 | 
			
		||||
 | 
			
		||||
        let bin = new St.Bin({ name: 'appMenu' });
 | 
			
		||||
        this.actor.set_child(bin);
 | 
			
		||||
 | 
			
		||||
        this.actor.reactive = false;
 | 
			
		||||
        this._targetIsCurrent = false;
 | 
			
		||||
 | 
			
		||||
        this._container = new Shell.GenericContainer();
 | 
			
		||||
        bin.set_child(this._container);
 | 
			
		||||
        this._container.connect('get-preferred-width', Lang.bind(this, this._getContentPreferredWidth));
 | 
			
		||||
@@ -271,20 +278,13 @@ AppMenuButton.prototype = {
 | 
			
		||||
            this.hide();
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._updateId = 0;
 | 
			
		||||
        this._animationStep = 0;
 | 
			
		||||
        this._clipWidth = PANEL_ICON_SIZE;
 | 
			
		||||
        this._direction = SPINNER_SPEED;
 | 
			
		||||
        this._stop = true;
 | 
			
		||||
 | 
			
		||||
        this._spinner = new AnimatedIcon('process-working.svg',
 | 
			
		||||
                                         PANEL_ICON_SIZE);
 | 
			
		||||
        this._container.add_actor(this._spinner.actor);
 | 
			
		||||
        this._spinner.actor.lower_bottom();
 | 
			
		||||
 | 
			
		||||
        this._shadow = new St.Bin({ style_class: 'label-real-shadow' });
 | 
			
		||||
        this._shadow.hide();
 | 
			
		||||
        this._container.add_actor(this._shadow);
 | 
			
		||||
 | 
			
		||||
        let tracker = Shell.WindowTracker.get_default();
 | 
			
		||||
        tracker.connect('notify::focus-app', Lang.bind(this, this._sync));
 | 
			
		||||
        tracker.connect('app-state-changed', Lang.bind(this, this._onAppStateChanged));
 | 
			
		||||
@@ -300,6 +300,10 @@ AppMenuButton.prototype = {
 | 
			
		||||
 | 
			
		||||
        this._visible = true;
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
 | 
			
		||||
        if (!this._targetIsCurrent)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        Tweener.removeTweens(this.actor);
 | 
			
		||||
        Tweener.addTween(this.actor,
 | 
			
		||||
                         { opacity: 255,
 | 
			
		||||
@@ -312,6 +316,11 @@ AppMenuButton.prototype = {
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._visible = false;
 | 
			
		||||
        if (!this._targetIsCurrent) {
 | 
			
		||||
            this.actor.hide();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Tweener.removeTweens(this.actor);
 | 
			
		||||
        Tweener.addTween(this.actor,
 | 
			
		||||
                         { opacity: 0,
 | 
			
		||||
@@ -334,62 +343,26 @@ AppMenuButton.prototype = {
 | 
			
		||||
            this._iconBox.remove_clip();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _stopAnimation: function(animate) {
 | 
			
		||||
        this._label.actor.remove_clip();
 | 
			
		||||
        if (this._updateId) {
 | 
			
		||||
            this._shadow.hide();
 | 
			
		||||
            if (animate) {
 | 
			
		||||
                Tweener.addTween(this._spinner.actor,
 | 
			
		||||
                                 { opacity: 0,
 | 
			
		||||
                                   time: 0.2,
 | 
			
		||||
                                   transition: "easeOutQuad",
 | 
			
		||||
                                   onCompleteScope: this,
 | 
			
		||||
                                   onComplete: function() {
 | 
			
		||||
                                       this._spinner.actor.opacity = 255;
 | 
			
		||||
                                       this._spinner.actor.hide();
 | 
			
		||||
                                   }
 | 
			
		||||
                                 });
 | 
			
		||||
            }
 | 
			
		||||
            Mainloop.source_remove(this._updateId);
 | 
			
		||||
            this._updateId = 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (!animate)
 | 
			
		||||
            this._spinner.actor.hide();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    stopAnimation: function() {
 | 
			
		||||
        this._direction = SPINNER_SPEED * 3;
 | 
			
		||||
        this._stop = true;
 | 
			
		||||
    },
 | 
			
		||||
        if (this._stop)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
    _update: function() {
 | 
			
		||||
        this._animationStep += this._direction;
 | 
			
		||||
        if (this._animationStep > 1 && this._stop) {
 | 
			
		||||
            this._animationStep = 1;
 | 
			
		||||
            this._stopAnimation(true);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (this._animationStep > 1)
 | 
			
		||||
            this._animationStep = 1;
 | 
			
		||||
        this._clipWidth = this._label.actor.width - (this._label.actor.width - PANEL_ICON_SIZE) * (1 - this._animationStep);
 | 
			
		||||
        if (this.actor.get_direction() == St.TextDirection.LTR) {
 | 
			
		||||
            this._label.actor.set_clip(0, 0, this._clipWidth + this._shadow.width, this.actor.height);
 | 
			
		||||
        } else {
 | 
			
		||||
            this._label.actor.set_clip(this._label.actor.width - this._clipWidth, 0, this._clipWidth, this.actor.height);
 | 
			
		||||
        }
 | 
			
		||||
        this._container.queue_relayout();
 | 
			
		||||
        return true;
 | 
			
		||||
        this._stop = true;
 | 
			
		||||
        Tweener.addTween(this._spinner.actor,
 | 
			
		||||
                         { opacity: 0,
 | 
			
		||||
                           time: SPINNER_ANIMATION_TIME,
 | 
			
		||||
                           transition: "easeOutQuad",
 | 
			
		||||
                           onCompleteScope: this,
 | 
			
		||||
                           onComplete: function() {
 | 
			
		||||
                               this._spinner.actor.opacity = 255;
 | 
			
		||||
                               this._spinner.actor.hide();
 | 
			
		||||
                           }
 | 
			
		||||
                         });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    startAnimation: function() {
 | 
			
		||||
        this._direction = SPINNER_SPEED;
 | 
			
		||||
        this._stopAnimation(false);
 | 
			
		||||
        this._animationStep = 0;
 | 
			
		||||
        this._update();
 | 
			
		||||
        this._stop = false;
 | 
			
		||||
        this._updateId = Mainloop.timeout_add(SPINNER_UPDATE_TIMEOUT, Lang.bind(this, this._update));
 | 
			
		||||
        this._spinner.actor.show();
 | 
			
		||||
        this._shadow.show();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getContentPreferredWidth: function(actor, forHeight, alloc) {
 | 
			
		||||
@@ -451,18 +424,13 @@ AppMenuButton.prototype = {
 | 
			
		||||
        this._label.actor.allocate(childBox, flags);
 | 
			
		||||
 | 
			
		||||
        if (direction == St.TextDirection.LTR) {
 | 
			
		||||
            childBox.x1 = Math.floor(iconWidth / 2) + this._clipWidth + this._shadow.width;
 | 
			
		||||
            childBox.x1 = Math.floor(iconWidth / 2) + this._label.actor.width;
 | 
			
		||||
            childBox.x2 = childBox.x1 + this._spinner.actor.width;
 | 
			
		||||
            childBox.y1 = box.y1;
 | 
			
		||||
            childBox.y2 = box.y2 - 1;
 | 
			
		||||
            this._spinner.actor.allocate(childBox, flags);
 | 
			
		||||
            childBox.x1 = Math.floor(iconWidth / 2) + this._clipWidth + 2;
 | 
			
		||||
            childBox.x2 = childBox.x1 + this._shadow.width;
 | 
			
		||||
            childBox.y1 = box.y1;
 | 
			
		||||
            childBox.y2 = box.y2 - 1;
 | 
			
		||||
            this._shadow.allocate(childBox, flags);
 | 
			
		||||
        } else {
 | 
			
		||||
            childBox.x1 = this._label.actor.width - this._clipWidth - this._spinner.actor.width;
 | 
			
		||||
            childBox.x1 = -this._spinner.actor.width;
 | 
			
		||||
            childBox.x2 = childBox.x1 + this._spinner.actor.width;
 | 
			
		||||
            childBox.y1 = box.y1;
 | 
			
		||||
            childBox.y2 = box.y2 - 1;
 | 
			
		||||
@@ -501,13 +469,6 @@ AppMenuButton.prototype = {
 | 
			
		||||
                lastStartedApp = this._startingApps[i];
 | 
			
		||||
 | 
			
		||||
        let focusedApp = tracker.focus_app;
 | 
			
		||||
        let targetApp = focusedApp != null ? focusedApp : lastStartedApp;
 | 
			
		||||
        if (targetApp == this._targetApp) {
 | 
			
		||||
            if (targetApp && targetApp.get_state() != Shell.AppState.STARTING)
 | 
			
		||||
                this.stopAnimation();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        this._stopAnimation();
 | 
			
		||||
 | 
			
		||||
        if (!focusedApp) {
 | 
			
		||||
            // If the app has just lost focus to the panel, pretend
 | 
			
		||||
@@ -517,27 +478,56 @@ AppMenuButton.prototype = {
 | 
			
		||||
                return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let targetApp = focusedApp != null ? focusedApp : lastStartedApp;
 | 
			
		||||
 | 
			
		||||
        if (targetApp == null) {
 | 
			
		||||
            if (!this._targetIsCurrent)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            this.actor.reactive = false;
 | 
			
		||||
            this._targetIsCurrent = false;
 | 
			
		||||
 | 
			
		||||
            Tweener.removeTweens(this.actor);
 | 
			
		||||
            Tweener.addTween(this.actor, { opacity: 0,
 | 
			
		||||
                                           time: Overview.ANIMATION_TIME,
 | 
			
		||||
                                           transition: 'easeOutQuad' });
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!this._targetIsCurrent) {
 | 
			
		||||
            this.actor.reactive = true;
 | 
			
		||||
            this._targetIsCurrent = true;
 | 
			
		||||
 | 
			
		||||
            Tweener.removeTweens(this.actor);
 | 
			
		||||
            Tweener.addTween(this.actor, { opacity: 255,
 | 
			
		||||
                                           time: Overview.ANIMATION_TIME,
 | 
			
		||||
                                           transition: 'easeOutQuad' });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (targetApp == this._targetApp) {
 | 
			
		||||
            if (targetApp && targetApp.get_state() != Shell.AppState.STARTING)
 | 
			
		||||
                this.stopAnimation();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._spinner.actor.hide();
 | 
			
		||||
        if (this._iconBox.child != null)
 | 
			
		||||
            this._iconBox.child.destroy();
 | 
			
		||||
        this._iconBox.hide();
 | 
			
		||||
        this._label.setText('');
 | 
			
		||||
        this.actor.reactive = false;
 | 
			
		||||
 | 
			
		||||
        this._targetApp = targetApp;
 | 
			
		||||
        if (targetApp != null) {
 | 
			
		||||
            let icon = targetApp.get_faded_icon(2 * PANEL_ICON_SIZE);
 | 
			
		||||
        let icon = targetApp.get_faded_icon(2 * PANEL_ICON_SIZE);
 | 
			
		||||
 | 
			
		||||
            this._label.setText(targetApp.get_name());
 | 
			
		||||
            // TODO - _quit() doesn't really work on apps in state STARTING yet
 | 
			
		||||
            this._quitMenu.label.set_text(_("Quit %s").format(targetApp.get_name()));
 | 
			
		||||
        this._label.setText(targetApp.get_name());
 | 
			
		||||
        // TODO - _quit() doesn't really work on apps in state STARTING yet
 | 
			
		||||
        this._quitMenu.label.set_text(_("Quit %s").format(targetApp.get_name()));
 | 
			
		||||
 | 
			
		||||
            this.actor.reactive = true;
 | 
			
		||||
            this._iconBox.set_child(icon);
 | 
			
		||||
            this._iconBox.show();
 | 
			
		||||
        this._iconBox.set_child(icon);
 | 
			
		||||
        this._iconBox.show();
 | 
			
		||||
 | 
			
		||||
            if (targetApp.get_state() == Shell.AppState.STARTING)
 | 
			
		||||
                this.startAnimation();
 | 
			
		||||
        }
 | 
			
		||||
        if (targetApp.get_state() == Shell.AppState.STARTING)
 | 
			
		||||
            this.startAnimation();
 | 
			
		||||
 | 
			
		||||
        this.emit('changed');
 | 
			
		||||
    }
 | 
			
		||||
@@ -641,12 +631,17 @@ PanelCorner.prototype = {
 | 
			
		||||
 * This class manages the "hot corner" that can toggle switching to
 | 
			
		||||
 * overview.
 | 
			
		||||
 */
 | 
			
		||||
function HotCorner() {
 | 
			
		||||
    this._init();
 | 
			
		||||
function HotCorner(button) {
 | 
			
		||||
    this._init(button);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HotCorner.prototype = {
 | 
			
		||||
    _init : function() {
 | 
			
		||||
    _init : function(button) {
 | 
			
		||||
        // This is the activities button associated with this hot corner,
 | 
			
		||||
        // if this is on the primary monitor (or null with the corner is
 | 
			
		||||
        // on a different monitor)
 | 
			
		||||
        this._button = button;
 | 
			
		||||
 | 
			
		||||
        // We use this flag to mark the case where the user has entered the
 | 
			
		||||
        // hot corner and has not left both the hot corner and a surrounding
 | 
			
		||||
        // guard area (the "environs"). This avoids triggering the hot corner
 | 
			
		||||
@@ -673,6 +668,8 @@ HotCorner.prototype = {
 | 
			
		||||
 | 
			
		||||
        this._activationTime = 0;
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('enter-event',
 | 
			
		||||
                           Lang.bind(this, this._onEnvironsEntered));
 | 
			
		||||
        this.actor.connect('leave-event',
 | 
			
		||||
                           Lang.bind(this, this._onEnvironsLeft));
 | 
			
		||||
        // Clicking on the hot corner environs should result in the same bahavior
 | 
			
		||||
@@ -725,6 +722,8 @@ HotCorner.prototype = {
 | 
			
		||||
                                        x: x,
 | 
			
		||||
                                        y: y });
 | 
			
		||||
        ripple._opacity =  startOpacity;
 | 
			
		||||
        if (ripple.get_direction() == St.TextDirection.RTL)
 | 
			
		||||
            ripple.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
 | 
			
		||||
        Tweener.addTween(ripple, { _opacity: finalOpacity,
 | 
			
		||||
                                   scale_x: finalScale,
 | 
			
		||||
                                   scale_y: finalScale,
 | 
			
		||||
@@ -747,6 +746,11 @@ HotCorner.prototype = {
 | 
			
		||||
        this._addRipple(0.35,  1.0,   0.0,   0.3,    1,    0.0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onEnvironsEntered : function() {
 | 
			
		||||
        if (this._button)
 | 
			
		||||
            this._button.hover = true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onCornerEntered : function() {
 | 
			
		||||
        if (!this._entered) {
 | 
			
		||||
            this._entered = true;
 | 
			
		||||
@@ -774,6 +778,9 @@ HotCorner.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onEnvironsLeft : function(actor, event) {
 | 
			
		||||
        if (this._button)
 | 
			
		||||
            this._button.hover = false;
 | 
			
		||||
 | 
			
		||||
        if (event.get_related() != this._corner)
 | 
			
		||||
            this._entered = false;
 | 
			
		||||
        return false;
 | 
			
		||||
@@ -808,6 +815,8 @@ Panel.prototype = {
 | 
			
		||||
            this.actor.remove_style_class_name('in-overview');
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._leftPointerBarrier = 0;
 | 
			
		||||
        this._rightPointerBarrier = 0;
 | 
			
		||||
        this._menus = new PopupMenu.PopupMenuManager(this);
 | 
			
		||||
 | 
			
		||||
        this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
 | 
			
		||||
@@ -991,7 +1000,7 @@ Panel.prototype = {
 | 
			
		||||
                                                  affectsStruts: false,
 | 
			
		||||
                                                  affectsInputRegion: false });
 | 
			
		||||
 | 
			
		||||
        Main.ctrlAltTabManager.addGroup(this.actor, _("Panel"), 'start-here',
 | 
			
		||||
        Main.ctrlAltTabManager.addGroup(this.actor, _("Top Bar"), 'start-here',
 | 
			
		||||
                                        { sortGroup: CtrlAltTab.SortGroup.TOP });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -1068,7 +1077,21 @@ Panel.prototype = {
 | 
			
		||||
        let primary = global.get_primary_monitor();
 | 
			
		||||
 | 
			
		||||
        this.actor.set_position(primary.x, primary.y);
 | 
			
		||||
        this.actor.set_size(primary.width, PANEL_HEIGHT);
 | 
			
		||||
        this.actor.set_size(primary.width, -1);
 | 
			
		||||
 | 
			
		||||
        if (this._leftPointerBarrier)
 | 
			
		||||
            global.destroy_pointer_barrier(this._leftPointerBarrier);
 | 
			
		||||
        if (this._rightPointerBarrier)
 | 
			
		||||
            global.destroy_pointer_barrier(this._rightPointerBarrier);
 | 
			
		||||
 | 
			
		||||
        this._leftPointerBarrier =
 | 
			
		||||
            global.create_pointer_barrier(primary.x, primary.y,
 | 
			
		||||
                                          primary.x, primary.y + this.actor.height,
 | 
			
		||||
                                          1 /* BarrierPositiveX */);
 | 
			
		||||
        this._rightPointerBarrier =
 | 
			
		||||
            global.create_pointer_barrier(primary.x + primary.width, primary.y,
 | 
			
		||||
                                          primary.x + primary.width, primary.y + this.actor.height,
 | 
			
		||||
                                          4 /* BarrierNegativeX */);
 | 
			
		||||
 | 
			
		||||
        this._leftCorner.relayout();
 | 
			
		||||
        this._rightCorner.relayout();
 | 
			
		||||
 
 | 
			
		||||
@@ -176,37 +176,8 @@ PlacesManager.prototype = {
 | 
			
		||||
                Util.spawn(['nautilus-connect-server']);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        let networkApp = null;
 | 
			
		||||
        try {
 | 
			
		||||
            networkApp = Shell.AppSystem.get_default().load_from_desktop_file('gnome-network-scheme.desktop');
 | 
			
		||||
        } catch(e) {
 | 
			
		||||
            try {
 | 
			
		||||
                networkApp = Shell.AppSystem.get_default().load_from_desktop_file('network-scheme.desktop');
 | 
			
		||||
            } catch(e) {
 | 
			
		||||
                log('Cannot create "Network" item, .desktop file not found or corrupt.');
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (networkApp != null) {
 | 
			
		||||
            this._network = new PlaceInfo('special:network', networkApp.get_name(),
 | 
			
		||||
                function(size) {
 | 
			
		||||
                    return networkApp.create_icon_texture(size);
 | 
			
		||||
                },
 | 
			
		||||
                function (params) {
 | 
			
		||||
                    params = Params.parse(params, { workspace: null,
 | 
			
		||||
                                                    timestamp: 0 });
 | 
			
		||||
 | 
			
		||||
                    networkApp.launch_full(params.timestamp, [],
 | 
			
		||||
                                           params.workspace ? params.workspace.index() : -1);
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._defaultPlaces.push(this._home);
 | 
			
		||||
        this._defaultPlaces.push(this._desktopMenu);
 | 
			
		||||
 | 
			
		||||
        if (this._network)
 | 
			
		||||
            this._defaultPlaces.push(this._network);
 | 
			
		||||
 | 
			
		||||
        this._defaultPlaces.push(this._connect);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,8 @@ AuthenticationDialog.prototype = {
 | 
			
		||||
        this.actionId = actionId;
 | 
			
		||||
        this.message = message;
 | 
			
		||||
        this.userNames = userNames;
 | 
			
		||||
        this._wasDismissed = false;
 | 
			
		||||
        this._completed = false;
 | 
			
		||||
 | 
			
		||||
        let mainContentBox = new St.BoxLayout({ style_class: 'polkit-dialog-main-layout',
 | 
			
		||||
                                                vertical: false });
 | 
			
		||||
@@ -69,7 +71,7 @@ AuthenticationDialog.prototype = {
 | 
			
		||||
                           { y_align: St.Align.START });
 | 
			
		||||
 | 
			
		||||
        this._subjectLabel = new St.Label({ style_class: 'polkit-dialog-headline',
 | 
			
		||||
                                            text: _('Authentication Required') });
 | 
			
		||||
                                            text: _("Authentication Required") });
 | 
			
		||||
 | 
			
		||||
        messageBox.add(this._subjectLabel,
 | 
			
		||||
                       { y_fill:  false,
 | 
			
		||||
@@ -100,32 +102,35 @@ AuthenticationDialog.prototype = {
 | 
			
		||||
                                                 Lang.bind(this, this._onUserChanged));
 | 
			
		||||
 | 
			
		||||
        // Special case 'root'
 | 
			
		||||
        if (userName == 'root')
 | 
			
		||||
            userRealName = _('Administrator');
 | 
			
		||||
        let userIsRoot = false;
 | 
			
		||||
        if (userName == 'root') {
 | 
			
		||||
            userIsRoot = true;
 | 
			
		||||
            userRealName = _("Administrator");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Work around Gdm.UserManager returning an empty string for the real name
 | 
			
		||||
        if (userRealName.length == 0)
 | 
			
		||||
            userRealName = userName;
 | 
			
		||||
 | 
			
		||||
        let userBox = new St.BoxLayout({ style_class: 'polkit-dialog-user-layout',
 | 
			
		||||
                                         vertical: false });
 | 
			
		||||
        messageBox.add(userBox);
 | 
			
		||||
 | 
			
		||||
        this._userIcon = new St.Icon();
 | 
			
		||||
        this._userIcon.hide();
 | 
			
		||||
        userBox.add(this._userIcon,
 | 
			
		||||
                    { x_fill:  true,
 | 
			
		||||
                      y_fill:  false,
 | 
			
		||||
                      x_align: St.Align.END,
 | 
			
		||||
                      y_align: St.Align.START });
 | 
			
		||||
 | 
			
		||||
        let userLabel = new St.Label(({ style_class: 'polkit-dialog-user-label',
 | 
			
		||||
                                        text: userRealName }));
 | 
			
		||||
        userBox.add(userLabel,
 | 
			
		||||
                    { x_fill:  true,
 | 
			
		||||
                      y_fill:  false,
 | 
			
		||||
                      x_align: St.Align.END,
 | 
			
		||||
                      y_align: St.Align.MIDDLE });
 | 
			
		||||
        if (userIsRoot) {
 | 
			
		||||
            let userLabel = new St.Label(({ style_class: 'polkit-dialog-user-root-label',
 | 
			
		||||
                                            text: userRealName }));
 | 
			
		||||
            messageBox.add(userLabel);
 | 
			
		||||
        } else {
 | 
			
		||||
            let userBox = new St.BoxLayout({ style_class: 'polkit-dialog-user-layout',
 | 
			
		||||
                                             vertical: false });
 | 
			
		||||
            messageBox.add(userBox);
 | 
			
		||||
            this._userIcon = new St.Icon();
 | 
			
		||||
            this._userIcon.hide();
 | 
			
		||||
            userBox.add(this._userIcon,
 | 
			
		||||
                        { x_fill:  true,
 | 
			
		||||
                          y_fill:  false,
 | 
			
		||||
                          x_align: St.Align.END,
 | 
			
		||||
                          y_align: St.Align.START });
 | 
			
		||||
            let userLabel = new St.Label(({ style_class: 'polkit-dialog-user-label',
 | 
			
		||||
                                            text: userRealName }));
 | 
			
		||||
            userBox.add(userLabel,
 | 
			
		||||
                        { x_fill:  true,
 | 
			
		||||
                          y_fill:  false,
 | 
			
		||||
                          x_align: St.Align.END,
 | 
			
		||||
                          y_align: St.Align.MIDDLE });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._onUserChanged();
 | 
			
		||||
 | 
			
		||||
@@ -134,45 +139,41 @@ AuthenticationDialog.prototype = {
 | 
			
		||||
        this._passwordLabel = new St.Label(({ style_class: 'polkit-dialog-password-label' }));
 | 
			
		||||
        this._passwordBox.add(this._passwordLabel);
 | 
			
		||||
        this._passwordEntry = new St.Entry({ style_class: 'polkit-dialog-password-entry',
 | 
			
		||||
                                             text: _(''),
 | 
			
		||||
                                             text: "",
 | 
			
		||||
                                             can_focus: true});
 | 
			
		||||
        this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivate));
 | 
			
		||||
        this._passwordBox.add(this._passwordEntry,
 | 
			
		||||
                              {expand: true });
 | 
			
		||||
        this._passwordBox.hide();
 | 
			
		||||
 | 
			
		||||
        this._errorBox = new St.BoxLayout({ style_class: 'polkit-dialog-error-box' });
 | 
			
		||||
        messageBox.add(this._errorBox);
 | 
			
		||||
        let errorIcon = new St.Icon({ icon_name: 'dialog-error',
 | 
			
		||||
                                      icon_size: 24,
 | 
			
		||||
                                      style_class: 'polkit-dialog-error-icon' });
 | 
			
		||||
        this._errorBox.add(errorIcon, { y_align: St.Align.MIDDLE });
 | 
			
		||||
        this._errorMessage = new St.Label({ style_class: 'polkit-dialog-error-label' });
 | 
			
		||||
        this._errorMessage.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
 | 
			
		||||
        this._errorMessage.clutter_text.line_wrap = true;
 | 
			
		||||
        this._errorBox.add(this._errorMessage, { expand: true,
 | 
			
		||||
                                                 y_align: St.Align.MIDDLE,
 | 
			
		||||
                                                 y_fill: true });
 | 
			
		||||
        this._errorBox.hide();
 | 
			
		||||
        this._errorMessageLabel = new St.Label({ style_class: 'polkit-dialog-error-label' });
 | 
			
		||||
        this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
 | 
			
		||||
        this._errorMessageLabel.clutter_text.line_wrap = true;
 | 
			
		||||
        messageBox.add(this._errorMessageLabel);
 | 
			
		||||
        this._errorMessageLabel.hide();
 | 
			
		||||
 | 
			
		||||
        this._infoBox = new St.BoxLayout({ style_class: 'polkit-dialog-info-box' });
 | 
			
		||||
        messageBox.add(this._infoBox);
 | 
			
		||||
        let infoIcon = new St.Icon({ icon_name: 'dialog-information',
 | 
			
		||||
                                     icon_size: 24,
 | 
			
		||||
                                     style_class: 'polkit-dialog-info-icon' });
 | 
			
		||||
        this._infoBox.add(infoIcon, { y_align: St.Align.MIDDLE });
 | 
			
		||||
        this._infoMessage = new St.Label({ style_class: 'polkit-dialog-info-label'});
 | 
			
		||||
        this._infoMessage.clutter_text.line_wrap = true;
 | 
			
		||||
        this._infoBox.add(this._infoMessage, { expand: true,
 | 
			
		||||
                                               y_align: St.Align.MIDDLE,
 | 
			
		||||
                                               y_fill: true });
 | 
			
		||||
        this._infoBox.hide();
 | 
			
		||||
        this._infoMessageLabel = new St.Label({ style_class: 'polkit-dialog-info-label' });
 | 
			
		||||
        this._infoMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
 | 
			
		||||
        this._infoMessageLabel.clutter_text.line_wrap = true;
 | 
			
		||||
        messageBox.add(this._infoMessageLabel);
 | 
			
		||||
        this._infoMessageLabel.hide();
 | 
			
		||||
 | 
			
		||||
        this.setButtons([{ label: _('Cancel'),
 | 
			
		||||
        /* text is intentionally non-blank otherwise the height is not the same as for
 | 
			
		||||
         * infoMessage and errorMessageLabel - but it is still invisible because
 | 
			
		||||
         * gnome-shell.css sets the color to be transparent
 | 
			
		||||
         */
 | 
			
		||||
        this._nullMessageLabel = new St.Label({ style_class: 'polkit-dialog-null-label',
 | 
			
		||||
                                                text: 'abc'});
 | 
			
		||||
        this._nullMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
 | 
			
		||||
        this._nullMessageLabel.clutter_text.line_wrap = true;
 | 
			
		||||
        messageBox.add(this._nullMessageLabel);
 | 
			
		||||
        this._nullMessageLabel.show();
 | 
			
		||||
 | 
			
		||||
        this.setButtons([{ label: _("Cancel"),
 | 
			
		||||
                           action: Lang.bind(this, this.cancel),
 | 
			
		||||
                           key:    Clutter.Escape
 | 
			
		||||
                         },
 | 
			
		||||
                         { label:  _('Authenticate'),
 | 
			
		||||
                         { label:  _("Authenticate"),
 | 
			
		||||
                           action: Lang.bind(this, this._onAuthenticateButtonPressed)
 | 
			
		||||
                         }]);
 | 
			
		||||
 | 
			
		||||
@@ -234,8 +235,9 @@ AuthenticationDialog.prototype = {
 | 
			
		||||
        this._session.response(response);
 | 
			
		||||
        // When the user responds, dismiss already shown info and
 | 
			
		||||
        // error texts (if any)
 | 
			
		||||
        this._errorBox.hide();
 | 
			
		||||
        this._infoBox.hide();
 | 
			
		||||
        this._errorMessageLabel.hide();
 | 
			
		||||
        this._infoMessageLabel.hide();
 | 
			
		||||
        this._nullMessageLabel.show();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onAuthenticateButtonPressed: function() {
 | 
			
		||||
@@ -243,14 +245,35 @@ AuthenticationDialog.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSessionCompleted: function(session, gainedAuthorization) {
 | 
			
		||||
        this._passwordBox.hide();
 | 
			
		||||
        if (this._completed)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._completed = true;
 | 
			
		||||
 | 
			
		||||
        if (!gainedAuthorization) {
 | 
			
		||||
            /* Unless we are showing an existing error message from the PAM
 | 
			
		||||
             * module (the PAM module could be reporting the authentication
 | 
			
		||||
             * error providing authentication-method specific information),
 | 
			
		||||
             * show "Sorry, that didn't work. Please try again."
 | 
			
		||||
             */
 | 
			
		||||
            if (!this._errorMessageLabel.visible && !this._wasDismissed) {
 | 
			
		||||
                /* Translators: "that didn't work" refers to the fact that the
 | 
			
		||||
                 * requested authentication was not gained; this can happen
 | 
			
		||||
                 * because of an authentication error (like invalid password),
 | 
			
		||||
                 * for instance. */
 | 
			
		||||
                this._errorMessageLabel.set_text(_("Sorry, that didn\'t work. Please try again."));
 | 
			
		||||
                this._errorMessageLabel.show();
 | 
			
		||||
                this._infoMessageLabel.hide();
 | 
			
		||||
                this._nullMessageLabel.hide();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        this._emitDone(!gainedAuthorization, false);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSessionRequest: function(session, request, echo_on) {
 | 
			
		||||
        // Cheap localization trick
 | 
			
		||||
        if (request == 'Password:')
 | 
			
		||||
            this._passwordLabel.set_text(_('Password:'));
 | 
			
		||||
            this._passwordLabel.set_text(_("Password:"));
 | 
			
		||||
        else
 | 
			
		||||
            this._passwordLabel.set_text(request);
 | 
			
		||||
 | 
			
		||||
@@ -267,41 +290,49 @@ AuthenticationDialog.prototype = {
 | 
			
		||||
 | 
			
		||||
    _onSessionShowError: function(session, text) {
 | 
			
		||||
        this._passwordEntry.set_text('');
 | 
			
		||||
        this._errorMessage.set_text(text);
 | 
			
		||||
        this._errorBox.show();
 | 
			
		||||
        this._errorMessageLabel.set_text(text);
 | 
			
		||||
        this._errorMessageLabel.show();
 | 
			
		||||
        this._infoMessageLabel.hide();
 | 
			
		||||
        this._nullMessageLabel.hide();
 | 
			
		||||
        this._ensureOpen();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSessionShowInfo: function(session, text) {
 | 
			
		||||
        this._passwordEntry.set_text('');
 | 
			
		||||
        this._infoMessage.set_text(text);
 | 
			
		||||
        this._infoBox.show();
 | 
			
		||||
        this._infoMessageLabel.set_text(text);
 | 
			
		||||
        this._infoMessageLabel.show();
 | 
			
		||||
        this._errorMessageLabel.hide();
 | 
			
		||||
        this._nullMessageLabel.hide();
 | 
			
		||||
        this._ensureOpen();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroySession: function() {
 | 
			
		||||
        if (this._session) {
 | 
			
		||||
            this._session.cancel();
 | 
			
		||||
            if (!this._completed)
 | 
			
		||||
                this._session.cancel();
 | 
			
		||||
            this._session = null;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onUserChanged: function() {
 | 
			
		||||
        if (this._user.is_loaded) {
 | 
			
		||||
            let iconFileName = this._user.get_icon_file();
 | 
			
		||||
            let iconFile = Gio.file_new_for_path(iconFileName);
 | 
			
		||||
            let icon;
 | 
			
		||||
            if (iconFile.query_exists(null)) {
 | 
			
		||||
                icon = new Gio.FileIcon({file: iconFile});
 | 
			
		||||
            } else {
 | 
			
		||||
                icon = new Gio.ThemedIcon({name: 'avatar-default'});
 | 
			
		||||
            if (this._userIcon) {
 | 
			
		||||
                let iconFileName = this._user.get_icon_file();
 | 
			
		||||
                let iconFile = Gio.file_new_for_path(iconFileName);
 | 
			
		||||
                let icon;
 | 
			
		||||
                if (iconFile.query_exists(null)) {
 | 
			
		||||
                    icon = new Gio.FileIcon({file: iconFile});
 | 
			
		||||
                } else {
 | 
			
		||||
                    icon = new Gio.ThemedIcon({name: 'avatar-default'});
 | 
			
		||||
                }
 | 
			
		||||
                this._userIcon.set_gicon (icon);
 | 
			
		||||
                this._userIcon.show();
 | 
			
		||||
            }
 | 
			
		||||
            this._userIcon.set_gicon (icon);
 | 
			
		||||
            this._userIcon.show();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    cancel: function() {
 | 
			
		||||
        this._wasDismissed = true;
 | 
			
		||||
        this.close(global.get_current_time());
 | 
			
		||||
        this._emitDone(false, true);
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -61,7 +61,7 @@ PopupBaseMenuItem.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onStyleChanged: function (actor) {
 | 
			
		||||
        this._spacing = actor.get_theme_node().get_length('spacing');
 | 
			
		||||
        this._spacing = Math.round(actor.get_theme_node().get_length('spacing'));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onButtonReleaseEvent: function (actor, event) {
 | 
			
		||||
@@ -173,6 +173,8 @@ PopupBaseMenuItem.prototype = {
 | 
			
		||||
        cr.fill();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // This returns column widths in logical order (i.e. from the dot
 | 
			
		||||
    // to the image), not in visual order (left to right)
 | 
			
		||||
    getColumnWidths: function() {
 | 
			
		||||
        let widths = [];
 | 
			
		||||
        for (let i = 0, col = 0; i < this._children.length; i++) {
 | 
			
		||||
@@ -224,19 +226,36 @@ PopupBaseMenuItem.prototype = {
 | 
			
		||||
 | 
			
		||||
    _allocate: function(actor, box, flags) {
 | 
			
		||||
        let height = box.y2 - box.y1;
 | 
			
		||||
        let direction = this.actor.get_direction();
 | 
			
		||||
 | 
			
		||||
        if (this._dot) {
 | 
			
		||||
            // The dot is placed outside box
 | 
			
		||||
            // one quarter of padding from the border of the container
 | 
			
		||||
            // (so 3/4 from the inner border)
 | 
			
		||||
            // (padding is box.x1)
 | 
			
		||||
            let dotBox = new Clutter.ActorBox();
 | 
			
		||||
            let dotWidth = Math.round(box.x1 / 2);
 | 
			
		||||
 | 
			
		||||
            dotBox.x1 = Math.round(box.x1 / 4);
 | 
			
		||||
            dotBox.x2 = dotBox.x1 + dotWidth;
 | 
			
		||||
            if (direction == St.TextDirection.LTR) {
 | 
			
		||||
                dotBox.x1 = Math.round(box.x1 / 4);
 | 
			
		||||
                dotBox.x2 = dotBox.x1 + dotWidth;
 | 
			
		||||
            } else {
 | 
			
		||||
                dotBox.x2 = box.x2 + 3 * Math.round(box.x1 / 4);
 | 
			
		||||
                dotBox.x1 = dotBox.x2 - dotWidth;
 | 
			
		||||
            }
 | 
			
		||||
            dotBox.y1 = Math.round(box.y1 + (height - dotWidth) / 2);
 | 
			
		||||
            dotBox.y2 = dotBox.y1 + dotWidth;
 | 
			
		||||
            this._dot.allocate(dotBox, flags);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let x = box.x1;
 | 
			
		||||
        let x;
 | 
			
		||||
        if (direction == St.TextDirection.LTR)
 | 
			
		||||
            x = box.x1;
 | 
			
		||||
        else
 | 
			
		||||
            x = box.x2;
 | 
			
		||||
        // if direction is ltr, x is the right edge of the last added
 | 
			
		||||
        // actor, and it's constantly increasing, whereas if rtl, x is
 | 
			
		||||
        // the left edge and it decreases
 | 
			
		||||
        for (let i = 0, col = 0; i < this._children.length; i++) {
 | 
			
		||||
            let child = this._children[i];
 | 
			
		||||
            let childBox = new Clutter.ActorBox();
 | 
			
		||||
@@ -244,9 +263,12 @@ PopupBaseMenuItem.prototype = {
 | 
			
		||||
            let [minWidth, naturalWidth] = child.actor.get_preferred_width(-1);
 | 
			
		||||
            let availWidth, extraWidth;
 | 
			
		||||
            if (this._columnWidths) {
 | 
			
		||||
                if (child.span == -1)
 | 
			
		||||
                    availWidth = box.x2 - x;
 | 
			
		||||
                else {
 | 
			
		||||
                if (child.span == -1) {
 | 
			
		||||
                    if (direction == St.TextDirection.LTR)
 | 
			
		||||
                        availWidth = box.x2 - x;
 | 
			
		||||
                    else
 | 
			
		||||
                        availWidth = x - box.x1;
 | 
			
		||||
                } else {
 | 
			
		||||
                    availWidth = 0;
 | 
			
		||||
                    for (let j = 0; j < child.span; j++)
 | 
			
		||||
                        availWidth += this._columnWidths[col++];
 | 
			
		||||
@@ -257,18 +279,36 @@ PopupBaseMenuItem.prototype = {
 | 
			
		||||
                extraWidth = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (child.expand) {
 | 
			
		||||
                childBox.x1 = x;
 | 
			
		||||
                childBox.x2 = x + availWidth;
 | 
			
		||||
            } else if (child.align === St.Align.CENTER) {
 | 
			
		||||
                childBox.x1 = x + Math.round(extraWidth / 2);
 | 
			
		||||
                childBox.x2 = childBox.x1 + naturalWidth;
 | 
			
		||||
            } else if (child.align === St.Align.END) {
 | 
			
		||||
                childBox.x2 = x + availWidth;
 | 
			
		||||
                childBox.x1 = childBox.x2 - naturalWidth;
 | 
			
		||||
            if (direction == St.TextDirection.LTR) {
 | 
			
		||||
                if (child.expand) {
 | 
			
		||||
                    childBox.x1 = x;
 | 
			
		||||
                    childBox.x2 = x + availWidth;
 | 
			
		||||
                } else if (child.align === St.Align.CENTER) {
 | 
			
		||||
                    childBox.x1 = x + Math.round(extraWidth / 2);
 | 
			
		||||
                    childBox.x2 = childBox.x1 + naturalWidth;
 | 
			
		||||
                } else if (child.align === St.Align.END) {
 | 
			
		||||
                    childBox.x2 = x + availWidth;
 | 
			
		||||
                    childBox.x1 = childBox.x2 - naturalWidth;
 | 
			
		||||
                } else {
 | 
			
		||||
                    childBox.x1 = x;
 | 
			
		||||
                    childBox.x2 = x + naturalWidth;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                childBox.x1 = x;
 | 
			
		||||
                childBox.x2 = x + naturalWidth;
 | 
			
		||||
                if (child.expand) {
 | 
			
		||||
                    childBox.x1 = x - availWidth;
 | 
			
		||||
                    childBox.x2 = x;
 | 
			
		||||
                } else if (child.align === St.Align.CENTER) {
 | 
			
		||||
                    childBox.x1 = x - Math.round(extraWidth / 2);
 | 
			
		||||
                    childBox.x2 = childBox.x1 + naturalWidth;
 | 
			
		||||
                } else if (child.align === St.Align.END) {
 | 
			
		||||
                    // align to the left
 | 
			
		||||
                    childBox.x1 = x - availWidth;
 | 
			
		||||
                    childBox.x2 = childBox.x1 + naturalWidth;
 | 
			
		||||
                } else {
 | 
			
		||||
                    // align to the right
 | 
			
		||||
                    childBox.x2 = x;
 | 
			
		||||
                    childBox.x1 = x - naturalWidth;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let [minHeight, naturalHeight] = child.actor.get_preferred_height(-1);
 | 
			
		||||
@@ -277,7 +317,10 @@ PopupBaseMenuItem.prototype = {
 | 
			
		||||
 | 
			
		||||
            child.actor.allocate(childBox, flags);
 | 
			
		||||
 | 
			
		||||
            x += availWidth + this._spacing;
 | 
			
		||||
            if (direction == St.TextDirection.LTR)
 | 
			
		||||
                x += availWidth + this._spacing;
 | 
			
		||||
            else
 | 
			
		||||
                x -= availWidth + this._spacing;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
@@ -485,12 +528,30 @@ PopupSliderMenuItem.prototype = {
 | 
			
		||||
        let sliderBorderColor = themeNode.get_color('-slider-border-color');
 | 
			
		||||
        let sliderColor = themeNode.get_color('-slider-background-color');
 | 
			
		||||
 | 
			
		||||
        let sliderActiveBorderColor = themeNode.get_color('-slider-active-border-color');
 | 
			
		||||
        let sliderActiveColor = themeNode.get_color('-slider-active-background-color');
 | 
			
		||||
 | 
			
		||||
        cr.setSourceRGBA (
 | 
			
		||||
            sliderActiveColor.red / 255,
 | 
			
		||||
            sliderActiveColor.green / 255,
 | 
			
		||||
            sliderActiveColor.blue / 255,
 | 
			
		||||
            sliderActiveColor.alpha / 255);
 | 
			
		||||
        cr.rectangle(handleRadius, (height - sliderHeight) / 2, sliderWidth * this._value, sliderHeight);
 | 
			
		||||
        cr.fillPreserve();
 | 
			
		||||
        cr.setSourceRGBA (
 | 
			
		||||
            sliderActiveBorderColor.red / 255,
 | 
			
		||||
            sliderActiveBorderColor.green / 255,
 | 
			
		||||
            sliderActiveBorderColor.blue / 255,
 | 
			
		||||
            sliderActiveBorderColor.alpha / 255);
 | 
			
		||||
        cr.setLineWidth(sliderBorderWidth);
 | 
			
		||||
        cr.stroke();
 | 
			
		||||
 | 
			
		||||
        cr.setSourceRGBA (
 | 
			
		||||
            sliderColor.red / 255,
 | 
			
		||||
            sliderColor.green / 255,
 | 
			
		||||
            sliderColor.blue / 255,
 | 
			
		||||
            sliderColor.alpha / 255);
 | 
			
		||||
        cr.rectangle(handleRadius, (height - sliderHeight) / 2, sliderWidth, sliderHeight);
 | 
			
		||||
        cr.rectangle(handleRadius + sliderWidth * this._value, (height - sliderHeight) / 2, sliderWidth * (1 - this._value), sliderHeight);
 | 
			
		||||
        cr.fillPreserve();
 | 
			
		||||
        cr.setSourceRGBA (
 | 
			
		||||
            sliderBorderColor.red / 255,
 | 
			
		||||
@@ -704,8 +765,14 @@ PopupMenuBase.prototype = {
 | 
			
		||||
        } else {
 | 
			
		||||
            this.box = new St.BoxLayout({ vertical: true });
 | 
			
		||||
        }
 | 
			
		||||
        this.box.connect_after('queue-relayout', Lang.bind(this, this._menuQueueRelayout));
 | 
			
		||||
 | 
			
		||||
        this.isOpen = false;
 | 
			
		||||
 | 
			
		||||
        // If set, we don't send events (including crossing events) to the source actor
 | 
			
		||||
        // for the menu which causes its prelight state to freeze
 | 
			
		||||
        this.blockSourceEvents = false;
 | 
			
		||||
 | 
			
		||||
        this._activeMenuItem = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -806,6 +873,8 @@ PopupMenuBase.prototype = {
 | 
			
		||||
        let columnWidths = [];
 | 
			
		||||
        let items = this.box.get_children();
 | 
			
		||||
        for (let i = 0; i < items.length; i++) {
 | 
			
		||||
            if (!items[i].visible)
 | 
			
		||||
                continue;
 | 
			
		||||
            if (items[i]._delegate instanceof PopupBaseMenuItem || items[i]._delegate instanceof PopupMenuBase) {
 | 
			
		||||
                let itemColumnWidths = items[i]._delegate.getColumnWidths();
 | 
			
		||||
                for (let j = 0; j < itemColumnWidths.length; j++) {
 | 
			
		||||
@@ -825,6 +894,16 @@ PopupMenuBase.prototype = {
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Because of the above column-width funniness, we need to do a
 | 
			
		||||
    // queue-relayout on every item whenever the menu itself changes
 | 
			
		||||
    // size, to force clutter to drop its cached size requests. (The
 | 
			
		||||
    // menuitems will in turn call queue_relayout on their parent, the
 | 
			
		||||
    // menu, but that call will be a no-op since the menu already
 | 
			
		||||
    // has a relayout queued, so we won't get stuck in a loop.
 | 
			
		||||
    _menuQueueRelayout: function() {
 | 
			
		||||
        this.box.get_children().map(function (actor) { actor.queue_relayout(); });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addActor: function(actor) {
 | 
			
		||||
        this.box.add(actor);
 | 
			
		||||
    },
 | 
			
		||||
@@ -1311,14 +1390,20 @@ PopupMenuManager.prototype = {
 | 
			
		||||
        return this._activeMenuContains(event.get_source());
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _eventIsOnAnyMenuSource: function(event) {
 | 
			
		||||
    _shouldBlockEvent: function(event) {
 | 
			
		||||
        let src = event.get_source();
 | 
			
		||||
 | 
			
		||||
        if (this._activeMenu != null && this._activeMenu.actor.contains(src))
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < this._menus.length; i++) {
 | 
			
		||||
            let menu = this._menus[i].menu;
 | 
			
		||||
            if (menu.sourceActor && menu.sourceActor.contains(src))
 | 
			
		||||
                return true;
 | 
			
		||||
            if (menu.sourceActor && !menu.blockSourceEvents && menu.sourceActor.contains(src)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _findMenu: function(item) {
 | 
			
		||||
@@ -1350,7 +1435,7 @@ PopupMenuManager.prototype = {
 | 
			
		||||
        } else if (eventType == Clutter.EventType.BUTTON_PRESS && !activeMenuContains) {
 | 
			
		||||
            this._closeMenu();
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if (activeMenuContains || this._eventIsOnAnyMenuSource(event)) {
 | 
			
		||||
        } else if (!this._shouldBlockEvent(event)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,9 @@ const MAX_FILE_DELETED_BEFORE_INVALID = 10;
 | 
			
		||||
 | 
			
		||||
const HISTORY_KEY = 'command-history';
 | 
			
		||||
 | 
			
		||||
const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
 | 
			
		||||
const DISABLE_COMMAND_LINE_KEY = 'disable-command-line';
 | 
			
		||||
 | 
			
		||||
const DIALOG_GROW_TIME = 0.1;
 | 
			
		||||
 | 
			
		||||
function CommandCompleter() {
 | 
			
		||||
@@ -167,6 +170,7 @@ __proto__: ModalDialog.ModalDialog.prototype,
 | 
			
		||||
    _init : function() {
 | 
			
		||||
        ModalDialog.ModalDialog.prototype._init.call(this, { styleClass: 'run-dialog' });
 | 
			
		||||
 | 
			
		||||
        this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA });
 | 
			
		||||
        global.settings.connect('changed::development-tools', Lang.bind(this, function () {
 | 
			
		||||
            this._enableInternalCommands = global.settings.get_boolean('development-tools');
 | 
			
		||||
        }));
 | 
			
		||||
@@ -206,10 +210,7 @@ __proto__: ModalDialog.ModalDialog.prototype,
 | 
			
		||||
 | 
			
		||||
        this._entryText = entry.clutter_text;
 | 
			
		||||
        this.contentLayout.add(entry, { y_align: St.Align.START });
 | 
			
		||||
        this.connect('opened',
 | 
			
		||||
                     Lang.bind(this, function() {
 | 
			
		||||
                         this._entryText.grab_key_focus();
 | 
			
		||||
                     }));
 | 
			
		||||
        this.setInitialKeyFocus(this._entryText);
 | 
			
		||||
 | 
			
		||||
        this._errorBox = new St.BoxLayout({ style_class: 'run-dialog-error-box' });
 | 
			
		||||
 | 
			
		||||
@@ -239,15 +240,21 @@ __proto__: ModalDialog.ModalDialog.prototype,
 | 
			
		||||
        this._entryText.connect('key-press-event', Lang.bind(this, function(o, e) {
 | 
			
		||||
            let symbol = e.get_key_symbol();
 | 
			
		||||
            if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) {
 | 
			
		||||
                this.popModal();
 | 
			
		||||
                if (Shell.get_event_state(e) & Clutter.ModifierType.CONTROL_MASK)
 | 
			
		||||
                    this._run(o.get_text(), true);
 | 
			
		||||
                else
 | 
			
		||||
                    this._run(o.get_text(), false);
 | 
			
		||||
                if (!this._commandError)
 | 
			
		||||
                    this.close(global.get_current_time());
 | 
			
		||||
                    this.close();
 | 
			
		||||
                else {
 | 
			
		||||
                    if (!this.pushModal())
 | 
			
		||||
                        this.close();
 | 
			
		||||
                }
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            if (symbol == Clutter.Escape) {
 | 
			
		||||
                this.close(global.get_current_time());
 | 
			
		||||
                this.close();
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            if (symbol == Clutter.slash) {
 | 
			
		||||
@@ -353,6 +360,9 @@ __proto__: ModalDialog.ModalDialog.prototype,
 | 
			
		||||
        this._entryText.set_text('');
 | 
			
		||||
        this._commandError = false;
 | 
			
		||||
 | 
			
		||||
        if (this._lockdownSettings.get_boolean(DISABLE_COMMAND_LINE_KEY))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        ModalDialog.ModalDialog.prototype.open.call(this);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 | 
			
		||||
 | 
			
		||||
const DBus = imports.dbus;
 | 
			
		||||
const Gio = imports.gi.Gio;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
 | 
			
		||||
@@ -68,6 +69,104 @@ function waitLeisure() {
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const PerfHelperIface = {
 | 
			
		||||
    name: 'org.gnome.Shell.PerfHelper',
 | 
			
		||||
    methods: [{ name: 'CreateWindow', inSignature: 'iibb', outSignature: '' },
 | 
			
		||||
              { name: 'WaitWindows', inSignature: '', outSignature: '' },
 | 
			
		||||
              { name: 'DestroyWindows', inSignature: '', outSignature: ''}]
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const PerfHelper = function () {
 | 
			
		||||
    this._init();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PerfHelper.prototype = {
 | 
			
		||||
     _init: function() {
 | 
			
		||||
         DBus.session.proxifyObject(this, 'org.gnome.Shell.PerfHelper', '/org/gnome/Shell/PerfHelper');
 | 
			
		||||
     }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DBus.proxifyPrototype(PerfHelper.prototype, PerfHelperIface);
 | 
			
		||||
 | 
			
		||||
let _perfHelper = null;
 | 
			
		||||
function _getPerfHelper() {
 | 
			
		||||
    if (_perfHelper == null)
 | 
			
		||||
        _perfHelper = new PerfHelper();
 | 
			
		||||
 | 
			
		||||
    return _perfHelper;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * createTestWindow:
 | 
			
		||||
 * @width: width of window, in pixels
 | 
			
		||||
 * @height: height of window, in pixels
 | 
			
		||||
 * @alpha: whether the window should be alpha transparent
 | 
			
		||||
 * @maximized: whethe the window should be created maximized
 | 
			
		||||
 *
 | 
			
		||||
 * Creates a window using gnome-shell-perf-helper for testing purposes.
 | 
			
		||||
 * While this function can be used with yield in an automation
 | 
			
		||||
 * script to pause until the D-Bus call to the helper process returns,
 | 
			
		||||
 * because of the normal X asynchronous mapping process, to actually wait
 | 
			
		||||
 * until the window has been mapped and exposed, use waitTestWindows().
 | 
			
		||||
 */
 | 
			
		||||
function createTestWindow(width, height, alpha, maximized) {
 | 
			
		||||
    let cb;
 | 
			
		||||
    let perfHelper = _getPerfHelper();
 | 
			
		||||
 | 
			
		||||
    perfHelper.CreateWindowRemote(width, height, alpha, maximized,
 | 
			
		||||
                                  function(result, excp) {
 | 
			
		||||
                                      if (cb)
 | 
			
		||||
                                          cb();
 | 
			
		||||
                                  });
 | 
			
		||||
 | 
			
		||||
    return function(callback) {
 | 
			
		||||
        cb = callback;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * waitTestWindows:
 | 
			
		||||
 *
 | 
			
		||||
 * Used within an automation script to pause until all windows previously
 | 
			
		||||
 * created with createTestWindow have been mapped and exposed.
 | 
			
		||||
 */
 | 
			
		||||
function waitTestWindows() {
 | 
			
		||||
    let cb;
 | 
			
		||||
    let perfHelper = _getPerfHelper();
 | 
			
		||||
 | 
			
		||||
    perfHelper.WaitWindowsRemote(function(result, excp) {
 | 
			
		||||
                                     if (cb)
 | 
			
		||||
                                         cb();
 | 
			
		||||
                                 });
 | 
			
		||||
 | 
			
		||||
    return function(callback) {
 | 
			
		||||
        cb = callback;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * destroyTestWindows:
 | 
			
		||||
 *
 | 
			
		||||
 * Destroys all windows previously created with createTestWindow().
 | 
			
		||||
 * While this function can be used with yield in an automation
 | 
			
		||||
 * script to pause until the D-Bus call to the helper process returns,
 | 
			
		||||
 * this doesn't guarantee that Mutter has actually finished the destroy
 | 
			
		||||
 * process because of normal X asynchronicity.
 | 
			
		||||
 */
 | 
			
		||||
function destroyTestWindows() {
 | 
			
		||||
    let cb;
 | 
			
		||||
    let perfHelper = _getPerfHelper();
 | 
			
		||||
 | 
			
		||||
    perfHelper.DestroyWindowsRemote(function(result, excp) {
 | 
			
		||||
                                        if (cb)
 | 
			
		||||
                                            cb();
 | 
			
		||||
                                    });
 | 
			
		||||
 | 
			
		||||
    return function(callback) {
 | 
			
		||||
        cb = callback;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * defineScriptEvent
 | 
			
		||||
 * @name: The event will be called script.<name>
 | 
			
		||||
@@ -147,8 +246,8 @@ function _collect(scriptModule, outputFile) {
 | 
			
		||||
        Shell.write_string_to_stream(out, '"events":\n');
 | 
			
		||||
        Shell.PerfLog.get_default().dump_events(out);
 | 
			
		||||
 | 
			
		||||
        let monitors = global.get_monitors()
 | 
			
		||||
        let primary = global.get_primary_monitor()
 | 
			
		||||
        let monitors = global.get_monitors();
 | 
			
		||||
        let primary = global.get_primary_monitor();
 | 
			
		||||
        Shell.write_string_to_stream(out, ',\n"monitors":\n[');
 | 
			
		||||
        for (let i = 0; i < monitors.length; i++) {
 | 
			
		||||
            let monitor = monitors[i];
 | 
			
		||||
@@ -167,7 +266,21 @@ function _collect(scriptModule, outputFile) {
 | 
			
		||||
        Shell.write_string_to_stream(out, ',\n"metrics":\n[ ');
 | 
			
		||||
        let first = true;
 | 
			
		||||
        for (let name in scriptModule.METRICS) {
 | 
			
		||||
            let metric = scriptModule.METRICS[name]; 
 | 
			
		||||
            let metric = scriptModule.METRICS[name];
 | 
			
		||||
            // Extra checks here because JSON.stringify generates
 | 
			
		||||
            // invalid JSON for undefined values
 | 
			
		||||
            if (metric.description == null) {
 | 
			
		||||
                log("Error: No description found for metric " + name);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (metric.units == null) {
 | 
			
		||||
                log("Error: No units found for metric " + name);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (metric.value == null) {
 | 
			
		||||
                log("Error: No value found for metric " + name);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!first)
 | 
			
		||||
                Shell.write_string_to_stream(out, ',\n  ');
 | 
			
		||||
 
 | 
			
		||||
@@ -115,6 +115,43 @@ function SearchProvider(title) {
 | 
			
		||||
SearchProvider.prototype = {
 | 
			
		||||
    _init: function(title) {
 | 
			
		||||
        this.title = title;
 | 
			
		||||
        this.searchSystem = null;
 | 
			
		||||
        this.searchAsync  = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _asyncCancelled: function() {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    startAsync: function() {
 | 
			
		||||
        this.searchAsync = true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    tryCancelAsync: function() {
 | 
			
		||||
        if (!this.searchAsync)
 | 
			
		||||
            return;
 | 
			
		||||
        this._asyncCancelled();
 | 
			
		||||
        this.searchAsync = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * addItems:
 | 
			
		||||
     * @items: an array of result identifier strings representing
 | 
			
		||||
     * items which match the last given search terms.
 | 
			
		||||
     *
 | 
			
		||||
     * This should be used for something that requires a bit more
 | 
			
		||||
     * logic; it's designed to be an asyncronous way to add a result
 | 
			
		||||
     * to the current search.
 | 
			
		||||
     */
 | 
			
		||||
    addItems: function( items) {
 | 
			
		||||
        if (!this.searchSystem)
 | 
			
		||||
            throw new Error('Search provider not registered');
 | 
			
		||||
 | 
			
		||||
        if (!items.length)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this.tryCancelAsync();
 | 
			
		||||
 | 
			
		||||
        this.searchSystem.addProviderItems(this, items);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -212,6 +249,7 @@ SearchProvider.prototype = {
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(SearchProvider.prototype);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function OpenSearchSystem() {
 | 
			
		||||
    this._init();
 | 
			
		||||
}
 | 
			
		||||
@@ -324,6 +362,7 @@ SearchSystem.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    registerProvider: function (provider) {
 | 
			
		||||
        provider.searchSystem = this;
 | 
			
		||||
        this._providers.push(provider);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -340,30 +379,50 @@ SearchSystem.prototype = {
 | 
			
		||||
        this._previousResults = [];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addProviderItems: function(provider, items) {
 | 
			
		||||
        let index = this._providers.indexOf(provider);
 | 
			
		||||
        let [provider2, results] = this._previousResults[index];
 | 
			
		||||
        if (provider !== provider2)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        results.push.apply(results, items);
 | 
			
		||||
        this.emit('results-updated', this._previousResults);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    updateSearch: function(searchString) {
 | 
			
		||||
        searchString = searchString.replace(/^\s+/g, '').replace(/\s+$/g, '');
 | 
			
		||||
        if (searchString == '')
 | 
			
		||||
            return [];
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let terms = searchString.split(/\s+/);
 | 
			
		||||
        let isSubSearch = terms.length == this._previousTerms.length;
 | 
			
		||||
        if (isSubSearch) {
 | 
			
		||||
            for (let i = 0; i < terms.length; i++) {
 | 
			
		||||
                if (terms[i].indexOf(this._previousTerms[i]) != 0) {
 | 
			
		||||
                    isSubSearch = false;
 | 
			
		||||
                    break;
 | 
			
		||||
        this.updateSearchResults(terms);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    updateSearchResults: function(terms) {
 | 
			
		||||
        let isSubSearch = false;
 | 
			
		||||
 | 
			
		||||
        if (terms) {
 | 
			
		||||
            isSubSearch = terms.length == this._previousTerms.length;
 | 
			
		||||
            if (isSubSearch) {
 | 
			
		||||
                for (let i = 0; i < terms.length; i++) {
 | 
			
		||||
                    if (terms[i].indexOf(this._previousTerms[i]) != 0) {
 | 
			
		||||
                        isSubSearch = false;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            terms = this._previousTerms;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let results = [];
 | 
			
		||||
        if (isSubSearch) {
 | 
			
		||||
            for (let i = 0; i < this._previousResults.length; i++) {
 | 
			
		||||
            for (let i = 0; i < this._providers.length; i++) {
 | 
			
		||||
                let [provider, previousResults] = this._previousResults[i];
 | 
			
		||||
                provider.tryCancelAsync();
 | 
			
		||||
                try {
 | 
			
		||||
                    let providerResults = provider.getSubsearchResultSet(previousResults, terms);
 | 
			
		||||
                    if (providerResults.length > 0)
 | 
			
		||||
                        results.push([provider, providerResults]);
 | 
			
		||||
                    results.push([provider, providerResults]);
 | 
			
		||||
                } catch (error) {
 | 
			
		||||
                    global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
 | 
			
		||||
                }
 | 
			
		||||
@@ -371,10 +430,10 @@ SearchSystem.prototype = {
 | 
			
		||||
        } else {
 | 
			
		||||
            for (let i = 0; i < this._providers.length; i++) {
 | 
			
		||||
                let provider = this._providers[i];
 | 
			
		||||
                provider.tryCancelAsync();
 | 
			
		||||
                try {
 | 
			
		||||
                    let providerResults = provider.getInitialResultSet(terms);
 | 
			
		||||
                    if (providerResults.length > 0)
 | 
			
		||||
                        results.push([provider, providerResults]);
 | 
			
		||||
                    results.push([provider, providerResults]);
 | 
			
		||||
                } catch (error) {
 | 
			
		||||
                    global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
 | 
			
		||||
                }
 | 
			
		||||
@@ -383,8 +442,7 @@ SearchSystem.prototype = {
 | 
			
		||||
 | 
			
		||||
        this._previousTerms = terms;
 | 
			
		||||
        this._previousResults = results;
 | 
			
		||||
 | 
			
		||||
        return results;
 | 
			
		||||
    }
 | 
			
		||||
        this.emit('results-updated', results);
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(SearchSystem.prototype);
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ const Lang = imports.lang;
 | 
			
		||||
const Gettext = imports.gettext.domain('gnome-shell');
 | 
			
		||||
const _ = Gettext.gettext;
 | 
			
		||||
const Gtk = imports.gi.Gtk;
 | 
			
		||||
const Meta = imports.gi.Meta;
 | 
			
		||||
const St = imports.gi.St;
 | 
			
		||||
 | 
			
		||||
const DND = imports.ui.dnd;
 | 
			
		||||
@@ -49,6 +50,10 @@ SearchResult.prototype = {
 | 
			
		||||
                          Lang.bind(this, function() {
 | 
			
		||||
                              Main.overview.beginItemDrag(this);
 | 
			
		||||
                          }));
 | 
			
		||||
        draggable.connect('drag-cancelled',
 | 
			
		||||
                          Lang.bind(this, function() {
 | 
			
		||||
                              Main.overview.cancelledItemDrag(this);
 | 
			
		||||
                          }));
 | 
			
		||||
        draggable.connect('drag-end',
 | 
			
		||||
                          Lang.bind(this, function() {
 | 
			
		||||
                              Main.overview.endItemDrag(this);
 | 
			
		||||
@@ -100,8 +105,30 @@ GridSearchResults.prototype = {
 | 
			
		||||
        this._grid = new IconGrid.IconGrid({ rowLimit: MAX_SEARCH_RESULTS_ROWS,
 | 
			
		||||
                                             xAlign: St.Align.START });
 | 
			
		||||
        this.actor = new St.Bin({ x_align: St.Align.START });
 | 
			
		||||
 | 
			
		||||
        this.actor.set_child(this._grid.actor);
 | 
			
		||||
        this.selectionIndex = -1;
 | 
			
		||||
        this._width = 0;
 | 
			
		||||
        this.actor.connect('notify::width', Lang.bind(this, function() {
 | 
			
		||||
            this._width = this.actor.width;
 | 
			
		||||
            Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
 | 
			
		||||
                this._tryAddResults();
 | 
			
		||||
            }));
 | 
			
		||||
        }));
 | 
			
		||||
        this._notDisplayedResult = [];
 | 
			
		||||
        this._terms = [];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _tryAddResults: function() {
 | 
			
		||||
        let canDisplay = this._grid.childrenInRow(this._width) * MAX_SEARCH_RESULTS_ROWS
 | 
			
		||||
                         - this._grid.visibleItemsCount();
 | 
			
		||||
 | 
			
		||||
        for (let i = Math.min(this._notDisplayedResult.length, canDisplay); i > 0; i--) {
 | 
			
		||||
            let result = this._notDisplayedResult.shift();
 | 
			
		||||
            let meta = this.provider.getResultMeta(result);
 | 
			
		||||
            let display = new SearchResult(this.provider, meta, this._terms);
 | 
			
		||||
            this._grid.addItem(display.actor);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getVisibleResultCount: function() {
 | 
			
		||||
@@ -109,15 +136,15 @@ GridSearchResults.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    renderResults: function(results, terms) {
 | 
			
		||||
        for (let i = 0; i < results.length; i++) {
 | 
			
		||||
            let result = results[i];
 | 
			
		||||
            let meta = this.provider.getResultMeta(result);
 | 
			
		||||
            let display = new SearchResult(this.provider, meta, terms);
 | 
			
		||||
            this._grid.addItem(display.actor);
 | 
			
		||||
        }
 | 
			
		||||
        // copy the lists
 | 
			
		||||
        this._notDisplayedResult = results.slice(0);
 | 
			
		||||
        this._terms = terms.slice(0);
 | 
			
		||||
        this._tryAddResults();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    clear: function () {
 | 
			
		||||
        this._terms = [];
 | 
			
		||||
        this._notDisplayedResult = [];
 | 
			
		||||
        this._grid.removeAll();
 | 
			
		||||
        this.selectionIndex = -1;
 | 
			
		||||
    },
 | 
			
		||||
@@ -155,6 +182,7 @@ function SearchResults(searchSystem, openSearchSystem) {
 | 
			
		||||
SearchResults.prototype = {
 | 
			
		||||
    _init: function(searchSystem, openSearchSystem) {
 | 
			
		||||
        this._searchSystem = searchSystem;
 | 
			
		||||
        this._searchSystem.connect('results-updated', Lang.bind(this, this._updateResults));
 | 
			
		||||
        this._openSearchSystem = openSearchSystem;
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.BoxLayout({ name: 'searchResults',
 | 
			
		||||
@@ -189,9 +217,11 @@ SearchResults.prototype = {
 | 
			
		||||
        this._selectedProvider = -1;
 | 
			
		||||
        this._providers = this._searchSystem.getProviders();
 | 
			
		||||
        this._providerMeta = [];
 | 
			
		||||
        for (let i = 0; i < this._providers.length; i++)
 | 
			
		||||
        this._providerMetaResults = {};
 | 
			
		||||
        for (let i = 0; i < this._providers.length; i++) {
 | 
			
		||||
            this.createProviderMeta(this._providers[i]);
 | 
			
		||||
 | 
			
		||||
            this._providerMetaResults[this.providers[i].title] = [];
 | 
			
		||||
        }
 | 
			
		||||
        this._searchProvidersBox = new St.BoxLayout({ style_class: 'search-providers-box' });
 | 
			
		||||
        this.actor.add(this._searchProvidersBox);
 | 
			
		||||
 | 
			
		||||
@@ -269,6 +299,12 @@ SearchResults.prototype = {
 | 
			
		||||
            meta.actor.hide();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    
 | 
			
		||||
    _clearDisplayForProvider: function(index) {
 | 
			
		||||
        let meta = this._providerMeta[index];
 | 
			
		||||
        meta.resultDisplay.clear();
 | 
			
		||||
        meta.actor.hide();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    reset: function() {
 | 
			
		||||
        this._searchSystem.reset();
 | 
			
		||||
@@ -284,15 +320,15 @@ SearchResults.prototype = {
 | 
			
		||||
        this._statusText.show();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    doSearch: function (searchString) {
 | 
			
		||||
        this._searchSystem.updateSearch(searchString);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _metaForProvider: function(provider) {
 | 
			
		||||
        return this._providerMeta[this._providers.indexOf(provider)];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    updateSearch: function (searchString) {
 | 
			
		||||
        let results = this._searchSystem.updateSearch(searchString);
 | 
			
		||||
 | 
			
		||||
        this._clearDisplay();
 | 
			
		||||
 | 
			
		||||
    _updateResults: function(searchSystem, results) {
 | 
			
		||||
        if (results.length == 0) {
 | 
			
		||||
            this._statusText.set_text(_("No matching results."));
 | 
			
		||||
            this._statusText.show();
 | 
			
		||||
@@ -302,14 +338,22 @@ SearchResults.prototype = {
 | 
			
		||||
            this._statusText.hide();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let terms = this._searchSystem.getTerms();
 | 
			
		||||
        let terms = searchSystem.getTerms();
 | 
			
		||||
        this._openSearchSystem.setSearchTerms(terms);
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < results.length; i++) {
 | 
			
		||||
            let [provider, providerResults] = results[i];
 | 
			
		||||
            let meta = this._metaForProvider(provider);
 | 
			
		||||
            meta.actor.show();
 | 
			
		||||
            meta.resultDisplay.renderResults(providerResults, terms);
 | 
			
		||||
            if (providerResults.length == 0)
 | 
			
		||||
                this._clearDisplayForProvider(i)
 | 
			
		||||
            else {
 | 
			
		||||
                if (this._providerMetaResults[provider.title] != providerResults) {
 | 
			
		||||
                    this._providerMetaResults[provider.title] = providerResults;
 | 
			
		||||
                    this._clearDisplayForProvider(i);
 | 
			
		||||
                    let meta = this._metaForProvider(provider);
 | 
			
		||||
                    meta.actor.show();
 | 
			
		||||
                    meta.resultDisplay.renderResults(providerResults, terms);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._selectedOpenSearchButton == -1)
 | 
			
		||||
 
 | 
			
		||||
@@ -66,13 +66,13 @@ ATIndicator.prototype = {
 | 
			
		||||
        let textZoom = this._buildFontItem();
 | 
			
		||||
        this.menu.addMenuItem(textZoom);
 | 
			
		||||
 | 
			
		||||
        let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
 | 
			
		||||
                                                               'screen-reader-enabled');
 | 
			
		||||
        this.menu.addMenuItem(screenReader);
 | 
			
		||||
//        let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
 | 
			
		||||
//                                                               'screen-reader-enabled');
 | 
			
		||||
//        this.menu.addMenuItem(screenReader);
 | 
			
		||||
 | 
			
		||||
        let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
 | 
			
		||||
                                                                   'screen-keyboard-enabled');
 | 
			
		||||
        this.menu.addMenuItem(screenKeyboard);
 | 
			
		||||
//        let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
 | 
			
		||||
//                                                                   'screen-keyboard-enabled');
 | 
			
		||||
//        this.menu.addMenuItem(screenKeyboard);
 | 
			
		||||
 | 
			
		||||
        let visualBell = this._buildItemGConf(_("Visual Alerts"), client, KEY_VISUAL_BELL);
 | 
			
		||||
        this.menu.addMenuItem(visualBell);
 | 
			
		||||
@@ -91,7 +91,8 @@ ATIndicator.prototype = {
 | 
			
		||||
 | 
			
		||||
        this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
 | 
			
		||||
        this.menu.addAction(_("Universal Access Settings"), function() {
 | 
			
		||||
            Util.spawnDesktop('gnome-universal-access-panel');
 | 
			
		||||
            let app = Shell.AppSystem.get_default().get_app('gnome-universal-access-panel.desktop');
 | 
			
		||||
            app.activate(-1);
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -93,7 +93,8 @@ Indicator.prototype = {
 | 
			
		||||
        this._updateFullMenu();
 | 
			
		||||
 | 
			
		||||
        this.menu.addAction(_("Bluetooth Settings"), function() {
 | 
			
		||||
            GLib.spawn_command_line_async('gnome-control-center bluetooth');
 | 
			
		||||
            let app = Shell.AppSystem.get_default().get_app('bluetooth-properties.desktop');
 | 
			
		||||
            app.activate(-1);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._applet.connect('pincode-request', Lang.bind(this, this._pinRequest));
 | 
			
		||||
@@ -136,6 +137,7 @@ Indicator.prototype = {
 | 
			
		||||
    _updateDevices: function() {
 | 
			
		||||
        let devices = this._applet.get_devices();
 | 
			
		||||
 | 
			
		||||
        let newlist = [ ];
 | 
			
		||||
        for (let i = 0; i < this._deviceItems.length; i++) {
 | 
			
		||||
            let item = this._deviceItems[i];
 | 
			
		||||
            let destroy = true;
 | 
			
		||||
@@ -143,26 +145,20 @@ Indicator.prototype = {
 | 
			
		||||
                // we need to deep compare because BluetoothSimpleDevice is a boxed type
 | 
			
		||||
                // (but we take advantage of that, because _skip will disappear the next
 | 
			
		||||
                // time get_devices() is called)
 | 
			
		||||
                if (this._deviceCompare(item._device, devices[i])) {
 | 
			
		||||
                    item.label.text = devices[i].alias;
 | 
			
		||||
                    devices[i]._skip = true;
 | 
			
		||||
                if (this._deviceCompare(item._device, devices[j])) {
 | 
			
		||||
                    item.label.text = devices[j].alias;
 | 
			
		||||
                    devices[j]._skip = true;
 | 
			
		||||
                    destroy = false;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (destroy) {
 | 
			
		||||
            if (destroy)
 | 
			
		||||
                item.destroy();
 | 
			
		||||
                item._destroyed = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let newlist = [ ];
 | 
			
		||||
        for (let i = 0; i < this._deviceItems.length; i++) {
 | 
			
		||||
            let item = this._deviceItems[i];
 | 
			
		||||
            if (!item._destroyed)
 | 
			
		||||
            else
 | 
			
		||||
                newlist.push(item);
 | 
			
		||||
        }
 | 
			
		||||
        this._deviceItems = newlist;
 | 
			
		||||
 | 
			
		||||
        this._deviceItems = newlist;
 | 
			
		||||
        this._hasDevices = newlist.length > 0;
 | 
			
		||||
        for (let i = 0; i < devices.length; i++) {
 | 
			
		||||
            let d = devices[i];
 | 
			
		||||
@@ -471,9 +467,15 @@ PinNotification.prototype = {
 | 
			
		||||
 | 
			
		||||
        this.connect('action-invoked', Lang.bind(this, function(self, action) {
 | 
			
		||||
            if (action == 'ok') {
 | 
			
		||||
                if (this._numeric)
 | 
			
		||||
                    this._applet.agent_reply_passkey(this._devicePath, parseInt(this._entry.text));
 | 
			
		||||
                else
 | 
			
		||||
                if (this._numeric) {
 | 
			
		||||
                    let num = parseInt(this._entry.text);
 | 
			
		||||
                    if (isNaN(num)) {
 | 
			
		||||
                        // user reply was empty, or was invalid
 | 
			
		||||
                        // cancel the operation
 | 
			
		||||
                        num = -1;
 | 
			
		||||
                    }
 | 
			
		||||
                    this._applet.agent_reply_passkey(this._devicePath, num);
 | 
			
		||||
                } else
 | 
			
		||||
                    this._applet.agent_reply_pincode(this._devicePath, this._entry.text);
 | 
			
		||||
            } else {
 | 
			
		||||
                if (this._numeric)
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,8 @@ XKBIndicator.prototype = {
 | 
			
		||||
            Util.spawn(['gkbd-keyboard-display', '-g', String(this._config.get_current_group() + 1)]);
 | 
			
		||||
        }));
 | 
			
		||||
        this.menu.addAction(_("Localization Settings"), function() {
 | 
			
		||||
            Util.spawn(['gnome-control-center', 'region']);
 | 
			
		||||
            let app = Shell.AppSystem.get_default().get_app('gnome-region-panel.desktop');
 | 
			
		||||
            app.activate(-1);
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2124
									
								
								js/ui/status/network.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2124
									
								
								js/ui/status/network.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -83,7 +83,8 @@ Indicator.prototype = {
 | 
			
		||||
        this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
 | 
			
		||||
 | 
			
		||||
        this.menu.addAction(_("Power Settings"),function() {
 | 
			
		||||
            Util.spawnDesktop('gnome-power-panel');
 | 
			
		||||
            let app = Shell.AppSystem.get_default().get_app('gnome-power-panel.desktop');
 | 
			
		||||
            app.activate(-1);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._proxy.connect('Changed', Lang.bind(this, this._devicesChanged));
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,6 @@ const Util = imports.misc.util;
 | 
			
		||||
const Gettext = imports.gettext.domain('gnome-shell');
 | 
			
		||||
const _ = Gettext.gettext;
 | 
			
		||||
 | 
			
		||||
const VOLUME_MAX = 65536.0; /* PA_VOLUME_NORM */
 | 
			
		||||
const VOLUME_ADJUSTMENT_STEP = 0.05; /* Volume adjustment step in % */
 | 
			
		||||
 | 
			
		||||
const VOLUME_NOTIFY_ID = 1;
 | 
			
		||||
@@ -37,6 +36,8 @@ Indicator.prototype = {
 | 
			
		||||
        this._control.connect('default-source-changed', Lang.bind(this, this._readInput));
 | 
			
		||||
        this._control.connect('stream-added', Lang.bind(this, this._maybeShowInput));
 | 
			
		||||
        this._control.connect('stream-removed', Lang.bind(this, this._maybeShowInput));
 | 
			
		||||
        this._volumeMax = this._control.get_vol_max_norm();
 | 
			
		||||
        this._volumeMaxAmplified = this._control.get_vol_max_amplified();
 | 
			
		||||
 | 
			
		||||
        this._output = null;
 | 
			
		||||
        this._outputVolumeId = 0;
 | 
			
		||||
@@ -63,7 +64,8 @@ Indicator.prototype = {
 | 
			
		||||
 | 
			
		||||
        this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
 | 
			
		||||
        this.menu.addAction(_("Sound Settings"), function() {
 | 
			
		||||
            Util.spawnDesktop('gnome-sound-panel');
 | 
			
		||||
            let app = Shell.AppSystem.get_default().get_app('gnome-sound-panel.desktop');
 | 
			
		||||
            app.activate(-1);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
 | 
			
		||||
@@ -72,9 +74,9 @@ Indicator.prototype = {
 | 
			
		||||
 | 
			
		||||
    _getMaxVolume: function(property) {
 | 
			
		||||
        if (this[property].get_can_decibel())
 | 
			
		||||
            return (VOLUME_MAX * 1.5);
 | 
			
		||||
            return this._volumeMaxAmplified;
 | 
			
		||||
        else
 | 
			
		||||
            return VOLUME_MAX;
 | 
			
		||||
            return this._volumeMax;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onScrollEvent: function(actor, event) {
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,8 @@ const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
 | 
			
		||||
    'a11y-keyboard': 'a11y',
 | 
			
		||||
    'kbd-scrolllock': 'keyboard',
 | 
			
		||||
    'kbd-numlock': 'keyboard',
 | 
			
		||||
    'kbd-capslock': 'keyboard'
 | 
			
		||||
    'kbd-capslock': 'keyboard',
 | 
			
		||||
    'ibus-ui-gtk': 'input-method'
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function StatusIconDispatcher() {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 | 
			
		||||
 | 
			
		||||
const Gdm = imports.gi.Gdm;
 | 
			
		||||
const DBus = imports.dbus;
 | 
			
		||||
const Gio = imports.gi.Gio;
 | 
			
		||||
const GLib = imports.gi.GLib;
 | 
			
		||||
const Lang = imports.lang;
 | 
			
		||||
const Shell = imports.gi.Shell;
 | 
			
		||||
@@ -16,6 +18,21 @@ const PanelMenu = imports.ui.panelMenu;
 | 
			
		||||
const PopupMenu = imports.ui.popupMenu;
 | 
			
		||||
const Util = imports.misc.util;
 | 
			
		||||
 | 
			
		||||
const BUS_NAME = 'org.gnome.ScreenSaver';
 | 
			
		||||
const OBJECT_PATH = '/org/gnome/ScreenSaver';
 | 
			
		||||
 | 
			
		||||
const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
 | 
			
		||||
const DISABLE_USER_SWITCH_KEY = 'disable-user-switching';
 | 
			
		||||
const DISABLE_LOCK_SCREEN_KEY = 'disable-lock-screen';
 | 
			
		||||
const DISABLE_LOG_OUT_KEY = 'disable-log-out';
 | 
			
		||||
 | 
			
		||||
const ScreenSaverInterface = {
 | 
			
		||||
    name: BUS_NAME,
 | 
			
		||||
    methods: [ { name: 'Lock', inSignature: '' } ]
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
let ScreenSaverProxy = DBus.makeProxyClass(ScreenSaverInterface);
 | 
			
		||||
 | 
			
		||||
// Adapted from gdm/gui/user-switch-applet/applet.c
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
 | 
			
		||||
@@ -33,17 +50,20 @@ StatusMenuButton.prototype = {
 | 
			
		||||
        let box = new St.BoxLayout({ name: 'panelStatusMenu' });
 | 
			
		||||
        this.actor.set_child(box);
 | 
			
		||||
 | 
			
		||||
        this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA });
 | 
			
		||||
 | 
			
		||||
        this._gdm = Gdm.UserManager.ref_default();
 | 
			
		||||
        this._gdm.queue_load();
 | 
			
		||||
 | 
			
		||||
        this._user = this._gdm.get_user(GLib.get_user_name());
 | 
			
		||||
        this._presence = new GnomeSession.Presence();
 | 
			
		||||
        this._presenceItems = {};
 | 
			
		||||
        this._session = new GnomeSession.SessionManager();
 | 
			
		||||
 | 
			
		||||
        this._account_mgr = Tp.AccountManager.dup()
 | 
			
		||||
 | 
			
		||||
        this._upClient = new UPowerGlib.Client();
 | 
			
		||||
 | 
			
		||||
        this._screenSaverProxy = new ScreenSaverProxy(DBus.session, BUS_NAME, OBJECT_PATH);
 | 
			
		||||
        this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
 | 
			
		||||
 | 
			
		||||
        this._iconBox = new St.Bin();
 | 
			
		||||
@@ -67,6 +87,15 @@ StatusMenuButton.prototype = {
 | 
			
		||||
        this._gdm.connect('notify::is-loaded', Lang.bind(this, this._updateSwitchUser));
 | 
			
		||||
        this._gdm.connect('user-added', Lang.bind(this, this._updateSwitchUser));
 | 
			
		||||
        this._gdm.connect('user-removed', Lang.bind(this, this._updateSwitchUser));
 | 
			
		||||
        this._lockdownSettings.connect('changed::' + DISABLE_USER_SWITCH_KEY,
 | 
			
		||||
                                       Lang.bind(this, this._updateSwitchUser));
 | 
			
		||||
        this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY,
 | 
			
		||||
                                       Lang.bind(this, this._updateLogout));
 | 
			
		||||
        this._lockdownSettings.connect('changed::' + DISABLE_LOCK_SCREEN_KEY,
 | 
			
		||||
                                       Lang.bind(this, this._updateLockScreen));
 | 
			
		||||
        this._updateSwitchUser();
 | 
			
		||||
        this._updateLogout();
 | 
			
		||||
        this._updateLockScreen();
 | 
			
		||||
 | 
			
		||||
        this._upClient.connect('notify::can-suspend', Lang.bind(this, this._updateSuspendOrPowerOff));
 | 
			
		||||
    },
 | 
			
		||||
@@ -83,11 +112,41 @@ StatusMenuButton.prototype = {
 | 
			
		||||
          this._name.set_text("");
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateSessionSeparator: function() {
 | 
			
		||||
        let showSeparator = this._loginScreenItem.actor.visible ||
 | 
			
		||||
                            this._logoutItem.actor.visible ||
 | 
			
		||||
                            this._lockScreenItem.actor.visible;
 | 
			
		||||
        if (showSeparator)
 | 
			
		||||
            this._sessionSeparator.actor.show();
 | 
			
		||||
        else
 | 
			
		||||
            this._sessionSeparator.actor.hide();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateSwitchUser: function() {
 | 
			
		||||
        if (this._gdm.can_switch ())
 | 
			
		||||
        let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY);
 | 
			
		||||
        if (allowSwitch && this._gdm.can_switch ())
 | 
			
		||||
            this._loginScreenItem.actor.show();
 | 
			
		||||
        else
 | 
			
		||||
            this._loginScreenItem.actor.hide();
 | 
			
		||||
        this._updateSessionSeparator();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateLogout: function() {
 | 
			
		||||
        let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY);
 | 
			
		||||
        if (allowLogout)
 | 
			
		||||
            this._logoutItem.actor.show();
 | 
			
		||||
        else
 | 
			
		||||
            this._logoutItem.actor.hide();
 | 
			
		||||
        this._updateSessionSeparator();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateLockScreen: function() {
 | 
			
		||||
        let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
 | 
			
		||||
        if (allowLockScreen)
 | 
			
		||||
            this._lockScreenItem.actor.show();
 | 
			
		||||
        else
 | 
			
		||||
            this._lockScreenItem.actor.hide();
 | 
			
		||||
        this._updateSessionSeparator();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateSuspendOrPowerOff: function() {
 | 
			
		||||
@@ -101,7 +160,7 @@ StatusMenuButton.prototype = {
 | 
			
		||||
        if (!this._haveSuspend) {
 | 
			
		||||
            this._suspendOrPowerOffItem.updateText(_("Power Off..."), null);
 | 
			
		||||
        } else {
 | 
			
		||||
            this._suspendOrPowerOffItem.updateText(_("Suspend"), ("Power Off..."));
 | 
			
		||||
            this._suspendOrPowerOffItem.updateText(_("Suspend"), _("Power Off..."));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -149,6 +208,7 @@ StatusMenuButton.prototype = {
 | 
			
		||||
        item = new PopupMenu.PopupMenuItem(_("Lock Screen"));
 | 
			
		||||
        item.connect('activate', Lang.bind(this, this._onLockScreenActivate));
 | 
			
		||||
        this.menu.addMenuItem(item);
 | 
			
		||||
        this._lockScreenItem = item;
 | 
			
		||||
 | 
			
		||||
        item = new PopupMenu.PopupMenuItem(_("Switch User"));
 | 
			
		||||
        item.connect('activate', Lang.bind(this, this._onLoginScreenActivate));
 | 
			
		||||
@@ -158,9 +218,11 @@ StatusMenuButton.prototype = {
 | 
			
		||||
        item = new PopupMenu.PopupMenuItem(_("Log Out..."));
 | 
			
		||||
        item.connect('activate', Lang.bind(this, this._onQuitSessionActivate));
 | 
			
		||||
        this.menu.addMenuItem(item);
 | 
			
		||||
        this._logoutItem = item;
 | 
			
		||||
 | 
			
		||||
        item = new PopupMenu.PopupSeparatorMenuItem();
 | 
			
		||||
        this.menu.addMenuItem(item);
 | 
			
		||||
        this._sessionSeparator = item;
 | 
			
		||||
 | 
			
		||||
        item = new PopupMenu.PopupAlternatingMenuItem(_("Suspend"),
 | 
			
		||||
                                                      _("Power Off..."));
 | 
			
		||||
@@ -178,17 +240,19 @@ StatusMenuButton.prototype = {
 | 
			
		||||
 | 
			
		||||
    _onMyAccountActivate: function() {
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
        Util.spawnDesktop('gnome-user-accounts-panel');
 | 
			
		||||
        let app = Shell.AppSystem.get_default().get_app('gnome-user-accounts-panel.desktop');
 | 
			
		||||
        app.activate(-1);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onPreferencesActivate: function() {
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
        Util.spawnDesktop('gnome-control-center');
 | 
			
		||||
        let app = Shell.AppSystem.get_default().get_app('gnome-control-center.desktop');
 | 
			
		||||
        app.activate(-1);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onLockScreenActivate: function() {
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
        Util.spawn(['gnome-screensaver-command', '--lock']);
 | 
			
		||||
        this._screenSaverProxy.LockRemote();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onLoginScreenActivate: function() {
 | 
			
		||||
@@ -199,7 +263,7 @@ StatusMenuButton.prototype = {
 | 
			
		||||
 | 
			
		||||
    _onQuitSessionActivate: function() {
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
        Util.spawn(['gnome-session-quit', '--logout']);
 | 
			
		||||
        this._session.LogoutRemote(0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSuspendOrPowerOffActivate: function() {
 | 
			
		||||
@@ -207,9 +271,11 @@ StatusMenuButton.prototype = {
 | 
			
		||||
 | 
			
		||||
        if (this._haveSuspend &&
 | 
			
		||||
            this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) {
 | 
			
		||||
            this._upClient.suspend_sync(null);
 | 
			
		||||
            this._screenSaverProxy.LockRemote(Lang.bind(this, function() {
 | 
			
		||||
                this._upClient.suspend_sync(null);
 | 
			
		||||
            }));
 | 
			
		||||
        } else {
 | 
			
		||||
            Util.spawn(['gnome-session-quit', '--power-off']);
 | 
			
		||||
            this._session.ShutdownRemote();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,10 +7,13 @@ const Mainloop = imports.mainloop;
 | 
			
		||||
const Shell = imports.gi.Shell;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
const St = imports.gi.St;
 | 
			
		||||
const Tpl = imports.gi.TelepathyLogger;
 | 
			
		||||
const Tp = imports.gi.TelepathyGLib;
 | 
			
		||||
const Gettext = imports.gettext.domain('gnome-shell');
 | 
			
		||||
const _ = Gettext.gettext;
 | 
			
		||||
const C_ = Gettext.pgettext;
 | 
			
		||||
 | 
			
		||||
const History = imports.misc.history;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const MessageTray = imports.ui.messageTray;
 | 
			
		||||
 | 
			
		||||
@@ -21,6 +24,9 @@ const SCROLLBACK_RECENT_TIME = 15 * 60; // 15 minutes
 | 
			
		||||
const SCROLLBACK_RECENT_LENGTH = 20;
 | 
			
		||||
const SCROLLBACK_IDLE_LENGTH = 5;
 | 
			
		||||
 | 
			
		||||
// See Source._displayPendingMessages
 | 
			
		||||
const SCROLLBACK_HISTORY_LINES = 10;
 | 
			
		||||
 | 
			
		||||
const NotificationDirection = {
 | 
			
		||||
    SENT: 'chat-sent',
 | 
			
		||||
    RECEIVED: 'chat-received'
 | 
			
		||||
@@ -35,6 +41,31 @@ let contactFeatures = [Tp.ContactFeature.ALIAS,
 | 
			
		||||
// lets us see messages even if they belong to another app (eg,
 | 
			
		||||
// Empathy).
 | 
			
		||||
 | 
			
		||||
function makeMessageFromTpMessage(tpMessage, direction) {
 | 
			
		||||
    let [text, flags] = tpMessage.to_text();
 | 
			
		||||
    return {
 | 
			
		||||
        messageType: tpMessage.get_message_type(),
 | 
			
		||||
        text: text,
 | 
			
		||||
        sender: tpMessage.sender.alias,
 | 
			
		||||
        timestamp: tpMessage.get_received_timestamp(),
 | 
			
		||||
        direction: direction
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function makeMessageFromTplEvent(event) {
 | 
			
		||||
    let sent = event.get_sender().get_entity_type() == Tpl.EntityType.SELF;
 | 
			
		||||
    let direction = sent ? NotificationDirection.SENT : NotificationDirection.RECEIVED;
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        messageType: event.get_message_type(),
 | 
			
		||||
        text: event.get_message(),
 | 
			
		||||
        sender: event.get_sender().get_alias(),
 | 
			
		||||
        timestamp: event.get_timestamp(),
 | 
			
		||||
        direction: direction
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function Client() {
 | 
			
		||||
    this._init();
 | 
			
		||||
};
 | 
			
		||||
@@ -67,7 +98,22 @@ Client.prototype = {
 | 
			
		||||
 | 
			
		||||
    _observeChannels: function(observer, account, conn, channels,
 | 
			
		||||
                               dispatchOp, requests, context) {
 | 
			
		||||
        let connPath = conn.get_object_path();
 | 
			
		||||
        // If the self_contact doesn't have the ALIAS, make sure
 | 
			
		||||
        // to fetch it before trying to grab the channels.
 | 
			
		||||
        let self_contact = conn.get_self_contact();
 | 
			
		||||
        if (self_contact.has_feature(Tp.ContactFeature.ALIAS)) {
 | 
			
		||||
            this._finishObserveChannels(account, conn, channels, context);
 | 
			
		||||
        } else {
 | 
			
		||||
            Shell.get_self_contact_features(conn,
 | 
			
		||||
                                            contactFeatures.length, contactFeatures,
 | 
			
		||||
                                            Lang.bind(this, function() {
 | 
			
		||||
                                                this._finishObserveChannels(account, conn, channels, context);
 | 
			
		||||
                                            }));
 | 
			
		||||
            context.delay();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _finishObserveChannels: function(account, conn, channels, context) {
 | 
			
		||||
        let len = channels.length;
 | 
			
		||||
        for (let i = 0; i < len; i++) {
 | 
			
		||||
            let channel = channels[i];
 | 
			
		||||
@@ -90,7 +136,6 @@ Client.prototype = {
 | 
			
		||||
                    }), null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Allow dbus method to return
 | 
			
		||||
        context.accept();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -116,7 +161,7 @@ Source.prototype = {
 | 
			
		||||
    __proto__:  MessageTray.Source.prototype,
 | 
			
		||||
 | 
			
		||||
    _init: function(account, conn, channel, contact) {
 | 
			
		||||
        MessageTray.Source.prototype._init.call(this, channel.get_identifier());
 | 
			
		||||
        MessageTray.Source.prototype._init.call(this, contact.get_alias());
 | 
			
		||||
 | 
			
		||||
        this.isChat = true;
 | 
			
		||||
 | 
			
		||||
@@ -127,8 +172,6 @@ Source.prototype = {
 | 
			
		||||
        this._channel = channel;
 | 
			
		||||
        this._closedId = this._channel.connect('invalidated', Lang.bind(this, this._channelClosed));
 | 
			
		||||
 | 
			
		||||
        this._updateAlias();
 | 
			
		||||
 | 
			
		||||
        this._notification = new Notification(this);
 | 
			
		||||
        this._notification.setUrgency(MessageTray.Urgency.HIGH);
 | 
			
		||||
 | 
			
		||||
@@ -143,11 +186,18 @@ Source.prototype = {
 | 
			
		||||
        this._notifyAvatarId = this._contact.connect('notify::avatar-file', Lang.bind(this, this._updateAvatarIcon));
 | 
			
		||||
        this._presenceChangedId = this._contact.connect('presence-changed', Lang.bind(this, this._presenceChanged));
 | 
			
		||||
 | 
			
		||||
        this._displayPendingMessages();
 | 
			
		||||
        // Add ourselves as a source.
 | 
			
		||||
        Main.messageTray.add(this);
 | 
			
		||||
        this.pushNotification(this._notification);
 | 
			
		||||
 | 
			
		||||
        this._getLogMessages();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateAlias: function() {
 | 
			
		||||
        let oldAlias = this.title;
 | 
			
		||||
        this.title = this._contact.get_alias();
 | 
			
		||||
        this._notification.appendAliasChange(oldAlias, this.title);
 | 
			
		||||
        this.pushNotification(this._notification);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    createNotificationIcon: function() {
 | 
			
		||||
@@ -183,13 +233,52 @@ Source.prototype = {
 | 
			
		||||
        req.ensure_channel_async('', null, null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _displayPendingMessages: function() {
 | 
			
		||||
        let msgs = this._channel.get_pending_messages();
 | 
			
		||||
    _getLogMessages: function() {
 | 
			
		||||
        let logManager = Tpl.LogManager.dup_singleton();
 | 
			
		||||
        let entity = Tpl.Entity.new_from_tp_contact(this._contact, Tpl.EntityType.CONTACT);
 | 
			
		||||
        Shell.get_contact_events(logManager,
 | 
			
		||||
                                 this._account, entity,
 | 
			
		||||
                                 SCROLLBACK_HISTORY_LINES,
 | 
			
		||||
                                 Lang.bind(this, this._displayPendingMessages));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < msgs.length; i++) {
 | 
			
		||||
            let msg = msgs[i];
 | 
			
		||||
            this._messageReceived(this._channel, msg);
 | 
			
		||||
    _displayPendingMessages: function(logManager, result) {
 | 
			
		||||
        let [success, events] = logManager.get_filtered_events_finish(result);
 | 
			
		||||
 | 
			
		||||
        let logMessages = events.map(makeMessageFromTplEvent);
 | 
			
		||||
 | 
			
		||||
        let pendingTpMessages = this._channel.get_pending_messages();
 | 
			
		||||
        let pendingMessages = pendingTpMessages.map(function (tpMessage) { return makeMessageFromTpMessage(tpMessage, NotificationDirection.RECEIVED); });
 | 
			
		||||
 | 
			
		||||
        let showTimestamp = false;
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < logMessages.length; i++) {
 | 
			
		||||
            let logMessage = logMessages[i];
 | 
			
		||||
            let isPending = false;
 | 
			
		||||
 | 
			
		||||
            // Skip any log messages that are also in pendingMessages
 | 
			
		||||
            for (let j = 0; j < pendingMessages.length; j++) {
 | 
			
		||||
                let pending = pendingMessages[j];
 | 
			
		||||
                if (logMessage.timestamp == pending.timestamp && logMessage.text == pending.text) {
 | 
			
		||||
                    isPending = true;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!isPending) {
 | 
			
		||||
                showTimestamp = true;
 | 
			
		||||
                this._notification.appendMessage(logMessage, true, ['chat-log-message']);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (showTimestamp)
 | 
			
		||||
            this._notification.appendTimestamp();
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < pendingMessages.length; i++)
 | 
			
		||||
            this._notification.appendMessage(pendingMessages[i], true);
 | 
			
		||||
 | 
			
		||||
        if (pendingMessages.length > 0)
 | 
			
		||||
            this.notify();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _channelClosed: function() {
 | 
			
		||||
@@ -205,25 +294,32 @@ Source.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _messageReceived: function(channel, message) {
 | 
			
		||||
        this._notification.appendMessage(message, NotificationDirection.RECEIVED);
 | 
			
		||||
        message = makeMessageFromTpMessage(message, NotificationDirection.RECEIVED);
 | 
			
		||||
        this._notification.appendMessage(message);
 | 
			
		||||
        this.notify();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // This is called for both messages we send from
 | 
			
		||||
    // our client and other clients as well.
 | 
			
		||||
    _messageSent: function(channel, message, flags, token) {
 | 
			
		||||
        this._notification.appendMessage(message, NotificationDirection.SENT);
 | 
			
		||||
        message = makeMessageFromTpMessage(message, NotificationDirection.SENT);
 | 
			
		||||
        this._notification.appendMessage(message);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    notify: function() {
 | 
			
		||||
        if (!Main.messageTray.contains(this))
 | 
			
		||||
            Main.messageTray.add(this);
 | 
			
		||||
 | 
			
		||||
        MessageTray.Source.prototype.notify.call(this, this._notification);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    respond: function(text) {
 | 
			
		||||
        let msg = Tp.ClientMessage.new_text(Tp.ChannelTextMessageType.NORMAL, text);
 | 
			
		||||
        let type;
 | 
			
		||||
        if (text.slice(0, 4) == '/me ') {
 | 
			
		||||
            type = Tp.ChannelTextMessageType.ACTION;
 | 
			
		||||
            text = text.slice(4);
 | 
			
		||||
        } else {
 | 
			
		||||
            type = Tp.ChannelTextMessageType.NORMAL;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let msg = Tp.ClientMessage.new_text(type, text);
 | 
			
		||||
        this._channel.send_message_async(msg, 0, null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -279,19 +375,52 @@ Notification.prototype = {
 | 
			
		||||
        this._responseEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivated));
 | 
			
		||||
        this.setActionArea(this._responseEntry);
 | 
			
		||||
 | 
			
		||||
        this._oldMaxScrollAdjustment = 0;
 | 
			
		||||
        this._createScrollArea();
 | 
			
		||||
 | 
			
		||||
        this._scrollArea.vscroll.adjustment.connect('changed', Lang.bind(this, function(adjustment) {
 | 
			
		||||
            let currentValue = adjustment.value + adjustment.page_size;
 | 
			
		||||
            if (currentValue == this._oldMaxScrollAdjustment)
 | 
			
		||||
                this.scrollTo(St.Side.BOTTOM);
 | 
			
		||||
            this._oldMaxScrollAdjustment = adjustment.upper;
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._inputHistory = new History.HistoryManager({ entry: this._responseEntry.clutter_text });
 | 
			
		||||
 | 
			
		||||
        this._history = [];
 | 
			
		||||
        this._timestampTimeoutId = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    appendMessage: function(message, direction) {
 | 
			
		||||
        let [text, flags] = message.to_text();
 | 
			
		||||
        let timestamp = message.get_received_timestamp();
 | 
			
		||||
    /**
 | 
			
		||||
     * appendMessage:
 | 
			
		||||
     * @message: An object with the properties:
 | 
			
		||||
     *   text: the body of the message,
 | 
			
		||||
     *   messageType: a #Tp.ChannelTextMessageType,
 | 
			
		||||
     *   sender: the name of the sender,
 | 
			
		||||
     *   timestamp: the time the message was sent
 | 
			
		||||
     *   direction: a #NotificationDirection
 | 
			
		||||
     * 
 | 
			
		||||
     * @noTimestamp: Whether to add a timestamp. If %true, no timestamp
 | 
			
		||||
     *   will be added, regardless of the difference since the
 | 
			
		||||
     *   last timestamp
 | 
			
		||||
     * @styles: A list of CSS class names.
 | 
			
		||||
     */
 | 
			
		||||
    appendMessage: function(message, noTimestamp, styles) {
 | 
			
		||||
        let messageBody = GLib.markup_escape_text(message.text, -1);
 | 
			
		||||
        styles = styles || [];
 | 
			
		||||
        styles.push(message.direction);
 | 
			
		||||
 | 
			
		||||
        this.update(this.source.title, text, { customContent: true });
 | 
			
		||||
        this._append(text, direction, timestamp);
 | 
			
		||||
        if (message.messageType == Tp.ChannelTextMessageType.ACTION) {
 | 
			
		||||
            let senderAlias = GLib.markup_escape_text(message.sender, -1);
 | 
			
		||||
            messageBody = '<i>%s</i> %s'.format(senderAlias, messageBody);
 | 
			
		||||
            styles.push('chat-action');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.update(this.source.title, messageBody, { customContent: true, bannerMarkup: true });
 | 
			
		||||
        this._append(messageBody, styles, message.timestamp, noTimestamp);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _append: function(text, style, timestamp) {
 | 
			
		||||
    _append: function(text, styles, timestamp, noTimestamp) {
 | 
			
		||||
        let currentTime = (Date.now() / 1000);
 | 
			
		||||
        if (!timestamp)
 | 
			
		||||
            timestamp = currentTime;
 | 
			
		||||
@@ -303,20 +432,22 @@ Notification.prototype = {
 | 
			
		||||
        if (this._timestampTimeoutId)
 | 
			
		||||
            Mainloop.source_remove(this._timestampTimeoutId);
 | 
			
		||||
 | 
			
		||||
        let body = this.addBody(text);
 | 
			
		||||
        body.add_style_class_name(style);
 | 
			
		||||
        this.scrollTo(St.Side.BOTTOM);
 | 
			
		||||
        let body = this.addBody(text, true);
 | 
			
		||||
        for (let i = 0; i < styles.length; i ++)
 | 
			
		||||
            body.add_style_class_name(styles[i]);
 | 
			
		||||
 | 
			
		||||
        this._history.unshift({ actor: body, time: timestamp, realMessage: true });
 | 
			
		||||
 | 
			
		||||
        if (timestamp < currentTime - SCROLLBACK_IMMEDIATE_TIME)
 | 
			
		||||
            this._appendTimestamp();
 | 
			
		||||
        else
 | 
			
		||||
            // Schedule a new timestamp in SCROLLBACK_IMMEDIATE_TIME
 | 
			
		||||
            // from the timestamp of the message.
 | 
			
		||||
            this._timestampTimeoutId = Mainloop.timeout_add_seconds(
 | 
			
		||||
                SCROLLBACK_IMMEDIATE_TIME - (currentTime - timestamp),
 | 
			
		||||
                Lang.bind(this, this._appendTimestamp));
 | 
			
		||||
        if (!noTimestamp) {
 | 
			
		||||
            if (timestamp < currentTime - SCROLLBACK_IMMEDIATE_TIME)
 | 
			
		||||
                this.appendTimestamp();
 | 
			
		||||
            else
 | 
			
		||||
                // Schedule a new timestamp in SCROLLBACK_IMMEDIATE_TIME
 | 
			
		||||
                // from the timestamp of the message.
 | 
			
		||||
                this._timestampTimeoutId = Mainloop.timeout_add_seconds(
 | 
			
		||||
                    SCROLLBACK_IMMEDIATE_TIME - (currentTime - timestamp),
 | 
			
		||||
                    Lang.bind(this, this.appendTimestamp));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._history.length > 1) {
 | 
			
		||||
            // Keep the scrollback from growing too long. If the most
 | 
			
		||||
@@ -337,15 +468,39 @@ Notification.prototype = {
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _appendTimestamp: function() {
 | 
			
		||||
    _formatTimestamp: function(date) {
 | 
			
		||||
        let now = new Date();
 | 
			
		||||
 | 
			
		||||
        var daysAgo = (now.getTime() - date.getTime()) / (24 * 60 * 60 * 1000);
 | 
			
		||||
 | 
			
		||||
        // Show a week day and time if date is in the last week
 | 
			
		||||
        if (daysAgo < 1 || (daysAgo < 7 && now.getDay() != date.getDay())) {
 | 
			
		||||
            /* Translators: this is a time format string followed by a date.
 | 
			
		||||
             If applicable, replace %X with a strftime format valid for your
 | 
			
		||||
             locale, without seconds. */
 | 
			
		||||
            // xgettext:no-c-format
 | 
			
		||||
            format = _("Sent at %X on %A");
 | 
			
		||||
 | 
			
		||||
        // FIXME: The next two are stolen from calendar.js with the comment to avoid
 | 
			
		||||
        // a string-freeze break. They should be replaced with better strings
 | 
			
		||||
        // with 'Sent at', appropriate context and appropriate translator comment.
 | 
			
		||||
 | 
			
		||||
        } else if (date.getYear() == now.getYear()) {
 | 
			
		||||
            /* Translators: Shown on calendar heading when selected day occurs on current year */
 | 
			
		||||
            format = C_("calendar heading", "%A, %B %d");
 | 
			
		||||
        } else {
 | 
			
		||||
            /* Translators: Shown on calendar heading when selected day occurs on different year */
 | 
			
		||||
            format = C_("calendar heading", "%A, %B %d, %Y");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return date.toLocaleFormat(format);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    appendTimestamp: function() {
 | 
			
		||||
        let lastMessageTime = this._history[0].time;
 | 
			
		||||
        let lastMessageDate = new Date(lastMessageTime * 1000);
 | 
			
		||||
 | 
			
		||||
        /* Translators: this is a time format string followed by a date.
 | 
			
		||||
           If applicable, replace %X with a strftime format valid for your
 | 
			
		||||
           locale, without seconds. */
 | 
			
		||||
        // xgettext:no-c-format
 | 
			
		||||
        let timeLabel = this.addBody(lastMessageDate.toLocaleFormat(_("Sent at %X on %A")), false, { expand: true, x_fill: false, x_align: St.Align.END });
 | 
			
		||||
        let timeLabel = this.addBody(this._formatTimestamp(lastMessageDate), false, { expand: true, x_fill: false, x_align: St.Align.END });
 | 
			
		||||
        timeLabel.add_style_class_name('chat-meta-message');
 | 
			
		||||
        this._history.unshift({ actor: timeLabel, time: lastMessageTime, realMessage: false });
 | 
			
		||||
 | 
			
		||||
@@ -363,11 +518,28 @@ Notification.prototype = {
 | 
			
		||||
        this._history.unshift({ actor: label, time: (Date.now() / 1000), realMessage: false});
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    appendAliasChange: function(oldAlias, newAlias) {
 | 
			
		||||
        // FIXME: uncomment this after 3.0 string freeze ends
 | 
			
		||||
 | 
			
		||||
        // oldAlias = GLib.markup_escape_text(oldAlias, -1);
 | 
			
		||||
        // newAlias = GLib.markup_escape_text(newAlias, -1);
 | 
			
		||||
 | 
			
		||||
        // /* Translators: this is the other person changing their old IM name to their new
 | 
			
		||||
        //    IM name. */
 | 
			
		||||
        // let message = '<i>' + _("%s is now known as %s").format(oldAlias, newAlias) + '</i>';
 | 
			
		||||
        // let label = this.addBody(message, true);
 | 
			
		||||
        // label.add_style_class_name('chat-meta-message');
 | 
			
		||||
        // this._history.unshift({ actor: label, time: (Date.now() / 1000), realMessage: false });
 | 
			
		||||
        // this.update(newAlias, null, { customContent: true });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onEntryActivated: function() {
 | 
			
		||||
        let text = this._responseEntry.get_text();
 | 
			
		||||
        if (text == '')
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._inputHistory.addItem(text);
 | 
			
		||||
 | 
			
		||||
        // Telepathy sends out the Sent signal for us.
 | 
			
		||||
        // see Source._messageSent
 | 
			
		||||
        this._responseEntry.set_text('');
 | 
			
		||||
 
 | 
			
		||||
@@ -41,11 +41,14 @@ BaseTab.prototype = {
 | 
			
		||||
        this.visible = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    show: function() {
 | 
			
		||||
    show: function(animate) {
 | 
			
		||||
        this.visible = true;
 | 
			
		||||
        this.page.opacity = 0;
 | 
			
		||||
        this.page.show();
 | 
			
		||||
 | 
			
		||||
        if (!animate)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this.page.opacity = 0;
 | 
			
		||||
        Tweener.addTween(this.page,
 | 
			
		||||
                         { opacity: 255,
 | 
			
		||||
                           time: 0.1,
 | 
			
		||||
@@ -77,14 +80,16 @@ BaseTab.prototype = {
 | 
			
		||||
Signals.addSignalMethods(BaseTab.prototype);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function ViewTab(label, pageActor, a11yIcon) {
 | 
			
		||||
    this._init(label, pageActor, a11yIcon);
 | 
			
		||||
function ViewTab(id, label, pageActor, a11yIcon) {
 | 
			
		||||
    this._init(id, label, pageActor, a11yIcon);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ViewTab.prototype = {
 | 
			
		||||
    __proto__: BaseTab.prototype,
 | 
			
		||||
 | 
			
		||||
    _init: function(label, pageActor, a11yIcon) {
 | 
			
		||||
    _init: function(id, label, pageActor, a11yIcon) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
 | 
			
		||||
        let titleActor = new St.Button({ label: label,
 | 
			
		||||
                                         style_class: 'view-tab-title' });
 | 
			
		||||
        titleActor.connect('clicked', Lang.bind(this, this._activate));
 | 
			
		||||
@@ -285,7 +290,7 @@ SearchTab.prototype = {
 | 
			
		||||
    _doSearch: function () {
 | 
			
		||||
        this._searchTimeoutId = 0;
 | 
			
		||||
        let text = this._text.get_text().replace(/^\s+/g, '').replace(/\s+$/g, '');
 | 
			
		||||
        this._searchResults.updateSearch(text);
 | 
			
		||||
        this._searchResults.doSearch(text);
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
@@ -383,14 +388,16 @@ ViewSelector.prototype = {
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addViewTab: function(title, pageActor, a11yIcon) {
 | 
			
		||||
        let viewTab = new ViewTab(title, pageActor, a11yIcon);
 | 
			
		||||
    addViewTab: function(id, title, pageActor, a11yIcon) {
 | 
			
		||||
        let viewTab = new ViewTab(id, title, pageActor, a11yIcon);
 | 
			
		||||
        this._tabs.push(viewTab);
 | 
			
		||||
        this._tabBox.add(viewTab.title);
 | 
			
		||||
        this._addTab(viewTab);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _switchTab: function(tab) {
 | 
			
		||||
        let firstSwitch = this._activeTab == null;
 | 
			
		||||
 | 
			
		||||
        if (this._activeTab && this._activeTab.visible) {
 | 
			
		||||
            if (this._activeTab == tab)
 | 
			
		||||
                return;
 | 
			
		||||
@@ -406,11 +413,13 @@ ViewSelector.prototype = {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Only fade when switching between tabs,
 | 
			
		||||
        // not when setting the initially selected one.
 | 
			
		||||
        if (!tab.visible)
 | 
			
		||||
            tab.show();
 | 
			
		||||
            tab.show(!firstSwitch);
 | 
			
		||||
 | 
			
		||||
        // Pull a Meg Ryan:
 | 
			
		||||
        if (Main.overview && Main.overview.workspaces) {
 | 
			
		||||
        if (!firstSwitch && Main.overview.workspaces) {
 | 
			
		||||
            if (tab != this._tabs[0]) {
 | 
			
		||||
                Tweener.addTween(Main.overview.workspaces.actor,
 | 
			
		||||
                                 { opacity: 0,
 | 
			
		||||
@@ -433,6 +442,14 @@ ViewSelector.prototype = {
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    switchTab: function(id) {
 | 
			
		||||
        for (let i = 0; i < this._tabs.length; i++)
 | 
			
		||||
            if (this._tabs[i].id == id) {
 | 
			
		||||
                this._switchTab(this._tabs[i]);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _switchDefaultTab: function() {
 | 
			
		||||
        if (this._tabs.length > 0)
 | 
			
		||||
            this._switchTab(this._tabs[0]);
 | 
			
		||||
 
 | 
			
		||||
@@ -93,6 +93,8 @@ WindowManager.prototype = {
 | 
			
		||||
 | 
			
		||||
        this._dimmedWindows = [];
 | 
			
		||||
 | 
			
		||||
        this._animationBlockCount = 0;
 | 
			
		||||
 | 
			
		||||
        this._switchData = null;
 | 
			
		||||
        this._shellwm.connect('kill-switch-workspace', Lang.bind(this, this._switchWorkspaceDone));
 | 
			
		||||
        this._shellwm.connect('kill-window-effects', Lang.bind(this, function (shellwm, actor) {
 | 
			
		||||
@@ -121,11 +123,11 @@ WindowManager.prototype = {
 | 
			
		||||
 | 
			
		||||
        Main.overview.connect('showing', Lang.bind(this, function() {
 | 
			
		||||
            for (let i = 0; i < this._dimmedWindows.length; i++)
 | 
			
		||||
                this._undimParentWindow(this._dimmedWindows[i], true);
 | 
			
		||||
                this._undimWindow(this._dimmedWindows[i], true);
 | 
			
		||||
        }));
 | 
			
		||||
        Main.overview.connect('hiding', Lang.bind(this, function() {
 | 
			
		||||
            for (let i = 0; i < this._dimmedWindows.length; i++)
 | 
			
		||||
                this._dimParentWindow(this._dimmedWindows[i], true);
 | 
			
		||||
                this._dimWindow(this._dimmedWindows[i], true);
 | 
			
		||||
        }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -139,8 +141,16 @@ WindowManager.prototype = {
 | 
			
		||||
            this._shellwm.connect('keybinding::' + keybinding, handler);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    blockAnimations: function() {
 | 
			
		||||
        this._animationBlockCount++;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    unblockAnimations: function() {
 | 
			
		||||
        this._animationBlockCount = Math.max(0, this._animationBlockCount - 1);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _shouldAnimate : function(actor) {
 | 
			
		||||
        if (Main.overview.visible)
 | 
			
		||||
        if (Main.overview.visible || this._animationsBlocked > 0)
 | 
			
		||||
            return false;
 | 
			
		||||
        if (actor && (actor.meta_window.get_window_type() != Meta.WindowType.NORMAL))
 | 
			
		||||
            return false;
 | 
			
		||||
@@ -224,41 +234,39 @@ WindowManager.prototype = {
 | 
			
		||||
    _unmaximizeWindowDone : function(shellwm, actor) {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _parentHasOtherAttachedDialog: function(parent, self) {
 | 
			
		||||
    _hasAttachedDialogs: function(window, ignoreWindow) {
 | 
			
		||||
        var count = 0;
 | 
			
		||||
        parent.foreach_transient(function(win) {
 | 
			
		||||
            if (win.get_window_type() == Meta.WindowType.MODAL_DIALOG && win != self)
 | 
			
		||||
        window.foreach_transient(function(win) {
 | 
			
		||||
            if (win != ignoreWindow && win.get_window_type() == Meta.WindowType.MODAL_DIALOG)
 | 
			
		||||
                count++;
 | 
			
		||||
            return false;
 | 
			
		||||
        });
 | 
			
		||||
        return count != 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _markParentWindowAsDimmable: function(actor, animate) {
 | 
			
		||||
        if (Meta.prefs_get_attach_modal_dialogs()) {
 | 
			
		||||
            this._dimmedWindows.push(actor);
 | 
			
		||||
            if (this._shouldAnimate())
 | 
			
		||||
                this._dimParentWindow(actor, animate);
 | 
			
		||||
    _checkDimming: function(window, ignoreWindow) {
 | 
			
		||||
        let shouldDim = Meta.prefs_get_attach_modal_dialogs() && this._hasAttachedDialogs(window, ignoreWindow);
 | 
			
		||||
 | 
			
		||||
        if (shouldDim && !window._dimmed) {
 | 
			
		||||
            window._dimmed = true;
 | 
			
		||||
            this._dimmedWindows.push(window);
 | 
			
		||||
            if (!Main.overview.visible)
 | 
			
		||||
                this._dimWindow(window, true);
 | 
			
		||||
        } else if (!shouldDim && window._dimmed) {
 | 
			
		||||
            window._dimmed = false;
 | 
			
		||||
            this._dimmedWindows = this._dimmedWindows.filter(function(win) {
 | 
			
		||||
                                                                 return win != window;
 | 
			
		||||
                                                             });
 | 
			
		||||
            if (!Main.overview.visible)
 | 
			
		||||
                this._undimWindow(window, true);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _unmarkParentWindowAsDimmable: function(actor, animate) {
 | 
			
		||||
        if (!Main.overview.visible)
 | 
			
		||||
            this._undimParentWindow(actor, true);
 | 
			
		||||
        this._dimmedWindows = this._dimmedWindows.filter(function(win) {
 | 
			
		||||
            return win != actor;
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _dimParentWindow: function(actor, animate) {
 | 
			
		||||
        let meta = actor.get_meta_window();
 | 
			
		||||
        let parent = meta.get_transient_for();
 | 
			
		||||
        if (!parent)
 | 
			
		||||
    _dimWindow: function(window, animate) {
 | 
			
		||||
        let actor = window.get_compositor_private();
 | 
			
		||||
        if (!actor)
 | 
			
		||||
            return;
 | 
			
		||||
        let parentActor = parent.get_compositor_private();
 | 
			
		||||
        if (!parentActor || this._parentHasOtherAttachedDialog(parent, meta))
 | 
			
		||||
            return;
 | 
			
		||||
        let texture = parentActor.get_texture();
 | 
			
		||||
        let texture = actor.get_texture();
 | 
			
		||||
        if (animate)
 | 
			
		||||
            Tweener.addTween(getWindowDimmer(texture),
 | 
			
		||||
                             { dimFraction: 1.0,
 | 
			
		||||
@@ -269,15 +277,11 @@ WindowManager.prototype = {
 | 
			
		||||
            getWindowDimmer(texture).dimFraction = 1.0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _undimParentWindow: function(actor, animate) {
 | 
			
		||||
        let meta = actor.get_meta_window();
 | 
			
		||||
        let parent = meta.get_transient_for();
 | 
			
		||||
        if (!parent)
 | 
			
		||||
    _undimWindow: function(window, animate) {
 | 
			
		||||
        let actor = window.get_compositor_private();
 | 
			
		||||
        if (!actor)
 | 
			
		||||
            return;
 | 
			
		||||
        let parentActor = parent.get_compositor_private();
 | 
			
		||||
        if (!parentActor || this._parentHasOtherAttachedDialog(parent, meta))
 | 
			
		||||
            return;
 | 
			
		||||
        let texture = parentActor.get_texture();
 | 
			
		||||
        let texture = actor.get_texture();
 | 
			
		||||
        if (animate)
 | 
			
		||||
            Tweener.addTween(getWindowDimmer(texture),
 | 
			
		||||
                             { dimFraction: 0.0,
 | 
			
		||||
@@ -294,17 +298,19 @@ WindowManager.prototype = {
 | 
			
		||||
            let type = actor.meta_window.get_window_type();
 | 
			
		||||
            if (type == actor._windowType)
 | 
			
		||||
                return;
 | 
			
		||||
            if (type == Meta.WindowType.MODAL_DIALOG)
 | 
			
		||||
                this._markParentWindowAsDimmable(actor, true);
 | 
			
		||||
            else if (actor._windowType == Meta.WindowType.MODAL_DIALOG)
 | 
			
		||||
                this._unmarkParentWindowAsDimmable(actor, true);
 | 
			
		||||
            if (type == Meta.WindowType.MODAL_DIALOG ||
 | 
			
		||||
                actor._windowType == Meta.WindowType.MODAL_DIALOG) {
 | 
			
		||||
                let parent = actor.get_meta_window().get_transient_for();
 | 
			
		||||
                if (parent)
 | 
			
		||||
                    this._checkDimming(parent);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            actor._windowType = type;
 | 
			
		||||
        }));
 | 
			
		||||
        if (actor.meta_window.get_window_type() == Meta.WindowType.MODAL_DIALOG
 | 
			
		||||
            && Meta.prefs_get_attach_modal_dialogs()
 | 
			
		||||
            && actor.get_meta_window().get_transient_for()) {
 | 
			
		||||
            this._markParentWindowAsDimmable(actor, true);
 | 
			
		||||
            this._checkDimming(actor.get_meta_window().get_transient_for());
 | 
			
		||||
            if (this._shouldAnimate()) {
 | 
			
		||||
                actor.set_scale(1.0, 0.0);
 | 
			
		||||
                actor.show();
 | 
			
		||||
@@ -364,14 +370,20 @@ WindowManager.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _destroyWindow : function(shellwm, actor) {
 | 
			
		||||
        let parent = actor.meta_window.get_transient_for();
 | 
			
		||||
        let window = actor.meta_window;
 | 
			
		||||
        let parent = window.get_transient_for();
 | 
			
		||||
        if (actor._notifyWindowTypeSignalId) {
 | 
			
		||||
            actor.meta_window.disconnect(actor._notifyWindowTypeSignalId);
 | 
			
		||||
            window.disconnect(actor._notifyWindowTypeSignalId);
 | 
			
		||||
            actor._notifyWindowTypeSignalId = 0;
 | 
			
		||||
        }
 | 
			
		||||
        while (actor.meta_window.get_window_type() == Meta.WindowType.MODAL_DIALOG
 | 
			
		||||
        if (window._dimmed) {
 | 
			
		||||
            this._dimmedWindows = this._dimmedWindows.filter(function(win) {
 | 
			
		||||
                                                                 return win != window;
 | 
			
		||||
                                                             });
 | 
			
		||||
        }
 | 
			
		||||
        while (window.get_window_type() == Meta.WindowType.MODAL_DIALOG
 | 
			
		||||
               && parent) {
 | 
			
		||||
            this._unmarkParentWindowAsDimmable(actor, true);
 | 
			
		||||
            this._checkDimming(parent, window);
 | 
			
		||||
            if (!Meta.prefs_get_attach_modal_dialogs()
 | 
			
		||||
                || !this._shouldAnimate())
 | 
			
		||||
                break;
 | 
			
		||||
 
 | 
			
		||||
@@ -125,6 +125,7 @@ WindowClone.prototype = {
 | 
			
		||||
                                              dragActorMaxSize: WINDOW_DND_SIZE,
 | 
			
		||||
                                              dragActorOpacity: DRAGGING_WINDOW_OPACITY });
 | 
			
		||||
        this._draggable.connect('drag-begin', Lang.bind(this, this._onDragBegin));
 | 
			
		||||
        this._draggable.connect('drag-cancelled', Lang.bind(this, this._onDragCancelled));
 | 
			
		||||
        this._draggable.connect('drag-end', Lang.bind(this, this._onDragEnd));
 | 
			
		||||
        this.inDrag = false;
 | 
			
		||||
 | 
			
		||||
@@ -220,8 +221,15 @@ WindowClone.prototype = {
 | 
			
		||||
 | 
			
		||||
        let [width, height] = this.actor.get_transformed_size();
 | 
			
		||||
 | 
			
		||||
        this.actor.x = _clamp(this.actor.x, 0, global.screen_width  - width);
 | 
			
		||||
        this.actor.y = _clamp(this.actor.y, Panel.PANEL_HEIGHT, global.screen_height - height);
 | 
			
		||||
        let monitorIndex = this.metaWindow.get_monitor();
 | 
			
		||||
        let availArea = global.get_monitors()[monitorIndex];
 | 
			
		||||
        if (monitorIndex == global.get_primary_monitor_index()) {
 | 
			
		||||
            availArea.y += Main.panel.actor.height;
 | 
			
		||||
            availArea.height -= Main.panel.actor.height;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.actor.x = _clamp(this.actor.x, availArea.x, availArea.x + availArea.width - width);
 | 
			
		||||
        this.actor.y = _clamp(this.actor.y, availArea.y, availArea.y + availArea.height - height);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _zoomStart : function () {
 | 
			
		||||
@@ -288,10 +296,16 @@ WindowClone.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragBegin : function (draggable, time) {
 | 
			
		||||
        [this.dragOrigX, this.dragOrigY] = this.actor.get_position();
 | 
			
		||||
        this.dragOrigScale = this.actor.scale_x;
 | 
			
		||||
        this.inDrag = true;
 | 
			
		||||
        this.emit('drag-begin');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragCancelled : function (draggable, time) {
 | 
			
		||||
        this.emit('drag-cancelled');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragEnd : function (draggable, time, snapback) {
 | 
			
		||||
        this.inDrag = false;
 | 
			
		||||
 | 
			
		||||
@@ -327,6 +341,7 @@ WindowOverlay.prototype = {
 | 
			
		||||
 | 
			
		||||
        this._windowClone = windowClone;
 | 
			
		||||
        this._parentActor = parentActor;
 | 
			
		||||
        this._hidden = false;
 | 
			
		||||
 | 
			
		||||
        let title = new St.Label({ style_class: 'window-caption',
 | 
			
		||||
                                   text: metaWindow.title });
 | 
			
		||||
@@ -372,23 +387,19 @@ WindowOverlay.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hide: function() {
 | 
			
		||||
        this._hidden = true;
 | 
			
		||||
        this.closeButton.hide();
 | 
			
		||||
        this.title.hide();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    show: function() {
 | 
			
		||||
        let [x, y, mask] = global.get_pointer();
 | 
			
		||||
        let actor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE,
 | 
			
		||||
                                                  x, y);
 | 
			
		||||
        if (actor == this._windowClone.actor) {
 | 
			
		||||
            this.closeButton.show();
 | 
			
		||||
        }
 | 
			
		||||
        this._hidden = false;
 | 
			
		||||
        this.title.show();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    fadeIn: function() {
 | 
			
		||||
        this.show();
 | 
			
		||||
        this.title.opacity = 0;
 | 
			
		||||
        this.title.show();
 | 
			
		||||
        this._parentActor.raise_top();
 | 
			
		||||
        Tweener.addTween(this.title,
 | 
			
		||||
                        { opacity: 255,
 | 
			
		||||
@@ -480,6 +491,12 @@ WindowOverlay.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onEnter: function() {
 | 
			
		||||
        // We might get enter events on the clone while the overlay is
 | 
			
		||||
        // hidden, e.g. during animations, we ignore these events,
 | 
			
		||||
        // as the close button will be shown as needed when the overlays
 | 
			
		||||
        // are shown again
 | 
			
		||||
        if (this._hidden)
 | 
			
		||||
            return;
 | 
			
		||||
        this._parentActor.raise_top();
 | 
			
		||||
        this.closeButton.show();
 | 
			
		||||
        this.emit('show-close-button');
 | 
			
		||||
@@ -520,44 +537,45 @@ WindowOverlay.prototype = {
 | 
			
		||||
Signals.addSignalMethods(WindowOverlay.prototype);
 | 
			
		||||
 | 
			
		||||
const WindowPositionFlags = {
 | 
			
		||||
    ZOOM: 1 << 0,
 | 
			
		||||
    INITIAL: 1 << 0,
 | 
			
		||||
    ANIMATE: 1 << 1
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @metaWorkspace: a #Meta.Workspace
 | 
			
		||||
 * @metaWorkspace: a #Meta.Workspace, or null
 | 
			
		||||
 */
 | 
			
		||||
function Workspace(metaWorkspace) {
 | 
			
		||||
    this._init(metaWorkspace);
 | 
			
		||||
function Workspace(metaWorkspace, monitorIndex) {
 | 
			
		||||
    this._init(metaWorkspace, monitorIndex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Workspace.prototype = {
 | 
			
		||||
    _init : function(metaWorkspace) {
 | 
			
		||||
    _init : function(metaWorkspace, monitorIndex) {
 | 
			
		||||
        // When dragging a window, we use this slot for reserve space.
 | 
			
		||||
        this._reservedSlot = null;
 | 
			
		||||
        this.metaWorkspace = metaWorkspace;
 | 
			
		||||
        this._x = 0;
 | 
			
		||||
        this._y = 0;
 | 
			
		||||
        this._width = 0;
 | 
			
		||||
        this._height = 0;
 | 
			
		||||
 | 
			
		||||
        this.monitorIndex = monitorIndex;
 | 
			
		||||
        this._monitor = global.get_monitors()[this.monitorIndex];
 | 
			
		||||
        this._windowOverlaysGroup = new Clutter.Group();
 | 
			
		||||
        // Without this the drop area will be overlapped.
 | 
			
		||||
        this._windowOverlaysGroup.set_size(0, 0);
 | 
			
		||||
 | 
			
		||||
        this.actor = new Clutter.Group();
 | 
			
		||||
        this.actor._delegate = this;
 | 
			
		||||
        this.actor.set_size(0, 0);
 | 
			
		||||
 | 
			
		||||
        this._dropRect = new Clutter.Rectangle({ opacity: 0 });
 | 
			
		||||
        this._dropRect._delegate = this;
 | 
			
		||||
 | 
			
		||||
        this.actor.add_actor(this._dropRect);
 | 
			
		||||
        this.actor.add_actor(this._windowOverlaysGroup);
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
 | 
			
		||||
 | 
			
		||||
        // Items in _windowOverlaysGroup should not be scaled, so we don't
 | 
			
		||||
        // add them to this.actor, but to its parent whenever it changes
 | 
			
		||||
        this.actor.connect('parent-set', Lang.bind(this, this._onParentSet));
 | 
			
		||||
 | 
			
		||||
        // Auto-sizing is unreliable in the presence of ClutterClone, so rather than
 | 
			
		||||
        // implicitly counting on the workspace actor to be sized to the size of the
 | 
			
		||||
        // included desktop actor clone, set the size explicitly to the screen size.
 | 
			
		||||
        // See http://bugzilla.openedhand.com/show_bug.cgi?id=1755
 | 
			
		||||
        this.actor.width = global.screen_width;
 | 
			
		||||
        this.actor.height = global.screen_height;
 | 
			
		||||
        this.scale = 1.0;
 | 
			
		||||
 | 
			
		||||
        let windows = Main.getWindowActorsForWorkspace(this.metaWorkspace.index());
 | 
			
		||||
        let windows = global.get_window_actors().filter(this._isMyWindow, this);
 | 
			
		||||
 | 
			
		||||
        // Create clones for windows that should be
 | 
			
		||||
        // visible in the Overview
 | 
			
		||||
@@ -570,15 +588,37 @@ Workspace.prototype = {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Track window changes
 | 
			
		||||
        this._windowAddedId = this.metaWorkspace.connect('window-added',
 | 
			
		||||
                                                          Lang.bind(this, this._windowAdded));
 | 
			
		||||
        this._windowRemovedId = this.metaWorkspace.connect('window-removed',
 | 
			
		||||
                                                            Lang.bind(this, this._windowRemoved));
 | 
			
		||||
        if (this.metaWorkspace) {
 | 
			
		||||
            this._windowAddedId = this.metaWorkspace.connect('window-added',
 | 
			
		||||
                                                             Lang.bind(this, this._windowAdded));
 | 
			
		||||
            this._windowRemovedId = this.metaWorkspace.connect('window-removed',
 | 
			
		||||
                                                               Lang.bind(this, this._windowRemoved));
 | 
			
		||||
        }
 | 
			
		||||
        this._windowEnteredMonitorId = global.screen.connect('window-entered-monitor',
 | 
			
		||||
                                                           Lang.bind(this, this._windowEnteredMonitor));
 | 
			
		||||
        this._windowLeftMonitorId = global.screen.connect('window-left-monitor',
 | 
			
		||||
                                                           Lang.bind(this, this._windowLeftMonitor));
 | 
			
		||||
        this._repositionWindowsId = 0;
 | 
			
		||||
 | 
			
		||||
        this.leavingOverview = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setGeometry: function(x, y, width, height) {
 | 
			
		||||
        this._x = x;
 | 
			
		||||
        this._y = y;
 | 
			
		||||
        this._width = width;
 | 
			
		||||
        this._height = height;
 | 
			
		||||
 | 
			
		||||
        // This is sometimes called during allocation, so we do this later
 | 
			
		||||
        Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
 | 
			
		||||
            function () {
 | 
			
		||||
                this._dropRect.set_position(x, y);
 | 
			
		||||
                this._dropRect.set_size(width, height);
 | 
			
		||||
                return false;
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _lookupIndex: function (metaWindow) {
 | 
			
		||||
        for (let i = 0; i < this._windows.length; i++) {
 | 
			
		||||
            if (this._windows[i].metaWindow == metaWindow) {
 | 
			
		||||
@@ -588,17 +628,6 @@ Workspace.prototype = {
 | 
			
		||||
        return -1;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onParentSet: function(actor, old_parent) {
 | 
			
		||||
        let new_parent = this.actor.get_parent();
 | 
			
		||||
        if (new_parent == null)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (old_parent)
 | 
			
		||||
            this._windowOverlaysGroup.reparent(new_parent);
 | 
			
		||||
        else
 | 
			
		||||
            new_parent.add_actor(this._windowOverlaysGroup);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    containsMetaWindow: function (metaWindow) {
 | 
			
		||||
        return this._lookupIndex(metaWindow) >= 0;
 | 
			
		||||
    },
 | 
			
		||||
@@ -677,10 +706,20 @@ Workspace.prototype = {
 | 
			
		||||
        let xDelta, yDelta, distanceSquared;
 | 
			
		||||
        let actorWidth, actorHeight;
 | 
			
		||||
 | 
			
		||||
        actorWidth = actor.width * actor.scale_x;
 | 
			
		||||
        actorHeight = actor.height * actor.scale_y;
 | 
			
		||||
        xDelta = actor.x + actorWidth / 2.0 - xCenter * global.screen_width;
 | 
			
		||||
        yDelta = actor.y + actorHeight / 2.0 - yCenter * global.screen_height;
 | 
			
		||||
        let x = actor.x;
 | 
			
		||||
        let y = actor.y;
 | 
			
		||||
        let scale = actor.scale_x;
 | 
			
		||||
 | 
			
		||||
        if (actor._delegate.inDrag) {
 | 
			
		||||
            x = actor._delegate.dragOrigX;
 | 
			
		||||
            y = actor._delegate.dragOrigY;
 | 
			
		||||
            scale = actor._delegate.dragOrigScale;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        actorWidth = actor.width * scale;
 | 
			
		||||
        actorHeight = actor.height * scale;
 | 
			
		||||
        xDelta = x + actorWidth / 2.0 - xCenter * this._width - this._x;
 | 
			
		||||
        yDelta = y + actorHeight / 2.0 - yCenter * this._height - this._y;
 | 
			
		||||
        distanceSquared = xDelta * xDelta + yDelta * yDelta;
 | 
			
		||||
 | 
			
		||||
        return distanceSquared;
 | 
			
		||||
@@ -705,6 +744,12 @@ Workspace.prototype = {
 | 
			
		||||
                let delta = this._computeWindowMotion(cloneActor, slot);
 | 
			
		||||
 | 
			
		||||
                motion += delta;
 | 
			
		||||
 | 
			
		||||
                // Bail out early if we're already larger than the
 | 
			
		||||
                // previous best
 | 
			
		||||
                if (minimumMotionPermutation != null &&
 | 
			
		||||
                    motion > minimumMotion)
 | 
			
		||||
                    continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (minimumMotionPermutation == null || motion < minimumMotion) {
 | 
			
		||||
@@ -765,38 +810,35 @@ Workspace.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * _getSlotRelativeGeometry:
 | 
			
		||||
     * _getSlotGeometry:
 | 
			
		||||
     * @slot: A layout slot
 | 
			
		||||
     *
 | 
			
		||||
     * Returns: the workspace-relative [x, y, width, height]
 | 
			
		||||
     * Returns: the screen-relative [x, y, width, height]
 | 
			
		||||
     * of a given window layout slot.
 | 
			
		||||
     */
 | 
			
		||||
    _getSlotRelativeGeometry: function(slot) {
 | 
			
		||||
    _getSlotGeometry: function(slot) {
 | 
			
		||||
        let [xCenter, yCenter, fraction] = slot;
 | 
			
		||||
 | 
			
		||||
        let width = global.screen_width * fraction;
 | 
			
		||||
        let height = global.screen_height * fraction;
 | 
			
		||||
        let width = this._width * fraction;
 | 
			
		||||
        let height = this._height * fraction;
 | 
			
		||||
 | 
			
		||||
        let x = xCenter * global.screen_width - width / 2;
 | 
			
		||||
        let y = yCenter * global.screen_height - height / 2;
 | 
			
		||||
        let x = this._x + xCenter * this._width - width / 2 ;
 | 
			
		||||
        let y = this._y + yCenter * this._height - height / 2;
 | 
			
		||||
 | 
			
		||||
        return [x, y, width, height];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * _computeWindowRelativeLayout:
 | 
			
		||||
     * _computeWindowLayout:
 | 
			
		||||
     * @metaWindow: A #MetaWindow
 | 
			
		||||
     * @slot: A layout slot
 | 
			
		||||
     *
 | 
			
		||||
     * Given a window and slot to fit it in, compute its
 | 
			
		||||
     * workspace-relative [x, y, scale] where scale applies
 | 
			
		||||
     * screen-relative [x, y, scale] where scale applies
 | 
			
		||||
     * to both X and Y directions.
 | 
			
		||||
     */
 | 
			
		||||
    _computeWindowRelativeLayout: function(metaWindow, slot) {
 | 
			
		||||
        let [xCenter, yCenter, fraction] = slot;
 | 
			
		||||
        let [x, y, width, height] = this._getSlotRelativeGeometry(slot);
 | 
			
		||||
 | 
			
		||||
        xCenter = xCenter * global.screen_width;
 | 
			
		||||
    _computeWindowLayout: function(metaWindow, slot) {
 | 
			
		||||
        let [x, y, width, height] = this._getSlotGeometry(slot);
 | 
			
		||||
 | 
			
		||||
        let rect = metaWindow.get_outer_rect();
 | 
			
		||||
        let buttonOuterHeight, captionHeight;
 | 
			
		||||
@@ -804,23 +846,19 @@ Workspace.prototype = {
 | 
			
		||||
 | 
			
		||||
        if (this._windowOverlays[0]) {
 | 
			
		||||
            [buttonOuterHeight, captionHeight] = this._windowOverlays[0].chromeHeights();
 | 
			
		||||
            buttonOuterWidth = this._windowOverlays[0].chromeWidth() / this.scale;
 | 
			
		||||
            buttonOuterWidth = this._windowOverlays[0].chromeWidth();
 | 
			
		||||
        } else
 | 
			
		||||
            [buttonOuterHeight, captionHeight] = [0, 0];
 | 
			
		||||
        buttonOuterHeight /= this.scale;
 | 
			
		||||
        captionHeight /= this.scale;
 | 
			
		||||
 | 
			
		||||
        let desiredWidth = global.screen_width * fraction;
 | 
			
		||||
        let desiredHeight = global.screen_height * fraction;
 | 
			
		||||
        let scale = Math.min((desiredWidth - buttonOuterWidth) / rect.width,
 | 
			
		||||
                             (desiredHeight - buttonOuterHeight - captionHeight) / rect.height,
 | 
			
		||||
                             1.0 / this.scale);
 | 
			
		||||
        let scale = Math.min((width - buttonOuterWidth) / rect.width,
 | 
			
		||||
                             (height - buttonOuterHeight - captionHeight) / rect.height,
 | 
			
		||||
                             1.0);
 | 
			
		||||
 | 
			
		||||
        x = Math.floor(xCenter - 0.5 * scale * rect.width);
 | 
			
		||||
        x = Math.floor(x + (width - scale * rect.width) / 2);
 | 
			
		||||
 | 
			
		||||
        // We want to center the window in case we have just one
 | 
			
		||||
        if (metaWindow.get_workspace().n_windows == 1)
 | 
			
		||||
            y = Math.floor(yCenter * global.screen_height - 0.5 * scale * rect.height);
 | 
			
		||||
            y = Math.floor(y + (height - scale * rect.height) / 2);
 | 
			
		||||
        else
 | 
			
		||||
            y = Math.floor(y + height - rect.height * scale - captionHeight);
 | 
			
		||||
 | 
			
		||||
@@ -846,7 +884,7 @@ Workspace.prototype = {
 | 
			
		||||
    /**
 | 
			
		||||
     * positionWindows:
 | 
			
		||||
     * @flags:
 | 
			
		||||
     *  ZOOM - workspace is moving at the same time and we need to take that into account.
 | 
			
		||||
     *  INITIAL - this is the initial positioning of the windows.
 | 
			
		||||
     *  ANIMATE - Indicates that we need animate changing position.
 | 
			
		||||
     */
 | 
			
		||||
    positionWindows : function(flags) {
 | 
			
		||||
@@ -859,7 +897,7 @@ Workspace.prototype = {
 | 
			
		||||
        if (this._reservedSlot)
 | 
			
		||||
            clones.push(this._reservedSlot);
 | 
			
		||||
 | 
			
		||||
        let workspaceZooming = flags & WindowPositionFlags.ZOOM;
 | 
			
		||||
        let initialPositioning = flags & WindowPositionFlags.INITIAL;
 | 
			
		||||
        let animate = flags & WindowPositionFlags.ANIMATE;
 | 
			
		||||
 | 
			
		||||
        // Start the animations
 | 
			
		||||
@@ -867,7 +905,7 @@ Workspace.prototype = {
 | 
			
		||||
        clones = this._orderWindowsByMotionAndStartup(clones, slots);
 | 
			
		||||
 | 
			
		||||
        let currentWorkspace = global.screen.get_active_workspace();
 | 
			
		||||
        let isOnCurrentWorkspace = this.metaWorkspace == currentWorkspace;
 | 
			
		||||
        let isOnCurrentWorkspace = this.metaWorkspace == null || this.metaWorkspace == currentWorkspace;
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < clones.length; i++) {
 | 
			
		||||
            let slot = slots[i];
 | 
			
		||||
@@ -881,7 +919,7 @@ Workspace.prototype = {
 | 
			
		||||
            if (clone.inDrag)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            let [x, y, scale] = this._computeWindowRelativeLayout(metaWindow, slot);
 | 
			
		||||
            let [x, y, scale] = this._computeWindowLayout(metaWindow, slot);
 | 
			
		||||
 | 
			
		||||
            if (overlay)
 | 
			
		||||
                overlay.hide();
 | 
			
		||||
@@ -890,7 +928,7 @@ Workspace.prototype = {
 | 
			
		||||
                    /* Hidden windows should fade in and grow
 | 
			
		||||
                     * therefore we need to resize them now so they
 | 
			
		||||
                     * can be scaled up later */
 | 
			
		||||
                     if (workspaceZooming) {
 | 
			
		||||
                     if (initialPositioning) {
 | 
			
		||||
                         clone.actor.opacity = 0;
 | 
			
		||||
                         clone.actor.scale_x = 0;
 | 
			
		||||
                         clone.actor.scale_y = 0;
 | 
			
		||||
@@ -911,7 +949,6 @@ Workspace.prototype = {
 | 
			
		||||
                                   y: y,
 | 
			
		||||
                                   scale_x: scale,
 | 
			
		||||
                                   scale_y: scale,
 | 
			
		||||
                                   workspace_relative: workspaceZooming ? this : null,
 | 
			
		||||
                                   time: Overview.ANIMATION_TIME,
 | 
			
		||||
                                   transition: 'easeOutQuad',
 | 
			
		||||
                                   onComplete: Lang.bind(this, function() {
 | 
			
		||||
@@ -934,7 +971,7 @@ Workspace.prototype = {
 | 
			
		||||
            let clone = clones[i];
 | 
			
		||||
            let metaWindow = clone.metaWindow;
 | 
			
		||||
            if (i == 0) {
 | 
			
		||||
                clone.setStackAbove(null);
 | 
			
		||||
                clone.setStackAbove(this._dropRect);
 | 
			
		||||
            } else {
 | 
			
		||||
                let previousClone = clones[i - 1];
 | 
			
		||||
                clone.setStackAbove(previousClone.actor);
 | 
			
		||||
@@ -954,10 +991,8 @@ Workspace.prototype = {
 | 
			
		||||
        // be after the workspace animation finishes.
 | 
			
		||||
        let [cloneX, cloneY] = clone.actor.get_position();
 | 
			
		||||
        let [cloneWidth, cloneHeight] = clone.actor.get_size();
 | 
			
		||||
        cloneX = this.x + this.scale * cloneX;
 | 
			
		||||
        cloneY = this.y + this.scale * cloneY;
 | 
			
		||||
        cloneWidth = this.scale * clone.actor.scale_x * cloneWidth;
 | 
			
		||||
        cloneHeight = this.scale * clone.actor.scale_y * cloneHeight;
 | 
			
		||||
        cloneWidth = clone.actor.scale_x * cloneWidth;
 | 
			
		||||
        cloneHeight = clone.actor.scale_y * cloneHeight;
 | 
			
		||||
 | 
			
		||||
        if (overlay) {
 | 
			
		||||
            overlay.updatePositions(cloneX, cloneY, cloneWidth, cloneHeight);
 | 
			
		||||
@@ -973,7 +1008,8 @@ Workspace.prototype = {
 | 
			
		||||
        for (let i = 0; i < this._windows.length; i++) {
 | 
			
		||||
            let clone = this._windows[i];
 | 
			
		||||
            let overlay = this._windowOverlays[i];
 | 
			
		||||
            this._showWindowOverlay(clone, overlay, this.metaWorkspace == currentWorkspace);
 | 
			
		||||
            this._showWindowOverlay(clone, overlay,
 | 
			
		||||
                                    this.metaWorkspace == null || this.metaWorkspace == currentWorkspace);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -982,12 +1018,10 @@ Workspace.prototype = {
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        let [x, y, mask] = global.get_pointer();
 | 
			
		||||
        let wsWidth = this.actor.width * this.scale;
 | 
			
		||||
        let wsHeight = this.actor.height * this.scale;
 | 
			
		||||
 | 
			
		||||
        let pointerHasMoved = (this._cursorX != x && this._cursorY != y);
 | 
			
		||||
        let inWorkspace = (this.x < x && x < this.x + wsWidth &&
 | 
			
		||||
                           this.y < y && y < this.y + wsHeight);
 | 
			
		||||
        let inWorkspace = (this._x < x && x < this._x + this._width &&
 | 
			
		||||
                           this._y < y && y < this._y + this._height);
 | 
			
		||||
 | 
			
		||||
        if (pointerHasMoved && inWorkspace) {
 | 
			
		||||
            // store current cursor position
 | 
			
		||||
@@ -1012,7 +1046,7 @@ Workspace.prototype = {
 | 
			
		||||
        this._windowOverlaysGroup.hide();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowRemoved : function(metaWorkspace, metaWin) {
 | 
			
		||||
    _doRemoveWindow : function(metaWin) {
 | 
			
		||||
        let win = metaWin.get_compositor_private();
 | 
			
		||||
 | 
			
		||||
        // find the position of the window in our list
 | 
			
		||||
@@ -1021,6 +1055,10 @@ Workspace.prototype = {
 | 
			
		||||
        if (index == -1)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // Check if window still should be here
 | 
			
		||||
        if (win && this._isMyWindow(win))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let clone = this._windows[index];
 | 
			
		||||
 | 
			
		||||
        this._windows.splice(index, 1);
 | 
			
		||||
@@ -1064,7 +1102,7 @@ Workspace.prototype = {
 | 
			
		||||
            Lang.bind(this, this._delayedWindowRepositioning));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowAdded : function(metaWorkspace, metaWin) {
 | 
			
		||||
    _doAddWindow : function(metaWin) {
 | 
			
		||||
        if (this.leavingOverview)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -1076,30 +1114,62 @@ Workspace.prototype = {
 | 
			
		||||
            Mainloop.idle_add(Lang.bind(this,
 | 
			
		||||
                                        function () {
 | 
			
		||||
                                            if (this.actor && metaWin.get_compositor_private())
 | 
			
		||||
                                                this._windowAdded(metaWorkspace, metaWin);
 | 
			
		||||
                                                this._doAddWindow(metaWin);
 | 
			
		||||
                                            return false;
 | 
			
		||||
                                        }));
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!this._isOverviewWindow(win))
 | 
			
		||||
        // We might have the window in our list already if it was on all workspaces and
 | 
			
		||||
        // now was moved to this workspace
 | 
			
		||||
        if (this._lookupIndex (metaWin) != -1)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (!this._isMyWindow(win) || !this._isOverviewWindow(win))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let clone = this._addWindowClone(win);
 | 
			
		||||
 | 
			
		||||
        if (win._overviewHint) {
 | 
			
		||||
            let x = (win._overviewHint.x - this.actor.x) / this.scale;
 | 
			
		||||
            let y = (win._overviewHint.y - this.actor.y) / this.scale;
 | 
			
		||||
            let scale = win._overviewHint.scale / this.scale;
 | 
			
		||||
            let x = win._overviewHint.x - this.actor.x;
 | 
			
		||||
            let y = win._overviewHint.y - this.actor.y;
 | 
			
		||||
            let scale = win._overviewHint.scale;
 | 
			
		||||
            delete win._overviewHint;
 | 
			
		||||
 | 
			
		||||
            clone.actor.set_position (x, y);
 | 
			
		||||
            clone.actor.set_scale (scale, scale);
 | 
			
		||||
        } else {
 | 
			
		||||
            // Position new windows at the top corner of the workspace rather
 | 
			
		||||
            // than where they were placed for real to avoid the window
 | 
			
		||||
            // being clipped to the workspaceView. Its not really more
 | 
			
		||||
            // natural for the window to suddenly appear in the overview
 | 
			
		||||
            // on some seemingly random location anyway.
 | 
			
		||||
            clone.actor.set_position (this._x, this._y);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.positionWindows(WindowPositionFlags.ANIMATE);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowAdded : function(metaWorkspace, metaWin) {
 | 
			
		||||
        this._doAddWindow(metaWin);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowRemoved : function(metaWorkspace, metaWin) {
 | 
			
		||||
        this._doRemoveWindow(metaWin);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowEnteredMonitor : function(metaScreen, monitorIndex, metaWin) {
 | 
			
		||||
        if (monitorIndex == this.monitorIndex) {
 | 
			
		||||
            this._doAddWindow(metaWin);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowLeftMonitor : function(metaScreen, monitorIndex, metaWin) {
 | 
			
		||||
        if (monitorIndex == this.monitorIndex) {
 | 
			
		||||
            this._doRemoveWindow(metaWin);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // check for maximized windows on the workspace
 | 
			
		||||
    hasMaximizedWindows: function() {
 | 
			
		||||
        for (let i = 0; i < this._windows.length; i++) {
 | 
			
		||||
@@ -1114,14 +1184,11 @@ Workspace.prototype = {
 | 
			
		||||
 | 
			
		||||
    // Animate the full-screen to Overview transition.
 | 
			
		||||
    zoomToOverview : function() {
 | 
			
		||||
        this.actor.set_position(this.x, this.y);
 | 
			
		||||
        this.actor.set_scale(this.scale, this.scale);
 | 
			
		||||
 | 
			
		||||
        // Position and scale the windows.
 | 
			
		||||
        if (Main.overview.animationInProgress)
 | 
			
		||||
            this.positionWindows(WindowPositionFlags.ANIMATE | WindowPositionFlags.ZOOM);
 | 
			
		||||
            this.positionWindows(WindowPositionFlags.ANIMATE | WindowPositionFlags.INITIAL);
 | 
			
		||||
        else
 | 
			
		||||
            this.positionWindows(WindowPositionFlags.ZOOM);
 | 
			
		||||
            this.positionWindows(WindowPositionFlags.INITIAL);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Animates the return from Overview mode
 | 
			
		||||
@@ -1139,7 +1206,7 @@ Workspace.prototype = {
 | 
			
		||||
        this._overviewHiddenId = Main.overview.connect('hidden', Lang.bind(this,
 | 
			
		||||
                                                                           this._doneLeavingOverview));
 | 
			
		||||
 | 
			
		||||
        if (this._metaWorkspace == currentWorkspace)
 | 
			
		||||
        if (this.metaWorkspace != null && this.metaWorkspace != currentWorkspace)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // Position and scale the windows.
 | 
			
		||||
@@ -1154,7 +1221,6 @@ Workspace.prototype = {
 | 
			
		||||
                                   y: clone.origY,
 | 
			
		||||
                                   scale_x: 1.0,
 | 
			
		||||
                                   scale_y: 1.0,
 | 
			
		||||
                                   workspace_relative: this,
 | 
			
		||||
                                   time: Overview.ANIMATION_TIME,
 | 
			
		||||
                                   opacity: 255,
 | 
			
		||||
                                   transition: 'easeOutQuad'
 | 
			
		||||
@@ -1165,7 +1231,6 @@ Workspace.prototype = {
 | 
			
		||||
                                 { scale_x: 0,
 | 
			
		||||
                                   scale_y: 0,
 | 
			
		||||
                                   opacity: 0,
 | 
			
		||||
                                   workspace_relative: this,
 | 
			
		||||
                                   time: Overview.ANIMATION_TIME,
 | 
			
		||||
                                   transition: 'easeOutQuad'
 | 
			
		||||
                                 });
 | 
			
		||||
@@ -1185,8 +1250,12 @@ Workspace.prototype = {
 | 
			
		||||
        }
 | 
			
		||||
        Tweener.removeTweens(actor);
 | 
			
		||||
 | 
			
		||||
        this.metaWorkspace.disconnect(this._windowAddedId);
 | 
			
		||||
        this.metaWorkspace.disconnect(this._windowRemovedId);
 | 
			
		||||
        if (this.metaWorkspace) {
 | 
			
		||||
            this.metaWorkspace.disconnect(this._windowAddedId);
 | 
			
		||||
            this.metaWorkspace.disconnect(this._windowRemovedId);
 | 
			
		||||
        }
 | 
			
		||||
        global.screen.disconnect(this._windowEnteredMonitorId);
 | 
			
		||||
        global.screen.disconnect(this._windowLeftMonitorId);
 | 
			
		||||
 | 
			
		||||
        if (this._repositionWindowsId > 0)
 | 
			
		||||
            Mainloop.source_remove(this._repositionWindowsId);
 | 
			
		||||
@@ -1205,9 +1274,10 @@ Workspace.prototype = {
 | 
			
		||||
        this.leavingOverview = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Tests if @win belongs to this workspaces
 | 
			
		||||
    // Tests if @win belongs to this workspaces and monitor
 | 
			
		||||
    _isMyWindow : function (win) {
 | 
			
		||||
        return Main.isWindowActorDisplayedOnWorkspace(win, this.metaWorkspace.index());
 | 
			
		||||
        return (this.metaWorkspace == null || Main.isWindowActorDisplayedOnWorkspace(win, this.metaWorkspace.index())) &&
 | 
			
		||||
            (!win.get_meta_window() || win.get_meta_window().get_monitor() == this.monitorIndex);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Tests if @win should be shown in the Overview
 | 
			
		||||
@@ -1228,6 +1298,10 @@ Workspace.prototype = {
 | 
			
		||||
                          Main.overview.beginWindowDrag();
 | 
			
		||||
                          overlay.hide();
 | 
			
		||||
                      }));
 | 
			
		||||
        clone.connect('drag-cancelled',
 | 
			
		||||
                      Lang.bind(this, function(clone) {
 | 
			
		||||
                          Main.overview.cancelledWindowDrag();
 | 
			
		||||
                      }));
 | 
			
		||||
        clone.connect('drag-end',
 | 
			
		||||
                      Lang.bind(this, function(clone) {
 | 
			
		||||
                          Main.overview.endWindowDrag();
 | 
			
		||||
@@ -1291,8 +1365,10 @@ Workspace.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onCloneSelected : function (clone, time) {
 | 
			
		||||
        Main.activateWindow(clone.metaWindow, time,
 | 
			
		||||
                            this.metaWorkspace.index());
 | 
			
		||||
        let wsIndex = undefined;
 | 
			
		||||
        if (this.metaWorkspace)
 | 
			
		||||
            wsIndex = this.metaWorkspace.index();
 | 
			
		||||
        Main.activateWindow(clone.metaWindow, time, wsIndex);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Draggable target interface
 | 
			
		||||
@@ -1320,7 +1396,15 @@ Workspace.prototype = {
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            let metaWindow = win.get_meta_window();
 | 
			
		||||
            metaWindow.change_workspace_by_index(this.metaWorkspace.index(),
 | 
			
		||||
 | 
			
		||||
            // We need to move the window before changing the workspace, because
 | 
			
		||||
            // the move itself could cause a workspace change if the window enters
 | 
			
		||||
            // the primary monitor
 | 
			
		||||
            if (metaWindow.get_monitor() != this.monitorIndex)
 | 
			
		||||
                metaWindow.move_to_monitor(this.monitorIndex);
 | 
			
		||||
 | 
			
		||||
            let index = this.metaWorkspace ? this.metaWorkspace.index() : global.screen.get_active_workspace_index();
 | 
			
		||||
            metaWindow.change_workspace_by_index(index,
 | 
			
		||||
                                                 false, // don't create workspace
 | 
			
		||||
                                                 time);
 | 
			
		||||
            return true;
 | 
			
		||||
@@ -1335,56 +1419,3 @@ Workspace.prototype = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Signals.addSignalMethods(Workspace.prototype);
 | 
			
		||||
 | 
			
		||||
// Create a SpecialPropertyModifier to let us move windows in a
 | 
			
		||||
// straight line on the screen even though their containing workspace
 | 
			
		||||
// is also moving.
 | 
			
		||||
Tweener.registerSpecialPropertyModifier('workspace_relative', _workspaceRelativeModifier, _workspaceRelativeGet);
 | 
			
		||||
 | 
			
		||||
function _workspaceRelativeModifier(workspace) {
 | 
			
		||||
    let [startX, startY] = Main.overview.getPosition();
 | 
			
		||||
    let overviewPosX, overviewPosY, overviewScale;
 | 
			
		||||
 | 
			
		||||
    if (!workspace)
 | 
			
		||||
        return [];
 | 
			
		||||
 | 
			
		||||
    if (workspace.leavingOverview) {
 | 
			
		||||
        let [zoomedInX, zoomedInY] = Main.overview.getZoomedInPosition();
 | 
			
		||||
        overviewPosX = { begin: startX, end: zoomedInX };
 | 
			
		||||
        overviewPosY = { begin: startY, end: zoomedInY };
 | 
			
		||||
        overviewScale = { begin: Main.overview.getScale(),
 | 
			
		||||
                          end: Main.overview.getZoomedInScale() };
 | 
			
		||||
    } else {
 | 
			
		||||
        overviewPosX = { begin: startX, end: 0 };
 | 
			
		||||
        overviewPosY = { begin: startY, end: 0 };
 | 
			
		||||
        overviewScale = { begin: Main.overview.getScale(), end: 1 };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return [ { name: 'x',
 | 
			
		||||
               parameters: { workspacePos: workspace.x,
 | 
			
		||||
                             overviewPos: overviewPosX,
 | 
			
		||||
                             overviewScale: overviewScale } },
 | 
			
		||||
             { name: 'y',
 | 
			
		||||
               parameters: { workspacePos: workspace.y,
 | 
			
		||||
                             overviewPos: overviewPosY,
 | 
			
		||||
                             overviewScale: overviewScale } }
 | 
			
		||||
           ];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _workspaceRelativeGet(begin, end, time, params) {
 | 
			
		||||
    let curOverviewPos = (1 - time) * params.overviewPos.begin +
 | 
			
		||||
                         time * params.overviewPos.end;
 | 
			
		||||
    let curOverviewScale = (1 - time) * params.overviewScale.begin +
 | 
			
		||||
                           time * params.overviewScale.end;
 | 
			
		||||
 | 
			
		||||
    // Calculate the screen position of the window.
 | 
			
		||||
    let screen = (1 - time) *
 | 
			
		||||
                 ((begin + params.workspacePos) * params.overviewScale.begin +
 | 
			
		||||
                  params.overviewPos.begin) +
 | 
			
		||||
                 time *
 | 
			
		||||
                 ((end + params.workspacePos) * params.overviewScale.end +
 | 
			
		||||
                 params.overviewPos.end);
 | 
			
		||||
 | 
			
		||||
    // Return the workspace coordinates.
 | 
			
		||||
    return (screen - curOverviewPos) / curOverviewScale - params.workspacePos;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -146,6 +146,7 @@ function WorkspaceThumbnail(metaWorkspace) {
 | 
			
		||||
WorkspaceThumbnail.prototype = {
 | 
			
		||||
    _init : function(metaWorkspace) {
 | 
			
		||||
        this.metaWorkspace = metaWorkspace;
 | 
			
		||||
        this.monitorIndex = global.get_primary_monitor_index();
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Group({ reactive: true,
 | 
			
		||||
                                    clip_to_allocation: true,
 | 
			
		||||
@@ -169,7 +170,8 @@ WorkspaceThumbnail.prototype = {
 | 
			
		||||
        this._background = new Clutter.Clone({ source: global.background_actor });
 | 
			
		||||
        this._contents.add_actor(this._background);
 | 
			
		||||
 | 
			
		||||
        this.setPorthole(0, 0, global.screen_width, global.screen_height);
 | 
			
		||||
        let monitor = global.get_primary_monitor();
 | 
			
		||||
        this.setPorthole(monitor.x, monitor.y, monitor.width, monitor.height);
 | 
			
		||||
 | 
			
		||||
        let windows = global.get_window_actors().filter(this._isMyWindow, this);
 | 
			
		||||
 | 
			
		||||
@@ -186,6 +188,10 @@ WorkspaceThumbnail.prototype = {
 | 
			
		||||
                                                          Lang.bind(this, this._windowAdded));
 | 
			
		||||
        this._windowRemovedId = this.metaWorkspace.connect('window-removed',
 | 
			
		||||
                                                           Lang.bind(this, this._windowRemoved));
 | 
			
		||||
        this._windowEnteredMonitorId = global.screen.connect('window-entered-monitor',
 | 
			
		||||
                                                           Lang.bind(this, this._windowEnteredMonitor));
 | 
			
		||||
        this._windowLeftMonitorId = global.screen.connect('window-left-monitor',
 | 
			
		||||
                                                           Lang.bind(this, this._windowLeftMonitor));
 | 
			
		||||
 | 
			
		||||
        this.state = ThumbnailState.NORMAL;
 | 
			
		||||
        this._slidePosition = 0; // Fully slid in
 | 
			
		||||
@@ -193,6 +199,8 @@ WorkspaceThumbnail.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setPorthole: function(x, y, width, height) {
 | 
			
		||||
        this._portholeX = x;
 | 
			
		||||
        this._portholeY = y;
 | 
			
		||||
        this.actor.set_size(width, height);
 | 
			
		||||
        this._contents.set_position(-x, -y);
 | 
			
		||||
    },
 | 
			
		||||
@@ -239,7 +247,7 @@ WorkspaceThumbnail.prototype = {
 | 
			
		||||
        return this._collapseFraction;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowRemoved : function(metaWorkspace, metaWin) {
 | 
			
		||||
    _doRemoveWindow : function(metaWin) {
 | 
			
		||||
        let win = metaWin.get_compositor_private();
 | 
			
		||||
 | 
			
		||||
        // find the position of the window in our list
 | 
			
		||||
@@ -248,12 +256,16 @@ WorkspaceThumbnail.prototype = {
 | 
			
		||||
        if (index == -1)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // Check if window still should be here
 | 
			
		||||
        if (win && this._isMyWindow(win))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let clone = this._windows[index];
 | 
			
		||||
        this._windows.splice(index, 1);
 | 
			
		||||
        clone.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowAdded : function(metaWorkspace, metaWin) {
 | 
			
		||||
    _doAddWindow : function(metaWin) {
 | 
			
		||||
        if (this.leavingOverview)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -265,18 +277,43 @@ WorkspaceThumbnail.prototype = {
 | 
			
		||||
            Mainloop.idle_add(Lang.bind(this,
 | 
			
		||||
                                        function () {
 | 
			
		||||
                                            if (this.actor && metaWin.get_compositor_private())
 | 
			
		||||
                                                this._windowAdded(metaWorkspace, metaWin);
 | 
			
		||||
                                                this._doAddWindow(metaWin);
 | 
			
		||||
                                            return false;
 | 
			
		||||
                                        }));
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!this._isOverviewWindow(win))
 | 
			
		||||
        // We might have the window in our list already if it was on all workspaces and
 | 
			
		||||
        // now was moved to this workspace
 | 
			
		||||
        if (this._lookupIndex (metaWin) != -1)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (!this._isMyWindow(win) || !this._isOverviewWindow(win))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let clone = this._addWindowClone(win);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowAdded : function(metaWorkspace, metaWin) {
 | 
			
		||||
        this._doAddWindow(metaWin);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowRemoved : function(metaWorkspace, metaWin) {
 | 
			
		||||
        this._doRemoveWindow(metaWin);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowEnteredMonitor : function(metaScreen, monitorIndex, metaWin) {
 | 
			
		||||
        if (monitorIndex == this.monitorIndex) {
 | 
			
		||||
            this._doAddWindow(metaWin);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowLeftMonitor : function(metaScreen, monitorIndex, metaWin) {
 | 
			
		||||
        if (monitorIndex == this.monitorIndex) {
 | 
			
		||||
            this._doRemoveWindow(metaWin);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy : function() {
 | 
			
		||||
        this.actor.destroy();
 | 
			
		||||
    },
 | 
			
		||||
@@ -284,15 +321,17 @@ WorkspaceThumbnail.prototype = {
 | 
			
		||||
    _onDestroy: function(actor) {
 | 
			
		||||
        this.metaWorkspace.disconnect(this._windowAddedId);
 | 
			
		||||
        this.metaWorkspace.disconnect(this._windowRemovedId);
 | 
			
		||||
        global.screen.disconnect(this._windowEnteredMonitorId);
 | 
			
		||||
        global.screen.disconnect(this._windowLeftMonitorId);
 | 
			
		||||
 | 
			
		||||
        this._windows = [];
 | 
			
		||||
        this.actor = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Tests if @win belongs to this workspaces
 | 
			
		||||
    // Tests if @win belongs to this workspace and monitor
 | 
			
		||||
    _isMyWindow : function (win) {
 | 
			
		||||
        return win.get_workspace() == this.metaWorkspace.index() ||
 | 
			
		||||
            (win.get_meta_window() && win.get_meta_window().is_on_all_workspaces());
 | 
			
		||||
        return Main.isWindowActorDisplayedOnWorkspace(win, this.metaWorkspace.index()) &&
 | 
			
		||||
            (!win.get_meta_window() || win.get_meta_window().get_monitor() == this.monitorIndex);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Tests if @win should be shown in the Overview
 | 
			
		||||
@@ -340,6 +379,11 @@ WorkspaceThumbnail.prototype = {
 | 
			
		||||
 | 
			
		||||
    // Draggable target interface
 | 
			
		||||
    handleDragOver : function(source, actor, x, y, time) {
 | 
			
		||||
        if (source == Main.xdndHandler) {
 | 
			
		||||
            this.metaWorkspace.activate(time);
 | 
			
		||||
            return DND.DragMotionResult.CONTINUE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.state > ThumbnailState.NORMAL)
 | 
			
		||||
            return DND.DragMotionResult.CONTINUE;
 | 
			
		||||
 | 
			
		||||
@@ -361,6 +405,13 @@ WorkspaceThumbnail.prototype = {
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            let metaWindow = win.get_meta_window();
 | 
			
		||||
 | 
			
		||||
            // We need to move the window before changing the workspace, because
 | 
			
		||||
            // the move itself could cause a workspace change if the window enters
 | 
			
		||||
            // the primary monitor
 | 
			
		||||
            if (metaWindow.get_monitor() != this.monitorIndex)
 | 
			
		||||
                metaWindow.move_to_monitor(this.monitorIndex);
 | 
			
		||||
 | 
			
		||||
            metaWindow.change_workspace_by_index(this.metaWorkspace.index(),
 | 
			
		||||
                                                 false, // don't create workspace
 | 
			
		||||
                                                 time);
 | 
			
		||||
@@ -442,11 +493,12 @@ ThumbnailsBox.prototype = {
 | 
			
		||||
 | 
			
		||||
        // The "porthole" is the portion of the screen that we show in the workspaces
 | 
			
		||||
        let panelHeight = Main.panel.actor.height;
 | 
			
		||||
        let monitor = global.get_primary_monitor();
 | 
			
		||||
        this._porthole = {
 | 
			
		||||
            x: 0,
 | 
			
		||||
            y: panelHeight,
 | 
			
		||||
            width: global.screen_width,
 | 
			
		||||
            height: global.screen_height - panelHeight
 | 
			
		||||
            x: monitor.x,
 | 
			
		||||
            y: monitor.y + panelHeight,
 | 
			
		||||
            width: monitor.width,
 | 
			
		||||
            height: monitor.height - panelHeight
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        this.addThumbnails(0, global.screen.n_workspaces);
 | 
			
		||||
 
 | 
			
		||||
@@ -25,14 +25,13 @@ const MAX_WORKSPACES = 16;
 | 
			
		||||
const CONTROLS_POP_IN_TIME = 0.1;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function WorkspacesView(width, height, x, y, workspaces) {
 | 
			
		||||
    this._init(width, height, x, y, workspaces);
 | 
			
		||||
function WorkspacesView(workspaces) {
 | 
			
		||||
    this._init(workspaces);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WorkspacesView.prototype = {
 | 
			
		||||
    _init: function(width, height, x, y, workspaces) {
 | 
			
		||||
    _init: function(workspaces) {
 | 
			
		||||
        this.actor = new St.Group({ style_class: 'workspaces-view' });
 | 
			
		||||
        this.actor.set_clip(x, y, width, height);
 | 
			
		||||
 | 
			
		||||
        // The actor itself isn't a drop target, so we don't want to pick on its area
 | 
			
		||||
        this.actor.set_size(0, 0);
 | 
			
		||||
@@ -43,19 +42,17 @@ WorkspacesView.prototype = {
 | 
			
		||||
            function() {
 | 
			
		||||
                let node = this.actor.get_theme_node();
 | 
			
		||||
                this._spacing = node.get_length('spacing');
 | 
			
		||||
                this._computeWorkspacePositions();
 | 
			
		||||
                this._updateWorkspaceActors(false);
 | 
			
		||||
            }));
 | 
			
		||||
        this.actor.connect('notify::mapped',
 | 
			
		||||
                           Lang.bind(this, this._onMappedChanged));
 | 
			
		||||
 | 
			
		||||
        this._width = width;
 | 
			
		||||
        this._height = height;
 | 
			
		||||
        this._x = x;
 | 
			
		||||
        this._y = y;
 | 
			
		||||
        this._zoomScale = 1.0;
 | 
			
		||||
        this._width = 0;
 | 
			
		||||
        this._height = 0;
 | 
			
		||||
        this._x = 0;
 | 
			
		||||
        this._y = 0;
 | 
			
		||||
        this._workspaceRatioSpacing = 0;
 | 
			
		||||
        this._spacing = 0;
 | 
			
		||||
        this._activeWorkspaceX = 0; // x offset of active ws while dragging
 | 
			
		||||
        this._activeWorkspaceY = 0; // y offset of active ws while dragging
 | 
			
		||||
        this._lostWorkspaces = [];
 | 
			
		||||
        this._animating = false; // tweening
 | 
			
		||||
        this._scrolling = false; // swipe-scrolling
 | 
			
		||||
@@ -71,6 +68,18 @@ WorkspacesView.prototype = {
 | 
			
		||||
            this._workspaces[w].actor.reparent(this.actor);
 | 
			
		||||
        this._workspaces[activeWorkspaceIndex].actor.raise_top();
 | 
			
		||||
 | 
			
		||||
        this._extraWorkspaces = [];
 | 
			
		||||
        let monitors = global.get_monitors();
 | 
			
		||||
        let m = 0;
 | 
			
		||||
        for (let i = 0; i < monitors.length; i++) {
 | 
			
		||||
            if (i == global.get_primary_monitor_index())
 | 
			
		||||
                continue;
 | 
			
		||||
            let ws = new Workspace.Workspace(null, i);
 | 
			
		||||
            this._extraWorkspaces[m++] = ws;
 | 
			
		||||
            ws.setGeometry(monitors[i].x, monitors[i].y, monitors[i].width, monitors[i].height);
 | 
			
		||||
            global.overlay_group.add_actor(ws.actor);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Position/scale the desktop windows and their children after the
 | 
			
		||||
        // workspaces have been created. This cannot be done first because
 | 
			
		||||
        // window movement depends on the Workspaces object being accessible
 | 
			
		||||
@@ -80,6 +89,13 @@ WorkspacesView.prototype = {
 | 
			
		||||
                                 Lang.bind(this, function() {
 | 
			
		||||
                for (let w = 0; w < this._workspaces.length; w++)
 | 
			
		||||
                    this._workspaces[w].zoomToOverview();
 | 
			
		||||
                for (let w = 0; w < this._extraWorkspaces.length; w++)
 | 
			
		||||
                    this._extraWorkspaces[w].zoomToOverview();
 | 
			
		||||
        }));
 | 
			
		||||
        this._overviewShownId =
 | 
			
		||||
            Main.overview.connect('shown',
 | 
			
		||||
                                 Lang.bind(this, function() {
 | 
			
		||||
                this.actor.set_clip(this._x, this._y, this._width, this._height);
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._scrollAdjustment = new St.Adjustment({ value: activeWorkspaceIndex,
 | 
			
		||||
@@ -109,30 +125,18 @@ WorkspacesView.prototype = {
 | 
			
		||||
        this._swipeScrollEndId = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setZoomScale: function(zoomScale) {
 | 
			
		||||
        if (zoomScale == this._zoomScale)
 | 
			
		||||
            return;
 | 
			
		||||
    setGeometry: function(x, y, width, height, spacing) {
 | 
			
		||||
      if (this._x == x && this._y == y &&
 | 
			
		||||
          this._width == width && this._height == height)
 | 
			
		||||
          return;
 | 
			
		||||
        this._width = width;
 | 
			
		||||
        this._height = height;
 | 
			
		||||
        this._x = x;
 | 
			
		||||
        this._y = y;
 | 
			
		||||
        this._workspaceRatioSpacing = spacing;
 | 
			
		||||
 | 
			
		||||
        this._zoomScale = zoomScale;
 | 
			
		||||
        if (this._zoomOut) {
 | 
			
		||||
            // If we are already zoomed out, then we have to reposition.
 | 
			
		||||
            // Note that when shown initially zoomOut is false, so we
 | 
			
		||||
            // won't trigger this.
 | 
			
		||||
 | 
			
		||||
            // setZoomScale can be invoked when the workspaces view is
 | 
			
		||||
            // reallocated. Since we just want to animate things to the
 | 
			
		||||
            // new position it seems OK to call updateWorkspaceActors
 | 
			
		||||
            // immediately - adding a tween doesn't immediately cause
 | 
			
		||||
            // a new allocation. But hide/show of the window overlays we
 | 
			
		||||
            // do around animation does, so we need to do it later.
 | 
			
		||||
            // This can be removed when we fix things to not hide/show
 | 
			
		||||
            // the window overlay.
 | 
			
		||||
            Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
 | 
			
		||||
                           Lang.bind(this, function() {
 | 
			
		||||
                                         this._computeWorkspacePositions();
 | 
			
		||||
                                         this._updateWorkspaceActors(true);
 | 
			
		||||
                                     }));
 | 
			
		||||
        }
 | 
			
		||||
        for (let i = 0; i < this._workspaces.length; i++)
 | 
			
		||||
            this._workspaces[i].setGeometry(x, y, width, height);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _lookupWorkspaceForMetaWindow: function (metaWindow) {
 | 
			
		||||
@@ -154,101 +158,41 @@ WorkspacesView.prototype = {
 | 
			
		||||
 | 
			
		||||
        activeWorkspace.actor.raise_top();
 | 
			
		||||
 | 
			
		||||
       this.actor.remove_clip(this._x, this._y, this._width, this._height);
 | 
			
		||||
 | 
			
		||||
        for (let w = 0; w < this._workspaces.length; w++)
 | 
			
		||||
            this._workspaces[w].zoomFromOverview();
 | 
			
		||||
        for (let w = 0; w < this._extraWorkspaces.length; w++)
 | 
			
		||||
            this._extraWorkspaces[w].zoomFromOverview();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy: function() {
 | 
			
		||||
        this.actor.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getScale: function() {
 | 
			
		||||
        return this._workspaces[0].scale;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    syncStacking: function(stackIndices) {
 | 
			
		||||
        for (let i = 0; i < this._workspaces.length; i++)
 | 
			
		||||
            this._workspaces[i].syncStacking(stackIndices);
 | 
			
		||||
        for (let i = 0; i < this._extraWorkspaces.length; i++)
 | 
			
		||||
            this._extraWorkspaces[i].syncStacking(stackIndices);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Get the grid position of the active workspace.
 | 
			
		||||
    getActiveWorkspacePosition: function() {
 | 
			
		||||
        let activeWorkspaceIndex = global.screen.get_active_workspace_index();
 | 
			
		||||
        let activeWorkspace = this._workspaces[activeWorkspaceIndex];
 | 
			
		||||
 | 
			
		||||
        return [activeWorkspace.x, activeWorkspace.y];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    zoomOut: function() {
 | 
			
		||||
        if (this._zoomOut)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._zoomOut = true;
 | 
			
		||||
        this._computeWorkspacePositions();
 | 
			
		||||
        this._updateWorkspaceActors(true);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    zoomIn: function() {
 | 
			
		||||
        if (!this._zoomOut)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._zoomOut = false;
 | 
			
		||||
        this._computeWorkspacePositions();
 | 
			
		||||
        this._updateWorkspaceActors(true);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Compute the position, scale and opacity of the workspaces, but don't
 | 
			
		||||
    // actually change the actors to match
 | 
			
		||||
    _computeWorkspacePositions: function() {
 | 
			
		||||
        let active = global.screen.get_active_workspace_index();
 | 
			
		||||
        let zoomScale = this._zoomOut ? this._zoomScale : 1;
 | 
			
		||||
        let scale = zoomScale * this._width / global.screen_width;
 | 
			
		||||
 | 
			
		||||
        let _width = this._workspaces[0].actor.width * scale;
 | 
			
		||||
        let _height = this._workspaces[0].actor.height * scale;
 | 
			
		||||
 | 
			
		||||
        this._activeWorkspaceX = (this._width - _width) / 2;
 | 
			
		||||
        this._activeWorkspaceY = (this._height - _height) / 2;
 | 
			
		||||
 | 
			
		||||
        for (let w = 0; w < this._workspaces.length; w++) {
 | 
			
		||||
            let workspace = this._workspaces[w];
 | 
			
		||||
 | 
			
		||||
            workspace.opacity = (this._inDrag && w != active) ? 200 : 255;
 | 
			
		||||
 | 
			
		||||
            workspace.scale = scale;
 | 
			
		||||
            workspace.x = this._x + this._activeWorkspaceX;
 | 
			
		||||
 | 
			
		||||
            // We adjust the center because the zoomScale is to leave space for
 | 
			
		||||
            // the expanded workspace control so we want to zoom to either the
 | 
			
		||||
            // left part of the area or the right part of the area
 | 
			
		||||
            let offset = 0.5 * (1 - this._zoomScale) * this._width;
 | 
			
		||||
            let rtl = (St.Widget.get_default_direction () == St.TextDirection.RTL);
 | 
			
		||||
            if (this._zoomOut)
 | 
			
		||||
                workspace.x += rtl ? offset : - offset;
 | 
			
		||||
 | 
			
		||||
            // We divide by zoomScale so that adjacent workspaces are always offscreen
 | 
			
		||||
            // except when we are switching between workspaces
 | 
			
		||||
            workspace.y = this._y + this._activeWorkspaceY
 | 
			
		||||
                                  + (w - active) * (_height + this._spacing) / zoomScale;
 | 
			
		||||
        }
 | 
			
		||||
    updateWindowPositions: function() {
 | 
			
		||||
        for (let w = 0; w < this._workspaces.length; w++)
 | 
			
		||||
            this._workspaces[w].positionWindows(Workspace.WindowPositionFlags.ANIMATE);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _scrollToActive: function(showAnimation) {
 | 
			
		||||
        let active = global.screen.get_active_workspace_index();
 | 
			
		||||
 | 
			
		||||
        this._computeWorkspacePositions();
 | 
			
		||||
        this._updateWorkspaceActors(showAnimation);
 | 
			
		||||
        this._updateScrollAdjustment(active, showAnimation);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Update workspace actors parameters to the values calculated in
 | 
			
		||||
    // _computeWorkspacePositions()
 | 
			
		||||
    // Update workspace actors parameters
 | 
			
		||||
    // @showAnimation: iff %true, transition between states
 | 
			
		||||
    _updateWorkspaceActors: function(showAnimation) {
 | 
			
		||||
        let active = global.screen.get_active_workspace_index();
 | 
			
		||||
        let targetWorkspaceNewY = this._y + this._activeWorkspaceY;
 | 
			
		||||
        let targetWorkspaceCurrentY = this._workspaces[active].y;
 | 
			
		||||
        let dy = targetWorkspaceNewY - targetWorkspaceCurrentY;
 | 
			
		||||
 | 
			
		||||
        this._animating = showAnimation;
 | 
			
		||||
 | 
			
		||||
@@ -257,14 +201,12 @@ WorkspacesView.prototype = {
 | 
			
		||||
 | 
			
		||||
            Tweener.removeTweens(workspace.actor);
 | 
			
		||||
 | 
			
		||||
            workspace.y += dy;
 | 
			
		||||
            let opacity = (this._inDrag && w != active) ? 200 : 255;
 | 
			
		||||
            let y = (w - active) * (this._height + this._spacing + this._workspaceRatioSpacing);
 | 
			
		||||
 | 
			
		||||
            if (showAnimation) {
 | 
			
		||||
                let params = { x: workspace.x,
 | 
			
		||||
                               y: workspace.y,
 | 
			
		||||
                               scale_x: workspace.scale,
 | 
			
		||||
                               scale_y: workspace.scale,
 | 
			
		||||
                               opacity: workspace.opacity,
 | 
			
		||||
                let params = { y: y,
 | 
			
		||||
                               opacity: opacity,
 | 
			
		||||
                               time: WORKSPACE_SWITCH_TIME,
 | 
			
		||||
                               transition: 'easeOutQuad'
 | 
			
		||||
                             };
 | 
			
		||||
@@ -281,9 +223,8 @@ WorkspacesView.prototype = {
 | 
			
		||||
                }
 | 
			
		||||
                Tweener.addTween(workspace.actor, params);
 | 
			
		||||
            } else {
 | 
			
		||||
                workspace.actor.set_scale(workspace.scale, workspace.scale);
 | 
			
		||||
                workspace.actor.set_position(workspace.x, workspace.y);
 | 
			
		||||
                workspace.actor.opacity = workspace.opacity;
 | 
			
		||||
                workspace.actor.set_position(0, y);
 | 
			
		||||
                workspace.actor.opacity = opacity;
 | 
			
		||||
                if (w == 0)
 | 
			
		||||
                    this._updateVisibility();
 | 
			
		||||
            }
 | 
			
		||||
@@ -294,7 +235,6 @@ WorkspacesView.prototype = {
 | 
			
		||||
 | 
			
		||||
            Tweener.removeTweens(workspace.actor);
 | 
			
		||||
 | 
			
		||||
            workspace.y += dy;
 | 
			
		||||
            workspace.actor.show();
 | 
			
		||||
            workspace.hideWindowsOverlays();
 | 
			
		||||
 | 
			
		||||
@@ -338,7 +278,6 @@ WorkspacesView.prototype = {
 | 
			
		||||
            this._lostWorkspaces[l].destroy();
 | 
			
		||||
        this._lostWorkspaces = [];
 | 
			
		||||
 | 
			
		||||
        this._computeWorkspacePositions();
 | 
			
		||||
        this._updateWorkspaceActors(false);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -380,7 +319,6 @@ WorkspacesView.prototype = {
 | 
			
		||||
            for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++)
 | 
			
		||||
                this.actor.add_actor(this._workspaces[w].actor);
 | 
			
		||||
 | 
			
		||||
            this._computeWorkspacePositions();
 | 
			
		||||
            this._updateWorkspaceActors(false);
 | 
			
		||||
        } else {
 | 
			
		||||
            this._lostWorkspaces = lostWorkspaces;
 | 
			
		||||
@@ -397,10 +335,16 @@ WorkspacesView.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
        for (let i = 0; i < this._extraWorkspaces.length; i++)
 | 
			
		||||
            this._extraWorkspaces[i].destroy();
 | 
			
		||||
        this._scrollAdjustment.run_dispose();
 | 
			
		||||
        Main.overview.disconnect(this._overviewShowingId);
 | 
			
		||||
        Main.overview.disconnect(this._overviewShownId);
 | 
			
		||||
        global.window_manager.disconnect(this._switchWorkspaceNotifyId);
 | 
			
		||||
 | 
			
		||||
        if (this._inDrag)
 | 
			
		||||
            this._dragEnd();
 | 
			
		||||
 | 
			
		||||
        if (this._timeoutId) {
 | 
			
		||||
            Mainloop.source_remove(this._timeoutId);
 | 
			
		||||
            this._timeoutId = 0;
 | 
			
		||||
@@ -443,6 +387,7 @@ WorkspacesView.prototype = {
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._inDrag = true;
 | 
			
		||||
        this._firstDragMotion = true;
 | 
			
		||||
 | 
			
		||||
        this._dragMonitor = {
 | 
			
		||||
            dragMotion: Lang.bind(this, this._onDragMotion)
 | 
			
		||||
@@ -454,6 +399,14 @@ WorkspacesView.prototype = {
 | 
			
		||||
        if (Main.overview.animationInProgress)
 | 
			
		||||
             return DND.DragMotionResult.CONTINUE;
 | 
			
		||||
 | 
			
		||||
        if (this._firstDragMotion) {
 | 
			
		||||
            this._firstDragMotion = false;
 | 
			
		||||
            for (let i = 0; i < this._workspaces.length; i++)
 | 
			
		||||
                this._workspaces[i].setReservedSlot(dragEvent.dragActor._delegate);
 | 
			
		||||
            for (let i = 0; i < this._extraWorkspaces.length; i++)
 | 
			
		||||
                this._extraWorkspaces[i].setReservedSlot(dragEvent.dragActor._delegate);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let primary = global.get_primary_monitor();
 | 
			
		||||
 | 
			
		||||
        let activeWorkspaceIndex = global.screen.get_active_workspace_index();
 | 
			
		||||
@@ -467,7 +420,6 @@ WorkspacesView.prototype = {
 | 
			
		||||
        let switchTop = (dragEvent.y <= topEdge && topWorkspace);
 | 
			
		||||
        if (switchTop && this._dragOverLastY != topEdge) {
 | 
			
		||||
            topWorkspace.metaWorkspace.activate(global.get_current_time());
 | 
			
		||||
            topWorkspace.setReservedSlot(dragEvent.dragActor._delegate);
 | 
			
		||||
            this._dragOverLastY = topEdge;
 | 
			
		||||
 | 
			
		||||
            return DND.DragMotionResult.CONTINUE;
 | 
			
		||||
@@ -476,7 +428,6 @@ WorkspacesView.prototype = {
 | 
			
		||||
        let switchBottom = (dragEvent.y >= bottomEdge && bottomWorkspace);
 | 
			
		||||
        if (switchBottom && this._dragOverLastY != bottomEdge) {
 | 
			
		||||
            bottomWorkspace.metaWorkspace.activate(global.get_current_time());
 | 
			
		||||
            bottomWorkspace.setReservedSlot(dragEvent.dragActor._delegate);
 | 
			
		||||
            this._dragOverLastY = bottomEdge;
 | 
			
		||||
 | 
			
		||||
            return DND.DragMotionResult.CONTINUE;
 | 
			
		||||
@@ -511,7 +462,6 @@ WorkspacesView.prototype = {
 | 
			
		||||
                this._timeoutId = Mainloop.timeout_add_seconds(1,
 | 
			
		||||
                    Lang.bind(this, function() {
 | 
			
		||||
                       hoverWorkspace.metaWorkspace.activate(global.get_current_time());
 | 
			
		||||
                       hoverWorkspace.setReservedSlot(dragEvent.dragActor._delegate);
 | 
			
		||||
                       return false;
 | 
			
		||||
                    }));
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -534,6 +484,8 @@ WorkspacesView.prototype = {
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < this._workspaces.length; i++)
 | 
			
		||||
            this._workspaces[i].setReservedSlot(null);
 | 
			
		||||
        for (let i = 0; i < this._extraWorkspaces.length; i++)
 | 
			
		||||
            this._extraWorkspaces[i].setReservedSlot(null);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _swipeScrollBegin: function() {
 | 
			
		||||
@@ -557,12 +509,6 @@ WorkspacesView.prototype = {
 | 
			
		||||
                Main.overview.hide();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (result == Overview.SwipeScrollResult.SWIPE)
 | 
			
		||||
            // The active workspace has changed; while swipe-scrolling
 | 
			
		||||
            // has already taken care of the positioning, the cached
 | 
			
		||||
            // positions need to be updated
 | 
			
		||||
            this._computeWorkspacePositions();
 | 
			
		||||
 | 
			
		||||
        // Make sure title captions etc are shown as necessary
 | 
			
		||||
        this._updateVisibility();
 | 
			
		||||
    },
 | 
			
		||||
@@ -590,7 +536,7 @@ WorkspacesView.prototype = {
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let currentY = firstWorkspaceY;
 | 
			
		||||
        let newY = this._y - adj.value / (adj.upper - 1) * workspacesHeight;
 | 
			
		||||
        let newY =  - adj.value / (adj.upper - 1) * workspacesHeight;
 | 
			
		||||
 | 
			
		||||
        let dy = newY - currentY;
 | 
			
		||||
 | 
			
		||||
@@ -618,6 +564,7 @@ WorkspacesDisplay.prototype = {
 | 
			
		||||
        this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
 | 
			
		||||
        this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
 | 
			
		||||
        this.actor.connect('allocate', Lang.bind(this, this._allocate));
 | 
			
		||||
        this.actor.set_clip_to_allocation(true);
 | 
			
		||||
 | 
			
		||||
        let controls = new St.Bin({ style_class: 'workspace-controls',
 | 
			
		||||
                                    request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT,
 | 
			
		||||
@@ -633,6 +580,8 @@ WorkspacesDisplay.prototype = {
 | 
			
		||||
        controls.connect('scroll-event',
 | 
			
		||||
                         Lang.bind(this, this._onScrollEvent));
 | 
			
		||||
 | 
			
		||||
        this._monitorIndex = global.get_primary_monitor_index();
 | 
			
		||||
        this._monitor = global.get_monitors()[this._monitorIndex];
 | 
			
		||||
 | 
			
		||||
        this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
 | 
			
		||||
        controls.add_actor(this._thumbnailsBox.actor);
 | 
			
		||||
@@ -640,65 +589,53 @@ WorkspacesDisplay.prototype = {
 | 
			
		||||
        this.workspacesView = null;
 | 
			
		||||
 | 
			
		||||
        this._inDrag = false;
 | 
			
		||||
        this._cancelledDrag = false;
 | 
			
		||||
 | 
			
		||||
        this._alwaysZoomOut = false;
 | 
			
		||||
        this._zoomOut = false;
 | 
			
		||||
        this._zoomFraction = 0;
 | 
			
		||||
 | 
			
		||||
        this._updateAlwaysZoom();
 | 
			
		||||
 | 
			
		||||
        global.screen.connect('monitors-changed', Lang.bind(this, this._updateAlwaysZoom));
 | 
			
		||||
        Main.xdndHandler.connect('drag-begin', Lang.bind(this, function(){
 | 
			
		||||
            this._alwaysZoomOut = true;
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        Main.xdndHandler.connect('drag-end', Lang.bind(this, function(){
 | 
			
		||||
            this._alwaysZoomOut = false;
 | 
			
		||||
            this._updateAlwaysZoom();
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        this._nWorkspacesNotifyId = 0;
 | 
			
		||||
        this._switchWorkspaceNotifyId = 0;
 | 
			
		||||
 | 
			
		||||
        this._itemDragBeginId = 0;
 | 
			
		||||
        this._itemDragCancelledId = 0;
 | 
			
		||||
        this._itemDragEndId = 0;
 | 
			
		||||
        this._windowDragBeginId = 0;
 | 
			
		||||
        this._windowDragCancelledId = 0;
 | 
			
		||||
        this._windowDragEndId = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
   show: function() {
 | 
			
		||||
        this._zoomOut = this._alwaysZoomOut;
 | 
			
		||||
        this._zoomFraction = this._alwaysZoomOut ? 1 : 0;
 | 
			
		||||
        this._updateZoom();
 | 
			
		||||
 | 
			
		||||
        this._controls.show();
 | 
			
		||||
        this._thumbnailsBox.show();
 | 
			
		||||
 | 
			
		||||
        this._workspaces = [];
 | 
			
		||||
        for (let i = 0; i < global.screen.n_workspaces; i++) {
 | 
			
		||||
            let metaWorkspace = global.screen.get_workspace_by_index(i);
 | 
			
		||||
            this._workspaces[i] = new Workspace.Workspace(metaWorkspace);
 | 
			
		||||
            this._workspaces[i] = new Workspace.Workspace(metaWorkspace, this._monitorIndex);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let rtl = (St.Widget.get_default_direction () == St.TextDirection.RTL);
 | 
			
		||||
 | 
			
		||||
        let totalAllocation = this.actor.allocation;
 | 
			
		||||
        let totalWidth = totalAllocation.x2 - totalAllocation.x1;
 | 
			
		||||
        let totalHeight = totalAllocation.y2 - totalAllocation.y1;
 | 
			
		||||
 | 
			
		||||
        let controlsVisible = this._controls.get_theme_node().get_length('visible-width');
 | 
			
		||||
 | 
			
		||||
        totalWidth -= controlsVisible;
 | 
			
		||||
 | 
			
		||||
        // Workspaces expect to have the same ratio as the screen, so take
 | 
			
		||||
        // this into account when fitting the workspace into the available space
 | 
			
		||||
        let width, height;
 | 
			
		||||
        let totalRatio = totalWidth / totalHeight;
 | 
			
		||||
        let wsRatio = global.screen_width / global.screen_height;
 | 
			
		||||
        if (wsRatio > totalRatio) {
 | 
			
		||||
            width = totalWidth;
 | 
			
		||||
            height = Math.floor(totalWidth / wsRatio);
 | 
			
		||||
        } else {
 | 
			
		||||
            width = Math.floor(totalHeight * wsRatio);
 | 
			
		||||
            height = totalHeight;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Position workspaces in the available space
 | 
			
		||||
        let [x, y] = this.actor.get_transformed_position();
 | 
			
		||||
        x = Math.floor(x + Math.abs(totalWidth - width) / 2);
 | 
			
		||||
        y = Math.floor(y + Math.abs(totalHeight - height) / 2);
 | 
			
		||||
 | 
			
		||||
        if (rtl)
 | 
			
		||||
            x += controlsVisible;
 | 
			
		||||
 | 
			
		||||
        let newView = new WorkspacesView(width, height, x, y, this._workspaces);
 | 
			
		||||
        this._updateZoomScale();
 | 
			
		||||
 | 
			
		||||
        if (this.workspacesView)
 | 
			
		||||
            this.workspacesView.destroy();
 | 
			
		||||
        this.workspacesView = newView;
 | 
			
		||||
        this.workspacesView = new WorkspacesView(this._workspaces);
 | 
			
		||||
        this._updateWorkspacesGeometry();
 | 
			
		||||
 | 
			
		||||
        this._nWorkspacesNotifyId =
 | 
			
		||||
            global.screen.connect('notify::n-workspaces',
 | 
			
		||||
@@ -711,20 +648,23 @@ WorkspacesDisplay.prototype = {
 | 
			
		||||
        if (this._itemDragBeginId == 0)
 | 
			
		||||
            this._itemDragBeginId = Main.overview.connect('item-drag-begin',
 | 
			
		||||
                                                          Lang.bind(this, this._dragBegin));
 | 
			
		||||
        if (this._itemDragCancelledId == 0)
 | 
			
		||||
            this._itemDragCancelledId = Main.overview.connect('item-drag-cancelled',
 | 
			
		||||
                                                              Lang.bind(this, this._dragCancelled));
 | 
			
		||||
        if (this._itemDragEndId == 0)
 | 
			
		||||
            this._itemDragEndId = Main.overview.connect('item-drag-end',
 | 
			
		||||
                                                        Lang.bind(this, this._dragEnd));
 | 
			
		||||
        if (this._windowDragBeginId == 0)
 | 
			
		||||
            this._windowDragBeginId = Main.overview.connect('window-drag-begin',
 | 
			
		||||
                                                            Lang.bind(this, this._dragBegin));
 | 
			
		||||
        if (this._windowDragCancelledId == 0)
 | 
			
		||||
            this._windowDragCancelledId = Main.overview.connect('window-drag-cancelled',
 | 
			
		||||
                                                            Lang.bind(this, this._dragCancelled));
 | 
			
		||||
        if (this._windowDragEndId == 0)
 | 
			
		||||
            this._windowDragEndId = Main.overview.connect('window-drag-end',
 | 
			
		||||
                                                          Lang.bind(this, this._dragEnd));
 | 
			
		||||
 | 
			
		||||
        this._onRestacked();
 | 
			
		||||
        this._zoomOut = false;
 | 
			
		||||
        this._zoomFraction = 0;
 | 
			
		||||
        this._updateZoom();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hide: function() {
 | 
			
		||||
@@ -743,7 +683,11 @@ WorkspacesDisplay.prototype = {
 | 
			
		||||
            Main.overview.disconnect(this._itemDragBeginId);
 | 
			
		||||
            this._itemDragBeginId = 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (this._itemEndBeginId > 0) {
 | 
			
		||||
        if (this._itemDragCancelledId > 0) {
 | 
			
		||||
            Main.overview.disconnect(this._itemDragCancelledId);
 | 
			
		||||
            this._itemDragCancelledId = 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (this._itemDragEndId > 0) {
 | 
			
		||||
            Main.overview.disconnect(this._itemDragEndId);
 | 
			
		||||
            this._itemDragEndId = 0;
 | 
			
		||||
        }
 | 
			
		||||
@@ -751,6 +695,10 @@ WorkspacesDisplay.prototype = {
 | 
			
		||||
            Main.overview.disconnect(this._windowDragBeginId);
 | 
			
		||||
            this._windowDragBeginId = 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (this._windowDragCancelledId > 0) {
 | 
			
		||||
            Main.overview.disconnect(this._windowDragCancelledId);
 | 
			
		||||
            this._windowDragCancelledId = 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (this._windowDragEndId > 0) {
 | 
			
		||||
            Main.overview.disconnect(this._windowDragEndId);
 | 
			
		||||
            this._windowDragEndId = 0;
 | 
			
		||||
@@ -774,6 +722,23 @@ WorkspacesDisplay.prototype = {
 | 
			
		||||
        return this._zoomFraction;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateAlwaysZoom: function()  {
 | 
			
		||||
        this._alwaysZoomOut = false;
 | 
			
		||||
 | 
			
		||||
        let monitors = global.get_monitors();
 | 
			
		||||
        let primary = global.get_primary_monitor();
 | 
			
		||||
 | 
			
		||||
        /* Look for any monitor to the right of the primary, if there is
 | 
			
		||||
         * one, we always keep zoom out, otherwise its hard to reach
 | 
			
		||||
         * the thumbnail area without passing into the next monitor. */
 | 
			
		||||
        for (let i = 0; i < monitors.length; i++) {
 | 
			
		||||
            if (monitors[i].x >= primary.x + primary.width) {
 | 
			
		||||
                this._alwaysZoomOut = true;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getPreferredWidth: function (actor, forHeight, alloc) {
 | 
			
		||||
        // pass through the call in case the child needs it, but report 0x0
 | 
			
		||||
        this._controls.get_preferred_width(forHeight);
 | 
			
		||||
@@ -809,22 +774,41 @@ WorkspacesDisplay.prototype = {
 | 
			
		||||
        childBox.y2 = box.y2- box.y1;
 | 
			
		||||
        this._controls.allocate(childBox, flags);
 | 
			
		||||
 | 
			
		||||
        this._updateZoomScale();
 | 
			
		||||
        this._updateWorkspacesGeometry();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateZoomScale: function() {
 | 
			
		||||
    _updateWorkspacesGeometry: function() {
 | 
			
		||||
        if (!this.workspacesView)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let totalAllocation = this.actor.allocation;
 | 
			
		||||
        let totalWidth = totalAllocation.x2 - totalAllocation.x1;
 | 
			
		||||
        let totalHeight = totalAllocation.y2 - totalAllocation.y1;
 | 
			
		||||
        let fullWidth = this.actor.allocation.x2 - this.actor.allocation.x1;
 | 
			
		||||
        let fullHeight = this.actor.allocation.y2 - this.actor.allocation.y1;
 | 
			
		||||
 | 
			
		||||
        let [controlsMin, controlsNatural] = this._controls.get_preferred_width(totalHeight);
 | 
			
		||||
        let width = fullWidth;
 | 
			
		||||
        let height = fullHeight;
 | 
			
		||||
 | 
			
		||||
        let [controlsMin, controlsNatural] = this._controls.get_preferred_width(height);
 | 
			
		||||
        let controlsVisible = this._controls.get_theme_node().get_length('visible-width');
 | 
			
		||||
 | 
			
		||||
        let zoomScale = (totalWidth - controlsNatural) / (totalWidth - controlsVisible);
 | 
			
		||||
        this.workspacesView.setZoomScale(zoomScale);
 | 
			
		||||
        let [x, y] = this.actor.get_transformed_position();
 | 
			
		||||
 | 
			
		||||
        let rtl = (St.Widget.get_default_direction () == St.TextDirection.RTL);
 | 
			
		||||
 | 
			
		||||
        if (this._zoomOut) {
 | 
			
		||||
            width -= controlsNatural;
 | 
			
		||||
            if (rtl)
 | 
			
		||||
                x += controlsNatural;
 | 
			
		||||
        } else {
 | 
			
		||||
            width -= controlsVisible;
 | 
			
		||||
            if (rtl)
 | 
			
		||||
                x += controlsVisible;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        height = (fullHeight / fullWidth) * width;
 | 
			
		||||
        let difference = fullHeight - height;
 | 
			
		||||
        y += difference / 2;
 | 
			
		||||
 | 
			
		||||
        this.workspacesView.setGeometry(x, y, width, height, difference);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onRestacked: function() {
 | 
			
		||||
@@ -853,7 +837,7 @@ WorkspacesDisplay.prototype = {
 | 
			
		||||
            // Assume workspaces are only added at the end
 | 
			
		||||
            for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
 | 
			
		||||
                let metaWorkspace = global.screen.get_workspace_by_index(w);
 | 
			
		||||
                this._workspaces[w] = new Workspace.Workspace(metaWorkspace);
 | 
			
		||||
                this._workspaces[w] = new Workspace.Workspace(metaWorkspace, this._monitorIndex);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this._thumbnailsBox.addThumbnails(oldNumWorkspaces, newNumWorkspaces - oldNumWorkspaces);
 | 
			
		||||
@@ -890,9 +874,10 @@ WorkspacesDisplay.prototype = {
 | 
			
		||||
        if (Main.overview.animationInProgress)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let shouldZoom = this._controls.hover || this._inDrag;
 | 
			
		||||
        let shouldZoom = this._alwaysZoomOut || this._controls.hover || (this._inDrag && !this._cancelledDrag);
 | 
			
		||||
        if (shouldZoom != this._zoomOut) {
 | 
			
		||||
            this._zoomOut = shouldZoom;
 | 
			
		||||
            this._updateWorkspacesGeometry();
 | 
			
		||||
 | 
			
		||||
            if (!this.workspacesView)
 | 
			
		||||
                return;
 | 
			
		||||
@@ -902,10 +887,7 @@ WorkspacesDisplay.prototype = {
 | 
			
		||||
                               time: WORKSPACE_SWITCH_TIME,
 | 
			
		||||
                               transition: 'easeOutQuad' });
 | 
			
		||||
 | 
			
		||||
            if (shouldZoom)
 | 
			
		||||
                this.workspacesView.zoomOut();
 | 
			
		||||
            else
 | 
			
		||||
                this.workspacesView.zoomIn();
 | 
			
		||||
            this.workspacesView.updateWindowPositions();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -915,6 +897,12 @@ WorkspacesDisplay.prototype = {
 | 
			
		||||
 | 
			
		||||
    _dragBegin: function() {
 | 
			
		||||
        this._inDrag = true;
 | 
			
		||||
        this._cancelledDrag = false;
 | 
			
		||||
        this._updateZoom();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _dragCancelled: function() {
 | 
			
		||||
        this._cancelledDrag = true;
 | 
			
		||||
        this._updateZoom();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										202
									
								
								js/ui/zeitgeistSearch.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								js/ui/zeitgeistSearch.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,202 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010 Seif Lotfy <seif@lotfy.com>
 | 
			
		||||
 * Copyright (C) 2011 Siegfried-Angel Gevatter Pujals <siegfried@gevatter.com>
 | 
			
		||||
 * Copyright (C) 2010-2011 Collabora Ltd.
 | 
			
		||||
 *     Authored by: Seif Lotfy <seif@lotfy.com>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2, or (at your option)
 | 
			
		||||
 * any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
const Lang = imports.lang;
 | 
			
		||||
const GLib = imports.gi.GLib;
 | 
			
		||||
const Gio = imports.gi.Gio
 | 
			
		||||
const Semantic = imports.misc.semantic;
 | 
			
		||||
const Zeitgeist = imports.misc.zeitgeist;
 | 
			
		||||
 | 
			
		||||
const Gettext = imports.gettext.domain('gnome-shell');
 | 
			
		||||
const _ = Gettext.gettext;
 | 
			
		||||
 | 
			
		||||
const DocInfo = imports.misc.docInfo;
 | 
			
		||||
const Search = imports.ui.search;
 | 
			
		||||
 | 
			
		||||
// FIXME: The subject cache is never being emptied.
 | 
			
		||||
let ZeitgeistSubjectCache = {};
 | 
			
		||||
 | 
			
		||||
function ZeitgeistAsyncSearchProvider(title, interpretations) {
 | 
			
		||||
    this._init(title, interpretations);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ZeitgeistAsyncSearchProvider.prototype = {
 | 
			
		||||
    __proto__: Search.SearchProvider.prototype,
 | 
			
		||||
 | 
			
		||||
    _init: function(title, interpretations) {
 | 
			
		||||
        Search.SearchProvider.prototype._init.call(this, title);
 | 
			
		||||
        this._buildTemplates(interpretations);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _buildTemplates: function(interpretations) {
 | 
			
		||||
        this.templates = [];
 | 
			
		||||
        for (let i = 0; i < interpretations.length; i++) {
 | 
			
		||||
            let subject = new Zeitgeist.Subject('', interpretations[i], '', '', '', '', '');
 | 
			
		||||
            let event = new Zeitgeist.Event('', '', '', [subject], []);
 | 
			
		||||
            this.templates.push(event);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _search: function(terms) {
 | 
			
		||||
        this._search_terms = terms;
 | 
			
		||||
        Zeitgeist.fullTextSearch(terms[0]+'*',
 | 
			
		||||
                                 this.templates,
 | 
			
		||||
                                 Lang.bind(this, function(events) {
 | 
			
		||||
                                     if (terms == this._search_terms)
 | 
			
		||||
                                         this._asyncCallback(events);
 | 
			
		||||
                                 }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _asyncCancelled: function() {
 | 
			
		||||
        this._search_terms = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getInitialResultSet: function(terms) {
 | 
			
		||||
        this._search(terms);
 | 
			
		||||
        return [];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getSubsearchResultSet: function(previousResults, terms) {
 | 
			
		||||
        this.tryCancelAsync();
 | 
			
		||||
        return this.getInitialResultSet(terms);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getResultMeta: function(resultId) {
 | 
			
		||||
        return { 'id': ZeitgeistSubjectCache[resultId].uri,
 | 
			
		||||
                 'name': ZeitgeistSubjectCache[resultId].name,
 | 
			
		||||
                 'createIcon': function (size) {
 | 
			
		||||
                                   return ZeitgeistSubjectCache[resultId].createIcon(size);
 | 
			
		||||
                               },
 | 
			
		||||
               };
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateResult: function(resultId) {
 | 
			
		||||
        Gio.app_info_launch_default_for_uri(resultId,
 | 
			
		||||
                                            global.create_app_launch_context());
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _asyncCallback: function(events) {
 | 
			
		||||
        let items = [];
 | 
			
		||||
        for (let i = 0; i < events.length; i++) {
 | 
			
		||||
            let event = events[i];
 | 
			
		||||
            let subject = event.subjects[0];
 | 
			
		||||
            let uri = subject.uri.replace('file://', '');
 | 
			
		||||
            uri = GLib.uri_unescape_string(uri, '');
 | 
			
		||||
            if (GLib.file_test(uri, GLib.FileTest.EXISTS)) {
 | 
			
		||||
                if (!ZeitgeistSubjectCache.hasOwnProperty(subject.uri)) {
 | 
			
		||||
                    let info = new DocInfo.ZeitgeistItemInfo(event);
 | 
			
		||||
                    ZeitgeistSubjectCache[info.uri] = info;
 | 
			
		||||
                }
 | 
			
		||||
                items.push(subject.uri);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        this.addItems(items);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function DocumentsAsyncSearchProvider() {
 | 
			
		||||
    this._init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DocumentsAsyncSearchProvider.prototype = {
 | 
			
		||||
    __proto__: ZeitgeistAsyncSearchProvider.prototype,
 | 
			
		||||
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        let interpretations = [Semantic.NFO_DOCUMENT];
 | 
			
		||||
        ZeitgeistAsyncSearchProvider.prototype._init.call(this, _("DOCUMENTS"), interpretations);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function VideosAsyncSearchProvider() {
 | 
			
		||||
    this._init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VideosAsyncSearchProvider.prototype = {
 | 
			
		||||
    __proto__: ZeitgeistAsyncSearchProvider.prototype,
 | 
			
		||||
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        let interpretations = [Semantic.NFO_VIDEO];
 | 
			
		||||
        ZeitgeistAsyncSearchProvider.prototype._init.call(this, _("VIDEOS"), interpretations);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function MusicAsyncSearchProvider() {
 | 
			
		||||
    this._init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MusicAsyncSearchProvider.prototype = {
 | 
			
		||||
    __proto__: ZeitgeistAsyncSearchProvider.prototype,
 | 
			
		||||
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        let interpretations = [
 | 
			
		||||
            Semantic.NFO_AUDIO,
 | 
			
		||||
            Semantic.NMM_MUSIC_PIECE];
 | 
			
		||||
        ZeitgeistAsyncSearchProvider.prototype._init.call(this, _("MUSIC"), interpretations);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function PicturesAsyncSearchProvider() {
 | 
			
		||||
    this._init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PicturesAsyncSearchProvider.prototype = {
 | 
			
		||||
    __proto__: ZeitgeistAsyncSearchProvider.prototype,
 | 
			
		||||
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        let interpretations = [Semantic.NFO_IMAGE];
 | 
			
		||||
        ZeitgeistAsyncSearchProvider.prototype._init.call(this, _("PICTURES"), interpretations);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function OtherAsyncSearchProvider() {
 | 
			
		||||
    this._init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
OtherAsyncSearchProvider.prototype = {
 | 
			
		||||
    __proto__: ZeitgeistAsyncSearchProvider.prototype,
 | 
			
		||||
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        let interpretations = [
 | 
			
		||||
            '!' + Semantic.NFO_IMAGE,
 | 
			
		||||
            '!' + Semantic.NFO_DOCUMENT,
 | 
			
		||||
            '!' + Semantic.NFO_VIDEO,
 | 
			
		||||
            '!' + Semantic.NFO_AUDIO,
 | 
			
		||||
            '!' + Semantic.NMM_MUSIC_PIECE];
 | 
			
		||||
        ZeitgeistAsyncSearchProvider.prototype._init.call(this, _("OTHER"), interpretations);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _buildTemplates: function(interpretations) {
 | 
			
		||||
        // Here we want to get everything matching all of the templates, and
 | 
			
		||||
        // not just any of them. Therefore we need to AND the interpretations
 | 
			
		||||
        // instead of OR'ing them; this is done by having an Event with
 | 
			
		||||
        // different Subjects.
 | 
			
		||||
        this.templates = [];
 | 
			
		||||
        let subjects = [];
 | 
			
		||||
        for (let i = 0; i < interpretations.length; i++) {
 | 
			
		||||
            let subject = new Zeitgeist.Subject('', interpretations[i], '', '', '', '', '');
 | 
			
		||||
            subjects.push(subject);
 | 
			
		||||
        }
 | 
			
		||||
        let event = new Zeitgeist.Event('', '', '', subjects, []);
 | 
			
		||||
        this.templates.push(event);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
af
 | 
			
		||||
ar
 | 
			
		||||
bg
 | 
			
		||||
bn_IN
 | 
			
		||||
ca
 | 
			
		||||
cs
 | 
			
		||||
da
 | 
			
		||||
@@ -15,6 +17,7 @@ ga
 | 
			
		||||
gl
 | 
			
		||||
gu
 | 
			
		||||
he
 | 
			
		||||
hi
 | 
			
		||||
hu
 | 
			
		||||
id
 | 
			
		||||
it
 | 
			
		||||
@@ -22,6 +25,8 @@ ja
 | 
			
		||||
ko
 | 
			
		||||
kn
 | 
			
		||||
lt
 | 
			
		||||
lv
 | 
			
		||||
mr
 | 
			
		||||
nb
 | 
			
		||||
nl
 | 
			
		||||
nn
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ js/ui/messageTray.js
 | 
			
		||||
js/ui/overview.js
 | 
			
		||||
js/ui/panel.js
 | 
			
		||||
js/ui/placeDisplay.js
 | 
			
		||||
js/ui/polkitAuthenticationAgent.js
 | 
			
		||||
js/ui/popupMenu.js
 | 
			
		||||
js/ui/runDialog.js
 | 
			
		||||
js/ui/searchDisplay.js
 | 
			
		||||
@@ -20,6 +21,7 @@ js/ui/statusMenu.js
 | 
			
		||||
js/ui/status/accessibility.js
 | 
			
		||||
js/ui/status/bluetooth.js
 | 
			
		||||
js/ui/status/keyboard.js
 | 
			
		||||
js/ui/status/network.js
 | 
			
		||||
js/ui/status/power.js
 | 
			
		||||
js/ui/status/volume.js
 | 
			
		||||
js/ui/telepathyClient.js
 | 
			
		||||
@@ -29,8 +31,10 @@ js/ui/workspacesView.js
 | 
			
		||||
src/gvc/gvc-mixer-control.c
 | 
			
		||||
src/gdmuser/gdm-user.c
 | 
			
		||||
src/main.c
 | 
			
		||||
src/shell-app.c
 | 
			
		||||
src/shell-app-system.c
 | 
			
		||||
src/shell-global.c
 | 
			
		||||
src/shell-mobile-providers.c
 | 
			
		||||
src/shell-polkit-authentication-agent.c
 | 
			
		||||
src/shell-util.c
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										471
									
								
								po/bg.po
									
									
									
									
									
								
							
							
						
						
									
										471
									
								
								po/bg.po
									
									
									
									
									
								
							@@ -7,8 +7,8 @@ msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: gnome-shell master\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: \n"
 | 
			
		||||
"POT-Creation-Date: 2011-03-05 23:07+0200\n"
 | 
			
		||||
"PO-Revision-Date: 2011-03-05 23:07+0200\n"
 | 
			
		||||
"POT-Creation-Date: 2011-03-27 08:03+0300\n"
 | 
			
		||||
"PO-Revision-Date: 2011-03-27 08:03+0300\n"
 | 
			
		||||
"Last-Translator: Ivaylo Valkov <ivaylo@e-valkov.org>\n"
 | 
			
		||||
"Language-Team: Bulgarian <dict@fsa-bg.org>\n"
 | 
			
		||||
"Language: bg\n"
 | 
			
		||||
@@ -174,47 +174,43 @@ msgstr "Дали да се събира статистика за използв
 | 
			
		||||
msgid "disabled OpenSearch providers"
 | 
			
		||||
msgstr "изключени доставчици на OpenSearch"
 | 
			
		||||
 | 
			
		||||
#: ../js/misc/util.js:86
 | 
			
		||||
#: ../js/misc/util.js:71
 | 
			
		||||
msgid "Command not found"
 | 
			
		||||
msgstr "Командата не беше открита"
 | 
			
		||||
 | 
			
		||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
 | 
			
		||||
#. something nicer
 | 
			
		||||
#: ../js/misc/util.js:113
 | 
			
		||||
#: ../js/misc/util.js:98
 | 
			
		||||
msgid "Could not parse command:"
 | 
			
		||||
msgstr "Неуспех при анализиране на командата:"
 | 
			
		||||
 | 
			
		||||
#: ../js/misc/util.js:135
 | 
			
		||||
msgid "No such application"
 | 
			
		||||
msgstr "Няма такава програма"
 | 
			
		||||
 | 
			
		||||
#: ../js/misc/util.js:148
 | 
			
		||||
#: ../js/misc/util.js:106
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Execution of '%s' failed:"
 | 
			
		||||
msgstr "Неуспешно изпълнение на „%s“:"
 | 
			
		||||
 | 
			
		||||
#. Translators: Filter to display all applications
 | 
			
		||||
#: ../js/ui/appDisplay.js:195
 | 
			
		||||
#: ../js/ui/appDisplay.js:230
 | 
			
		||||
msgid "All"
 | 
			
		||||
msgstr "Всички"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:285
 | 
			
		||||
#: ../js/ui/appDisplay.js:328
 | 
			
		||||
msgid "APPLICATIONS"
 | 
			
		||||
msgstr "ПРОГРАМИ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:311
 | 
			
		||||
#: ../js/ui/appDisplay.js:354
 | 
			
		||||
msgid "SETTINGS"
 | 
			
		||||
msgstr "НАСТРОЙКИ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:565
 | 
			
		||||
#: ../js/ui/appDisplay.js:625
 | 
			
		||||
msgid "New Window"
 | 
			
		||||
msgstr "Нов прозорец"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:568
 | 
			
		||||
#: ../js/ui/appDisplay.js:628
 | 
			
		||||
msgid "Remove from Favorites"
 | 
			
		||||
msgstr "Премахване от „Любими“"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:569
 | 
			
		||||
#: ../js/ui/appDisplay.js:629
 | 
			
		||||
msgid "Add to Favorites"
 | 
			
		||||
msgstr "Добавяне в „Любими“"
 | 
			
		||||
 | 
			
		||||
@@ -244,7 +240,6 @@ msgstr "%H:%M"
 | 
			
		||||
 | 
			
		||||
#. Transators: Shown in calendar event list, if 12h format
 | 
			
		||||
#: ../js/ui/calendar.js:78
 | 
			
		||||
#, fuzzy
 | 
			
		||||
msgctxt "event list time"
 | 
			
		||||
msgid "%l:%M %p"
 | 
			
		||||
msgstr "%l:%M %p"
 | 
			
		||||
@@ -349,14 +344,12 @@ msgstr "Няма нищо запланувано"
 | 
			
		||||
 | 
			
		||||
#. Translators: Shown on calendar heading when selected day occurs on current year
 | 
			
		||||
#: ../js/ui/calendar.js:720
 | 
			
		||||
#, fuzzy
 | 
			
		||||
msgctxt "calendar heading"
 | 
			
		||||
msgid "%A, %B %d"
 | 
			
		||||
msgstr "%A, %B %d"
 | 
			
		||||
 | 
			
		||||
#. Translators: Shown on calendar heading when selected day occurs on different year
 | 
			
		||||
#: ../js/ui/calendar.js:723
 | 
			
		||||
#, fuzzy
 | 
			
		||||
msgctxt "calendar heading"
 | 
			
		||||
msgid "%A, %B %d, %Y"
 | 
			
		||||
msgstr "%A, %B, %d, %Y"
 | 
			
		||||
@@ -377,7 +370,7 @@ msgstr "Тази седмица"
 | 
			
		||||
msgid "Next week"
 | 
			
		||||
msgstr "Следващата седмица"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dash.js:174
 | 
			
		||||
#: ../js/ui/dash.js:174 ../js/ui/messageTray.js:1000
 | 
			
		||||
msgid "Remove"
 | 
			
		||||
msgstr "Премахване"
 | 
			
		||||
 | 
			
		||||
@@ -385,55 +378,54 @@ msgstr "Премахване"
 | 
			
		||||
msgid "Date and Time Settings"
 | 
			
		||||
msgstr "Настройки на датата и времето"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:110
 | 
			
		||||
#: ../js/ui/dateMenu.js:111
 | 
			
		||||
msgid "Open Calendar"
 | 
			
		||||
msgstr "Отваряне на календара"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is the time format with date used
 | 
			
		||||
#. in 24-hour mode.
 | 
			
		||||
#: ../js/ui/dateMenu.js:162
 | 
			
		||||
#: ../js/ui/dateMenu.js:164
 | 
			
		||||
msgid "%a %b %e, %R:%S"
 | 
			
		||||
msgstr "%a, %e %b, %R:%S"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:163
 | 
			
		||||
#: ../js/ui/dateMenu.js:165
 | 
			
		||||
msgid "%a %b %e, %R"
 | 
			
		||||
msgstr "%a, %e %b, %R"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is the time format without date used
 | 
			
		||||
#. in 24-hour mode.
 | 
			
		||||
#: ../js/ui/dateMenu.js:167
 | 
			
		||||
#: ../js/ui/dateMenu.js:169
 | 
			
		||||
msgid "%a %R:%S"
 | 
			
		||||
msgstr "%a, %R:%S"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:168
 | 
			
		||||
#: ../js/ui/dateMenu.js:170
 | 
			
		||||
msgid "%a %R"
 | 
			
		||||
msgstr "%a, %R"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is a time format with date used
 | 
			
		||||
#. for AM/PM.
 | 
			
		||||
#: ../js/ui/dateMenu.js:175
 | 
			
		||||
#: ../js/ui/dateMenu.js:177
 | 
			
		||||
msgid "%a %b %e, %l:%M:%S %p"
 | 
			
		||||
msgstr "%a, %e %b, %l:%M:%S %p"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:176
 | 
			
		||||
#: ../js/ui/dateMenu.js:178
 | 
			
		||||
msgid "%a %b %e, %l:%M %p"
 | 
			
		||||
msgstr "%a, %e %b, %l:%M %p"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is a time format without date used
 | 
			
		||||
#. for AM/PM.
 | 
			
		||||
#: ../js/ui/dateMenu.js:180
 | 
			
		||||
#: ../js/ui/dateMenu.js:182
 | 
			
		||||
msgid "%a %l:%M:%S %p"
 | 
			
		||||
msgstr "%a %l:%M:%S %p"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:181
 | 
			
		||||
#: ../js/ui/dateMenu.js:183
 | 
			
		||||
msgid "%a %l:%M %p"
 | 
			
		||||
msgstr "%a, %H:%M"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is the date format to use when the calendar popup is
 | 
			
		||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
 | 
			
		||||
#.
 | 
			
		||||
#: ../js/ui/dateMenu.js:207
 | 
			
		||||
#, fuzzy
 | 
			
		||||
#: ../js/ui/dateMenu.js:194
 | 
			
		||||
msgid "%A %B %e, %Y"
 | 
			
		||||
msgstr "%A %B %e, %Y"
 | 
			
		||||
 | 
			
		||||
@@ -446,7 +438,7 @@ msgstr "СКОРО ОТВАРЯНИ"
 | 
			
		||||
msgid "Log Out %s"
 | 
			
		||||
msgstr "Изход на „%s“"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:69
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:70
 | 
			
		||||
msgid "Log Out"
 | 
			
		||||
msgstr "Изход"
 | 
			
		||||
 | 
			
		||||
@@ -469,49 +461,47 @@ msgstr "Ще излезете от системата автоматично с
 | 
			
		||||
msgid "Logging out of the system."
 | 
			
		||||
msgstr "Излизане от системата."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:74 ../js/ui/endSessionDialog.js:78
 | 
			
		||||
msgid "Shut Down"
 | 
			
		||||
msgstr "Изключване на компютъра"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:75
 | 
			
		||||
msgid "Click Shut Down to quit these applications and shut down the system."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Натиснете „Изключване на системата“, за да спрете тези програми и да "
 | 
			
		||||
"изключите системата."
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:75 ../js/ui/endSessionDialog.js:82
 | 
			
		||||
msgid "Power Off"
 | 
			
		||||
msgstr "Изключване"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:76
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The system will shut down automatically in %d seconds."
 | 
			
		||||
msgstr "Системата ще се изключи автоматично след %d секунди."
 | 
			
		||||
msgid "Click Power Off to quit these applications and power off the system."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Натиснете „Изключване“, за да спрете тези програми и да излезете от "
 | 
			
		||||
"системата."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:77
 | 
			
		||||
msgid "Shutting down the system."
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The system will power off automatically in %d seconds."
 | 
			
		||||
msgstr "Системата ще се изключи автоматично след %d секунди."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:78
 | 
			
		||||
msgid "Powering off the system."
 | 
			
		||||
msgstr "Изключване на системата."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:84 ../js/ui/endSessionDialog.js:88
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:80 ../js/ui/endSessionDialog.js:88
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:93
 | 
			
		||||
msgid "Restart"
 | 
			
		||||
msgstr "Рестартиране"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:85
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:89
 | 
			
		||||
msgid "Click Restart to quit these applications and restart the system."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Натиснете „Рестартиране“, за да спрете тези програми и да рестартирате "
 | 
			
		||||
"системата."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:86
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:90
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The system will restart automatically in %d seconds."
 | 
			
		||||
msgstr "Системата ще се рестартира автоматично след %d секунди."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:87
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:91
 | 
			
		||||
msgid "Restarting the system."
 | 
			
		||||
msgstr "Рестартиране на системата."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:395
 | 
			
		||||
msgid "Confirm"
 | 
			
		||||
msgstr "Потвърждаване"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:400 ../js/ui/status/bluetooth.js:470
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:415 ../js/ui/polkitAuthenticationAgent.js:172
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:466
 | 
			
		||||
msgid "Cancel"
 | 
			
		||||
msgstr "Отказване"
 | 
			
		||||
 | 
			
		||||
@@ -525,7 +515,7 @@ msgstr "Включено"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The device has been disabled
 | 
			
		||||
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1087
 | 
			
		||||
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1091
 | 
			
		||||
msgid "Disabled"
 | 
			
		||||
msgstr "Изключено"
 | 
			
		||||
 | 
			
		||||
@@ -545,34 +535,48 @@ msgstr "Преглед на изходния код"
 | 
			
		||||
msgid "Web Page"
 | 
			
		||||
msgstr "Домашна страница"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/messageTray.js:1907
 | 
			
		||||
#: ../js/ui/messageTray.js:993
 | 
			
		||||
msgid "Open"
 | 
			
		||||
msgstr "Отваряне"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/messageTray.js:2151
 | 
			
		||||
msgid "System Information"
 | 
			
		||||
msgstr "Информация за системата"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/overview.js:88
 | 
			
		||||
#: ../js/ui/overview.js:91
 | 
			
		||||
msgid "Undo"
 | 
			
		||||
msgstr "Отмяна"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/overview.js:183
 | 
			
		||||
#: ../js/ui/overview.js:186
 | 
			
		||||
msgid "Windows"
 | 
			
		||||
msgstr "Прозорци"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/overview.js:186
 | 
			
		||||
#: ../js/ui/overview.js:189
 | 
			
		||||
msgid "Applications"
 | 
			
		||||
msgstr "Програми"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is the name of the dock/favorites area on
 | 
			
		||||
#. the left of the overview
 | 
			
		||||
#: ../js/ui/overview.js:205
 | 
			
		||||
msgid "Dash"
 | 
			
		||||
msgstr "Най-ползвани"
 | 
			
		||||
 | 
			
		||||
#. TODO - _quit() doesn't really work on apps in state STARTING yet
 | 
			
		||||
#: ../js/ui/panel.js:531
 | 
			
		||||
#: ../js/ui/panel.js:515
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Quit %s"
 | 
			
		||||
msgstr "Спиране на програмата „%s“"
 | 
			
		||||
 | 
			
		||||
#. Button on the left side of the panel.
 | 
			
		||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
 | 
			
		||||
#: ../js/ui/panel.js:892
 | 
			
		||||
#: ../js/ui/panel.js:878
 | 
			
		||||
msgid "Activities"
 | 
			
		||||
msgstr "Дейности"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/panel.js:979
 | 
			
		||||
msgid "Top Bar"
 | 
			
		||||
msgstr "Горна лента"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/placeDisplay.js:122
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to unmount '%s'"
 | 
			
		||||
@@ -586,65 +590,85 @@ msgstr "Повторен опит"
 | 
			
		||||
msgid "Connect to..."
 | 
			
		||||
msgstr "Свързване към…"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/placeDisplay.js:409
 | 
			
		||||
#: ../js/ui/placeDisplay.js:380
 | 
			
		||||
msgid "PLACES & DEVICES"
 | 
			
		||||
msgstr "МЕСТА И УСТРОЙСТВА"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:74
 | 
			
		||||
msgid "Authentication Required"
 | 
			
		||||
msgstr "Необходимо е удостоверяване"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:108
 | 
			
		||||
msgid "Administrator"
 | 
			
		||||
msgstr "Администратор"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:176
 | 
			
		||||
msgid "Authenticate"
 | 
			
		||||
msgstr "Удостоверяване"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:260
 | 
			
		||||
msgid "Sorry, that didn't work. Please try again."
 | 
			
		||||
msgstr "Действието не беше успешно. Опитайте отново."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:272
 | 
			
		||||
msgid "Password:"
 | 
			
		||||
msgstr "Парола:"
 | 
			
		||||
 | 
			
		||||
#. Translators: this MUST be either "toggle-switch-us"
 | 
			
		||||
#. (for toggle switches containing the English words
 | 
			
		||||
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
 | 
			
		||||
#. switches containing "◯" and "|"). Other values will
 | 
			
		||||
#. simply result in invisible toggle switches.
 | 
			
		||||
#: ../js/ui/popupMenu.js:612
 | 
			
		||||
#: ../js/ui/popupMenu.js:679
 | 
			
		||||
msgid "toggle-switch-us"
 | 
			
		||||
msgstr "toggle-switch-intl"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/runDialog.js:201
 | 
			
		||||
#: ../js/ui/runDialog.js:205
 | 
			
		||||
msgid "Please enter a command:"
 | 
			
		||||
msgstr "Въведете команда:"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/searchDisplay.js:283
 | 
			
		||||
#: ../js/ui/searchDisplay.js:310
 | 
			
		||||
msgid "Searching..."
 | 
			
		||||
msgstr "Търсене…"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/searchDisplay.js:297
 | 
			
		||||
#: ../js/ui/searchDisplay.js:324
 | 
			
		||||
msgid "No matching results."
 | 
			
		||||
msgstr "Няма съвпадения."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:102 ../js/ui/statusMenu.js:166
 | 
			
		||||
#: ../js/ui/statusMenu.js:161 ../js/ui/statusMenu.js:163
 | 
			
		||||
#: ../js/ui/statusMenu.js:228
 | 
			
		||||
msgid "Power Off..."
 | 
			
		||||
msgstr "Изключване..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:104 ../js/ui/statusMenu.js:165
 | 
			
		||||
#: ../js/ui/statusMenu.js:163 ../js/ui/statusMenu.js:227
 | 
			
		||||
msgid "Suspend"
 | 
			
		||||
msgstr "Приспиване"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:125
 | 
			
		||||
#: ../js/ui/statusMenu.js:184
 | 
			
		||||
msgid "Available"
 | 
			
		||||
msgstr "На линия"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:130
 | 
			
		||||
#, fuzzy
 | 
			
		||||
#: ../js/ui/statusMenu.js:189
 | 
			
		||||
msgid "Busy"
 | 
			
		||||
msgstr "Правя нещо друго"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:138
 | 
			
		||||
#: ../js/ui/statusMenu.js:197
 | 
			
		||||
msgid "My Account"
 | 
			
		||||
msgstr "Моята регистрация"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:142
 | 
			
		||||
#: ../js/ui/statusMenu.js:201
 | 
			
		||||
msgid "System Settings"
 | 
			
		||||
msgstr "Настройки на системата"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:149
 | 
			
		||||
#: ../js/ui/statusMenu.js:208
 | 
			
		||||
msgid "Lock Screen"
 | 
			
		||||
msgstr "Заключване на екрана"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:153
 | 
			
		||||
#: ../js/ui/statusMenu.js:213
 | 
			
		||||
msgid "Switch User"
 | 
			
		||||
msgstr "Смяна на потребител"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:158
 | 
			
		||||
#: ../js/ui/statusMenu.js:218
 | 
			
		||||
msgid "Log Out..."
 | 
			
		||||
msgstr "Изход…"
 | 
			
		||||
 | 
			
		||||
@@ -652,14 +676,12 @@ msgstr "Изход…"
 | 
			
		||||
msgid "Zoom"
 | 
			
		||||
msgstr "Увеличаване"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:69
 | 
			
		||||
msgid "Screen Reader"
 | 
			
		||||
msgstr "Четец на екрана"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:73
 | 
			
		||||
msgid "Screen Keyboard"
 | 
			
		||||
msgstr "Екранна клавиатура"
 | 
			
		||||
 | 
			
		||||
#. let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
 | 
			
		||||
#. 'screen-reader-enabled');
 | 
			
		||||
#. this.menu.addMenuItem(screenReader);
 | 
			
		||||
#. let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
 | 
			
		||||
#. 'screen-keyboard-enabled');
 | 
			
		||||
#. this.menu.addMenuItem(screenKeyboard);
 | 
			
		||||
#: ../js/ui/status/accessibility.js:77
 | 
			
		||||
msgid "Visual Alerts"
 | 
			
		||||
msgstr "Визуална помощ"
 | 
			
		||||
@@ -684,17 +706,17 @@ msgstr "Клавиши за мишка"
 | 
			
		||||
msgid "Universal Access Settings"
 | 
			
		||||
msgstr "Настройки на универсалния достъп"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:145
 | 
			
		||||
#: ../js/ui/status/accessibility.js:146
 | 
			
		||||
msgid "High Contrast"
 | 
			
		||||
msgstr "Висок контраст"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:182
 | 
			
		||||
#: ../js/ui/status/accessibility.js:183
 | 
			
		||||
msgid "Large Text"
 | 
			
		||||
msgstr "Едър текст"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:241
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:337 ../js/ui/status/bluetooth.js:371
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:411 ../js/ui/status/bluetooth.js:444
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:237
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:333 ../js/ui/status/bluetooth.js:367
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:407 ../js/ui/status/bluetooth.js:440
 | 
			
		||||
msgid "Bluetooth"
 | 
			
		||||
msgstr "Bluetooth"
 | 
			
		||||
 | 
			
		||||
@@ -714,94 +736,94 @@ msgstr "Добавяне на ново устройство..."
 | 
			
		||||
msgid "Bluetooth Settings"
 | 
			
		||||
msgstr "Настройки на Bluetooth"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:192
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:188
 | 
			
		||||
msgid "Connection"
 | 
			
		||||
msgstr "Свързване"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:228
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:224
 | 
			
		||||
msgid "Send Files..."
 | 
			
		||||
msgstr "Изпращане на файлове..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:233
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:229
 | 
			
		||||
msgid "Browse Files..."
 | 
			
		||||
msgstr "Разглеждане на файлове..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:242
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:238
 | 
			
		||||
msgid "Error browsing device"
 | 
			
		||||
msgstr "Грешка при разглеждане на устройството"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:243
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:239
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The requested device cannot be browsed, error is '%s'"
 | 
			
		||||
msgstr "Заявеното устройство не може да бъде разгледано. Грешката е „%s“"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:251
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:247
 | 
			
		||||
msgid "Keyboard Settings"
 | 
			
		||||
msgstr "Настройка на клавиатурата"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:256
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:252
 | 
			
		||||
msgid "Mouse Settings"
 | 
			
		||||
msgstr "Настройки на мишката"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:263 ../js/ui/status/volume.js:65
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:259 ../js/ui/status/volume.js:66
 | 
			
		||||
msgid "Sound Settings"
 | 
			
		||||
msgstr "Настройки на звука"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:372
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:368
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Authorization request from %s"
 | 
			
		||||
msgstr "Заявка за упълномощаване от „%s“"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:378
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:374
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Device %s wants access to the service '%s'"
 | 
			
		||||
msgstr "Устройството %s иска достъп до услугата „%s“"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:380
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:376
 | 
			
		||||
msgid "Always grant access"
 | 
			
		||||
msgstr "Винаги позволяване на достъп"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:381
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:377
 | 
			
		||||
msgid "Grant this time only"
 | 
			
		||||
msgstr "Позволяване само този път"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:382
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:378
 | 
			
		||||
msgid "Reject"
 | 
			
		||||
msgstr "Отхвърляне"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:412
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:408
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Pairing confirmation for %s"
 | 
			
		||||
msgstr "Потвърждение за сдвояване с „%s“"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:418 ../js/ui/status/bluetooth.js:452
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:414 ../js/ui/status/bluetooth.js:448
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Device %s wants to pair with this computer"
 | 
			
		||||
msgstr "Устройството %s иска да се сдвои с този компютър"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:419
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:415
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Please confirm whether the PIN '%s' matches the one on the device."
 | 
			
		||||
msgstr "Потвърдете дали кодът „%s“ съвпада с този на устройството."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:421
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:417
 | 
			
		||||
msgid "Matches"
 | 
			
		||||
msgstr "Съвпадения"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:422
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:418
 | 
			
		||||
msgid "Does not match"
 | 
			
		||||
msgstr "Няма съвпадения"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:445
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:441
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Pairing request for %s"
 | 
			
		||||
msgstr "Запитване за свързване с „%s“"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:453
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:449
 | 
			
		||||
msgid "Please enter the PIN mentioned on the device."
 | 
			
		||||
msgstr "Въведете кода на устройството %s."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:469
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:465
 | 
			
		||||
msgid "OK"
 | 
			
		||||
msgstr "Добре"
 | 
			
		||||
 | 
			
		||||
@@ -813,17 +835,153 @@ msgstr "Показване клавиатурната подредба…"
 | 
			
		||||
msgid "Localization Settings"
 | 
			
		||||
msgstr "Настройка на локализацията"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:104 ../js/ui/status/network.js:1454
 | 
			
		||||
msgid "<unknown>"
 | 
			
		||||
msgstr "<неизвестно>"
 | 
			
		||||
 | 
			
		||||
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
 | 
			
		||||
#: ../js/ui/status/network.js:311
 | 
			
		||||
msgid "disabled"
 | 
			
		||||
msgstr "изключено"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:494
 | 
			
		||||
msgid "connecting..."
 | 
			
		||||
msgstr "свързване…"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for network connections that require some kind of key or password
 | 
			
		||||
#: ../js/ui/status/network.js:497
 | 
			
		||||
msgid "authentication required"
 | 
			
		||||
msgstr "изисква се удостоверяване"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for devices that require some kind of firmware or kernel
 | 
			
		||||
#. module, which is missing
 | 
			
		||||
#: ../js/ui/status/network.js:507
 | 
			
		||||
msgid "firmware missing"
 | 
			
		||||
msgstr "липсва фърмуер"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for wired network devices that are physically disconnected
 | 
			
		||||
#: ../js/ui/status/network.js:514
 | 
			
		||||
msgid "cable unplugged"
 | 
			
		||||
msgstr "кабелът е изваден"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for a network device that cannot be activated (for example it
 | 
			
		||||
#. is disabled by rfkill, or it has no coverage
 | 
			
		||||
#: ../js/ui/status/network.js:519
 | 
			
		||||
msgid "unavailable"
 | 
			
		||||
msgstr "недостъпно"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:521
 | 
			
		||||
msgid "connection failed"
 | 
			
		||||
msgstr "връзката е неуспешна"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
 | 
			
		||||
#. and we cannot access its settings (including the name)
 | 
			
		||||
#: ../js/ui/status/network.js:602 ../js/ui/status/network.js:1402
 | 
			
		||||
msgid "Connected (private)"
 | 
			
		||||
msgstr "Връзката е осъществена (няма налични данни)"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:683
 | 
			
		||||
msgid "Auto Ethernet"
 | 
			
		||||
msgstr "Автоматична мрежа по Ethernet"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:758
 | 
			
		||||
msgid "Auto broadband"
 | 
			
		||||
msgstr "Автоматична широколентова мрежа"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:761
 | 
			
		||||
msgid "Auto dial-up"
 | 
			
		||||
msgstr "Автоматична мрежа през модем"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
 | 
			
		||||
#: ../js/ui/status/network.js:904 ../js/ui/status/network.js:1414
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Auto %s"
 | 
			
		||||
msgstr "Автоматична мрежа към „%s“"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:906
 | 
			
		||||
msgid "Auto bluetooth"
 | 
			
		||||
msgstr "Автоматична мрежа по Bluetooth"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1416
 | 
			
		||||
msgid "Auto wireless"
 | 
			
		||||
msgstr "Автоматична безжична мрежа"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1474
 | 
			
		||||
msgid "More..."
 | 
			
		||||
msgstr "Повече…"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1497
 | 
			
		||||
msgid "Enable networking"
 | 
			
		||||
msgstr "Включване на мрежата"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1509
 | 
			
		||||
msgid "Wired"
 | 
			
		||||
msgstr "Жична"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1520
 | 
			
		||||
msgid "Wireless"
 | 
			
		||||
msgstr "Безжична"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1530
 | 
			
		||||
msgid "Mobile broadband"
 | 
			
		||||
msgstr "Мобилна широколентова"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1540
 | 
			
		||||
msgid "VPN Connections"
 | 
			
		||||
msgstr "Връзки към ВЧМ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1549
 | 
			
		||||
msgid "Network Settings"
 | 
			
		||||
msgstr "Настройки на мрежата"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1844
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to mobile broadband connection '%s'"
 | 
			
		||||
msgstr "Връзката в момента е към мобилната широколентова мрежа „%s“"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1848
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to wireless network '%s'"
 | 
			
		||||
msgstr "Връзката в момента е към безжичната мрежа „%s“"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1852
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to wired network '%s'"
 | 
			
		||||
msgstr "Връзката в момента е към жичната мрежа „%s“"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1856
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to VPN network '%s'"
 | 
			
		||||
msgstr "Връзката в момента е към ВЧМ „%s“"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1861
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to '%s'"
 | 
			
		||||
msgstr "Връзката в момента е към „%s“"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1869
 | 
			
		||||
msgid "Connection established"
 | 
			
		||||
msgstr "Връзката е осъществена"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1991
 | 
			
		||||
msgid "Networking is disabled"
 | 
			
		||||
msgstr "Мрежата е изключена"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:2116
 | 
			
		||||
msgid "Network Manager"
 | 
			
		||||
msgstr "Управление на мрежата"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:85
 | 
			
		||||
msgid "Power Settings"
 | 
			
		||||
msgstr "Настройка на захранването"
 | 
			
		||||
 | 
			
		||||
#. 0 is reported when UPower does not have enough data
 | 
			
		||||
#. to estimate battery life
 | 
			
		||||
#: ../js/ui/status/power.js:110
 | 
			
		||||
#: ../js/ui/status/power.js:111
 | 
			
		||||
msgid "Estimating..."
 | 
			
		||||
msgstr "Приблизително времето…"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:117
 | 
			
		||||
#: ../js/ui/status/power.js:118
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d hour remaining"
 | 
			
		||||
msgid_plural "%d hours remaining"
 | 
			
		||||
@@ -831,110 +989,110 @@ msgstr[0] "Остава %d час"
 | 
			
		||||
msgstr[1] "Остават %d часа"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
 | 
			
		||||
#: ../js/ui/status/power.js:120
 | 
			
		||||
#: ../js/ui/status/power.js:121
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d %s %d %s remaining"
 | 
			
		||||
msgstr "Остават %d %s и %d %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:122
 | 
			
		||||
#: ../js/ui/status/power.js:123
 | 
			
		||||
msgid "hour"
 | 
			
		||||
msgid_plural "hours"
 | 
			
		||||
msgstr[0] "час"
 | 
			
		||||
msgstr[1] "часа"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:122
 | 
			
		||||
#: ../js/ui/status/power.js:123
 | 
			
		||||
msgid "minute"
 | 
			
		||||
msgid_plural "minutes"
 | 
			
		||||
msgstr[0] "минута"
 | 
			
		||||
msgstr[1] "минути"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:125
 | 
			
		||||
#: ../js/ui/status/power.js:126
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d minute remaining"
 | 
			
		||||
msgid_plural "%d minutes remaining"
 | 
			
		||||
msgstr[0] "остават %d минути"
 | 
			
		||||
msgstr[1] "остават %d минути"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:227
 | 
			
		||||
#: ../js/ui/status/power.js:228
 | 
			
		||||
msgid "AC adapter"
 | 
			
		||||
msgstr "Адаптер за ел. мрежа"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:229
 | 
			
		||||
#: ../js/ui/status/power.js:230
 | 
			
		||||
msgid "Laptop battery"
 | 
			
		||||
msgstr "Батерия на преносим компютър"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:231
 | 
			
		||||
#: ../js/ui/status/power.js:232
 | 
			
		||||
msgid "UPS"
 | 
			
		||||
msgstr "Непрекъсваемо токозахранване"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:233
 | 
			
		||||
#: ../js/ui/status/power.js:234
 | 
			
		||||
msgid "Monitor"
 | 
			
		||||
msgstr "Монитор"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:235
 | 
			
		||||
#: ../js/ui/status/power.js:236
 | 
			
		||||
msgid "Mouse"
 | 
			
		||||
msgstr "Мишка"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:237
 | 
			
		||||
#: ../js/ui/status/power.js:238
 | 
			
		||||
msgid "Keyboard"
 | 
			
		||||
msgstr "Клавиатура"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:239
 | 
			
		||||
#: ../js/ui/status/power.js:240
 | 
			
		||||
msgid "PDA"
 | 
			
		||||
msgstr "Цифров помощник"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:241
 | 
			
		||||
#: ../js/ui/status/power.js:242
 | 
			
		||||
msgid "Cell phone"
 | 
			
		||||
msgstr "Мобилен телефон"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:243
 | 
			
		||||
#: ../js/ui/status/power.js:244
 | 
			
		||||
msgid "Media player"
 | 
			
		||||
msgstr "Музикално устройство"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:245
 | 
			
		||||
#: ../js/ui/status/power.js:246
 | 
			
		||||
msgid "Tablet"
 | 
			
		||||
msgstr "Таблет"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:247
 | 
			
		||||
#: ../js/ui/status/power.js:248
 | 
			
		||||
msgid "Computer"
 | 
			
		||||
msgstr "Компютър"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:249 ../src/shell-app-system.c:1013
 | 
			
		||||
#: ../js/ui/status/power.js:250 ../src/shell-app-system.c:1088
 | 
			
		||||
msgid "Unknown"
 | 
			
		||||
msgstr "Неизвестно"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/volume.js:44
 | 
			
		||||
#: ../js/ui/status/volume.js:45
 | 
			
		||||
msgid "Volume"
 | 
			
		||||
msgstr "Сила на звука"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/volume.js:57
 | 
			
		||||
#: ../js/ui/status/volume.js:58
 | 
			
		||||
msgid "Microphone"
 | 
			
		||||
msgstr "Микрофон"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:239
 | 
			
		||||
#: ../js/ui/telepathyClient.js:331
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is online."
 | 
			
		||||
msgstr "%s е на линия."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:244
 | 
			
		||||
#: ../js/ui/telepathyClient.js:336
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is offline."
 | 
			
		||||
msgstr "%s не е на линия."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:247
 | 
			
		||||
#: ../js/ui/telepathyClient.js:339
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is away."
 | 
			
		||||
msgstr "%s отсъства."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:250
 | 
			
		||||
#, fuzzy, c-format
 | 
			
		||||
#: ../js/ui/telepathyClient.js:342
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is busy."
 | 
			
		||||
msgstr "%s прави нещо друго."
 | 
			
		||||
 | 
			
		||||
#. Translators: this is a time format string followed by a date.
 | 
			
		||||
#. If applicable, replace %X with a strftime format valid for your
 | 
			
		||||
#. locale, without seconds.
 | 
			
		||||
#: ../js/ui/telepathyClient.js:348
 | 
			
		||||
#: ../js/ui/telepathyClient.js:473
 | 
			
		||||
#, no-c-format
 | 
			
		||||
msgid "Sent at %X on %A"
 | 
			
		||||
msgstr "Изпратено на %2$A в %1$X"
 | 
			
		||||
@@ -943,10 +1101,14 @@ msgstr "Изпратено на %2$A в %1$X"
 | 
			
		||||
#. in the search entry when no search is
 | 
			
		||||
#. active; it should not exceed ~30
 | 
			
		||||
#. characters.
 | 
			
		||||
#: ../js/ui/viewSelector.js:103
 | 
			
		||||
#: ../js/ui/viewSelector.js:122
 | 
			
		||||
msgid "Type to search..."
 | 
			
		||||
msgstr "Търсене на написаното…"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/viewSelector.js:142 ../src/shell-util.c:250
 | 
			
		||||
msgid "Search"
 | 
			
		||||
msgstr "Търсене"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/windowAttentionHandler.js:42
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s has finished starting"
 | 
			
		||||
@@ -959,7 +1121,7 @@ msgstr "Програмата „%s“ е готова за употреба"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The number of sound outputs on a particular device
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1094
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1098
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%u Output"
 | 
			
		||||
msgid_plural "%u Outputs"
 | 
			
		||||
@@ -968,49 +1130,66 @@ msgstr[1] "%u изхода"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The number of sound inputs on a particular device
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1104
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1108
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%u Input"
 | 
			
		||||
msgid_plural "%u Inputs"
 | 
			
		||||
msgstr[0] "%u вход"
 | 
			
		||||
msgstr[1] "%u входа"
 | 
			
		||||
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1402
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1406
 | 
			
		||||
msgid "System Sounds"
 | 
			
		||||
msgstr "Системни звуци"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1298
 | 
			
		||||
#: ../src/main.c:446
 | 
			
		||||
msgid "Print version"
 | 
			
		||||
msgstr "Показване на версията"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-app.c:454
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to launch '%s'"
 | 
			
		||||
msgstr "Неуспех при стартиране на „%s“"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1395
 | 
			
		||||
msgid "Less than a minute ago"
 | 
			
		||||
msgstr "Преди по-малко от минута"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1302
 | 
			
		||||
#: ../src/shell-global.c:1399
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d minute ago"
 | 
			
		||||
msgid_plural "%d minutes ago"
 | 
			
		||||
msgstr[0] "преди %d минута"
 | 
			
		||||
msgstr[1] "преди %d минути"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1307
 | 
			
		||||
#: ../src/shell-global.c:1404
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d hour ago"
 | 
			
		||||
msgid_plural "%d hours ago"
 | 
			
		||||
msgstr[0] "преди %d час"
 | 
			
		||||
msgstr[1] "преди %d часа"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1312
 | 
			
		||||
#: ../src/shell-global.c:1409
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d day ago"
 | 
			
		||||
msgid_plural "%d days ago"
 | 
			
		||||
msgstr[0] "преди %d ден"
 | 
			
		||||
msgstr[1] "преди %d дни"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1317
 | 
			
		||||
#: ../src/shell-global.c:1414
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d week ago"
 | 
			
		||||
msgid_plural "%d weeks ago"
 | 
			
		||||
msgstr[0] "преди %d седмица"
 | 
			
		||||
msgstr[1] "преди %d седмици"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-mobile-providers.c:80
 | 
			
		||||
msgid "United Kingdom"
 | 
			
		||||
msgstr "Великобритания"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-mobile-providers.c:526
 | 
			
		||||
msgid "Default"
 | 
			
		||||
msgstr "Стандартно"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-polkit-authentication-agent.c:334
 | 
			
		||||
msgid "Authentication dialog was dismissed by the user"
 | 
			
		||||
msgstr "Прозорецът за упълномощаване беше затворен от потребителя"
 | 
			
		||||
@@ -1025,10 +1204,6 @@ msgstr "Домашна папка"
 | 
			
		||||
msgid "File System"
 | 
			
		||||
msgstr "Файлова система"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-util.c:250
 | 
			
		||||
msgid "Search"
 | 
			
		||||
msgstr "Търсене"
 | 
			
		||||
 | 
			
		||||
#. Translators: the first string is the name of a gvfs
 | 
			
		||||
#. * method, and the second string is a path. For
 | 
			
		||||
#. * example, "Trash: some-directory". It means that the
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1189
									
								
								po/bn_IN.po
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1189
									
								
								po/bn_IN.po
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										493
									
								
								po/ca.po
									
									
									
									
									
								
							
							
						
						
									
										493
									
								
								po/ca.po
									
									
									
									
									
								
							@@ -8,8 +8,8 @@ msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: HEAD\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: \n"
 | 
			
		||||
"POT-Creation-Date: 2011-03-06 18:36+0100\n"
 | 
			
		||||
"PO-Revision-Date: 2011-03-06 18:36+0100\n"
 | 
			
		||||
"POT-Creation-Date: 2011-03-29 00:29+0200\n"
 | 
			
		||||
"PO-Revision-Date: 2011-03-27 13:05+0100\n"
 | 
			
		||||
"Last-Translator: Gil Forcada <gilforcada@guifi.net>\n"
 | 
			
		||||
"Language-Team: Catalan <tradgnome@softcatala.org>\n"
 | 
			
		||||
"Language: ca\n"
 | 
			
		||||
@@ -161,7 +161,7 @@ msgstr ""
 | 
			
		||||
"El GNOME Shell normalment fa un seguiment de les aplicacions actives per tal "
 | 
			
		||||
"de mostrar les més utilitzades (per exemple en els llançadors). Tot i que "
 | 
			
		||||
"les dades es mantindran en privat, podeu inhabilitar-ho per motius de "
 | 
			
		||||
"privacitat. Tingueu en compte que si ho inhabiliteu no es suprimiran les "
 | 
			
		||||
"privadesa. Tingueu en compte que si ho inhabiliteu no es suprimiran les "
 | 
			
		||||
"dades ja recollides."
 | 
			
		||||
 | 
			
		||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
 | 
			
		||||
@@ -176,47 +176,43 @@ msgstr "Si s'han de recollir estadístiques d'ús de les aplicacions"
 | 
			
		||||
msgid "disabled OpenSearch providers"
 | 
			
		||||
msgstr "inhabilita els proveïdors d'OpenSearch"
 | 
			
		||||
 | 
			
		||||
#: ../js/misc/util.js:86
 | 
			
		||||
#: ../js/misc/util.js:71
 | 
			
		||||
msgid "Command not found"
 | 
			
		||||
msgstr "No s'ha trobat l'ordre"
 | 
			
		||||
 | 
			
		||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
 | 
			
		||||
#. something nicer
 | 
			
		||||
#: ../js/misc/util.js:113
 | 
			
		||||
#: ../js/misc/util.js:98
 | 
			
		||||
msgid "Could not parse command:"
 | 
			
		||||
msgstr "No s'ha pogut analitzar l'ordre:"
 | 
			
		||||
 | 
			
		||||
#: ../js/misc/util.js:135
 | 
			
		||||
msgid "No such application"
 | 
			
		||||
msgstr "No hi ha cap aplicació"
 | 
			
		||||
 | 
			
		||||
#: ../js/misc/util.js:148
 | 
			
		||||
#: ../js/misc/util.js:106
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Execution of '%s' failed:"
 | 
			
		||||
msgstr "No s'ha pogut executar «%s»:"
 | 
			
		||||
 | 
			
		||||
#. Translators: Filter to display all applications
 | 
			
		||||
#: ../js/ui/appDisplay.js:195
 | 
			
		||||
#: ../js/ui/appDisplay.js:230
 | 
			
		||||
msgid "All"
 | 
			
		||||
msgstr "Totes"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:285
 | 
			
		||||
#: ../js/ui/appDisplay.js:328
 | 
			
		||||
msgid "APPLICATIONS"
 | 
			
		||||
msgstr "APLICACIONS"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:311
 | 
			
		||||
#: ../js/ui/appDisplay.js:354
 | 
			
		||||
msgid "SETTINGS"
 | 
			
		||||
msgstr "CONFIGURACIÓ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:565
 | 
			
		||||
#: ../js/ui/appDisplay.js:625
 | 
			
		||||
msgid "New Window"
 | 
			
		||||
msgstr "Finestra nova"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:568
 | 
			
		||||
#: ../js/ui/appDisplay.js:628
 | 
			
		||||
msgid "Remove from Favorites"
 | 
			
		||||
msgstr "Suprimeix dels preferits"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:569
 | 
			
		||||
#: ../js/ui/appDisplay.js:629
 | 
			
		||||
msgid "Add to Favorites"
 | 
			
		||||
msgstr "Afegeix als preferits"
 | 
			
		||||
 | 
			
		||||
@@ -376,7 +372,7 @@ msgstr "Aquesta setmana"
 | 
			
		||||
msgid "Next week"
 | 
			
		||||
msgstr "La setmana que ve"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dash.js:174
 | 
			
		||||
#: ../js/ui/dash.js:174 ../js/ui/messageTray.js:1000
 | 
			
		||||
msgid "Remove"
 | 
			
		||||
msgstr "Suprimeix"
 | 
			
		||||
 | 
			
		||||
@@ -384,54 +380,54 @@ msgstr "Suprimeix"
 | 
			
		||||
msgid "Date and Time Settings"
 | 
			
		||||
msgstr "Configuració de la data i l'hora"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:110
 | 
			
		||||
#: ../js/ui/dateMenu.js:111
 | 
			
		||||
msgid "Open Calendar"
 | 
			
		||||
msgstr "Obre el calendari"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is the time format with date used
 | 
			
		||||
#. in 24-hour mode.
 | 
			
		||||
#: ../js/ui/dateMenu.js:162
 | 
			
		||||
#: ../js/ui/dateMenu.js:164
 | 
			
		||||
msgid "%a %b %e, %R:%S"
 | 
			
		||||
msgstr "%a %d de %b, %R:%S"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:163
 | 
			
		||||
#: ../js/ui/dateMenu.js:165
 | 
			
		||||
msgid "%a %b %e, %R"
 | 
			
		||||
msgstr "%a %d de %b, %R"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is the time format without date used
 | 
			
		||||
#. in 24-hour mode.
 | 
			
		||||
#: ../js/ui/dateMenu.js:167
 | 
			
		||||
#: ../js/ui/dateMenu.js:169
 | 
			
		||||
msgid "%a %R:%S"
 | 
			
		||||
msgstr "%a %R:%S"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:168
 | 
			
		||||
#: ../js/ui/dateMenu.js:170
 | 
			
		||||
msgid "%a %R"
 | 
			
		||||
msgstr "%a %R"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is a time format with date used
 | 
			
		||||
#. for AM/PM.
 | 
			
		||||
#: ../js/ui/dateMenu.js:175
 | 
			
		||||
#: ../js/ui/dateMenu.js:177
 | 
			
		||||
msgid "%a %b %e, %l:%M:%S %p"
 | 
			
		||||
msgstr "%a %d de %b, %l:%M:%S %p"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:176
 | 
			
		||||
#: ../js/ui/dateMenu.js:178
 | 
			
		||||
msgid "%a %b %e, %l:%M %p"
 | 
			
		||||
msgstr "%a %d de %b, %l:%M %p"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is a time format without date used
 | 
			
		||||
#. for AM/PM.
 | 
			
		||||
#: ../js/ui/dateMenu.js:180
 | 
			
		||||
#: ../js/ui/dateMenu.js:182
 | 
			
		||||
msgid "%a %l:%M:%S %p"
 | 
			
		||||
msgstr "%a %l:%M:%S %p"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:181
 | 
			
		||||
#: ../js/ui/dateMenu.js:183
 | 
			
		||||
msgid "%a %l:%M %p"
 | 
			
		||||
msgstr "%a %l:%M %p"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is the date format to use when the calendar popup is
 | 
			
		||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
 | 
			
		||||
#.
 | 
			
		||||
#: ../js/ui/dateMenu.js:207
 | 
			
		||||
#: ../js/ui/dateMenu.js:194
 | 
			
		||||
msgid "%A %B %e, %Y"
 | 
			
		||||
msgstr "%A %d de %B, %Y"
 | 
			
		||||
 | 
			
		||||
@@ -444,7 +440,7 @@ msgstr "DOCUMENTS RECENTS"
 | 
			
		||||
msgid "Log Out %s"
 | 
			
		||||
msgstr "Surt %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:69
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:70
 | 
			
		||||
msgid "Log Out"
 | 
			
		||||
msgstr "Surt"
 | 
			
		||||
 | 
			
		||||
@@ -466,46 +462,44 @@ msgstr "Sortireu automàticament d'aquí %d segons."
 | 
			
		||||
msgid "Logging out of the system."
 | 
			
		||||
msgstr "S'està sortint de la sessió."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:74 ../js/ui/endSessionDialog.js:78
 | 
			
		||||
msgid "Shut Down"
 | 
			
		||||
msgstr "Atura"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:75
 | 
			
		||||
msgid "Click Shut Down to quit these applications and shut down the system."
 | 
			
		||||
msgstr "Feu clic a «Atura» per tancar les aplicacions i apagar l'ordinador."
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:75 ../js/ui/endSessionDialog.js:82
 | 
			
		||||
msgid "Power Off"
 | 
			
		||||
msgstr "Apaga"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:76
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The system will shut down automatically in %d seconds."
 | 
			
		||||
msgstr "S'apagarà l'ordinador automàticament d'aquí %d segons."
 | 
			
		||||
msgid "Click Power Off to quit these applications and power off the system."
 | 
			
		||||
msgstr "Feu clic a «Apaga» per tancar les aplicacions i apagar l'ordinador."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:77
 | 
			
		||||
msgid "Shutting down the system."
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The system will power off automatically in %d seconds."
 | 
			
		||||
msgstr "S'apagarà l'ordinador automàticament d'aquí %d segons."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:78
 | 
			
		||||
msgid "Powering off the system."
 | 
			
		||||
msgstr "S'està apagant l'ordinador."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:84 ../js/ui/endSessionDialog.js:88
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:80 ../js/ui/endSessionDialog.js:88
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:93
 | 
			
		||||
msgid "Restart"
 | 
			
		||||
msgstr "Reinicia"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:85
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:89
 | 
			
		||||
msgid "Click Restart to quit these applications and restart the system."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Feu clic a «Reinicia» per tancar les aplicacions i reiniciar l'ordinador."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:86
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:90
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The system will restart automatically in %d seconds."
 | 
			
		||||
msgstr "Es reiniciarà l'ordinador automàticament d'aquí %d segons."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:87
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:91
 | 
			
		||||
msgid "Restarting the system."
 | 
			
		||||
msgstr "S'està reiniciant l'ordinador."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:395
 | 
			
		||||
msgid "Confirm"
 | 
			
		||||
msgstr "D'acord"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:400 ../js/ui/status/bluetooth.js:470
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:415 ../js/ui/polkitAuthenticationAgent.js:172
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:466
 | 
			
		||||
msgid "Cancel"
 | 
			
		||||
msgstr "Cancel·la"
 | 
			
		||||
 | 
			
		||||
@@ -519,7 +513,7 @@ msgstr "Habilitat"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The device has been disabled
 | 
			
		||||
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1087
 | 
			
		||||
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1091
 | 
			
		||||
msgid "Disabled"
 | 
			
		||||
msgstr "Inhabilitat"
 | 
			
		||||
 | 
			
		||||
@@ -539,34 +533,48 @@ msgstr "Visualitza el font"
 | 
			
		||||
msgid "Web Page"
 | 
			
		||||
msgstr "Pàgina web"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/messageTray.js:1907
 | 
			
		||||
#: ../js/ui/messageTray.js:993
 | 
			
		||||
msgid "Open"
 | 
			
		||||
msgstr "Obre"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/messageTray.js:2151
 | 
			
		||||
msgid "System Information"
 | 
			
		||||
msgstr "Informació de l'ordinador"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/overview.js:88
 | 
			
		||||
#: ../js/ui/overview.js:91
 | 
			
		||||
msgid "Undo"
 | 
			
		||||
msgstr "Desfés"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/overview.js:183
 | 
			
		||||
#: ../js/ui/overview.js:186
 | 
			
		||||
msgid "Windows"
 | 
			
		||||
msgstr "Finestres"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/overview.js:186
 | 
			
		||||
#: ../js/ui/overview.js:189
 | 
			
		||||
msgid "Applications"
 | 
			
		||||
msgstr "Aplicacions"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is the name of the dock/favorites area on
 | 
			
		||||
#. the left of the overview
 | 
			
		||||
#: ../js/ui/overview.js:205
 | 
			
		||||
msgid "Dash"
 | 
			
		||||
msgstr "Quadre d'aplicacions"
 | 
			
		||||
 | 
			
		||||
#. TODO - _quit() doesn't really work on apps in state STARTING yet
 | 
			
		||||
#: ../js/ui/panel.js:531
 | 
			
		||||
#: ../js/ui/panel.js:515
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Quit %s"
 | 
			
		||||
msgstr "Tanca %s"
 | 
			
		||||
 | 
			
		||||
#. Button on the left side of the panel.
 | 
			
		||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
 | 
			
		||||
#: ../js/ui/panel.js:892
 | 
			
		||||
#: ../js/ui/panel.js:893
 | 
			
		||||
msgid "Activities"
 | 
			
		||||
msgstr "Activitats"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/panel.js:994
 | 
			
		||||
msgid "Top Bar"
 | 
			
		||||
msgstr "Barra superior"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/placeDisplay.js:122
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to unmount '%s'"
 | 
			
		||||
@@ -580,64 +588,89 @@ msgstr "Torna-ho a intentar"
 | 
			
		||||
msgid "Connect to..."
 | 
			
		||||
msgstr "Connecta a..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/placeDisplay.js:409
 | 
			
		||||
#: ../js/ui/placeDisplay.js:380
 | 
			
		||||
msgid "PLACES & DEVICES"
 | 
			
		||||
msgstr "LLOCS I DISPOSITIUS"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:74
 | 
			
		||||
msgid "Authentication Required"
 | 
			
		||||
msgstr "Cal autenticació"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:108
 | 
			
		||||
msgid "Administrator"
 | 
			
		||||
msgstr "Administrador"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:176
 | 
			
		||||
msgid "Authenticate"
 | 
			
		||||
msgstr "Autentica"
 | 
			
		||||
 | 
			
		||||
#. Translators: "that didn't work" refers to the fact that the
 | 
			
		||||
#. * requested authentication was not gained; this can happen
 | 
			
		||||
#. * because of an authentication error (like invalid password),
 | 
			
		||||
#. * for instance.
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:264
 | 
			
		||||
msgid "Sorry, that didn't work. Please try again."
 | 
			
		||||
msgstr "No ha funcionat. Torneu-ho a provar."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:276
 | 
			
		||||
msgid "Password:"
 | 
			
		||||
msgstr "Contrasenya:"
 | 
			
		||||
 | 
			
		||||
#. Translators: this MUST be either "toggle-switch-us"
 | 
			
		||||
#. (for toggle switches containing the English words
 | 
			
		||||
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
 | 
			
		||||
#. switches containing "◯" and "|"). Other values will
 | 
			
		||||
#. simply result in invisible toggle switches.
 | 
			
		||||
#: ../js/ui/popupMenu.js:612
 | 
			
		||||
#: ../js/ui/popupMenu.js:679
 | 
			
		||||
msgid "toggle-switch-us"
 | 
			
		||||
msgstr "toggle-switch-intl"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/runDialog.js:201
 | 
			
		||||
#: ../js/ui/runDialog.js:205
 | 
			
		||||
msgid "Please enter a command:"
 | 
			
		||||
msgstr "Introduïu una ordre:"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/searchDisplay.js:283
 | 
			
		||||
#: ../js/ui/searchDisplay.js:310
 | 
			
		||||
msgid "Searching..."
 | 
			
		||||
msgstr "S'està cercant..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/searchDisplay.js:297
 | 
			
		||||
#: ../js/ui/searchDisplay.js:324
 | 
			
		||||
msgid "No matching results."
 | 
			
		||||
msgstr "No s'ha trobat cap coincidència."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:102 ../js/ui/statusMenu.js:166
 | 
			
		||||
#: ../js/ui/statusMenu.js:161 ../js/ui/statusMenu.js:163
 | 
			
		||||
#: ../js/ui/statusMenu.js:228
 | 
			
		||||
msgid "Power Off..."
 | 
			
		||||
msgstr "Apaga..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:104 ../js/ui/statusMenu.js:165
 | 
			
		||||
#: ../js/ui/statusMenu.js:163 ../js/ui/statusMenu.js:227
 | 
			
		||||
msgid "Suspend"
 | 
			
		||||
msgstr "Atura temporalment"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:125
 | 
			
		||||
#: ../js/ui/statusMenu.js:184
 | 
			
		||||
msgid "Available"
 | 
			
		||||
msgstr "Disponible"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:130
 | 
			
		||||
#: ../js/ui/statusMenu.js:189
 | 
			
		||||
msgid "Busy"
 | 
			
		||||
msgstr "Ocupat"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:138
 | 
			
		||||
#: ../js/ui/statusMenu.js:197
 | 
			
		||||
msgid "My Account"
 | 
			
		||||
msgstr "El meu compte"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:142
 | 
			
		||||
#: ../js/ui/statusMenu.js:201
 | 
			
		||||
msgid "System Settings"
 | 
			
		||||
msgstr "Paràmetres de l'ordinador"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:149
 | 
			
		||||
#: ../js/ui/statusMenu.js:208
 | 
			
		||||
msgid "Lock Screen"
 | 
			
		||||
msgstr "Bloca la pantalla"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:153
 | 
			
		||||
#: ../js/ui/statusMenu.js:213
 | 
			
		||||
msgid "Switch User"
 | 
			
		||||
msgstr "Canvia d'usuari"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:158
 | 
			
		||||
#: ../js/ui/statusMenu.js:218
 | 
			
		||||
msgid "Log Out..."
 | 
			
		||||
msgstr "Surt..."
 | 
			
		||||
 | 
			
		||||
@@ -645,14 +678,12 @@ msgstr "Surt..."
 | 
			
		||||
msgid "Zoom"
 | 
			
		||||
msgstr "Amplia"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:69
 | 
			
		||||
msgid "Screen Reader"
 | 
			
		||||
msgstr "Lector de pantalla"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:73
 | 
			
		||||
msgid "Screen Keyboard"
 | 
			
		||||
msgstr "Teclat en pantalla"
 | 
			
		||||
 | 
			
		||||
#. let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
 | 
			
		||||
#. 'screen-reader-enabled');
 | 
			
		||||
#. this.menu.addMenuItem(screenReader);
 | 
			
		||||
#. let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
 | 
			
		||||
#. 'screen-keyboard-enabled');
 | 
			
		||||
#. this.menu.addMenuItem(screenKeyboard);
 | 
			
		||||
#: ../js/ui/status/accessibility.js:77
 | 
			
		||||
msgid "Visual Alerts"
 | 
			
		||||
msgstr "Avisos visuals"
 | 
			
		||||
@@ -677,17 +708,17 @@ msgstr "Tecles del ratolí"
 | 
			
		||||
msgid "Universal Access Settings"
 | 
			
		||||
msgstr "Paràmetres d'accés universal"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:145
 | 
			
		||||
#: ../js/ui/status/accessibility.js:146
 | 
			
		||||
msgid "High Contrast"
 | 
			
		||||
msgstr "Alt contrast"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:182
 | 
			
		||||
#: ../js/ui/status/accessibility.js:183
 | 
			
		||||
msgid "Large Text"
 | 
			
		||||
msgstr "Text gran"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:241
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:337 ../js/ui/status/bluetooth.js:371
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:411 ../js/ui/status/bluetooth.js:444
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:237
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:333 ../js/ui/status/bluetooth.js:367
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:407 ../js/ui/status/bluetooth.js:440
 | 
			
		||||
msgid "Bluetooth"
 | 
			
		||||
msgstr "Bluetooth"
 | 
			
		||||
 | 
			
		||||
@@ -707,94 +738,94 @@ msgstr "Establiu un dispositiu nou..."
 | 
			
		||||
msgid "Bluetooth Settings"
 | 
			
		||||
msgstr "Paràmetres del Bluetooth"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:192
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:188
 | 
			
		||||
msgid "Connection"
 | 
			
		||||
msgstr "Connexió"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:228
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:224
 | 
			
		||||
msgid "Send Files..."
 | 
			
		||||
msgstr "Envia fitxers..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:233
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:229
 | 
			
		||||
msgid "Browse Files..."
 | 
			
		||||
msgstr "Navega pels fitxers..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:242
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:238
 | 
			
		||||
msgid "Error browsing device"
 | 
			
		||||
msgstr "S'ha produït un error en navegar pel dispositiu"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:243
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:239
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The requested device cannot be browsed, error is '%s'"
 | 
			
		||||
msgstr "No es pot navegar pel dispositiu degut a l'error «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:251
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:247
 | 
			
		||||
msgid "Keyboard Settings"
 | 
			
		||||
msgstr "Paràmetres del teclat"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:256
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:252
 | 
			
		||||
msgid "Mouse Settings"
 | 
			
		||||
msgstr "Paràmetres del ratolí"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:263 ../js/ui/status/volume.js:65
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:259 ../js/ui/status/volume.js:66
 | 
			
		||||
msgid "Sound Settings"
 | 
			
		||||
msgstr "Paràmetres de so"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:372
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:368
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Authorization request from %s"
 | 
			
		||||
msgstr "Hi ha una petició d'autorització des de %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:378
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:374
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Device %s wants access to the service '%s'"
 | 
			
		||||
msgstr "El dispositiu %s vol accedir al servei «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:380
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:376
 | 
			
		||||
msgid "Always grant access"
 | 
			
		||||
msgstr "Permet l'accés sempre"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:381
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:377
 | 
			
		||||
msgid "Grant this time only"
 | 
			
		||||
msgstr "Permete-ho només ara"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:382
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:378
 | 
			
		||||
msgid "Reject"
 | 
			
		||||
msgstr "Rebutja"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:412
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:408
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Pairing confirmation for %s"
 | 
			
		||||
msgstr "Confirmació d'aparellament per %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:418 ../js/ui/status/bluetooth.js:452
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:414 ../js/ui/status/bluetooth.js:448
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Device %s wants to pair with this computer"
 | 
			
		||||
msgstr "El dispositiu %s vol aparellar-se amb aquest ordinador"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:419
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:415
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Please confirm whether the PIN '%s' matches the one on the device."
 | 
			
		||||
msgstr "Confirmeu que el PIN «%s» coincideix amb el que hi ha al dispositiu."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:421
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:417
 | 
			
		||||
msgid "Matches"
 | 
			
		||||
msgstr "Coincideix"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:422
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:418
 | 
			
		||||
msgid "Does not match"
 | 
			
		||||
msgstr "No coincideix"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:445
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:441
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Pairing request for %s"
 | 
			
		||||
msgstr "Teniu una sol·licitud d'aparellament amb %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:453
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:449
 | 
			
		||||
msgid "Please enter the PIN mentioned on the device."
 | 
			
		||||
msgstr "Introduïu el PIN que es mostra al dispositiu."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:469
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:465
 | 
			
		||||
msgid "OK"
 | 
			
		||||
msgstr "D'acord"
 | 
			
		||||
 | 
			
		||||
@@ -806,17 +837,153 @@ msgstr "Mostra la disposició del teclat..."
 | 
			
		||||
msgid "Localization Settings"
 | 
			
		||||
msgstr "Paràmetres de localització"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:104 ../js/ui/status/network.js:1454
 | 
			
		||||
msgid "<unknown>"
 | 
			
		||||
msgstr "<desconegut>"
 | 
			
		||||
 | 
			
		||||
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
 | 
			
		||||
#: ../js/ui/status/network.js:311
 | 
			
		||||
msgid "disabled"
 | 
			
		||||
msgstr "inhabilitada"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:494
 | 
			
		||||
msgid "connecting..."
 | 
			
		||||
msgstr "s'està connectant..."
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for network connections that require some kind of key or password
 | 
			
		||||
#: ../js/ui/status/network.js:497
 | 
			
		||||
msgid "authentication required"
 | 
			
		||||
msgstr "cal autenticació"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for devices that require some kind of firmware or kernel
 | 
			
		||||
#. module, which is missing
 | 
			
		||||
#: ../js/ui/status/network.js:507
 | 
			
		||||
msgid "firmware missing"
 | 
			
		||||
msgstr "manca el microprogramari"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for wired network devices that are physically disconnected
 | 
			
		||||
#: ../js/ui/status/network.js:514
 | 
			
		||||
msgid "cable unplugged"
 | 
			
		||||
msgstr "s'ha desconnectat el cable"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for a network device that cannot be activated (for example it
 | 
			
		||||
#. is disabled by rfkill, or it has no coverage
 | 
			
		||||
#: ../js/ui/status/network.js:519
 | 
			
		||||
msgid "unavailable"
 | 
			
		||||
msgstr "no disponible"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:521
 | 
			
		||||
msgid "connection failed"
 | 
			
		||||
msgstr "ha fallat la connexió"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
 | 
			
		||||
#. and we cannot access its settings (including the name)
 | 
			
		||||
#: ../js/ui/status/network.js:602 ../js/ui/status/network.js:1402
 | 
			
		||||
msgid "Connected (private)"
 | 
			
		||||
msgstr "Connectat (privat)"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:683
 | 
			
		||||
msgid "Auto Ethernet"
 | 
			
		||||
msgstr "Ethernet automàtic"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:758
 | 
			
		||||
msgid "Auto broadband"
 | 
			
		||||
msgstr "Banda ampla automàtica"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:761
 | 
			
		||||
msgid "Auto dial-up"
 | 
			
		||||
msgstr "Marcatge directe automàtic"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
 | 
			
		||||
#: ../js/ui/status/network.js:904 ../js/ui/status/network.js:1414
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Auto %s"
 | 
			
		||||
msgstr "%s automàtic"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:906
 | 
			
		||||
msgid "Auto bluetooth"
 | 
			
		||||
msgstr "Bluetooth automàtic"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1416
 | 
			
		||||
msgid "Auto wireless"
 | 
			
		||||
msgstr "Sense fil automàtic"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1474
 | 
			
		||||
msgid "More..."
 | 
			
		||||
msgstr "Més..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1497
 | 
			
		||||
msgid "Enable networking"
 | 
			
		||||
msgstr "Habilita la xarxa"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1509
 | 
			
		||||
msgid "Wired"
 | 
			
		||||
msgstr "Amb fil"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1520
 | 
			
		||||
msgid "Wireless"
 | 
			
		||||
msgstr "Sense fil"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1530
 | 
			
		||||
msgid "Mobile broadband"
 | 
			
		||||
msgstr "Ampla de banda mòbil"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1540
 | 
			
		||||
msgid "VPN Connections"
 | 
			
		||||
msgstr "Connexions VPN"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1549
 | 
			
		||||
msgid "Network Settings"
 | 
			
		||||
msgstr "Paràmetres de xarxa"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1844
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to mobile broadband connection '%s'"
 | 
			
		||||
msgstr "Us acabeu de connectar amb la connexió de banda ampla mòbil «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1848
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to wireless network '%s'"
 | 
			
		||||
msgstr "Us acabeu de connectar a la xarxa sense fil «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1852
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to wired network '%s'"
 | 
			
		||||
msgstr "Us acabeu de connectar a la xarxa amb fil «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1856
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to VPN network '%s'"
 | 
			
		||||
msgstr "Us acabeu de connectar a la xarxa VPN «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1861
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to '%s'"
 | 
			
		||||
msgstr "Us acabeu de connectar a «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1869
 | 
			
		||||
msgid "Connection established"
 | 
			
		||||
msgstr "S'ha establert la connexió"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1991
 | 
			
		||||
msgid "Networking is disabled"
 | 
			
		||||
msgstr "S'ha inhabilitat la xarxa"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:2116
 | 
			
		||||
msgid "Network Manager"
 | 
			
		||||
msgstr "Gestor de connexions de xarxa"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:85
 | 
			
		||||
msgid "Power Settings"
 | 
			
		||||
msgstr "Paràmetres d'energia"
 | 
			
		||||
 | 
			
		||||
#. 0 is reported when UPower does not have enough data
 | 
			
		||||
#. to estimate battery life
 | 
			
		||||
#: ../js/ui/status/power.js:110
 | 
			
		||||
#: ../js/ui/status/power.js:111
 | 
			
		||||
msgid "Estimating..."
 | 
			
		||||
msgstr "S'està estimant la durada..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:117
 | 
			
		||||
#: ../js/ui/status/power.js:118
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d hour remaining"
 | 
			
		||||
msgid_plural "%d hours remaining"
 | 
			
		||||
@@ -824,102 +991,102 @@ msgstr[0] "Queda %d hora"
 | 
			
		||||
msgstr[1] "Queden %d hores"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
 | 
			
		||||
#: ../js/ui/status/power.js:120
 | 
			
		||||
#: ../js/ui/status/power.js:121
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d %s %d %s remaining"
 | 
			
		||||
msgstr "Queden %d %s %d %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:122
 | 
			
		||||
#: ../js/ui/status/power.js:123
 | 
			
		||||
msgid "hour"
 | 
			
		||||
msgid_plural "hours"
 | 
			
		||||
msgstr[0] "hora"
 | 
			
		||||
msgstr[1] "hores"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:122
 | 
			
		||||
#: ../js/ui/status/power.js:123
 | 
			
		||||
msgid "minute"
 | 
			
		||||
msgid_plural "minutes"
 | 
			
		||||
msgstr[0] "minut"
 | 
			
		||||
msgstr[1] "minuts"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:125
 | 
			
		||||
#: ../js/ui/status/power.js:126
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d minute remaining"
 | 
			
		||||
msgid_plural "%d minutes remaining"
 | 
			
		||||
msgstr[0] "Queda %d minut"
 | 
			
		||||
msgstr[1] "Queden %d minuts"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:227
 | 
			
		||||
#: ../js/ui/status/power.js:228
 | 
			
		||||
msgid "AC adapter"
 | 
			
		||||
msgstr "Adaptador de corrent"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:229
 | 
			
		||||
#: ../js/ui/status/power.js:230
 | 
			
		||||
msgid "Laptop battery"
 | 
			
		||||
msgstr "Bateria del portàtil"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:231
 | 
			
		||||
#: ../js/ui/status/power.js:232
 | 
			
		||||
msgid "UPS"
 | 
			
		||||
msgstr "SAI"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:233
 | 
			
		||||
#: ../js/ui/status/power.js:234
 | 
			
		||||
msgid "Monitor"
 | 
			
		||||
msgstr "Pantalla"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:235
 | 
			
		||||
#: ../js/ui/status/power.js:236
 | 
			
		||||
msgid "Mouse"
 | 
			
		||||
msgstr "Ratolí"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:237
 | 
			
		||||
#: ../js/ui/status/power.js:238
 | 
			
		||||
msgid "Keyboard"
 | 
			
		||||
msgstr "Teclat"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:239
 | 
			
		||||
#: ../js/ui/status/power.js:240
 | 
			
		||||
msgid "PDA"
 | 
			
		||||
msgstr "PDA"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:241
 | 
			
		||||
#: ../js/ui/status/power.js:242
 | 
			
		||||
msgid "Cell phone"
 | 
			
		||||
msgstr "Telèfon mòbil"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:243
 | 
			
		||||
#: ../js/ui/status/power.js:244
 | 
			
		||||
msgid "Media player"
 | 
			
		||||
msgstr "Reproductor multimèdia"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:245
 | 
			
		||||
#: ../js/ui/status/power.js:246
 | 
			
		||||
msgid "Tablet"
 | 
			
		||||
msgstr "Tauleta"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:247
 | 
			
		||||
#: ../js/ui/status/power.js:248
 | 
			
		||||
msgid "Computer"
 | 
			
		||||
msgstr "Ordinador"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:249 ../src/shell-app-system.c:1013
 | 
			
		||||
#: ../js/ui/status/power.js:250 ../src/shell-app-system.c:1088
 | 
			
		||||
msgid "Unknown"
 | 
			
		||||
msgstr "Desconegut"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/volume.js:44
 | 
			
		||||
#: ../js/ui/status/volume.js:45
 | 
			
		||||
msgid "Volume"
 | 
			
		||||
msgstr "Volum"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/volume.js:57
 | 
			
		||||
#: ../js/ui/status/volume.js:58
 | 
			
		||||
msgid "Microphone"
 | 
			
		||||
msgstr "Micròfon"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:239
 | 
			
		||||
#: ../js/ui/telepathyClient.js:331
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is online."
 | 
			
		||||
msgstr "%s és en línia."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:244
 | 
			
		||||
#: ../js/ui/telepathyClient.js:336
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is offline."
 | 
			
		||||
msgstr "%s no hi és."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:247
 | 
			
		||||
#: ../js/ui/telepathyClient.js:339
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is away."
 | 
			
		||||
msgstr "%s és lluny."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:250
 | 
			
		||||
#: ../js/ui/telepathyClient.js:342
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is busy."
 | 
			
		||||
msgstr "%s està ocupat."
 | 
			
		||||
@@ -927,7 +1094,7 @@ msgstr "%s està ocupat."
 | 
			
		||||
#. Translators: this is a time format string followed by a date.
 | 
			
		||||
#. If applicable, replace %X with a strftime format valid for your
 | 
			
		||||
#. locale, without seconds.
 | 
			
		||||
#: ../js/ui/telepathyClient.js:348
 | 
			
		||||
#: ../js/ui/telepathyClient.js:473
 | 
			
		||||
#, no-c-format
 | 
			
		||||
msgid "Sent at %X on %A"
 | 
			
		||||
msgstr "Enviat a les %X del %A"
 | 
			
		||||
@@ -936,10 +1103,14 @@ msgstr "Enviat a les %X del %A"
 | 
			
		||||
#. in the search entry when no search is
 | 
			
		||||
#. active; it should not exceed ~30
 | 
			
		||||
#. characters.
 | 
			
		||||
#: ../js/ui/viewSelector.js:103
 | 
			
		||||
#: ../js/ui/viewSelector.js:122
 | 
			
		||||
msgid "Type to search..."
 | 
			
		||||
msgstr "Teclegeu per cercar..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/viewSelector.js:142 ../src/shell-util.c:250
 | 
			
		||||
msgid "Search"
 | 
			
		||||
msgstr "Cerca"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/windowAttentionHandler.js:42
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s has finished starting"
 | 
			
		||||
@@ -952,7 +1123,7 @@ msgstr "«%s» ja està apunt"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The number of sound outputs on a particular device
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1094
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1098
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%u Output"
 | 
			
		||||
msgid_plural "%u Outputs"
 | 
			
		||||
@@ -961,49 +1132,66 @@ msgstr[1] "%u sortides"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The number of sound inputs on a particular device
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1104
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1108
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%u Input"
 | 
			
		||||
msgid_plural "%u Inputs"
 | 
			
		||||
msgstr[0] "%u entrada"
 | 
			
		||||
msgstr[1] "%u entrades"
 | 
			
		||||
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1402
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1406
 | 
			
		||||
msgid "System Sounds"
 | 
			
		||||
msgstr "Sons del sistema"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1298
 | 
			
		||||
#: ../src/main.c:446
 | 
			
		||||
msgid "Print version"
 | 
			
		||||
msgstr "Mostra la versió"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-app.c:454
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to launch '%s'"
 | 
			
		||||
msgstr "No s'ha pogut iniciar «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1395
 | 
			
		||||
msgid "Less than a minute ago"
 | 
			
		||||
msgstr "Fa menys d'un minut"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1302
 | 
			
		||||
#: ../src/shell-global.c:1399
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d minute ago"
 | 
			
		||||
msgid_plural "%d minutes ago"
 | 
			
		||||
msgstr[0] "Fa %d minut"
 | 
			
		||||
msgstr[1] "Fa %d minuts"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1307
 | 
			
		||||
#: ../src/shell-global.c:1404
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d hour ago"
 | 
			
		||||
msgid_plural "%d hours ago"
 | 
			
		||||
msgstr[0] "Fa %d hora"
 | 
			
		||||
msgstr[1] "Fa %d hores"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1312
 | 
			
		||||
#: ../src/shell-global.c:1409
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d day ago"
 | 
			
		||||
msgid_plural "%d days ago"
 | 
			
		||||
msgstr[0] "Fa %d dia"
 | 
			
		||||
msgstr[1] "Fa %d dies"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1317
 | 
			
		||||
#: ../src/shell-global.c:1414
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d week ago"
 | 
			
		||||
msgid_plural "%d weeks ago"
 | 
			
		||||
msgstr[0] "Fa %d setmana"
 | 
			
		||||
msgstr[1] "Fa %d setmanes"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-mobile-providers.c:80
 | 
			
		||||
msgid "United Kingdom"
 | 
			
		||||
msgstr "Regne Unit"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-mobile-providers.c:526
 | 
			
		||||
msgid "Default"
 | 
			
		||||
msgstr "Predeterminat"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-polkit-authentication-agent.c:334
 | 
			
		||||
msgid "Authentication dialog was dismissed by the user"
 | 
			
		||||
msgstr "L'usuari ha descartat el diàleg d'autenticació"
 | 
			
		||||
@@ -1018,10 +1206,6 @@ msgstr "Carpeta d'inici"
 | 
			
		||||
msgid "File System"
 | 
			
		||||
msgstr "Sistema de fitxers"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-util.c:250
 | 
			
		||||
msgid "Search"
 | 
			
		||||
msgstr "Cerca"
 | 
			
		||||
 | 
			
		||||
#. Translators: the first string is the name of a gvfs
 | 
			
		||||
#. * method, and the second string is a path. For
 | 
			
		||||
#. * example, "Trash: some-directory". It means that the
 | 
			
		||||
@@ -1032,6 +1216,33 @@ msgstr "Cerca"
 | 
			
		||||
msgid "%1$s: %2$s"
 | 
			
		||||
msgstr "%1$s: %2$s"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Shut Down"
 | 
			
		||||
#~ msgstr "Atura"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Click Shut Down to quit these applications and shut down the system."
 | 
			
		||||
#~ msgstr "Feu clic a «Atura» per tancar les aplicacions i apagar l'ordinador."
 | 
			
		||||
 | 
			
		||||
#~ msgid "The system will shut down automatically in %d seconds."
 | 
			
		||||
#~ msgstr "S'apagarà l'ordinador automàticament d'aquí %d segons."
 | 
			
		||||
 | 
			
		||||
#~ msgid "Shutting down the system."
 | 
			
		||||
#~ msgstr "S'està apagant l'ordinador."
 | 
			
		||||
 | 
			
		||||
#~ msgid "Confirm"
 | 
			
		||||
#~ msgstr "D'acord"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Panel"
 | 
			
		||||
#~ msgstr "Quadre"
 | 
			
		||||
 | 
			
		||||
#~ msgid "No such application"
 | 
			
		||||
#~ msgstr "No hi ha cap aplicació"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Screen Reader"
 | 
			
		||||
#~ msgstr "Lector de pantalla"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Screen Keyboard"
 | 
			
		||||
#~ msgstr "Teclat en pantalla"
 | 
			
		||||
 | 
			
		||||
#~ msgid "PREFERENCES"
 | 
			
		||||
#~ msgstr "PREFERÈNCIES"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1118
									
								
								po/en_GB.po
									
									
									
									
									
								
							
							
						
						
									
										1118
									
								
								po/en_GB.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										495
									
								
								po/et.po
									
									
									
									
									
								
							
							
						
						
									
										495
									
								
								po/et.po
									
									
									
									
									
								
							@@ -12,21 +12,21 @@ msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: gnome-shell MASTER\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
 | 
			
		||||
"shell&component=general\n"
 | 
			
		||||
"POT-Creation-Date: 2011-02-04 22:28+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2011-02-06 08:43+0200\n"
 | 
			
		||||
"Last-Translator: Ivar Smolin <okul@linux.ee>\n"
 | 
			
		||||
"shell&keywords=I18N+L10N&component=general\n"
 | 
			
		||||
"POT-Creation-Date: 2011-03-18 10:35+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2011-03-18 21:33+0300\n"
 | 
			
		||||
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
 | 
			
		||||
"Language-Team: Estonian <gnome-et@linux.ee>\n"
 | 
			
		||||
"Language: et\n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
			
		||||
"Content-Transfer-Encoding: 8bit\n"
 | 
			
		||||
"Language: et\n"
 | 
			
		||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 | 
			
		||||
"X-Poedit-Language: Estonian\n"
 | 
			
		||||
"X-Poedit-Country: Estonia\n"
 | 
			
		||||
 | 
			
		||||
msgid "GNOME Shell"
 | 
			
		||||
msgstr "GNOME kest"
 | 
			
		||||
msgstr "GNOME Shell"
 | 
			
		||||
 | 
			
		||||
msgid "Window management and application launching"
 | 
			
		||||
msgstr "Aknahaldur ja rakenduste käivitaja"
 | 
			
		||||
@@ -58,6 +58,10 @@ msgstr ""
 | 
			
		||||
msgid "History for command (Alt-F2) dialog"
 | 
			
		||||
msgstr "Käsudialoogi (Alt-F2) ajalugu"
 | 
			
		||||
 | 
			
		||||
# suurendusklaasidialoog? miks ka mitte :)
 | 
			
		||||
msgid "History for the looking glass dialog"
 | 
			
		||||
msgstr "Otsingudialoogi ajalugu"
 | 
			
		||||
 | 
			
		||||
msgid "If true, display date in the clock, in addition to time."
 | 
			
		||||
msgstr "Kui määratud, siis kuvatakse kellaaja kõrval ka kuupäeva."
 | 
			
		||||
 | 
			
		||||
@@ -83,6 +87,16 @@ msgid ""
 | 
			
		||||
"records to WEBM using the VP8 codec. %T is used as a placeholder for a guess "
 | 
			
		||||
"at the optimal thread count on the system."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Määrab GStreameri toru, mida kasutatakse lindistuste kodeerimiseks. See peab "
 | 
			
		||||
"vastama gst-launch'i süntaksile. Torul peaks olema vaba plokk (pad), kuhu "
 | 
			
		||||
"lindistatav video salvestatakse. Tavaliselt on vaba plokk olemas; selle "
 | 
			
		||||
"ploki väljund kirjutatakse väljundfaili. Toru võib hoolitseda ka enda "
 | 
			
		||||
"väljundi eest - seda võib kasutada väljundi saatmiseks icecast serverisse "
 | 
			
		||||
"shout2send või sarnase tehnoloogia abil. Kui see on määramata või väärtus on "
 | 
			
		||||
"tühi, kasutatakse vaikimisi toru. See on praegu 'videorate ! vp8enc "
 | 
			
		||||
"quality=10 speed=2 threads=%T ! queue ! webmmux' ning lindistab WEBM "
 | 
			
		||||
"vormingusse VP8 koodekiga. %T asendatakse süsteemi oletatava optimaalseima "
 | 
			
		||||
"lõimede (thread) arvuga."
 | 
			
		||||
 | 
			
		||||
msgid "Show date in clock"
 | 
			
		||||
msgstr "Kell näitab kuupäeva"
 | 
			
		||||
@@ -96,7 +110,7 @@ msgstr "Kellaaega näidatakse sekunditega"
 | 
			
		||||
msgid ""
 | 
			
		||||
"The applications corresponding to these identifiers will be displayed in the "
 | 
			
		||||
"favorites area."
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Nendele tunnustele vastavaid rakendusi kuvatakse lemmikutes."
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"The filename for recorded screencasts will be a unique filename based on the "
 | 
			
		||||
@@ -112,9 +126,10 @@ msgid ""
 | 
			
		||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
 | 
			
		||||
"screencast recorder in frames-per-second."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"GNOME Shelli lindistatava ekraanivideo kaadrisagedus (kaadrit sekundis)."
 | 
			
		||||
 | 
			
		||||
msgid "The gstreamer pipeline used to encode the screencast"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "GStreameri toru, mida ekraanivideo kodeerimiseks kasutatakse"
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"The shell normally monitors active applications in order to present the most "
 | 
			
		||||
@@ -122,125 +137,19 @@ msgid ""
 | 
			
		||||
"want to disable this for privacy reasons. Please note that doing so won't "
 | 
			
		||||
"remove already saved data."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Shell tavaliselt seirab aktiivseid rakendusi, et näidata enamkasutatavaid "
 | 
			
		||||
"(näiteks käivitajaid). Kuigi neid andmeid hoitakse privaatselt, võid "
 | 
			
		||||
"privaatsuse suurendamiseks selle keelata. Selle keelamine siiski ei eemalda "
 | 
			
		||||
"juba salvestatud andmeid."
 | 
			
		||||
 | 
			
		||||
msgid "Uuids of extensions to disable"
 | 
			
		||||
msgstr "Keelatavate laienduste UUID-d"
 | 
			
		||||
 | 
			
		||||
msgid "Whether to collect stats about applications usage"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Kas rakenduste kasutuse kohta kogutakse andmeid"
 | 
			
		||||
 | 
			
		||||
msgid "disabled OpenSearch providers"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Clip the crosshairs at the center"
 | 
			
		||||
msgstr "Niitristi keskel on auk"
 | 
			
		||||
 | 
			
		||||
msgid "Color of the crosshairs"
 | 
			
		||||
msgstr "Niitristi värvus"
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Determines the length of the vertical and horizontal lines that make up the "
 | 
			
		||||
"crosshairs."
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Determines the position of the magnified mouse image within the magnified "
 | 
			
		||||
"view and how it reacts to system mouse movement. The values are - none: no "
 | 
			
		||||
"mouse tracking; - centered: the mouse image is displayed at the center of "
 | 
			
		||||
"the zoom region (which also represents the point under the system mouse) and "
 | 
			
		||||
"the magnified contents are scrolled as the system mouse moves; - "
 | 
			
		||||
"proportional: the position of the magnified mouse in the zoom region is "
 | 
			
		||||
"proportionally the same as the position of the system mouse on screen; - "
 | 
			
		||||
"push: when the magnified mouse intersects a boundary of the zoom region, the "
 | 
			
		||||
"contents are scrolled into view."
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Determines the transparency of the crosshairs, from fully opaque to fully "
 | 
			
		||||
"transparent."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Määrab niitristi läbipaistvuse, alates täiesti läbipaistmatust kuni täiesti "
 | 
			
		||||
"läbipaistvani."
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Determines whether the crosshairs intersect the magnified mouse sprite, or "
 | 
			
		||||
"are clipped such that the ends of the horizontal and vertical lines surround "
 | 
			
		||||
"the mouse image."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Määrab, kas niitrist kattub suurendatud hiire pildiga või on keskelt ära "
 | 
			
		||||
"lõigatud nii, et jooned ümbritsevad hiirekursori pilti."
 | 
			
		||||
 | 
			
		||||
msgid "Enable lens mode"
 | 
			
		||||
msgstr "Läätsede režiimi lubamine"
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Enables/disables display of crosshairs centered on the magnified mouse "
 | 
			
		||||
"sprite."
 | 
			
		||||
msgstr "Lubab/keelab niitristi kuvamise suurendatud hiirekursori kohal."
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"For centered mouse tracking, when the system pointer is at or near the edge "
 | 
			
		||||
"of the screen, the magnified contents continue to scroll such that the "
 | 
			
		||||
"screen edge moves into the magnified view."
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Length of the crosshairs"
 | 
			
		||||
msgstr "Niitristi pikkus"
 | 
			
		||||
 | 
			
		||||
msgid "Magnification factor"
 | 
			
		||||
msgstr "Suurendustegur"
 | 
			
		||||
 | 
			
		||||
msgid "Mouse Tracking Mode"
 | 
			
		||||
msgstr "Hiire jälitamise režiim"
 | 
			
		||||
 | 
			
		||||
msgid "Opacity of the crosshairs"
 | 
			
		||||
msgstr "Niitristi läbipaistvus"
 | 
			
		||||
 | 
			
		||||
msgid "Screen position"
 | 
			
		||||
msgstr "Ekraani asukoht"
 | 
			
		||||
 | 
			
		||||
msgid "Scroll magnified contents beyond the edges of the desktop"
 | 
			
		||||
msgstr "Suurendusklaas võib liikuda töölauapiiridest väljapoole"
 | 
			
		||||
 | 
			
		||||
msgid "Show or hide crosshairs"
 | 
			
		||||
msgstr "Niitristi kuvamine või peitmine"
 | 
			
		||||
 | 
			
		||||
msgid "Show or hide the magnifier"
 | 
			
		||||
msgstr "Suurendusklaasi kuvamine või peitmine"
 | 
			
		||||
 | 
			
		||||
msgid "Show or hide the magnifier and all of its zoom regions."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Suurendusklaasi ja selle kõigi suurenduspiirkondade kuvamine või peitmine."
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"The color of the the vertical and horizontal lines that make up the "
 | 
			
		||||
"crosshairs."
 | 
			
		||||
msgstr "Niitristi püst- ja rõhtjoone värvus."
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"The magnified view either fills the entire screen, or occupies the top-half, "
 | 
			
		||||
"bottom-half, left-half, or right-half of the screen."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Suurendatud vaade täidab kas kogu ekraani või täidab ülemise, alumise, "
 | 
			
		||||
"vasaku või parema ekraanipoole."
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"The power of the magnification. A value of 1.0 means no magnification. A "
 | 
			
		||||
"value of 2.0 doubles the size."
 | 
			
		||||
msgstr "Suurendustegur. 1,0 tähendab originaalsuurust. 2,0 muudab kaks korda."
 | 
			
		||||
 | 
			
		||||
msgid "Thickness of the crosshairs"
 | 
			
		||||
msgstr "Niitristi paksus"
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Whether the magnified view should be centered over the location of the "
 | 
			
		||||
"system mouse and move with it."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Kas suurendatud vaate keskkoht peaks asetsema süsteemi hiire kohal ning "
 | 
			
		||||
"liikuma sellega kaasa."
 | 
			
		||||
 | 
			
		||||
msgid "Width of the vertical and horizontal lines that make up the crosshairs."
 | 
			
		||||
msgstr "Niitristi moodustavate püst- ja rõhtjoone laius"
 | 
			
		||||
msgstr "keelatud OpenSearch pakkujad"
 | 
			
		||||
 | 
			
		||||
msgid "Command not found"
 | 
			
		||||
msgstr "Käsku ei leitud"
 | 
			
		||||
@@ -250,9 +159,6 @@ msgstr "Käsku ei leitud"
 | 
			
		||||
msgid "Could not parse command:"
 | 
			
		||||
msgstr "Käsku pole võimalik analüüsida:"
 | 
			
		||||
 | 
			
		||||
msgid "No such application"
 | 
			
		||||
msgstr "Sellist rakendust ei ole"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Execution of '%s' failed:"
 | 
			
		||||
msgstr "'%s' käivitamine nurjus:"
 | 
			
		||||
@@ -264,8 +170,8 @@ msgstr "Kõik"
 | 
			
		||||
msgid "APPLICATIONS"
 | 
			
		||||
msgstr "Rakendused"
 | 
			
		||||
 | 
			
		||||
msgid "PREFERENCES"
 | 
			
		||||
msgstr "Eelistused"
 | 
			
		||||
msgid "SETTINGS"
 | 
			
		||||
msgstr "Seaded"
 | 
			
		||||
 | 
			
		||||
msgid "New Window"
 | 
			
		||||
msgstr "Uus aken"
 | 
			
		||||
@@ -382,7 +288,7 @@ msgstr "L"
 | 
			
		||||
 | 
			
		||||
#. Translators: Text to show if there are no events
 | 
			
		||||
msgid "Nothing Scheduled"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Ühtegi sündmust pole plaanitud"
 | 
			
		||||
 | 
			
		||||
#. Translators: Shown on calendar heading when selected day occurs on current year
 | 
			
		||||
msgctxt "calendar heading"
 | 
			
		||||
@@ -465,6 +371,8 @@ msgstr "Logi välja"
 | 
			
		||||
 | 
			
		||||
msgid "Click Log Out to quit these applications and log out of the system."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Nende rakenduste sulgemiseks ja süsteemist väljalogimiseks klõpsa nupule "
 | 
			
		||||
"Logi välja."
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s will be logged out automatically in %d seconds."
 | 
			
		||||
@@ -482,6 +390,8 @@ msgstr "Lülita välja"
 | 
			
		||||
 | 
			
		||||
msgid "Click Shut Down to quit these applications and shut down the system."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Nende rakenduste sulgemiseks ja süsteemi väljalülitamiseks klõpsa nupule "
 | 
			
		||||
"Logi välja."
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The system will shut down automatically in %d seconds."
 | 
			
		||||
@@ -534,6 +444,9 @@ msgstr "Kuva lähtekoodi"
 | 
			
		||||
msgid "Web Page"
 | 
			
		||||
msgstr "Veebileht"
 | 
			
		||||
 | 
			
		||||
msgid "Open"
 | 
			
		||||
msgstr "Ava"
 | 
			
		||||
 | 
			
		||||
msgid "System Information"
 | 
			
		||||
msgstr "Süsteemi andmed"
 | 
			
		||||
 | 
			
		||||
@@ -546,6 +459,11 @@ msgstr "Aknad"
 | 
			
		||||
msgid "Applications"
 | 
			
		||||
msgstr "Rakendused"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is the name of the dock/favorites area on
 | 
			
		||||
#. the left of the overview
 | 
			
		||||
msgid "Dash"
 | 
			
		||||
msgstr "Dokk"
 | 
			
		||||
 | 
			
		||||
#. TODO - _quit() doesn't really work on apps in state STARTING yet
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Quit %s"
 | 
			
		||||
@@ -556,6 +474,9 @@ msgstr "Lõpeta %s"
 | 
			
		||||
msgid "Activities"
 | 
			
		||||
msgstr "Tegevused"
 | 
			
		||||
 | 
			
		||||
msgid "Panel"
 | 
			
		||||
msgstr "Paneel"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to unmount '%s'"
 | 
			
		||||
msgstr "'%s' lahtihaakimine nurjus"
 | 
			
		||||
@@ -580,6 +501,18 @@ msgstr "toggle-switch-intl"
 | 
			
		||||
msgid "Please enter a command:"
 | 
			
		||||
msgstr "Palun sisesta käsk:"
 | 
			
		||||
 | 
			
		||||
msgid "Searching..."
 | 
			
		||||
msgstr "Otsimine..."
 | 
			
		||||
 | 
			
		||||
msgid "No matching results."
 | 
			
		||||
msgstr "Tulemused puuduvad."
 | 
			
		||||
 | 
			
		||||
msgid "Power Off..."
 | 
			
		||||
msgstr "Lülita välja..."
 | 
			
		||||
 | 
			
		||||
msgid "Suspend"
 | 
			
		||||
msgstr "Uinak"
 | 
			
		||||
 | 
			
		||||
msgid "Available"
 | 
			
		||||
msgstr "Saadaval"
 | 
			
		||||
 | 
			
		||||
@@ -601,24 +534,15 @@ msgstr "Vaheta kasutajat"
 | 
			
		||||
msgid "Log Out..."
 | 
			
		||||
msgstr "Logi välja..."
 | 
			
		||||
 | 
			
		||||
#. This is temporarily removed, see
 | 
			
		||||
#. http://bugzilla.gnome.org/show_bug.cgi?id=636680
 | 
			
		||||
#. for details.
 | 
			
		||||
#. item = new PopupMenu.PopupMenuItem(_("Suspend..."));
 | 
			
		||||
#. item.connect('activate', Lang.bind(this, this._onShutDownActivate));
 | 
			
		||||
#. this.menu.addMenuItem(item);
 | 
			
		||||
msgid "Shut Down..."
 | 
			
		||||
msgstr "Lülita välja..."
 | 
			
		||||
 | 
			
		||||
msgid "Zoom"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
msgid "Screen Reader"
 | 
			
		||||
msgstr "Ekraanilugeja"
 | 
			
		||||
 | 
			
		||||
msgid "Screen Keyboard"
 | 
			
		||||
msgstr "Ekraaniklaviatuur"
 | 
			
		||||
msgstr "Suurendus"
 | 
			
		||||
 | 
			
		||||
#. let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
 | 
			
		||||
#. 'screen-reader-enabled');
 | 
			
		||||
#. this.menu.addMenuItem(screenReader);
 | 
			
		||||
#. let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
 | 
			
		||||
#. 'screen-keyboard-enabled');
 | 
			
		||||
#. this.menu.addMenuItem(screenKeyboard);
 | 
			
		||||
msgid "Visual Alerts"
 | 
			
		||||
msgstr "Visuaalsed märguanded"
 | 
			
		||||
 | 
			
		||||
@@ -638,10 +562,10 @@ msgid "Universal Access Settings"
 | 
			
		||||
msgstr "Universaalse ligipääsu sätted"
 | 
			
		||||
 | 
			
		||||
msgid "High Contrast"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Kõrgkontrastne"
 | 
			
		||||
 | 
			
		||||
msgid "Large Text"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Suur tekst"
 | 
			
		||||
 | 
			
		||||
msgid "Bluetooth"
 | 
			
		||||
msgstr "Bluetooth"
 | 
			
		||||
@@ -653,7 +577,7 @@ msgid "Send Files to Device..."
 | 
			
		||||
msgstr "Failide saatmine seadmesse..."
 | 
			
		||||
 | 
			
		||||
msgid "Setup a New Device..."
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Uue seadme häälestamine..."
 | 
			
		||||
 | 
			
		||||
msgid "Bluetooth Settings"
 | 
			
		||||
msgstr "Bluetoothi sätted"
 | 
			
		||||
@@ -672,7 +596,7 @@ msgstr "Viga seadme sirvimisel"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The requested device cannot be browsed, error is '%s'"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "Küsitud seadet pole võimalik sirvida, viga on '%s'"
 | 
			
		||||
 | 
			
		||||
msgid "Keyboard Settings"
 | 
			
		||||
msgstr "Klaviatuurisätted"
 | 
			
		||||
@@ -683,9 +607,6 @@ msgstr "Hiiresätted"
 | 
			
		||||
msgid "Sound Settings"
 | 
			
		||||
msgstr "Helisätted"
 | 
			
		||||
 | 
			
		||||
msgid "Bluetooth Agent"
 | 
			
		||||
msgstr "Bluetoothi agent"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Authorization request from %s"
 | 
			
		||||
msgstr "Autoriseerimise päring seadmelt %s"
 | 
			
		||||
@@ -731,12 +652,121 @@ msgstr "Palun sisesta seadme poolt öeldav PIN-kood."
 | 
			
		||||
msgid "OK"
 | 
			
		||||
msgstr "Olgu"
 | 
			
		||||
 | 
			
		||||
msgid "Show Keyboard Layout..."
 | 
			
		||||
msgstr "Klaviatuuripaigutuse kuvamine..."
 | 
			
		||||
 | 
			
		||||
msgid "Localization Settings"
 | 
			
		||||
msgstr "Lokaliseerimissätted"
 | 
			
		||||
 | 
			
		||||
msgid "<unknown>"
 | 
			
		||||
msgstr "<tundmatu>"
 | 
			
		||||
 | 
			
		||||
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
 | 
			
		||||
msgid "disabled"
 | 
			
		||||
msgstr "keelatud"
 | 
			
		||||
 | 
			
		||||
msgid "connecting..."
 | 
			
		||||
msgstr "ühendumine..."
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for network connections that require some kind of key or password
 | 
			
		||||
msgid "authentication required"
 | 
			
		||||
msgstr "vajalik on autentimine"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for wired network devices that are physically disconnected
 | 
			
		||||
msgid "cable unplugged"
 | 
			
		||||
msgstr "juhe eemaldatud"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for a network device that cannot be activated (for example it
 | 
			
		||||
#. is disabled by rfkill, or it has no coverage
 | 
			
		||||
msgid "unavailable"
 | 
			
		||||
msgstr "pole saadaval"
 | 
			
		||||
 | 
			
		||||
msgid "connection failed"
 | 
			
		||||
msgstr "ühendumine nurjus"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
 | 
			
		||||
#. and we cannot access its settings (including the name)
 | 
			
		||||
msgid "Connected (private)"
 | 
			
		||||
msgstr "Ühendatud (privaatne)"
 | 
			
		||||
 | 
			
		||||
msgid "Auto Ethernet"
 | 
			
		||||
msgstr "Automaatne ethernet"
 | 
			
		||||
 | 
			
		||||
msgid "Auto broadband"
 | 
			
		||||
msgstr "Automaatne lairibaühendus"
 | 
			
		||||
 | 
			
		||||
msgid "Auto dial-up"
 | 
			
		||||
msgstr "Automaatne sissehelistamine"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Auto %s"
 | 
			
		||||
msgstr "Automaatne %s"
 | 
			
		||||
 | 
			
		||||
msgid "Auto bluetooth"
 | 
			
		||||
msgstr "Automaatne bluetooth"
 | 
			
		||||
 | 
			
		||||
msgid "Auto wireless"
 | 
			
		||||
msgstr "Automaatne juhtmeta ühendus"
 | 
			
		||||
 | 
			
		||||
msgid "More..."
 | 
			
		||||
msgstr "Veel..."
 | 
			
		||||
 | 
			
		||||
msgid "Enable networking"
 | 
			
		||||
msgstr "Luba võrguühendused"
 | 
			
		||||
 | 
			
		||||
msgid "Wired"
 | 
			
		||||
msgstr "Juhtmega"
 | 
			
		||||
 | 
			
		||||
msgid "Wireless"
 | 
			
		||||
msgstr "Juhtmeta"
 | 
			
		||||
 | 
			
		||||
msgid "Mobile broadband"
 | 
			
		||||
msgstr "Mobiiliühendus"
 | 
			
		||||
 | 
			
		||||
msgid "VPN Connections"
 | 
			
		||||
msgstr "VPN-ühendused"
 | 
			
		||||
 | 
			
		||||
msgid "Network Settings"
 | 
			
		||||
msgstr "Võrgusätted"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to mobile broadband connection '%s'"
 | 
			
		||||
msgstr "Loodi mobiiliühendus '%s'"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to wireless network '%s'"
 | 
			
		||||
msgstr "Loodi ühendus juhtmeta võrguga '%s'"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to wired network '%s'"
 | 
			
		||||
msgstr "Loodi ühendus juhtmega võrguga '%s'"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to VPN network '%s'"
 | 
			
		||||
msgstr "Loodi ühendus VPN-võrguga '%s'"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to '%s'"
 | 
			
		||||
msgstr "Loodi võrguühendus '%s' kaudu"
 | 
			
		||||
 | 
			
		||||
msgid "Connection estabilished"
 | 
			
		||||
msgstr "Ühendus loodud"
 | 
			
		||||
 | 
			
		||||
msgid "Networking is disabled"
 | 
			
		||||
msgstr "Võrguühendused on keelatud"
 | 
			
		||||
 | 
			
		||||
msgid "Network Manager"
 | 
			
		||||
msgstr "Võrguhaldur"
 | 
			
		||||
 | 
			
		||||
msgid "Power Settings"
 | 
			
		||||
msgstr "Toitesätted..."
 | 
			
		||||
 | 
			
		||||
#. 0 is reported when UPower does not have enough data
 | 
			
		||||
#. to estimate battery life
 | 
			
		||||
msgid "Estimating..."
 | 
			
		||||
msgstr "Andmete kogumine..."
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d hour remaining"
 | 
			
		||||
msgid_plural "%d hours remaining"
 | 
			
		||||
@@ -829,8 +859,15 @@ msgstr "%s on hõivatud."
 | 
			
		||||
msgid "Sent at %X on %A"
 | 
			
		||||
msgstr "Saadetud: %a, kell %X"
 | 
			
		||||
 | 
			
		||||
msgid "Search your computer"
 | 
			
		||||
msgstr ""
 | 
			
		||||
#. Translators: this is the text displayed
 | 
			
		||||
#. in the search entry when no search is
 | 
			
		||||
#. active; it should not exceed ~30
 | 
			
		||||
#. characters.
 | 
			
		||||
msgid "Type to search..."
 | 
			
		||||
msgstr "Otsing..."
 | 
			
		||||
 | 
			
		||||
msgid "Search"
 | 
			
		||||
msgstr "Otsing"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s has finished starting"
 | 
			
		||||
@@ -840,32 +877,32 @@ msgstr "%s läks käima"
 | 
			
		||||
msgid "'%s' is ready"
 | 
			
		||||
msgstr "'%s' on valmis"
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Can't add a new workspace because maximum workspaces limit has been reached."
 | 
			
		||||
msgstr "Pole võimalik uut tööala lisada, kuna tööalade piir on saavutatud."
 | 
			
		||||
 | 
			
		||||
msgid "Can't remove the first workspace."
 | 
			
		||||
msgstr "Esimest tööala pole võimalik eemaldada."
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The number of sound outputs on a particular device
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%u Output"
 | 
			
		||||
msgid_plural "%u Outputs"
 | 
			
		||||
msgstr[0] ""
 | 
			
		||||
msgstr[1] ""
 | 
			
		||||
msgstr[0] "%u väljund"
 | 
			
		||||
msgstr[1] "%u väljundit"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The number of sound inputs on a particular device
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%u Input"
 | 
			
		||||
msgid_plural "%u Inputs"
 | 
			
		||||
msgstr[0] ""
 | 
			
		||||
msgstr[1] ""
 | 
			
		||||
msgstr[0] "%u sisend"
 | 
			
		||||
msgstr[1] "%u sisendit"
 | 
			
		||||
 | 
			
		||||
msgid "System Sounds"
 | 
			
		||||
msgstr "Süsteemi helid"
 | 
			
		||||
 | 
			
		||||
msgid "Print version"
 | 
			
		||||
msgstr "Printimise versioon"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to launch '%s'"
 | 
			
		||||
msgstr "'%s' käivitamine nurjus"
 | 
			
		||||
 | 
			
		||||
msgid "Less than a minute ago"
 | 
			
		||||
msgstr "Vähem kui minuti eest"
 | 
			
		||||
 | 
			
		||||
@@ -893,6 +930,15 @@ msgid_plural "%d weeks ago"
 | 
			
		||||
msgstr[0] "%d nädal tagasi"
 | 
			
		||||
msgstr[1] "%d nädalat tagasi"
 | 
			
		||||
 | 
			
		||||
msgid "United Kingdom"
 | 
			
		||||
msgstr "Suurbritannia"
 | 
			
		||||
 | 
			
		||||
msgid "Default"
 | 
			
		||||
msgstr "Vaikimisi"
 | 
			
		||||
 | 
			
		||||
msgid "Authentication dialog was dismissed by the user"
 | 
			
		||||
msgstr "Kasutaja katkestas autentimisdialoogi"
 | 
			
		||||
 | 
			
		||||
msgid "Home Folder"
 | 
			
		||||
msgstr "Kodukaust"
 | 
			
		||||
 | 
			
		||||
@@ -901,9 +947,6 @@ msgstr "Kodukaust"
 | 
			
		||||
msgid "File System"
 | 
			
		||||
msgstr "Failisüsteem"
 | 
			
		||||
 | 
			
		||||
msgid "Search"
 | 
			
		||||
msgstr "Otsing"
 | 
			
		||||
 | 
			
		||||
#. Translators: the first string is the name of a gvfs
 | 
			
		||||
#. * method, and the second string is a path. For
 | 
			
		||||
#. * example, "Trash: some-directory". It means that the
 | 
			
		||||
@@ -913,8 +956,120 @@ msgstr "Otsing"
 | 
			
		||||
msgid "%1$s: %2$s"
 | 
			
		||||
msgstr "%1$s: %2$s"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Suspend..."
 | 
			
		||||
#~ msgstr "Peata..."
 | 
			
		||||
#~ msgid "No such application"
 | 
			
		||||
#~ msgstr "Sellist rakendust ei ole"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Screen Reader"
 | 
			
		||||
#~ msgstr "Ekraanilugeja"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Screen Keyboard"
 | 
			
		||||
#~ msgstr "Ekraaniklaviatuur"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Clip the crosshairs at the center"
 | 
			
		||||
#~ msgstr "Niitristi keskel on auk"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Color of the crosshairs"
 | 
			
		||||
#~ msgstr "Niitristi värvus"
 | 
			
		||||
 | 
			
		||||
#~ msgid ""
 | 
			
		||||
#~ "Determines the transparency of the crosshairs, from fully opaque to fully "
 | 
			
		||||
#~ "transparent."
 | 
			
		||||
#~ msgstr ""
 | 
			
		||||
#~ "Määrab niitristi läbipaistvuse, alates täiesti läbipaistmatust kuni "
 | 
			
		||||
#~ "täiesti läbipaistvani."
 | 
			
		||||
 | 
			
		||||
#~ msgid ""
 | 
			
		||||
#~ "Determines whether the crosshairs intersect the magnified mouse sprite, "
 | 
			
		||||
#~ "or are clipped such that the ends of the horizontal and vertical lines "
 | 
			
		||||
#~ "surround the mouse image."
 | 
			
		||||
#~ msgstr ""
 | 
			
		||||
#~ "Määrab, kas niitrist kattub suurendatud hiire pildiga või on keskelt ära "
 | 
			
		||||
#~ "lõigatud nii, et jooned ümbritsevad hiirekursori pilti."
 | 
			
		||||
 | 
			
		||||
#~ msgid "Enable lens mode"
 | 
			
		||||
#~ msgstr "Läätsede režiimi lubamine"
 | 
			
		||||
 | 
			
		||||
#~ msgid ""
 | 
			
		||||
#~ "Enables/disables display of crosshairs centered on the magnified mouse "
 | 
			
		||||
#~ "sprite."
 | 
			
		||||
#~ msgstr "Lubab/keelab niitristi kuvamise suurendatud hiirekursori kohal."
 | 
			
		||||
 | 
			
		||||
#~ msgid "Length of the crosshairs"
 | 
			
		||||
#~ msgstr "Niitristi pikkus"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Magnification factor"
 | 
			
		||||
#~ msgstr "Suurendustegur"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Mouse Tracking Mode"
 | 
			
		||||
#~ msgstr "Hiire jälitamise režiim"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Opacity of the crosshairs"
 | 
			
		||||
#~ msgstr "Niitristi läbipaistvus"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Screen position"
 | 
			
		||||
#~ msgstr "Ekraani asukoht"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Scroll magnified contents beyond the edges of the desktop"
 | 
			
		||||
#~ msgstr "Suurendusklaas võib liikuda töölauapiiridest väljapoole"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Show or hide crosshairs"
 | 
			
		||||
#~ msgstr "Niitristi kuvamine või peitmine"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Show or hide the magnifier"
 | 
			
		||||
#~ msgstr "Suurendusklaasi kuvamine või peitmine"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Show or hide the magnifier and all of its zoom regions."
 | 
			
		||||
#~ msgstr ""
 | 
			
		||||
#~ "Suurendusklaasi ja selle kõigi suurenduspiirkondade kuvamine või peitmine."
 | 
			
		||||
 | 
			
		||||
#~ msgid ""
 | 
			
		||||
#~ "The color of the the vertical and horizontal lines that make up the "
 | 
			
		||||
#~ "crosshairs."
 | 
			
		||||
#~ msgstr "Niitristi püst- ja rõhtjoone värvus."
 | 
			
		||||
 | 
			
		||||
#~ msgid ""
 | 
			
		||||
#~ "The magnified view either fills the entire screen, or occupies the top-"
 | 
			
		||||
#~ "half, bottom-half, left-half, or right-half of the screen."
 | 
			
		||||
#~ msgstr ""
 | 
			
		||||
#~ "Suurendatud vaade täidab kas kogu ekraani või täidab ülemise, alumise, "
 | 
			
		||||
#~ "vasaku või parema ekraanipoole."
 | 
			
		||||
 | 
			
		||||
#~ msgid ""
 | 
			
		||||
#~ "The power of the magnification. A value of 1.0 means no magnification. A "
 | 
			
		||||
#~ "value of 2.0 doubles the size."
 | 
			
		||||
#~ msgstr ""
 | 
			
		||||
#~ "Suurendustegur. 1,0 tähendab originaalsuurust. 2,0 muudab kaks korda."
 | 
			
		||||
 | 
			
		||||
#~ msgid "Thickness of the crosshairs"
 | 
			
		||||
#~ msgstr "Niitristi paksus"
 | 
			
		||||
 | 
			
		||||
#~ msgid ""
 | 
			
		||||
#~ "Whether the magnified view should be centered over the location of the "
 | 
			
		||||
#~ "system mouse and move with it."
 | 
			
		||||
#~ msgstr ""
 | 
			
		||||
#~ "Kas suurendatud vaate keskkoht peaks asetsema süsteemi hiire kohal ning "
 | 
			
		||||
#~ "liikuma sellega kaasa."
 | 
			
		||||
 | 
			
		||||
#~ msgid ""
 | 
			
		||||
#~ "Width of the vertical and horizontal lines that make up the crosshairs."
 | 
			
		||||
#~ msgstr "Niitristi moodustavate püst- ja rõhtjoone laius"
 | 
			
		||||
 | 
			
		||||
#~ msgid "PREFERENCES"
 | 
			
		||||
#~ msgstr "Eelistused"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Shut Down..."
 | 
			
		||||
#~ msgstr "Lülita välja..."
 | 
			
		||||
 | 
			
		||||
#~ msgid "Bluetooth Agent"
 | 
			
		||||
#~ msgstr "Bluetoothi agent"
 | 
			
		||||
 | 
			
		||||
#~ msgid ""
 | 
			
		||||
#~ "Can't add a new workspace because maximum workspaces limit has been "
 | 
			
		||||
#~ "reached."
 | 
			
		||||
#~ msgstr "Pole võimalik uut tööala lisada, kuna tööalade piir on saavutatud."
 | 
			
		||||
 | 
			
		||||
#~ msgid "Can't remove the first workspace."
 | 
			
		||||
#~ msgstr "Esimest tööala pole võimalik eemaldada."
 | 
			
		||||
 | 
			
		||||
#~ msgid "Clock"
 | 
			
		||||
#~ msgstr "Kell"
 | 
			
		||||
@@ -958,11 +1113,5 @@ msgstr "%1$s: %2$s"
 | 
			
		||||
#~ msgid "Find"
 | 
			
		||||
#~ msgstr "Otsi"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Searching..."
 | 
			
		||||
#~ msgstr "Otsimine..."
 | 
			
		||||
 | 
			
		||||
#~ msgid "No matching results."
 | 
			
		||||
#~ msgstr "Tulemused puuduvad."
 | 
			
		||||
 | 
			
		||||
#~ msgid "Invisible"
 | 
			
		||||
#~ msgstr "Nähtamatu"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								po/kn.po
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								po/kn.po
									
									
									
									
									
								
							@@ -9,7 +9,7 @@ msgstr ""
 | 
			
		||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug."
 | 
			
		||||
"cgi?product=gnome-shell&component=general\n"
 | 
			
		||||
"POT-Creation-Date: 2011-02-21 01:21+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2011-03-04 17:37+0530\n"
 | 
			
		||||
"PO-Revision-Date: 2011-03-09 09:36+0530\n"
 | 
			
		||||
"Last-Translator: Shankar Prasad <svenkate@redhat.com>\n"
 | 
			
		||||
"Language-Team: Kannada <kn@li.org>\n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
@@ -112,6 +112,7 @@ msgid ""
 | 
			
		||||
"The applications corresponding to these identifiers will be displayed in the "
 | 
			
		||||
"favorites area."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"ಈ ಐಡೆಂಟಿಫಯರುಗಳಿಗೆ ಅನುಗುಣವಾದ ಅನ್ವಯಗಳನ್ನು ಮೆಚ್ಚಿನವುಗಳ ಜಾಗದಲ್ಲಿ ತೋರಿಸಲಾಗುತ್ತದೆ."
 | 
			
		||||
 | 
			
		||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
 | 
			
		||||
msgid ""
 | 
			
		||||
@@ -119,12 +120,17 @@ msgid ""
 | 
			
		||||
"current date, and use this extension. It should be changed when recording to "
 | 
			
		||||
"a different container format."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"ರೆಕಾರ್ಡು ಮಾಡಲಾದ ಸ್ಕ್ರೀನ್ಕ್ಯಾಸ್ಟುಗಳಿಗಾಗಿನ ಕಡತದ ಹೆಸರು ಪ್ರಸಕ್ತ ದಿನಾಂಕದ "
 | 
			
		||||
"ಆಧರಿತವಾದ ಒಂದು ವಿಶೇಷವಾದ ಕಡತದ ಹೆಸರಾಗಿರುತ್ತದೆ, ಹಾಗು ಈ ವಿಸ್ತರಣೆಯನ್ನು ಬಳಸುತ್ತದೆ. "
 | 
			
		||||
"ಬೇರೊಂದು ಕಂಟೈನರ್ ಶೈಲಿಗೆ ರೆಕಾರ್ಡ್ ಮಾಡುವಾಗ ಇದನ್ನು ಬದಲಾಯಿಸಬೇಕಾಗುತ್ತದೆ."
 | 
			
		||||
 | 
			
		||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
 | 
			
		||||
msgid ""
 | 
			
		||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
 | 
			
		||||
"screencast recorder in frames-per-second."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"ಪ್ರತಿ ಸೆಕೆಂಡಿನ ಫ್ರೇಮ್ಗಳಲ್ಲಿನ GNOME ಶೆಲ್ನ ಸ್ಕ್ರೀನ್ಕ್ಯಾಸ್ಟ್ ರೆಕಾರ್ಡರಿನಿಂದ "
 | 
			
		||||
"ರೆಕಾರ್ಡು ಮಾಡಲಾದ ಸ್ಕ್ರೀನ್ಕ್ಯಾಸ್ಟಿನ ಫ್ರೇಮ್ದರ. "
 | 
			
		||||
 | 
			
		||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
 | 
			
		||||
msgid "The gstreamer pipeline used to encode the screencast"
 | 
			
		||||
@@ -658,7 +664,7 @@ msgstr "ಜಾಗತಿಕ ನಿಲುಕಣೆ ಸಿದ್ಧತೆಗಳು"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:164
 | 
			
		||||
msgid "High Contrast"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "ಅತಿ ಹೆಚ್ಚು ವೈದೃಶ್ಯ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:206
 | 
			
		||||
msgid "Large Text"
 | 
			
		||||
@@ -767,7 +773,7 @@ msgstr "ತಾಳೆಯಾಗುತ್ತಿಲ್ಲ"
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:445
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Pairing request for %s"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "%s ಗಾಗಿ ಪೇರಿಂಗ್ ಮನವಿ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:453
 | 
			
		||||
msgid "Please enter the PIN mentioned on the device."
 | 
			
		||||
@@ -912,7 +918,7 @@ msgstr "ಹುಡುಕಲು ನಮೂದಿಸು..."
 | 
			
		||||
#: ../js/ui/windowAttentionHandler.js:43
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s has finished starting"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "ಆರಂಭಗೊಳಿಸುವುದನ್ನು %s ಪೂರ್ಣಗೊಳಿಸಿದ್ದಾರೆ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/windowAttentionHandler.js:45
 | 
			
		||||
#, c-format
 | 
			
		||||
@@ -925,8 +931,8 @@ msgstr "'%s' ಸಿದ್ಧಗೊಂಡಿದೆ"
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%u Output"
 | 
			
		||||
msgid_plural "%u Outputs"
 | 
			
		||||
msgstr[0] ""
 | 
			
		||||
msgstr[1] ""
 | 
			
		||||
msgstr[0] "%u ಔಟ್ಪುಟ್"
 | 
			
		||||
msgstr[1] "%u ಔಟ್ಪುಟ್ಗಳು"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The number of sound inputs on a particular device
 | 
			
		||||
@@ -934,8 +940,8 @@ msgstr[1] ""
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%u Input"
 | 
			
		||||
msgid_plural "%u Inputs"
 | 
			
		||||
msgstr[0] ""
 | 
			
		||||
msgstr[1] ""
 | 
			
		||||
msgstr[0] "%u ಇನ್ಪುಟ್"
 | 
			
		||||
msgstr[1] "%u ಇನ್ಪುಟ್ಗಳು"
 | 
			
		||||
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1402
 | 
			
		||||
msgid "System Sounds"
 | 
			
		||||
@@ -943,7 +949,7 @@ msgstr "ವ್ಯವಸ್ಥೆಯ ಧ್ವನಿಗಳು"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1363
 | 
			
		||||
msgid "Less than a minute ago"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "ಒಂದು ನಿಮಿಷಕ್ಕೂ ಹಿಂದೆ"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1367
 | 
			
		||||
#, c-format
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										457
									
								
								po/nb.po
									
									
									
									
									
								
							
							
						
						
									
										457
									
								
								po/nb.po
									
									
									
									
									
								
							@@ -4,12 +4,13 @@
 | 
			
		||||
#
 | 
			
		||||
# Kjartan Maraas <kmaraas@gnome.org>, 2009-2011.
 | 
			
		||||
# Torstein Adolf Winterseth <kvikende@fsfe.org>, 2010.
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:142
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: gnome-shell 2.91.x\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: \n"
 | 
			
		||||
"POT-Creation-Date: 2011-03-06 13:39+0100\n"
 | 
			
		||||
"PO-Revision-Date: 2011-03-06 13:40+0100\n"
 | 
			
		||||
"POT-Creation-Date: 2011-03-23 21:46+0100\n"
 | 
			
		||||
"PO-Revision-Date: 2011-03-23 21:47+0100\n"
 | 
			
		||||
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
 | 
			
		||||
"Language-Team: Norwegian Bokmål <i18n-nb@lister.ping.uio.no>\n"
 | 
			
		||||
"Language: \n"
 | 
			
		||||
@@ -145,49 +146,45 @@ msgstr "Om det skal samles statistikk om bruk av programmer"
 | 
			
		||||
 | 
			
		||||
#: ../data/org.gnome.shell.gschema.xml.in.h:24
 | 
			
		||||
msgid "disabled OpenSearch providers"
 | 
			
		||||
msgstr ""
 | 
			
		||||
msgstr "OpenSearch tilbydere slått av"
 | 
			
		||||
 | 
			
		||||
#: ../js/misc/util.js:86
 | 
			
		||||
#: ../js/misc/util.js:71
 | 
			
		||||
msgid "Command not found"
 | 
			
		||||
msgstr "Kommando ikke funnet"
 | 
			
		||||
 | 
			
		||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
 | 
			
		||||
#. something nicer
 | 
			
		||||
#: ../js/misc/util.js:113
 | 
			
		||||
#: ../js/misc/util.js:98
 | 
			
		||||
msgid "Could not parse command:"
 | 
			
		||||
msgstr "Klarte ikke å lese kommando:"
 | 
			
		||||
 | 
			
		||||
#: ../js/misc/util.js:135
 | 
			
		||||
msgid "No such application"
 | 
			
		||||
msgstr "Programmet finnes ikke"
 | 
			
		||||
 | 
			
		||||
#: ../js/misc/util.js:148
 | 
			
		||||
#: ../js/misc/util.js:106
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Execution of '%s' failed:"
 | 
			
		||||
msgstr "Kjøring av «%s» feilet:"
 | 
			
		||||
 | 
			
		||||
#. Translators: Filter to display all applications
 | 
			
		||||
#: ../js/ui/appDisplay.js:195
 | 
			
		||||
#: ../js/ui/appDisplay.js:230
 | 
			
		||||
msgid "All"
 | 
			
		||||
msgstr "Alle"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:285
 | 
			
		||||
#: ../js/ui/appDisplay.js:328
 | 
			
		||||
msgid "APPLICATIONS"
 | 
			
		||||
msgstr "PROGRAMMER"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:311
 | 
			
		||||
#: ../js/ui/appDisplay.js:354
 | 
			
		||||
msgid "SETTINGS"
 | 
			
		||||
msgstr "INNSTILLINGER"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:565
 | 
			
		||||
#: ../js/ui/appDisplay.js:625
 | 
			
		||||
msgid "New Window"
 | 
			
		||||
msgstr "Nytt vindu"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:568
 | 
			
		||||
#: ../js/ui/appDisplay.js:628
 | 
			
		||||
msgid "Remove from Favorites"
 | 
			
		||||
msgstr "Fjern fra favoritter"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:569
 | 
			
		||||
#: ../js/ui/appDisplay.js:629
 | 
			
		||||
msgid "Add to Favorites"
 | 
			
		||||
msgstr "Legg til i favoritter"
 | 
			
		||||
 | 
			
		||||
@@ -347,7 +344,7 @@ msgstr "Denne uken"
 | 
			
		||||
msgid "Next week"
 | 
			
		||||
msgstr "Neste uke"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dash.js:174
 | 
			
		||||
#: ../js/ui/dash.js:174 ../js/ui/messageTray.js:994
 | 
			
		||||
msgid "Remove"
 | 
			
		||||
msgstr "Fjern"
 | 
			
		||||
 | 
			
		||||
@@ -355,54 +352,54 @@ msgstr "Fjern"
 | 
			
		||||
msgid "Date and Time Settings"
 | 
			
		||||
msgstr "Innstillinger for dato og klokkeslett"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:110
 | 
			
		||||
#: ../js/ui/dateMenu.js:111
 | 
			
		||||
msgid "Open Calendar"
 | 
			
		||||
msgstr "Åpne kalender"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is the time format with date used
 | 
			
		||||
#. in 24-hour mode.
 | 
			
		||||
#: ../js/ui/dateMenu.js:162
 | 
			
		||||
#: ../js/ui/dateMenu.js:164
 | 
			
		||||
msgid "%a %b %e, %R:%S"
 | 
			
		||||
msgstr "%a %e %b, %R.%S"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:163
 | 
			
		||||
#: ../js/ui/dateMenu.js:165
 | 
			
		||||
msgid "%a %b %e, %R"
 | 
			
		||||
msgstr "%a %e %b, %R"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is the time format without date used
 | 
			
		||||
#. in 24-hour mode.
 | 
			
		||||
#: ../js/ui/dateMenu.js:167
 | 
			
		||||
#: ../js/ui/dateMenu.js:169
 | 
			
		||||
msgid "%a %R:%S"
 | 
			
		||||
msgstr "%a %R.%S"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:168
 | 
			
		||||
#: ../js/ui/dateMenu.js:170
 | 
			
		||||
msgid "%a %R"
 | 
			
		||||
msgstr "%a %R"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is a time format with date used
 | 
			
		||||
#. for AM/PM.
 | 
			
		||||
#: ../js/ui/dateMenu.js:175
 | 
			
		||||
#: ../js/ui/dateMenu.js:177
 | 
			
		||||
msgid "%a %b %e, %l:%M:%S %p"
 | 
			
		||||
msgstr "%a %e %b, %l.%M.%S %p"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:176
 | 
			
		||||
#: ../js/ui/dateMenu.js:178
 | 
			
		||||
msgid "%a %b %e, %l:%M %p"
 | 
			
		||||
msgstr "%a %e %b, %l.%M %p"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is a time format without date used
 | 
			
		||||
#. for AM/PM.
 | 
			
		||||
#: ../js/ui/dateMenu.js:180
 | 
			
		||||
#: ../js/ui/dateMenu.js:182
 | 
			
		||||
msgid "%a %l:%M:%S %p"
 | 
			
		||||
msgstr "%a %l.%M.%S %p"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:181
 | 
			
		||||
#: ../js/ui/dateMenu.js:183
 | 
			
		||||
msgid "%a %l:%M %p"
 | 
			
		||||
msgstr "%a %l.%M %p"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is the date format to use when the calendar popup is
 | 
			
		||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
 | 
			
		||||
#.
 | 
			
		||||
#: ../js/ui/dateMenu.js:207
 | 
			
		||||
#: ../js/ui/dateMenu.js:194
 | 
			
		||||
msgid "%A %B %e, %Y"
 | 
			
		||||
msgstr "%a %e %B, %Y"
 | 
			
		||||
 | 
			
		||||
@@ -415,7 +412,7 @@ msgstr "SISTE OPPFØRINGER"
 | 
			
		||||
msgid "Log Out %s"
 | 
			
		||||
msgstr "Logg ut %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:69
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:70
 | 
			
		||||
msgid "Log Out"
 | 
			
		||||
msgstr "Logg ut"
 | 
			
		||||
 | 
			
		||||
@@ -438,47 +435,46 @@ msgstr "Du vil bli logget ut automatisk om %d sekunder."
 | 
			
		||||
msgid "Logging out of the system."
 | 
			
		||||
msgstr "Logger ut av systemet"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:74 ../js/ui/endSessionDialog.js:78
 | 
			
		||||
msgid "Shut Down"
 | 
			
		||||
msgstr "Avslutt"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:75
 | 
			
		||||
msgid "Click Shut Down to quit these applications and shut down the system."
 | 
			
		||||
msgstr "Klikk Avslutt for å avslutte disse programmene og stenge ned systemet."
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:75 ../js/ui/endSessionDialog.js:82
 | 
			
		||||
msgid "Power Off"
 | 
			
		||||
msgstr "Slå av"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:76
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The system will shut down automatically in %d seconds."
 | 
			
		||||
msgstr "Systemet vil slås av automatisk om %d sekunder."
 | 
			
		||||
msgid "Click Power Off to quit these applications and power off the system."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Klikk «Slå av» for å avslutte disse programmene og logge ut av systemet."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:77
 | 
			
		||||
msgid "Shutting down the system."
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The system will power off automatically in %d seconds."
 | 
			
		||||
msgstr "Systemet vil slås av automatisk om %d sekunder."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:78
 | 
			
		||||
msgid "Powering off the system."
 | 
			
		||||
msgstr "Slår av systemet."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:84 ../js/ui/endSessionDialog.js:88
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:80 ../js/ui/endSessionDialog.js:88
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:93
 | 
			
		||||
msgid "Restart"
 | 
			
		||||
msgstr "Start på nytt"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:85
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:89
 | 
			
		||||
msgid "Click Restart to quit these applications and restart the system."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Klikk Start på nytt for å avslutte disse programmene og starte systemet på "
 | 
			
		||||
"nytt."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:86
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:90
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The system will restart automatically in %d seconds."
 | 
			
		||||
msgstr "Systemet vil starte på nytt automatisk om %d sekunder."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:87
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:91
 | 
			
		||||
msgid "Restarting the system."
 | 
			
		||||
msgstr "Starter systemet på nytt."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:395
 | 
			
		||||
msgid "Confirm"
 | 
			
		||||
msgstr "Bekreft"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:400 ../js/ui/status/bluetooth.js:470
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:415 ../js/ui/polkitAuthenticationAgent.js:172
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:466
 | 
			
		||||
msgid "Cancel"
 | 
			
		||||
msgstr "Avbryt"
 | 
			
		||||
 | 
			
		||||
@@ -492,7 +488,7 @@ msgstr "Aktivert"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The device has been disabled
 | 
			
		||||
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1087
 | 
			
		||||
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1091
 | 
			
		||||
msgid "Disabled"
 | 
			
		||||
msgstr "Deaktivert"
 | 
			
		||||
 | 
			
		||||
@@ -512,34 +508,48 @@ msgstr "Vis kildekode"
 | 
			
		||||
msgid "Web Page"
 | 
			
		||||
msgstr "Nettside"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/messageTray.js:1907
 | 
			
		||||
#: ../js/ui/messageTray.js:987
 | 
			
		||||
msgid "Open"
 | 
			
		||||
msgstr "Åpne"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/messageTray.js:2145
 | 
			
		||||
msgid "System Information"
 | 
			
		||||
msgstr "Systeminformasjon"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/overview.js:88
 | 
			
		||||
#: ../js/ui/overview.js:91
 | 
			
		||||
msgid "Undo"
 | 
			
		||||
msgstr "Angre"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/overview.js:183
 | 
			
		||||
#: ../js/ui/overview.js:186
 | 
			
		||||
msgid "Windows"
 | 
			
		||||
msgstr "Vinduer"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/overview.js:186
 | 
			
		||||
#: ../js/ui/overview.js:189
 | 
			
		||||
msgid "Applications"
 | 
			
		||||
msgstr "Programmer"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is the name of the dock/favorites area on
 | 
			
		||||
#. the left of the overview
 | 
			
		||||
#: ../js/ui/overview.js:205
 | 
			
		||||
msgid "Dash"
 | 
			
		||||
msgstr "Favoritter"
 | 
			
		||||
 | 
			
		||||
#. TODO - _quit() doesn't really work on apps in state STARTING yet
 | 
			
		||||
#: ../js/ui/panel.js:531
 | 
			
		||||
#: ../js/ui/panel.js:515
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Quit %s"
 | 
			
		||||
msgstr "Avslutt %s"
 | 
			
		||||
 | 
			
		||||
#. Button on the left side of the panel.
 | 
			
		||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
 | 
			
		||||
#: ../js/ui/panel.js:892
 | 
			
		||||
#: ../js/ui/panel.js:878
 | 
			
		||||
msgid "Activities"
 | 
			
		||||
msgstr "Aktiviteter"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/panel.js:979
 | 
			
		||||
msgid "Top Bar"
 | 
			
		||||
msgstr "Topp-panel"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/placeDisplay.js:122
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to unmount '%s'"
 | 
			
		||||
@@ -553,64 +563,84 @@ msgstr "Prøv igjen"
 | 
			
		||||
msgid "Connect to..."
 | 
			
		||||
msgstr "Koble til …"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/placeDisplay.js:409
 | 
			
		||||
#: ../js/ui/placeDisplay.js:380
 | 
			
		||||
msgid "PLACES & DEVICES"
 | 
			
		||||
msgstr "STEDER & ENHETER"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:74
 | 
			
		||||
msgid "Authentication Required"
 | 
			
		||||
msgstr "Autentisering kreves"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:108
 | 
			
		||||
msgid "Administrator"
 | 
			
		||||
msgstr "Administrator"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:176
 | 
			
		||||
msgid "Authenticate"
 | 
			
		||||
msgstr "Autentiser"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:260
 | 
			
		||||
msgid "Sorry, that didn't work. Please try again."
 | 
			
		||||
msgstr "Beklager, det virket ikke. Vennligst prøv igjen."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:272
 | 
			
		||||
msgid "Password:"
 | 
			
		||||
msgstr "Passord:"
 | 
			
		||||
 | 
			
		||||
#. Translators: this MUST be either "toggle-switch-us"
 | 
			
		||||
#. (for toggle switches containing the English words
 | 
			
		||||
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
 | 
			
		||||
#. switches containing "◯" and "|"). Other values will
 | 
			
		||||
#. simply result in invisible toggle switches.
 | 
			
		||||
#: ../js/ui/popupMenu.js:612
 | 
			
		||||
#: ../js/ui/popupMenu.js:679
 | 
			
		||||
msgid "toggle-switch-us"
 | 
			
		||||
msgstr "toggle-switch-intl"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/runDialog.js:201
 | 
			
		||||
#: ../js/ui/runDialog.js:205
 | 
			
		||||
msgid "Please enter a command:"
 | 
			
		||||
msgstr "Oppgi en kommando:"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/searchDisplay.js:283
 | 
			
		||||
#: ../js/ui/searchDisplay.js:310
 | 
			
		||||
msgid "Searching..."
 | 
			
		||||
msgstr "Søker …"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/searchDisplay.js:297
 | 
			
		||||
#: ../js/ui/searchDisplay.js:324
 | 
			
		||||
msgid "No matching results."
 | 
			
		||||
msgstr "Ingen treff."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:102 ../js/ui/statusMenu.js:166
 | 
			
		||||
#: ../js/ui/statusMenu.js:161 ../js/ui/statusMenu.js:228
 | 
			
		||||
msgid "Power Off..."
 | 
			
		||||
msgstr "Slå av …"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:104 ../js/ui/statusMenu.js:165
 | 
			
		||||
#: ../js/ui/statusMenu.js:163 ../js/ui/statusMenu.js:227
 | 
			
		||||
msgid "Suspend"
 | 
			
		||||
msgstr "Hvilemodus"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:125
 | 
			
		||||
#: ../js/ui/statusMenu.js:184
 | 
			
		||||
msgid "Available"
 | 
			
		||||
msgstr "Tilgjengelig"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:130
 | 
			
		||||
#: ../js/ui/statusMenu.js:189
 | 
			
		||||
msgid "Busy"
 | 
			
		||||
msgstr "Opptatt"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:138
 | 
			
		||||
#: ../js/ui/statusMenu.js:197
 | 
			
		||||
msgid "My Account"
 | 
			
		||||
msgstr "Min konto"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:142
 | 
			
		||||
#: ../js/ui/statusMenu.js:201
 | 
			
		||||
msgid "System Settings"
 | 
			
		||||
msgstr "Systeminnstillinger"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:149
 | 
			
		||||
#: ../js/ui/statusMenu.js:208
 | 
			
		||||
msgid "Lock Screen"
 | 
			
		||||
msgstr "Lås skjerm"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:153
 | 
			
		||||
#: ../js/ui/statusMenu.js:213
 | 
			
		||||
msgid "Switch User"
 | 
			
		||||
msgstr "Bytt bruker"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:158
 | 
			
		||||
#: ../js/ui/statusMenu.js:218
 | 
			
		||||
msgid "Log Out..."
 | 
			
		||||
msgstr "Logg ut …"
 | 
			
		||||
 | 
			
		||||
@@ -618,14 +648,12 @@ msgstr "Logg ut …"
 | 
			
		||||
msgid "Zoom"
 | 
			
		||||
msgstr "Zoom"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:69
 | 
			
		||||
msgid "Screen Reader"
 | 
			
		||||
msgstr "Skjermleser"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:73
 | 
			
		||||
msgid "Screen Keyboard"
 | 
			
		||||
msgstr "Tastatur på skjermen"
 | 
			
		||||
 | 
			
		||||
#. let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
 | 
			
		||||
#. 'screen-reader-enabled');
 | 
			
		||||
#. this.menu.addMenuItem(screenReader);
 | 
			
		||||
#. let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
 | 
			
		||||
#. 'screen-keyboard-enabled');
 | 
			
		||||
#. this.menu.addMenuItem(screenKeyboard);
 | 
			
		||||
#: ../js/ui/status/accessibility.js:77
 | 
			
		||||
msgid "Visual Alerts"
 | 
			
		||||
msgstr "Synlig varsling"
 | 
			
		||||
@@ -650,17 +678,17 @@ msgstr "Mustaster"
 | 
			
		||||
msgid "Universal Access Settings"
 | 
			
		||||
msgstr "Innstillinger for tilgjengelighet"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:145
 | 
			
		||||
#: ../js/ui/status/accessibility.js:146
 | 
			
		||||
msgid "High Contrast"
 | 
			
		||||
msgstr "Høy kontrast"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:182
 | 
			
		||||
#: ../js/ui/status/accessibility.js:183
 | 
			
		||||
msgid "Large Text"
 | 
			
		||||
msgstr "Stor tekst"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:241
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:337 ../js/ui/status/bluetooth.js:371
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:411 ../js/ui/status/bluetooth.js:444
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:237
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:333 ../js/ui/status/bluetooth.js:367
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:407 ../js/ui/status/bluetooth.js:440
 | 
			
		||||
msgid "Bluetooth"
 | 
			
		||||
msgstr "Bluetooth"
 | 
			
		||||
 | 
			
		||||
@@ -680,94 +708,94 @@ msgstr "Sett opp en ny enhet …"
 | 
			
		||||
msgid "Bluetooth Settings"
 | 
			
		||||
msgstr "Innstillinger for Bluetooth"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:192
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:188
 | 
			
		||||
msgid "Connection"
 | 
			
		||||
msgstr "Tilkobling"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:228
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:224
 | 
			
		||||
msgid "Send Files..."
 | 
			
		||||
msgstr "Send filer …"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:233
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:229
 | 
			
		||||
msgid "Browse Files..."
 | 
			
		||||
msgstr "Bla gjennom filer …"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:242
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:238
 | 
			
		||||
msgid "Error browsing device"
 | 
			
		||||
msgstr "Feil under lesing av enhet"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:243
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:239
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The requested device cannot be browsed, error is '%s'"
 | 
			
		||||
msgstr "Kan ikke bla gjennom forespurt enhet. Feilen er «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:251
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:247
 | 
			
		||||
msgid "Keyboard Settings"
 | 
			
		||||
msgstr "Innstillinger for tastatur"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:256
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:252
 | 
			
		||||
msgid "Mouse Settings"
 | 
			
		||||
msgstr "Innstillinger for mus"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:263 ../js/ui/status/volume.js:65
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:259 ../js/ui/status/volume.js:66
 | 
			
		||||
msgid "Sound Settings"
 | 
			
		||||
msgstr "Innstillinger for lyd"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:372
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:368
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Authorization request from %s"
 | 
			
		||||
msgstr "Forespørsel om autorisering fra %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:378
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:374
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Device %s wants access to the service '%s'"
 | 
			
		||||
msgstr "Enhet %s vil ha tilgang til tjenesten «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:380
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:376
 | 
			
		||||
msgid "Always grant access"
 | 
			
		||||
msgstr "Alltid gi tilgang"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:381
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:377
 | 
			
		||||
msgid "Grant this time only"
 | 
			
		||||
msgstr "Gi tilgang kun denne ene gangen"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:382
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:378
 | 
			
		||||
msgid "Reject"
 | 
			
		||||
msgstr "Avvis"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:412
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:408
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Pairing confirmation for %s"
 | 
			
		||||
msgstr "Bekreftelse for tilkobling for %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:418 ../js/ui/status/bluetooth.js:452
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:414 ../js/ui/status/bluetooth.js:448
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Device %s wants to pair with this computer"
 | 
			
		||||
msgstr "Enhet %s vil koble seg sammen med denne datamaskinen"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:419
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:415
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Please confirm whether the PIN '%s' matches the one on the device."
 | 
			
		||||
msgstr "Vennligst bekreft om PIN «%s» er lik den som brukes på enheten."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:421
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:417
 | 
			
		||||
msgid "Matches"
 | 
			
		||||
msgstr "Stemmer overens"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:422
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:418
 | 
			
		||||
msgid "Does not match"
 | 
			
		||||
msgstr "Stemmer ikke overens"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:445
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:441
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Pairing request for %s"
 | 
			
		||||
msgstr "Forespørsel om tilkobling for %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:453
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:449
 | 
			
		||||
msgid "Please enter the PIN mentioned on the device."
 | 
			
		||||
msgstr "Vennligst oppgi PIN som oppgitt på enheten."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:469
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:465
 | 
			
		||||
msgid "OK"
 | 
			
		||||
msgstr "OK"
 | 
			
		||||
 | 
			
		||||
@@ -779,17 +807,147 @@ msgstr "Vis tastaturutforming …"
 | 
			
		||||
msgid "Localization Settings"
 | 
			
		||||
msgstr "Innstillinger for lokalisering"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:102 ../js/ui/status/network.js:1393
 | 
			
		||||
msgid "<unknown>"
 | 
			
		||||
msgstr "<ukjent>"
 | 
			
		||||
 | 
			
		||||
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
 | 
			
		||||
#: ../js/ui/status/network.js:295
 | 
			
		||||
msgid "disabled"
 | 
			
		||||
msgstr "slått av"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:476
 | 
			
		||||
msgid "connecting..."
 | 
			
		||||
msgstr "kobler til …"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for network connections that require some kind of key or password
 | 
			
		||||
#: ../js/ui/status/network.js:479
 | 
			
		||||
msgid "authentication required"
 | 
			
		||||
msgstr "autentisering kreves"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for wired network devices that are physically disconnected
 | 
			
		||||
#: ../js/ui/status/network.js:485
 | 
			
		||||
msgid "cable unplugged"
 | 
			
		||||
msgstr "kabel koblet fra"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for a network device that cannot be activated (for example it
 | 
			
		||||
#. is disabled by rfkill, or it has no coverage
 | 
			
		||||
#: ../js/ui/status/network.js:489
 | 
			
		||||
msgid "unavailable"
 | 
			
		||||
msgstr "ikke tilgjengelig"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:491
 | 
			
		||||
msgid "connection failed"
 | 
			
		||||
msgstr "tilkobling feilet"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
 | 
			
		||||
#. and we cannot access its settings (including the name)
 | 
			
		||||
#: ../js/ui/status/network.js:571 ../js/ui/status/network.js:1341
 | 
			
		||||
msgid "Connected (private)"
 | 
			
		||||
msgstr "Tilkoblet (privat)"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:636
 | 
			
		||||
msgid "Auto Ethernet"
 | 
			
		||||
msgstr "Automatisk Ethernet"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:697
 | 
			
		||||
msgid "Auto broadband"
 | 
			
		||||
msgstr "Automatisk bredbånd"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:700
 | 
			
		||||
msgid "Auto dial-up"
 | 
			
		||||
msgstr "Automatisk oppringt"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
 | 
			
		||||
#: ../js/ui/status/network.js:843 ../js/ui/status/network.js:1353
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Auto %s"
 | 
			
		||||
msgstr "Automatisk %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:845
 | 
			
		||||
msgid "Auto bluetooth"
 | 
			
		||||
msgstr "Automatisk Bluetooth"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1355
 | 
			
		||||
msgid "Auto wireless"
 | 
			
		||||
msgstr "Automatisk trådløst"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1413
 | 
			
		||||
msgid "More..."
 | 
			
		||||
msgstr "Mer …"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1436
 | 
			
		||||
msgid "Enable networking"
 | 
			
		||||
msgstr "Slå på nettverk"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1448
 | 
			
		||||
msgid "Wired"
 | 
			
		||||
msgstr "Kablet"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1459
 | 
			
		||||
msgid "Wireless"
 | 
			
		||||
msgstr "Trådløst"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1469
 | 
			
		||||
msgid "Mobile broadband"
 | 
			
		||||
msgstr "Mobilt bredbånd"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1479
 | 
			
		||||
msgid "VPN Connections"
 | 
			
		||||
msgstr "VPN-tilkoblinger"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1488
 | 
			
		||||
msgid "Network Settings"
 | 
			
		||||
msgstr "Innstillinger for nettverk"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1783
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to mobile broadband connection '%s'"
 | 
			
		||||
msgstr "Du er nå koblet til mobil bredbåndstilkobling «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1787
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to wireless network '%s'"
 | 
			
		||||
msgstr "Du er nå koblet til trådløst nettverk «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1791
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to wired network '%s'"
 | 
			
		||||
msgstr "Du er nå koblet til kablet nettverk «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1795
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to VPN network '%s'"
 | 
			
		||||
msgstr "Du er nå koblet til virtuelt privat nettverk «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1800
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to '%s'"
 | 
			
		||||
msgstr "Du er nå koblet til «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1808
 | 
			
		||||
msgid "Connection established"
 | 
			
		||||
msgstr "Tilkobling etablert"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1930
 | 
			
		||||
msgid "Networking is disabled"
 | 
			
		||||
msgstr "Nettverk er slått av"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:2055
 | 
			
		||||
msgid "Network Manager"
 | 
			
		||||
msgstr "Nettverkshåndtering"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:85
 | 
			
		||||
msgid "Power Settings"
 | 
			
		||||
msgstr "Innstillinger for strøm"
 | 
			
		||||
 | 
			
		||||
#. 0 is reported when UPower does not have enough data
 | 
			
		||||
#. to estimate battery life
 | 
			
		||||
#: ../js/ui/status/power.js:110
 | 
			
		||||
#: ../js/ui/status/power.js:111
 | 
			
		||||
msgid "Estimating..."
 | 
			
		||||
msgstr "Estimerer …"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:117
 | 
			
		||||
#: ../js/ui/status/power.js:118
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d hour remaining"
 | 
			
		||||
msgid_plural "%d hours remaining"
 | 
			
		||||
@@ -797,102 +955,102 @@ msgstr[0] "%d time gjenstår"
 | 
			
		||||
msgstr[1] "%d timer gjenstår"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
 | 
			
		||||
#: ../js/ui/status/power.js:120
 | 
			
		||||
#: ../js/ui/status/power.js:121
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d %s %d %s remaining"
 | 
			
		||||
msgstr "%d %s %d %s gjenstår"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:122
 | 
			
		||||
#: ../js/ui/status/power.js:123
 | 
			
		||||
msgid "hour"
 | 
			
		||||
msgid_plural "hours"
 | 
			
		||||
msgstr[0] "time"
 | 
			
		||||
msgstr[1] "timer"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:122
 | 
			
		||||
#: ../js/ui/status/power.js:123
 | 
			
		||||
msgid "minute"
 | 
			
		||||
msgid_plural "minutes"
 | 
			
		||||
msgstr[0] "minutt"
 | 
			
		||||
msgstr[1] "minutter"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:125
 | 
			
		||||
#: ../js/ui/status/power.js:126
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d minute remaining"
 | 
			
		||||
msgid_plural "%d minutes remaining"
 | 
			
		||||
msgstr[0] "%d minutt gjenstår"
 | 
			
		||||
msgstr[1] "%d minutter gjenstår"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:227
 | 
			
		||||
#: ../js/ui/status/power.js:228
 | 
			
		||||
msgid "AC adapter"
 | 
			
		||||
msgstr "Strømadapter"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:229
 | 
			
		||||
#: ../js/ui/status/power.js:230
 | 
			
		||||
msgid "Laptop battery"
 | 
			
		||||
msgstr "Batteri på bærbar"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:231
 | 
			
		||||
#: ../js/ui/status/power.js:232
 | 
			
		||||
msgid "UPS"
 | 
			
		||||
msgstr "UPS"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:233
 | 
			
		||||
#: ../js/ui/status/power.js:234
 | 
			
		||||
msgid "Monitor"
 | 
			
		||||
msgstr "Skjerm"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:235
 | 
			
		||||
#: ../js/ui/status/power.js:236
 | 
			
		||||
msgid "Mouse"
 | 
			
		||||
msgstr "Mus"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:237
 | 
			
		||||
#: ../js/ui/status/power.js:238
 | 
			
		||||
msgid "Keyboard"
 | 
			
		||||
msgstr "Tastatur"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:239
 | 
			
		||||
#: ../js/ui/status/power.js:240
 | 
			
		||||
msgid "PDA"
 | 
			
		||||
msgstr "PDA"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:241
 | 
			
		||||
#: ../js/ui/status/power.js:242
 | 
			
		||||
msgid "Cell phone"
 | 
			
		||||
msgstr "Mobiltelefon"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:243
 | 
			
		||||
#: ../js/ui/status/power.js:244
 | 
			
		||||
msgid "Media player"
 | 
			
		||||
msgstr "Medieavspiller"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:245
 | 
			
		||||
#: ../js/ui/status/power.js:246
 | 
			
		||||
msgid "Tablet"
 | 
			
		||||
msgstr "Nettbrett"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:247
 | 
			
		||||
#: ../js/ui/status/power.js:248
 | 
			
		||||
msgid "Computer"
 | 
			
		||||
msgstr "Datamaskin"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:249 ../src/shell-app-system.c:1013
 | 
			
		||||
#: ../js/ui/status/power.js:250 ../src/shell-app-system.c:1088
 | 
			
		||||
msgid "Unknown"
 | 
			
		||||
msgstr "Ukjent"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/volume.js:44
 | 
			
		||||
#: ../js/ui/status/volume.js:45
 | 
			
		||||
msgid "Volume"
 | 
			
		||||
msgstr "Volum"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/volume.js:57
 | 
			
		||||
#: ../js/ui/status/volume.js:58
 | 
			
		||||
msgid "Microphone"
 | 
			
		||||
msgstr "Mikrofon"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:239
 | 
			
		||||
#: ../js/ui/telepathyClient.js:332
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is online."
 | 
			
		||||
msgstr "%s er tilkoblet."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:244
 | 
			
		||||
#: ../js/ui/telepathyClient.js:337
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is offline."
 | 
			
		||||
msgstr "%s er frakoblet."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:247
 | 
			
		||||
#: ../js/ui/telepathyClient.js:340
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is away."
 | 
			
		||||
msgstr "«%s» er borte."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:250
 | 
			
		||||
#: ../js/ui/telepathyClient.js:343
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is busy."
 | 
			
		||||
msgstr "%s er opptatt."
 | 
			
		||||
@@ -900,7 +1058,7 @@ msgstr "%s er opptatt."
 | 
			
		||||
#. Translators: this is a time format string followed by a date.
 | 
			
		||||
#. If applicable, replace %X with a strftime format valid for your
 | 
			
		||||
#. locale, without seconds.
 | 
			
		||||
#: ../js/ui/telepathyClient.js:348
 | 
			
		||||
#: ../js/ui/telepathyClient.js:474
 | 
			
		||||
#, no-c-format
 | 
			
		||||
msgid "Sent at %X on %A"
 | 
			
		||||
msgstr "Sendt %X på %A"
 | 
			
		||||
@@ -909,10 +1067,14 @@ msgstr "Sendt %X på %A"
 | 
			
		||||
#. in the search entry when no search is
 | 
			
		||||
#. active; it should not exceed ~30
 | 
			
		||||
#. characters.
 | 
			
		||||
#: ../js/ui/viewSelector.js:103
 | 
			
		||||
#: ../js/ui/viewSelector.js:122
 | 
			
		||||
msgid "Type to search..."
 | 
			
		||||
msgstr "Skriv for å søke …"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/viewSelector.js:142 ../src/shell-util.c:250
 | 
			
		||||
msgid "Search"
 | 
			
		||||
msgstr "Søk"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/windowAttentionHandler.js:42
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s has finished starting"
 | 
			
		||||
@@ -925,7 +1087,7 @@ msgstr "«%s» er klar"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The number of sound outputs on a particular device
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1094
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1098
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%u Output"
 | 
			
		||||
msgid_plural "%u Outputs"
 | 
			
		||||
@@ -934,49 +1096,66 @@ msgstr[1] "%u utganger"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The number of sound inputs on a particular device
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1104
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1108
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%u Input"
 | 
			
		||||
msgid_plural "%u Inputs"
 | 
			
		||||
msgstr[0] "%u inngang"
 | 
			
		||||
msgstr[1] "%u innganger"
 | 
			
		||||
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1402
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1406
 | 
			
		||||
msgid "System Sounds"
 | 
			
		||||
msgstr "Systemlyder"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1298
 | 
			
		||||
#: ../src/main.c:438
 | 
			
		||||
msgid "Print version"
 | 
			
		||||
msgstr "Skriv ut versjon"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-app.c:454
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to launch '%s'"
 | 
			
		||||
msgstr "Klarte ikke å starte «%s»"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1395
 | 
			
		||||
msgid "Less than a minute ago"
 | 
			
		||||
msgstr "Mindre enn ett minutt siden"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1302
 | 
			
		||||
#: ../src/shell-global.c:1399
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d minute ago"
 | 
			
		||||
msgid_plural "%d minutes ago"
 | 
			
		||||
msgstr[0] "%d minutt siden"
 | 
			
		||||
msgstr[1] "%d minutter siden"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1307
 | 
			
		||||
#: ../src/shell-global.c:1404
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d hour ago"
 | 
			
		||||
msgid_plural "%d hours ago"
 | 
			
		||||
msgstr[0] "%d time siden"
 | 
			
		||||
msgstr[1] "%d timer siden"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1312
 | 
			
		||||
#: ../src/shell-global.c:1409
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d day ago"
 | 
			
		||||
msgid_plural "%d days ago"
 | 
			
		||||
msgstr[0] "%d dag siden"
 | 
			
		||||
msgstr[1] "%d dager siden"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1317
 | 
			
		||||
#: ../src/shell-global.c:1414
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d week ago"
 | 
			
		||||
msgid_plural "%d weeks ago"
 | 
			
		||||
msgstr[0] "%d uke siden"
 | 
			
		||||
msgstr[1] "%d uker siden"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-mobile-providers.c:80
 | 
			
		||||
msgid "United Kingdom"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-mobile-providers.c:526
 | 
			
		||||
msgid "Default"
 | 
			
		||||
msgstr "Forvalg"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-polkit-authentication-agent.c:334
 | 
			
		||||
msgid "Authentication dialog was dismissed by the user"
 | 
			
		||||
msgstr "Autentiseringsdialogen ble lukket av brukeren"
 | 
			
		||||
@@ -991,10 +1170,6 @@ msgstr "Hjemmemappe"
 | 
			
		||||
msgid "File System"
 | 
			
		||||
msgstr "Filsystem"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-util.c:250
 | 
			
		||||
msgid "Search"
 | 
			
		||||
msgstr "Søk"
 | 
			
		||||
 | 
			
		||||
#. Translators: the first string is the name of a gvfs
 | 
			
		||||
#. * method, and the second string is a path. For
 | 
			
		||||
#. * example, "Trash: some-directory". It means that the
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										479
									
								
								po/pa.po
									
									
									
									
									
								
							
							
						
						
									
										479
									
								
								po/pa.po
									
									
									
									
									
								
							@@ -6,9 +6,9 @@ msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: gnome-shell master\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug."
 | 
			
		||||
"cgi?product=gnome-shell&component=general\n"
 | 
			
		||||
"POT-Creation-Date: 2011-03-07 16:15+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2011-03-08 08:27+0530\n"
 | 
			
		||||
"cgi?product=gnome-shell&keywords=I18N+L10N&component=general\n"
 | 
			
		||||
"POT-Creation-Date: 2011-03-25 20:20+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2011-03-27 10:02+0530\n"
 | 
			
		||||
"Last-Translator: A S Alam <aalam@users.sf.net>\n"
 | 
			
		||||
"Language-Team: Punjabi/Panjabi <punjabi-users@lists.sf.net>\n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
@@ -92,6 +92,20 @@ msgid ""
 | 
			
		||||
"records to WEBM using the VP8 codec. %T is used as a placeholder for a guess "
 | 
			
		||||
"at the optimal thread count on the system."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"ਰਿਕਾਰਡਿੰਗ ਇੰਕੋਡ ਕਰਨ ਲਈ ਜੀਸਟੀਮਰ ਪਾਇਪਲਾਈਨ ਸੈੱਟ ਕਰੋ। ਇਹ gst-launch ਲਈ ਵਰਤਿਆ "
 | 
			
		||||
"ਜਾਂਦਾ ਸੰਟੈਕਸ ਵਰਤਦਾ ਹੈ। ਪਾਇਪਲਾਈਨ ਲਈ ਸਿੰਕ ਪੈਡ ਲਈ ਕੁਨੈਕਟ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ, "
 | 
			
		||||
"ਜਿੱਥੇ "
 | 
			
		||||
"ਰਿਕਾਰਡ ਹੋਣ ਵਾਲੀ ਵਿਡੀਓ ਰਿਕਾਰਡ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ। ਇਹ ਆਮ ਤੌਰ ਉੱਤੇ ਨਾ-ਕੁਨੈਕਟ ਕੀਤਾ "
 | 
			
		||||
"ਸਰੋਤ ਪੈਡ ਹੋਵੇਗਾ, ਉਸ ਪੈਡ ਤੋਂ ਆਉਟਪੁੱਟ ਨੂੰ ਆਉਟਪੁੱਟ ਫਾਇਲ ਵਿੱਚ ਲਿਖਿਆ ਜਾਵੇਗਾ। ਪਰ "
 | 
			
		||||
"ਪਾਈਪਲਾਈਨ ਖੁਦ ਦੀ ਆਉਟਪੁੱਟ ਦਾ ਧਿਆਨ ਵੀ ਰੱਖ ਸਕਦੀ ਹੈ - ਇਸ ਨਾਲ ਆਉਟਪੁੱਟ ਨੂੰ "
 | 
			
		||||
"icecast ਸਰਵਰ ਉੱਤੇ shout2send ਜਾਂ ਕਿਸੇ ਹੋਰ ਰਾਹੀਂ ਵੀ ਭੇਜਿਆ ਜਾ ਸਕਦਾ ਹੈ। ਜਦੋਂ "
 | 
			
		||||
"ਅਣ-ਸੈੱਟ "
 | 
			
		||||
"ਕੀਤਾ ਜਾਂ ਖਾਲੀ ਮੁੱਲ ਨਾਲ ਸੈੱਟ ਕੀਤਾ ਤਾਂ, ਡਿਫਾਲਟ ਪਾਈਪਲਾਈਨ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ। ਇਸ ਇਸ "
 | 
			
		||||
"ਵੇਲੇ "
 | 
			
		||||
"'videorate ! vp8enc quality=10 speed=2 threads=%T ! queue ! webmmux'  ਹੈ ਅਤੇ "
 | 
			
		||||
"VP8 codec ਦੀ ਵਰਤੋਂ ਕਰਕੇ WEBM ਨਾਲ ਰਿਕਾਰਡ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। %T ਸਿਸਟਮ ਉੱਤੇ ਢੁੱਕਵੀ "
 | 
			
		||||
"ਥਰਿੱਡ "
 | 
			
		||||
"ਗਿਣਤੀ ਦਾ ਅੰਦਾਜ਼ਾ ਲਗਾਉਣ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ।"
 | 
			
		||||
 | 
			
		||||
#: ../data/org.gnome.shell.gschema.xml.in.h:14
 | 
			
		||||
msgid "Show date in clock"
 | 
			
		||||
@@ -164,47 +178,43 @@ msgstr "ਐਪਲੀਕੇਸ਼ਨ ਵਰਤੋਂ ਬਾਰੇ ਅੰਕੜੇ
 | 
			
		||||
msgid "disabled OpenSearch providers"
 | 
			
		||||
msgstr "ਓਪਨਸਰਚ ਉਪਲੱਬਧ ਕਰਵਾਉਣ ਵਾਲੇ ਬੰਦ ਹਨ"
 | 
			
		||||
 | 
			
		||||
#: ../js/misc/util.js:86
 | 
			
		||||
#: ../js/misc/util.js:71
 | 
			
		||||
msgid "Command not found"
 | 
			
		||||
msgstr "ਕਮਾਂਡ ਨਹੀਂ ਲੱਭੀ"
 | 
			
		||||
 | 
			
		||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
 | 
			
		||||
#. something nicer
 | 
			
		||||
#: ../js/misc/util.js:113
 | 
			
		||||
#: ../js/misc/util.js:98
 | 
			
		||||
msgid "Could not parse command:"
 | 
			
		||||
msgstr "ਕਮਾਂਡ ਪਾਰਸ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ:"
 | 
			
		||||
 | 
			
		||||
#: ../js/misc/util.js:135
 | 
			
		||||
msgid "No such application"
 | 
			
		||||
msgstr "ਇੰਞ ਦੀ ਕੋਈ ਐਪਲੀਕੇਸ਼ਨ ਨਹੀਂ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#: ../js/misc/util.js:148
 | 
			
		||||
#: ../js/misc/util.js:106
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Execution of '%s' failed:"
 | 
			
		||||
msgstr "'%s' ਚਲਾਉਣ ਲਈ ਫੇਲ੍ਹ:"
 | 
			
		||||
 | 
			
		||||
#. Translators: Filter to display all applications
 | 
			
		||||
#: ../js/ui/appDisplay.js:226
 | 
			
		||||
#: ../js/ui/appDisplay.js:230
 | 
			
		||||
msgid "All"
 | 
			
		||||
msgstr "ਸਭ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:324
 | 
			
		||||
#: ../js/ui/appDisplay.js:328
 | 
			
		||||
msgid "APPLICATIONS"
 | 
			
		||||
msgstr "ਐਪਲੀਕੇਸ਼ਨ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:350
 | 
			
		||||
#: ../js/ui/appDisplay.js:354
 | 
			
		||||
msgid "SETTINGS"
 | 
			
		||||
msgstr "ਸੈਟਿੰਗ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:612
 | 
			
		||||
#: ../js/ui/appDisplay.js:625
 | 
			
		||||
msgid "New Window"
 | 
			
		||||
msgstr "ਨਵੀਂ ਵਿੰਡੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:615
 | 
			
		||||
#: ../js/ui/appDisplay.js:628
 | 
			
		||||
msgid "Remove from Favorites"
 | 
			
		||||
msgstr "ਪਸੰਦ ਵਿੱਚੋਂ ਹਟਾਓ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:616
 | 
			
		||||
#: ../js/ui/appDisplay.js:629
 | 
			
		||||
msgid "Add to Favorites"
 | 
			
		||||
msgstr "ਪਸੰਦ 'ਚ ਸ਼ਾਮਲ ਕਰੋ"
 | 
			
		||||
 | 
			
		||||
@@ -364,7 +374,7 @@ msgstr "ਇਹ ਹਫ਼ਤਾ"
 | 
			
		||||
msgid "Next week"
 | 
			
		||||
msgstr "ਹਫ਼ਤਾ ਅੱਗੇ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dash.js:174 ../js/ui/messageTray.js:933
 | 
			
		||||
#: ../js/ui/dash.js:174 ../js/ui/messageTray.js:994
 | 
			
		||||
msgid "Remove"
 | 
			
		||||
msgstr "ਹਟਾਓ"
 | 
			
		||||
 | 
			
		||||
@@ -419,7 +429,7 @@ msgstr "%a %l:%M %p"
 | 
			
		||||
#. Translators: This is the date format to use when the calendar popup is
 | 
			
		||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
 | 
			
		||||
#.
 | 
			
		||||
#: ../js/ui/dateMenu.js:209
 | 
			
		||||
#: ../js/ui/dateMenu.js:194
 | 
			
		||||
msgid "%A %B %e, %Y"
 | 
			
		||||
msgstr "%A, %e %B %Y"
 | 
			
		||||
 | 
			
		||||
@@ -432,7 +442,7 @@ msgstr "ਤਾਜ਼ਾ ਆਈਟਮਾਂ"
 | 
			
		||||
msgid "Log Out %s"
 | 
			
		||||
msgstr "%s ਲਾਗਆਉਟ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:69
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:70
 | 
			
		||||
msgid "Log Out"
 | 
			
		||||
msgstr "ਲਾਗਆਉਟ"
 | 
			
		||||
 | 
			
		||||
@@ -455,46 +465,44 @@ msgstr "ਤੁਹਾਨੂੰ %d ਸਕਿੰਟਾਂ ਵਿੱਚ ਆਟੋਮ
 | 
			
		||||
msgid "Logging out of the system."
 | 
			
		||||
msgstr "ਸਿਸਟਮ ਲਾਗ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:74 ../js/ui/endSessionDialog.js:78
 | 
			
		||||
msgid "Shut Down"
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:75 ../js/ui/endSessionDialog.js:82
 | 
			
		||||
msgid "Power Off"
 | 
			
		||||
msgstr "ਬੰਦ ਕਰੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:75
 | 
			
		||||
msgid "Click Shut Down to quit these applications and shut down the system."
 | 
			
		||||
msgstr "ਇਹ ਐਪਲੀਕੇਸ਼ਨ ਬੰਦ ਕਰਕੇ ਸਿਸਟਮ ਨੂੰ ਬੰਦ ਕਰਨ ਲਈ ਬੰਦ ਕਰੋ ਨੂੰ ਕਲਿੱਕ ਕਰੋ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:76
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The system will shut down automatically in %d seconds."
 | 
			
		||||
msgstr "ਸਿਸਟਮ ਨੂੰ ਆਟੋਮੈਟਿਕ ਹੀ %d ਸਕਿੰਟਾਂ ਵਿੱਚ ਬੰਦ ਕੀਤਾ ਜਾਵੇਗਾ।"
 | 
			
		||||
msgid "Click Power Off to quit these applications and power off the system."
 | 
			
		||||
msgstr "ਇਹ ਐਪਲੀਕੇਸ਼ਨਾਂ ਬੰਦ ਕਰਨ ਅਤੇ ਸਿਸਟਮ ਨੂੰ ਬੰਦ ਕਰਨ ਲਈ ਬੰਦ ਕਰੋ ਨੂੰ ਕਲਿੱਕ ਕਰੋ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:77
 | 
			
		||||
msgid "Shutting down the system."
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The system will power off automatically in %d seconds."
 | 
			
		||||
msgstr "ਸਿਸਟਮ ਨੂੰ ਆਟੋਮੈਟਿਕ ਹੀ %d ਸਕਿੰਟਾਂ ਵਿੱਚ ਬੰਦ ਹੋ ਜਾਵੇਗਾ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:78
 | 
			
		||||
msgid "Powering off the system."
 | 
			
		||||
msgstr "ਸਿਸਟਮ ਬੰਦ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:84 ../js/ui/endSessionDialog.js:88
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:80 ../js/ui/endSessionDialog.js:88
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:93
 | 
			
		||||
msgid "Restart"
 | 
			
		||||
msgstr "ਮੁੜ-ਚਾਲੂ ਕਰੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:85
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:89
 | 
			
		||||
msgid "Click Restart to quit these applications and restart the system."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"ਇਹ ਐਪਲੀਕੇਸ਼ਨ ਬੰਦ ਕਰਨ ਤੇ ਸਿਸਟਮ ਨੂੰ ਮੁੜ-ਚਾਲੂ ਕਰਨ ਲਈ ਮੁੜ-ਚਾਲੂ ਕਰੋ ਨੂੰ ਕਲਿੱਕ ਕਰੋ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:86
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:90
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The system will restart automatically in %d seconds."
 | 
			
		||||
msgstr "ਸਿਸਟਮ ਨੂੰ ਆਟੋਮੈਟਿਕ ਹੀ %d ਸਕਿੰਟਾਂ ਵਿੱਚ ਮੁੜ-ਚਾਲੂ ਕੀਤਾ ਜਾ ਜਾਵੇਗਾ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:87
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:91
 | 
			
		||||
msgid "Restarting the system."
 | 
			
		||||
msgstr "ਸਿਸਟਮ ਮੁੜ-ਚਾਲੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:395
 | 
			
		||||
msgid "Confirm"
 | 
			
		||||
msgstr "ਪੁਸ਼ਟੀ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:400 ../js/ui/status/bluetooth.js:470
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:415 ../js/ui/polkitAuthenticationAgent.js:172
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:466
 | 
			
		||||
msgid "Cancel"
 | 
			
		||||
msgstr "ਰੱਦ ਕਰੋ"
 | 
			
		||||
 | 
			
		||||
@@ -508,7 +516,7 @@ msgstr "ਚਾਲੂ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The device has been disabled
 | 
			
		||||
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1087
 | 
			
		||||
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1091
 | 
			
		||||
msgid "Disabled"
 | 
			
		||||
msgstr "ਬੰਦ ਹੈ"
 | 
			
		||||
 | 
			
		||||
@@ -528,48 +536,47 @@ msgstr "ਸਰੋਤ ਵੇਖੋ"
 | 
			
		||||
msgid "Web Page"
 | 
			
		||||
msgstr "ਵੈੱਬ ਪੇਜ਼"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/messageTray.js:926
 | 
			
		||||
#: ../js/ui/messageTray.js:987
 | 
			
		||||
msgid "Open"
 | 
			
		||||
msgstr "ਖੋਲ੍ਹੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/messageTray.js:1963
 | 
			
		||||
#: ../js/ui/messageTray.js:2145
 | 
			
		||||
msgid "System Information"
 | 
			
		||||
msgstr "ਸਿਸਟਮ ਜਾਣਕਾਰੀ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/overview.js:88
 | 
			
		||||
#: ../js/ui/overview.js:91
 | 
			
		||||
msgid "Undo"
 | 
			
		||||
msgstr "ਵਾਪਸ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/overview.js:183
 | 
			
		||||
#: ../js/ui/overview.js:186
 | 
			
		||||
msgid "Windows"
 | 
			
		||||
msgstr "ਵਿੰਡੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/overview.js:186
 | 
			
		||||
#: ../js/ui/overview.js:189
 | 
			
		||||
msgid "Applications"
 | 
			
		||||
msgstr "ਐਪਲੀਕੇਸ਼ਨ"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is the name of the dock/favorites area on
 | 
			
		||||
#. the left of the overview
 | 
			
		||||
#: ../js/ui/overview.js:202
 | 
			
		||||
#: ../js/ui/overview.js:205
 | 
			
		||||
msgid "Dash"
 | 
			
		||||
msgstr "ਡੈਸ਼"
 | 
			
		||||
 | 
			
		||||
#. TODO - _quit() doesn't really work on apps in state STARTING yet
 | 
			
		||||
#: ../js/ui/panel.js:532
 | 
			
		||||
#: ../js/ui/panel.js:515
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Quit %s"
 | 
			
		||||
msgstr "%s ਬੰਦ ਕਰੋ"
 | 
			
		||||
 | 
			
		||||
#. Button on the left side of the panel.
 | 
			
		||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
 | 
			
		||||
#: ../js/ui/panel.js:893
 | 
			
		||||
#: ../js/ui/panel.js:878
 | 
			
		||||
msgid "Activities"
 | 
			
		||||
msgstr "ਸਰਗਰਮੀਆਂ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/panel.js:994
 | 
			
		||||
#| msgid "Cancel"
 | 
			
		||||
msgid "Panel"
 | 
			
		||||
msgstr "ਪੈਨਲ"
 | 
			
		||||
#: ../js/ui/panel.js:979
 | 
			
		||||
msgid "Top Bar"
 | 
			
		||||
msgstr "ਉੱਤਲੀ ਪੱਟੀ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/placeDisplay.js:122
 | 
			
		||||
#, c-format
 | 
			
		||||
@@ -584,64 +591,85 @@ msgstr "ਮੁੜ-ਕੋਸ਼ਿਸ਼"
 | 
			
		||||
msgid "Connect to..."
 | 
			
		||||
msgstr "...ਨਾਲ ਕੁਨੈਕਟ ਕਰੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/placeDisplay.js:409
 | 
			
		||||
#: ../js/ui/placeDisplay.js:380
 | 
			
		||||
msgid "PLACES & DEVICES"
 | 
			
		||||
msgstr "ਥਾਵਾਂ ਤੇ ਜੰਤਰ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:74
 | 
			
		||||
msgid "Authentication Required"
 | 
			
		||||
msgstr "ਪਰਮਾਣਕਿਤਾ ਚਾਹੀਦੀ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:108
 | 
			
		||||
msgid "Administrator"
 | 
			
		||||
msgstr "ਪਰਸ਼ਾਸ਼ਕ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:176
 | 
			
		||||
msgid "Authenticate"
 | 
			
		||||
msgstr "ਪਰਮਾਣਕਿਤਾ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:260
 | 
			
		||||
msgid "Sorry, that didn't work. Please try again."
 | 
			
		||||
msgstr "ਅਫਸੋਸ, ਉਹ ਕੰਮ ਨਹੀਂ ਕਰਦਾ। ਫੇਰ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਜੀ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:272
 | 
			
		||||
msgid "Password:"
 | 
			
		||||
msgstr "ਪਾਸਵਰਡ:"
 | 
			
		||||
 | 
			
		||||
#. Translators: this MUST be either "toggle-switch-us"
 | 
			
		||||
#. (for toggle switches containing the English words
 | 
			
		||||
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
 | 
			
		||||
#. switches containing "◯" and "|"). Other values will
 | 
			
		||||
#. simply result in invisible toggle switches.
 | 
			
		||||
#: ../js/ui/popupMenu.js:618
 | 
			
		||||
#: ../js/ui/popupMenu.js:679
 | 
			
		||||
msgid "toggle-switch-us"
 | 
			
		||||
msgstr "toggle-switch-us"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/runDialog.js:201
 | 
			
		||||
#: ../js/ui/runDialog.js:205
 | 
			
		||||
msgid "Please enter a command:"
 | 
			
		||||
msgstr "ਕਮਾਂਡ ਦਿਓ ਜੀ:"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/searchDisplay.js:283
 | 
			
		||||
#: ../js/ui/searchDisplay.js:310
 | 
			
		||||
msgid "Searching..."
 | 
			
		||||
msgstr "ਖੋਜ ਜਾਰੀ ਹੈ..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/searchDisplay.js:297
 | 
			
		||||
#: ../js/ui/searchDisplay.js:324
 | 
			
		||||
msgid "No matching results."
 | 
			
		||||
msgstr "ਕੋਈ ਨਤੀਜਾ ਨਹੀਂ ਲੱਭਿਆ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:102 ../js/ui/statusMenu.js:166
 | 
			
		||||
#: ../js/ui/statusMenu.js:161 ../js/ui/statusMenu.js:163
 | 
			
		||||
#: ../js/ui/statusMenu.js:228
 | 
			
		||||
msgid "Power Off..."
 | 
			
		||||
msgstr "...ਬੰਦ ਕਰੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:104 ../js/ui/statusMenu.js:165
 | 
			
		||||
#: ../js/ui/statusMenu.js:163 ../js/ui/statusMenu.js:227
 | 
			
		||||
msgid "Suspend"
 | 
			
		||||
msgstr "ਸਸਪੈਂਡ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:125
 | 
			
		||||
#: ../js/ui/statusMenu.js:184
 | 
			
		||||
msgid "Available"
 | 
			
		||||
msgstr "ਉਪਲੱਬਧ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:130
 | 
			
		||||
#: ../js/ui/statusMenu.js:189
 | 
			
		||||
msgid "Busy"
 | 
			
		||||
msgstr "ਰੁਝਿਆ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:138
 | 
			
		||||
#: ../js/ui/statusMenu.js:197
 | 
			
		||||
msgid "My Account"
 | 
			
		||||
msgstr "ਮੇਰਾ ਅਕਾਊਂਟ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:142
 | 
			
		||||
#: ../js/ui/statusMenu.js:201
 | 
			
		||||
msgid "System Settings"
 | 
			
		||||
msgstr "ਸਿਸਟਮ ਸੈਟਿੰਗ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:149
 | 
			
		||||
#: ../js/ui/statusMenu.js:208
 | 
			
		||||
msgid "Lock Screen"
 | 
			
		||||
msgstr "ਸਕਰੀਨ ਲਾਕ ਕਰੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:153
 | 
			
		||||
#: ../js/ui/statusMenu.js:213
 | 
			
		||||
msgid "Switch User"
 | 
			
		||||
msgstr "ਯੂਜ਼ਰ ਬਦਲੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:158
 | 
			
		||||
#: ../js/ui/statusMenu.js:218
 | 
			
		||||
msgid "Log Out..."
 | 
			
		||||
msgstr "...ਲਾਗਆਉਟ"
 | 
			
		||||
 | 
			
		||||
@@ -649,14 +677,12 @@ msgstr "...ਲਾਗਆਉਟ"
 | 
			
		||||
msgid "Zoom"
 | 
			
		||||
msgstr "ਜ਼ੂਮ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:69
 | 
			
		||||
msgid "Screen Reader"
 | 
			
		||||
msgstr "ਸਕਰੀਨ ਰੀਡਰ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:73
 | 
			
		||||
msgid "Screen Keyboard"
 | 
			
		||||
msgstr "ਸਕਰੀਨ ਕੀਬੋਰਡ"
 | 
			
		||||
 | 
			
		||||
#. let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
 | 
			
		||||
#. 'screen-reader-enabled');
 | 
			
		||||
#. this.menu.addMenuItem(screenReader);
 | 
			
		||||
#. let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
 | 
			
		||||
#. 'screen-keyboard-enabled');
 | 
			
		||||
#. this.menu.addMenuItem(screenKeyboard);
 | 
			
		||||
#: ../js/ui/status/accessibility.js:77
 | 
			
		||||
msgid "Visual Alerts"
 | 
			
		||||
msgstr "ਦਿੱਖ ਚੇਤਾਵਨੀ"
 | 
			
		||||
@@ -681,17 +707,17 @@ msgstr "ਮਾਊਸ ਸਵਿੱਚਾਂ"
 | 
			
		||||
msgid "Universal Access Settings"
 | 
			
		||||
msgstr "ਯੂਨੀਵਰਸਲ ਅਸੈੱਸ ਸੈਟਿੰਗ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:145
 | 
			
		||||
#: ../js/ui/status/accessibility.js:146
 | 
			
		||||
msgid "High Contrast"
 | 
			
		||||
msgstr "ਵੱਧ ਕਨਟਰਾਸਟ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:182
 | 
			
		||||
#: ../js/ui/status/accessibility.js:183
 | 
			
		||||
msgid "Large Text"
 | 
			
		||||
msgstr "ਵੱਡੇ ਅੱਖਰ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:241
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:337 ../js/ui/status/bluetooth.js:371
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:411 ../js/ui/status/bluetooth.js:444
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:237
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:333 ../js/ui/status/bluetooth.js:367
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:407 ../js/ui/status/bluetooth.js:440
 | 
			
		||||
msgid "Bluetooth"
 | 
			
		||||
msgstr "ਬਲਿਊਟੁੱਥ"
 | 
			
		||||
 | 
			
		||||
@@ -711,94 +737,94 @@ msgstr "...ਨਵਾਂ ਜੰਤਰ ਸੈਟਅੱਪ"
 | 
			
		||||
msgid "Bluetooth Settings"
 | 
			
		||||
msgstr "ਬਲਿਊਟੁੱਥ ਸੈਟਿੰਗ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:192
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:188
 | 
			
		||||
msgid "Connection"
 | 
			
		||||
msgstr "ਕੁਨੈਕਸ਼ਨ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:228
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:224
 | 
			
		||||
msgid "Send Files..."
 | 
			
		||||
msgstr "...ਫਾਇਲਾਂ ਭੇਜੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:233
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:229
 | 
			
		||||
msgid "Browse Files..."
 | 
			
		||||
msgstr "...ਫਾਇਲਾਂ ਦੀ ਝਲਕ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:242
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:238
 | 
			
		||||
msgid "Error browsing device"
 | 
			
		||||
msgstr "ਜੰਤਰ ਬਰਾਊਜ਼ ਕਰਨ ਲਈ ਗਲਤੀ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:243
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:239
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The requested device cannot be browsed, error is '%s'"
 | 
			
		||||
msgstr "ਮੰਗ ਕੀਤੇ ਗਏ ਜੰਤਰ ਨੂੰ ਬਰਾਊਜ਼ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ, ਗਲਤੀ ਸੀ '%s'"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:251
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:247
 | 
			
		||||
msgid "Keyboard Settings"
 | 
			
		||||
msgstr "ਕੀਬੋਰਡ ਸੈਟਿੰਗ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:256
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:252
 | 
			
		||||
msgid "Mouse Settings"
 | 
			
		||||
msgstr "ਮਾਊਸ ਸੈਟਿੰਗ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:263 ../js/ui/status/volume.js:65
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:259 ../js/ui/status/volume.js:66
 | 
			
		||||
msgid "Sound Settings"
 | 
			
		||||
msgstr "ਸਾਊਂਡ ਸੈਟਿੰਗ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:372
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:368
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Authorization request from %s"
 | 
			
		||||
msgstr "'%s' ਤੋਂ ਪਰਮਾਣਕਿਤਾ ਮੰਗ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:378
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:374
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Device %s wants access to the service '%s'"
 | 
			
		||||
msgstr "ਜੰਤਰ %s ਸਰਵਿਸ '%s' ਨੂੰ ਵਰਤਣੀ ਚਾਹੁੰਦਾ ਹੈ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:380
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:376
 | 
			
		||||
msgid "Always grant access"
 | 
			
		||||
msgstr "ਹਮੇਸ਼ਾ ਪਹੁੰਚ ਮਨਜ਼ੂਰ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:381
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:377
 | 
			
		||||
msgid "Grant this time only"
 | 
			
		||||
msgstr "ਕੇਵਲ ਇਸ ਸਮੇਂ ਹੀ ਮਨਜ਼ੂਰ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:382
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:378
 | 
			
		||||
msgid "Reject"
 | 
			
		||||
msgstr "ਨਾ-ਮਨਜ਼ੂਰ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:412
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:408
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Pairing confirmation for %s"
 | 
			
		||||
msgstr "%s ਲਈ ਪੇਅਰ ਕਰਨ ਦੀ ਪੁਸ਼ਟੀ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:418 ../js/ui/status/bluetooth.js:452
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:414 ../js/ui/status/bluetooth.js:448
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Device %s wants to pair with this computer"
 | 
			
		||||
msgstr "ਜੰਤਰ %s ਇਸ ਕੰਪਿਊਟਰ ਨਾਲ ਪੇਅਰ ਹੋਣਾ ਚਾਹੁੰਦਾ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:419
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:415
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Please confirm whether the PIN '%s' matches the one on the device."
 | 
			
		||||
msgstr "ਪੁਸ਼ਟੀ ਕਰੋ ਜੀ ਕਿ ਪਿੰਨ '%s' ਜੰਤਰ ਉੱਤੇ ਮੌਜੂਦ ਪਿੰਨ ਨਾਲ ਮਿਲਦਾ ਹੈ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:421
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:417
 | 
			
		||||
msgid "Matches"
 | 
			
		||||
msgstr "ਮਿਲਦਾ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:422
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:418
 | 
			
		||||
msgid "Does not match"
 | 
			
		||||
msgstr "ਮਿਲਦਾ ਨਹੀਂ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:445
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:441
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Pairing request for %s"
 | 
			
		||||
msgstr "%s ਲਈ ਪੇਅਰ ਕਰਨ ਦੀ ਮੰਗ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:453
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:449
 | 
			
		||||
msgid "Please enter the PIN mentioned on the device."
 | 
			
		||||
msgstr "ਜੰਤਰ ਉੱਤੇ ਦਿੱਤਾ ਗਿਆ ਪਿੰਨ ਦਿਉ ਜੀ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:469
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:465
 | 
			
		||||
msgid "OK"
 | 
			
		||||
msgstr "ਠੀਕ ਹੈ"
 | 
			
		||||
 | 
			
		||||
@@ -810,17 +836,153 @@ msgstr "...ਕੀਬੋਰਡ ਲੇਆਉਟ ਵੇਖੋ"
 | 
			
		||||
msgid "Localization Settings"
 | 
			
		||||
msgstr "ਲੋਕਲਾਈਜ਼ੇਸ਼ਨ ਸੈਟਿੰਗ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:102 ../js/ui/status/network.js:1437
 | 
			
		||||
msgid "<unknown>"
 | 
			
		||||
msgstr "<ਅਣਜਾਣ>"
 | 
			
		||||
 | 
			
		||||
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
 | 
			
		||||
#: ../js/ui/status/network.js:295
 | 
			
		||||
msgid "disabled"
 | 
			
		||||
msgstr "ਬੰਦ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:478
 | 
			
		||||
msgid "connecting..."
 | 
			
		||||
msgstr "ਕੁਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for network connections that require some kind of key or password
 | 
			
		||||
#: ../js/ui/status/network.js:481
 | 
			
		||||
msgid "authentication required"
 | 
			
		||||
msgstr "ਪਰਮਾਣਕਿਤਾ ਚਾਹੀਦੀ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for devices that require some kind of firmware or kernel
 | 
			
		||||
#. module, which is missing
 | 
			
		||||
#: ../js/ui/status/network.js:491
 | 
			
		||||
msgid "firmware missing"
 | 
			
		||||
msgstr "ਫਿਰਮਵੇਅਰ ਮੌਜੂਦ ਨਹੀਂ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for wired network devices that are physically disconnected
 | 
			
		||||
#: ../js/ui/status/network.js:498
 | 
			
		||||
msgid "cable unplugged"
 | 
			
		||||
msgstr "ਕੇਬਲ ਕੱਢੀ ਹੋਈ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for a network device that cannot be activated (for example it
 | 
			
		||||
#. is disabled by rfkill, or it has no coverage
 | 
			
		||||
#: ../js/ui/status/network.js:503
 | 
			
		||||
msgid "unavailable"
 | 
			
		||||
msgstr "ਨਾ-ਉਪਲੱਬਧ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:505
 | 
			
		||||
msgid "connection failed"
 | 
			
		||||
msgstr "ਕੁਨੈਕਸ਼ਨ ਫੇਲ੍ਹ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
 | 
			
		||||
#. and we cannot access its settings (including the name)
 | 
			
		||||
#: ../js/ui/status/network.js:585 ../js/ui/status/network.js:1385
 | 
			
		||||
msgid "Connected (private)"
 | 
			
		||||
msgstr "ਕੁਨੈਕਟ ਹੈ (ਪ੍ਰਾਈਵੇਟ)"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:666
 | 
			
		||||
msgid "Auto Ethernet"
 | 
			
		||||
msgstr "ਆਟੋ ਈਥਰਨੈੱਟ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:741
 | 
			
		||||
msgid "Auto broadband"
 | 
			
		||||
msgstr "ਆਟੋ ਬਰਾਡਬੈਂਡ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:744
 | 
			
		||||
msgid "Auto dial-up"
 | 
			
		||||
msgstr "ਆਟੋ ਡਾਇਲ-ਅੱਪ"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
 | 
			
		||||
#: ../js/ui/status/network.js:887 ../js/ui/status/network.js:1397
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Auto %s"
 | 
			
		||||
msgstr "ਆਟੋ %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:889
 | 
			
		||||
msgid "Auto bluetooth"
 | 
			
		||||
msgstr "ਆਟੋ ਬਲਿਊਟੁੱਥ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1399
 | 
			
		||||
msgid "Auto wireless"
 | 
			
		||||
msgstr "ਆਟੋ ਬੇਤਾਰ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1457
 | 
			
		||||
msgid "More..."
 | 
			
		||||
msgstr "ਹੋਰ..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1480
 | 
			
		||||
msgid "Enable networking"
 | 
			
		||||
msgstr "ਨੈੱਟਵਰਕਿੰਗ ਚਾਲੂ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1492
 | 
			
		||||
msgid "Wired"
 | 
			
		||||
msgstr "ਤਾਰ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1503
 | 
			
		||||
msgid "Wireless"
 | 
			
		||||
msgstr "ਬੇਤਾਰ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1513
 | 
			
		||||
msgid "Mobile broadband"
 | 
			
		||||
msgstr "ਮੋਬਾਇਲ ਬਰਾਡਬੈਂਡ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1523
 | 
			
		||||
msgid "VPN Connections"
 | 
			
		||||
msgstr "VPN ਕੁਨੈਕਸ਼ਨ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1532
 | 
			
		||||
msgid "Network Settings"
 | 
			
		||||
msgstr "ਨੈੱਟਵਰਕ ਸੈਟਿੰਗ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1827
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to mobile broadband connection '%s'"
 | 
			
		||||
msgstr "ਹੁਣ ਤੁਸੀਂ ਮੋਬਾਇਲ ਬਰਾਡਬੈਂਡ ਨੈੱਟਵਰਕ '%s' ਨਾਲ ਕੁਨੈਕਟ ਹੋ ਗਏ ਹੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1831
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to wireless network '%s'"
 | 
			
		||||
msgstr "ਹੁਣ ਤੁਸੀਂ ਬੇਤਾਰ ਨੈੱਟਵਰਕ '%s' ਨਾਲ ਕੁਨੈਕਟ ਹੋ ਗਏ ਹੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1835
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to wired network '%s'"
 | 
			
		||||
msgstr "ਹੁਣ ਤੁਸੀਂ ਤਾਰ ਵਾਲੇ ਨੈੱਟਵਰਕ '%s'  ਨਾਲ ਕੁਨੈਕਟ ਹੋ ਗਏ ਹੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1839
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to VPN network '%s'"
 | 
			
		||||
msgstr "ਤੁਸੀਂ ਹੁਣ VPN ਨੈੱਟਵਰਕ '%s' ਨਾਲ ਕੁਨੈਕਟ ਹੋ ਚੁੱਕੇ ਹੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1844
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to '%s'"
 | 
			
		||||
msgstr "ਤੁਸੀਂ ਹੁਣ '%s' ਨਾਲ ਕੁਨੈਕਟ ਹੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1852
 | 
			
		||||
msgid "Connection established"
 | 
			
		||||
msgstr "ਕੁਨੈਕਸ਼ਨ ਬਣਾਇਆ ਗਿਆ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1974
 | 
			
		||||
msgid "Networking is disabled"
 | 
			
		||||
msgstr "ਨੈੱਟਵਰਕਿੰਗ ਬੰਦ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:2099
 | 
			
		||||
msgid "Network Manager"
 | 
			
		||||
msgstr "ਨੈੱਟਵਰਕ ਮੈਨੇਜਰ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:85
 | 
			
		||||
msgid "Power Settings"
 | 
			
		||||
msgstr "ਪਾਵਰ ਸੈਟਿੰਗ"
 | 
			
		||||
 | 
			
		||||
#. 0 is reported when UPower does not have enough data
 | 
			
		||||
#. to estimate battery life
 | 
			
		||||
#: ../js/ui/status/power.js:110
 | 
			
		||||
#: ../js/ui/status/power.js:111
 | 
			
		||||
msgid "Estimating..."
 | 
			
		||||
msgstr "...ਅਨੁਮਾਨ ਲਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:117
 | 
			
		||||
#: ../js/ui/status/power.js:118
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d hour remaining"
 | 
			
		||||
msgid_plural "%d hours remaining"
 | 
			
		||||
@@ -828,102 +990,102 @@ msgstr[0] "%d ਘੰਟਾ ਬਾਕੀ"
 | 
			
		||||
msgstr[1] "%d ਘੰਟੇ ਬਾਕੀ"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
 | 
			
		||||
#: ../js/ui/status/power.js:120
 | 
			
		||||
#: ../js/ui/status/power.js:121
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d %s %d %s remaining"
 | 
			
		||||
msgstr "%d %s %d %s ਬਾਕੀ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:122
 | 
			
		||||
#: ../js/ui/status/power.js:123
 | 
			
		||||
msgid "hour"
 | 
			
		||||
msgid_plural "hours"
 | 
			
		||||
msgstr[0] "ਘੰਟਾ"
 | 
			
		||||
msgstr[1] "ਘੰਟੇ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:122
 | 
			
		||||
#: ../js/ui/status/power.js:123
 | 
			
		||||
msgid "minute"
 | 
			
		||||
msgid_plural "minutes"
 | 
			
		||||
msgstr[0] "ਮਿੰਟ"
 | 
			
		||||
msgstr[1] "ਮਿੰਟ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:125
 | 
			
		||||
#: ../js/ui/status/power.js:126
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d minute remaining"
 | 
			
		||||
msgid_plural "%d minutes remaining"
 | 
			
		||||
msgstr[0] "%d ਮਿੰਟ ਬਾਕੀ"
 | 
			
		||||
msgstr[1] "%d ਮਿੰਟ ਬਾਕੀ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:227
 | 
			
		||||
#: ../js/ui/status/power.js:228
 | 
			
		||||
msgid "AC adapter"
 | 
			
		||||
msgstr "AC ਐਡਪਟਰ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:229
 | 
			
		||||
#: ../js/ui/status/power.js:230
 | 
			
		||||
msgid "Laptop battery"
 | 
			
		||||
msgstr "ਲੈਪਟਾਪ ਬੈਟਰੀ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:231
 | 
			
		||||
#: ../js/ui/status/power.js:232
 | 
			
		||||
msgid "UPS"
 | 
			
		||||
msgstr "UPS"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:233
 | 
			
		||||
#: ../js/ui/status/power.js:234
 | 
			
		||||
msgid "Monitor"
 | 
			
		||||
msgstr "ਮਾਨੀਟਰ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:235
 | 
			
		||||
#: ../js/ui/status/power.js:236
 | 
			
		||||
msgid "Mouse"
 | 
			
		||||
msgstr "ਮਾਊਸ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:237
 | 
			
		||||
#: ../js/ui/status/power.js:238
 | 
			
		||||
msgid "Keyboard"
 | 
			
		||||
msgstr "ਕੀਬੋਰਡ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:239
 | 
			
		||||
#: ../js/ui/status/power.js:240
 | 
			
		||||
msgid "PDA"
 | 
			
		||||
msgstr "PDA"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:241
 | 
			
		||||
#: ../js/ui/status/power.js:242
 | 
			
		||||
msgid "Cell phone"
 | 
			
		||||
msgstr "ਸੈੱਲ ਫੋਨ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:243
 | 
			
		||||
#: ../js/ui/status/power.js:244
 | 
			
		||||
msgid "Media player"
 | 
			
		||||
msgstr "ਮੀਡਿਆ ਪਲੇਅਰ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:245
 | 
			
		||||
#: ../js/ui/status/power.js:246
 | 
			
		||||
msgid "Tablet"
 | 
			
		||||
msgstr "ਟੇਬਲੇਟ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:247
 | 
			
		||||
#: ../js/ui/status/power.js:248
 | 
			
		||||
msgid "Computer"
 | 
			
		||||
msgstr "ਕੰਪਿਊਟਰ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:249 ../src/shell-app-system.c:1013
 | 
			
		||||
#: ../js/ui/status/power.js:250 ../src/shell-app-system.c:1088
 | 
			
		||||
msgid "Unknown"
 | 
			
		||||
msgstr "ਅਣਜਾਣ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/volume.js:44
 | 
			
		||||
#: ../js/ui/status/volume.js:45
 | 
			
		||||
msgid "Volume"
 | 
			
		||||
msgstr "ਆਵਾਜ਼"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/volume.js:57
 | 
			
		||||
#: ../js/ui/status/volume.js:58
 | 
			
		||||
msgid "Microphone"
 | 
			
		||||
msgstr "ਮਾਈਕਰੋਫੋਨ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:239
 | 
			
		||||
#: ../js/ui/telepathyClient.js:332
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is online."
 | 
			
		||||
msgstr "%s ਆਨਲਾਈਨ ਹੈ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:244
 | 
			
		||||
#: ../js/ui/telepathyClient.js:337
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is offline."
 | 
			
		||||
msgstr "%s ਆਫਲਾਈਨ ਹੈ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:247
 | 
			
		||||
#: ../js/ui/telepathyClient.js:340
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is away."
 | 
			
		||||
msgstr "%s ਦੂਰ ਹੈ।"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:250
 | 
			
		||||
#: ../js/ui/telepathyClient.js:343
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is busy."
 | 
			
		||||
msgstr "%s ਰੁੱਝਿਆ/ਰੁੱਝੀ ਹੈ।"
 | 
			
		||||
@@ -931,7 +1093,7 @@ msgstr "%s ਰੁੱਝਿਆ/ਰੁੱਝੀ ਹੈ।"
 | 
			
		||||
#. Translators: this is a time format string followed by a date.
 | 
			
		||||
#. If applicable, replace %X with a strftime format valid for your
 | 
			
		||||
#. locale, without seconds.
 | 
			
		||||
#: ../js/ui/telepathyClient.js:348
 | 
			
		||||
#: ../js/ui/telepathyClient.js:474
 | 
			
		||||
#, no-c-format
 | 
			
		||||
msgid "Sent at %X on %A"
 | 
			
		||||
msgstr "%2$A ਨੂੰ %1$X ਵਜੇ ਭੇਜਿਆ"
 | 
			
		||||
@@ -940,11 +1102,11 @@ msgstr "%2$A ਨੂੰ %1$X ਵਜੇ ਭੇਜਿਆ"
 | 
			
		||||
#. in the search entry when no search is
 | 
			
		||||
#. active; it should not exceed ~30
 | 
			
		||||
#. characters.
 | 
			
		||||
#: ../js/ui/viewSelector.js:117
 | 
			
		||||
#: ../js/ui/viewSelector.js:122
 | 
			
		||||
msgid "Type to search..."
 | 
			
		||||
msgstr "...ਲੱਭਣ ਲਈ ਲਿਖੋ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/viewSelector.js:137 ../src/shell-util.c:250
 | 
			
		||||
#: ../js/ui/viewSelector.js:142 ../src/shell-util.c:250
 | 
			
		||||
msgid "Search"
 | 
			
		||||
msgstr "ਖੋਜ"
 | 
			
		||||
 | 
			
		||||
@@ -960,7 +1122,7 @@ msgstr "'%s' ਤਿਆਰ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The number of sound outputs on a particular device
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1094
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1098
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%u Output"
 | 
			
		||||
msgid_plural "%u Outputs"
 | 
			
		||||
@@ -969,51 +1131,67 @@ msgstr[1] "%u ਆਉਟਪੁੱਟ"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The number of sound inputs on a particular device
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1104
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1108
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%u Input"
 | 
			
		||||
msgid_plural "%u Inputs"
 | 
			
		||||
msgstr[0] "%u ਇੰਪੁੱਟ"
 | 
			
		||||
msgstr[1] "%u ਇੰਪੁੱਟ"
 | 
			
		||||
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1402
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1406
 | 
			
		||||
msgid "System Sounds"
 | 
			
		||||
msgstr "ਸਿਸਟਮ ਸਾਊਂਡ"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1298
 | 
			
		||||
#: ../src/main.c:446
 | 
			
		||||
msgid "Print version"
 | 
			
		||||
msgstr "ਵਰਜਨ ਛਾਪੋ"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-app.c:454
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to launch '%s'"
 | 
			
		||||
msgstr "'%s' ਚਲਾਉਣ ਲਈ ਫੇਲ੍ਹ"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1395
 | 
			
		||||
msgid "Less than a minute ago"
 | 
			
		||||
msgstr "ਇੱਕ ਮਿੰਟ ਤੋਂ ਘੱਟ ਚਿਰ ਪਹਿਲਾਂ"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1302
 | 
			
		||||
#: ../src/shell-global.c:1399
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d minute ago"
 | 
			
		||||
msgid_plural "%d minutes ago"
 | 
			
		||||
msgstr[0] "%d ਮਿੰਟ ਪਹਿਲਾਂ"
 | 
			
		||||
msgstr[1] "%d ਮਿੰਟ ਪਹਿਲਾਂ"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1307
 | 
			
		||||
#: ../src/shell-global.c:1404
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d hour ago"
 | 
			
		||||
msgid_plural "%d hours ago"
 | 
			
		||||
msgstr[0] "%d ਘੰਟਾ ਪਹਿਲਾਂ"
 | 
			
		||||
msgstr[1] "%d ਘੰਟੇ ਪਹਿਲਾਂ"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1312
 | 
			
		||||
#: ../src/shell-global.c:1409
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d day ago"
 | 
			
		||||
msgid_plural "%d days ago"
 | 
			
		||||
msgstr[0] "%d ਦਿਨ ਪਹਿਲਾਂ"
 | 
			
		||||
msgstr[1] "%d ਦਿਨ ਪਹਿਲਾਂ"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1317
 | 
			
		||||
#: ../src/shell-global.c:1414
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d week ago"
 | 
			
		||||
msgid_plural "%d weeks ago"
 | 
			
		||||
msgstr[0] "%d ਹਫ਼ਤਾ ਪਹਿਲਾਂ"
 | 
			
		||||
msgstr[1] "%d ਹਫ਼ਤੇ ਪਹਿਲਾਂ"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-mobile-providers.c:80
 | 
			
		||||
msgid "United Kingdom"
 | 
			
		||||
msgstr "ਬਰਤਾਨੀਆ"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-mobile-providers.c:526
 | 
			
		||||
msgid "Default"
 | 
			
		||||
msgstr "ਡਿਫਾਲਟ"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-polkit-authentication-agent.c:334
 | 
			
		||||
#| msgid "Authentation dialog was dismissed by the user"
 | 
			
		||||
msgid "Authentication dialog was dismissed by the user"
 | 
			
		||||
msgstr "ਪਰਮਾਣਕਿਤਾ ਡਾਈਲਾਗ ਯੂਜ਼ਰ ਵਲੋਂ ਰੱਦ ਕੀਤਾ"
 | 
			
		||||
 | 
			
		||||
@@ -1037,6 +1215,34 @@ msgstr "ਫਾਇਲ ਸਿਸਟਮ"
 | 
			
		||||
msgid "%1$s: %2$s"
 | 
			
		||||
msgstr "%1$s: %2$s"
 | 
			
		||||
 | 
			
		||||
#~ msgid "No such application"
 | 
			
		||||
#~ msgstr "ਇੰਞ ਦੀ ਕੋਈ ਐਪਲੀਕੇਸ਼ਨ ਨਹੀਂ ਹੈ"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Shut Down"
 | 
			
		||||
#~ msgstr "ਬੰਦ ਕਰੋ"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Click Shut Down to quit these applications and shut down the system."
 | 
			
		||||
#~ msgstr "ਇਹ ਐਪਲੀਕੇਸ਼ਨ ਬੰਦ ਕਰਕੇ ਸਿਸਟਮ ਨੂੰ ਬੰਦ ਕਰਨ ਲਈ ਬੰਦ ਕਰੋ ਨੂੰ ਕਲਿੱਕ ਕਰੋ।"
 | 
			
		||||
 | 
			
		||||
#~ msgid "The system will shut down automatically in %d seconds."
 | 
			
		||||
#~ msgstr "ਸਿਸਟਮ ਨੂੰ ਆਟੋਮੈਟਿਕ ਹੀ %d ਸਕਿੰਟਾਂ ਵਿੱਚ ਬੰਦ ਕੀਤਾ ਜਾਵੇਗਾ।"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Shutting down the system."
 | 
			
		||||
#~ msgstr "ਸਿਸਟਮ ਬੰਦ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Confirm"
 | 
			
		||||
#~ msgstr "ਪੁਸ਼ਟੀ"
 | 
			
		||||
 | 
			
		||||
#~| msgid "Cancel"
 | 
			
		||||
#~ msgid "Panel"
 | 
			
		||||
#~ msgstr "ਪੈਨਲ"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Screen Reader"
 | 
			
		||||
#~ msgstr "ਸਕਰੀਨ ਰੀਡਰ"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Screen Keyboard"
 | 
			
		||||
#~ msgstr "ਸਕਰੀਨ ਕੀਬੋਰਡ"
 | 
			
		||||
 | 
			
		||||
#~ msgid "PREFERENCES"
 | 
			
		||||
#~ msgstr "ਪਸੰਦ"
 | 
			
		||||
 | 
			
		||||
@@ -1246,9 +1452,6 @@ msgstr "%1$s: %2$s"
 | 
			
		||||
#~ msgid "Frequent"
 | 
			
		||||
#~ msgstr "ਅਕਸਰ"
 | 
			
		||||
 | 
			
		||||
#~ msgid "More"
 | 
			
		||||
#~ msgstr "ਹੋਰ"
 | 
			
		||||
 | 
			
		||||
#~ msgid "(see all)"
 | 
			
		||||
#~ msgstr "(ਸਭ ਵੇਖੋ)"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1251
									
								
								po/pt_BR.po
									
									
									
									
									
								
							
							
						
						
									
										1251
									
								
								po/pt_BR.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1320
									
								
								po/sr@latin.po
									
									
									
									
									
								
							
							
						
						
									
										1320
									
								
								po/sr@latin.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										521
									
								
								po/vi.po
									
									
									
									
									
								
							
							
						
						
									
										521
									
								
								po/vi.po
									
									
									
									
									
								
							@@ -7,9 +7,9 @@ msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: gnome-shell\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
 | 
			
		||||
"shell&component=general\n"
 | 
			
		||||
"POT-Creation-Date: 2011-03-05 08:37+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2011-03-05 15:41+0700\n"
 | 
			
		||||
"shell&keywords=I18N+L10N&component=general\n"
 | 
			
		||||
"POT-Creation-Date: 2011-03-25 20:20+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2011-03-26 13:58+0700\n"
 | 
			
		||||
"Last-Translator: Duy <pclouds@gmail.com>\n"
 | 
			
		||||
"Language-Team: Vietnamese <vi-VN@googlegroups.com>\n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
@@ -59,7 +59,6 @@ msgid "History for command (Alt-F2) dialog"
 | 
			
		||||
msgstr "Hộp thoại lịch sử lệnh (Alt-F2)"
 | 
			
		||||
 | 
			
		||||
#: ../data/org.gnome.shell.gschema.xml.in.h:7
 | 
			
		||||
#| msgid "History for command (Alt-F2) dialog"
 | 
			
		||||
msgid "History for the looking glass dialog"
 | 
			
		||||
msgstr "Lịch sử hộp thoại looking glass"
 | 
			
		||||
 | 
			
		||||
@@ -150,7 +149,10 @@ msgid ""
 | 
			
		||||
"used ones (e.g. in launchers). While this data will be kept private, you may "
 | 
			
		||||
"want to disable this for privacy reasons. Please note that doing so won't "
 | 
			
		||||
"remove already saved data."
 | 
			
		||||
msgstr "GNOME Shell bình thường sẽ theo dõi các ứng dụng tích cực để thể hiện phù hợp (ví dụ, bộ phóng). Mặc dù thông tin này là riêng tư, bạn vẫn có thể tắt vì lý do cá nhân. Chú ý là làm vậy sẽ không xoá bỏ những dữ liệu đã có."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"GNOME Shell bình thường sẽ theo dõi các ứng dụng tích cực để thể hiện phù "
 | 
			
		||||
"hợp (ví dụ, bộ phóng). Mặc dù thông tin này là riêng tư, bạn vẫn có thể tắt "
 | 
			
		||||
"vì lý do cá nhân. Chú ý là làm vậy sẽ không xoá bỏ những dữ liệu đã có."
 | 
			
		||||
 | 
			
		||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
 | 
			
		||||
msgid "Uuids of extensions to disable"
 | 
			
		||||
@@ -164,47 +166,43 @@ msgstr "Có thu thập thống kê sử dụng ứng dụng không"
 | 
			
		||||
msgid "disabled OpenSearch providers"
 | 
			
		||||
msgstr "Phần cung cấp OpenSearch bị tắt"
 | 
			
		||||
 | 
			
		||||
#: ../js/misc/util.js:86
 | 
			
		||||
#: ../js/misc/util.js:71
 | 
			
		||||
msgid "Command not found"
 | 
			
		||||
msgstr "Không tìm thấy lệnh"
 | 
			
		||||
 | 
			
		||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
 | 
			
		||||
#. something nicer
 | 
			
		||||
#: ../js/misc/util.js:113
 | 
			
		||||
#: ../js/misc/util.js:98
 | 
			
		||||
msgid "Could not parse command:"
 | 
			
		||||
msgstr "Không thể phân tích lệnh:"
 | 
			
		||||
 | 
			
		||||
#: ../js/misc/util.js:135
 | 
			
		||||
msgid "No such application"
 | 
			
		||||
msgstr "Không có ứng dụng đó"
 | 
			
		||||
 | 
			
		||||
#: ../js/misc/util.js:148
 | 
			
		||||
#: ../js/misc/util.js:106
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Execution of '%s' failed:"
 | 
			
		||||
msgstr "Lỗi thực hiện '%s':"
 | 
			
		||||
 | 
			
		||||
#. Translators: Filter to display all applications
 | 
			
		||||
#: ../js/ui/appDisplay.js:195
 | 
			
		||||
#: ../js/ui/appDisplay.js:230
 | 
			
		||||
msgid "All"
 | 
			
		||||
msgstr "Tất cả"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:285
 | 
			
		||||
#: ../js/ui/appDisplay.js:328
 | 
			
		||||
msgid "APPLICATIONS"
 | 
			
		||||
msgstr "ỨNG DỤNG"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:311
 | 
			
		||||
#: ../js/ui/appDisplay.js:354
 | 
			
		||||
msgid "SETTINGS"
 | 
			
		||||
msgstr "THIẾT LẬP"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:565
 | 
			
		||||
#: ../js/ui/appDisplay.js:625
 | 
			
		||||
msgid "New Window"
 | 
			
		||||
msgstr "Cửa sổ mới"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:568
 | 
			
		||||
#: ../js/ui/appDisplay.js:628
 | 
			
		||||
msgid "Remove from Favorites"
 | 
			
		||||
msgstr "Bỏ đánh dấu ưa thích"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/appDisplay.js:569
 | 
			
		||||
#: ../js/ui/appDisplay.js:629
 | 
			
		||||
msgid "Add to Favorites"
 | 
			
		||||
msgstr "Đánh dấu ưa thích"
 | 
			
		||||
 | 
			
		||||
@@ -224,7 +222,7 @@ msgstr "Đã bỏ đánh dấu ưa thích cho %s"
 | 
			
		||||
#: ../js/ui/calendar.js:66
 | 
			
		||||
msgctxt "event list time"
 | 
			
		||||
msgid "All Day"
 | 
			
		||||
msgstr "Nguyên ngày"
 | 
			
		||||
msgstr "Cả ngày"
 | 
			
		||||
 | 
			
		||||
#. Translators: Shown in calendar event list, if 24h format
 | 
			
		||||
#: ../js/ui/calendar.js:71
 | 
			
		||||
@@ -364,7 +362,7 @@ msgstr "Tuần này"
 | 
			
		||||
msgid "Next week"
 | 
			
		||||
msgstr "Tuần tới"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dash.js:174
 | 
			
		||||
#: ../js/ui/dash.js:174 ../js/ui/messageTray.js:994
 | 
			
		||||
msgid "Remove"
 | 
			
		||||
msgstr "Loại bỏ"
 | 
			
		||||
 | 
			
		||||
@@ -372,54 +370,54 @@ msgstr "Loại bỏ"
 | 
			
		||||
msgid "Date and Time Settings"
 | 
			
		||||
msgstr "Thiết lập ngày giờ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:110
 | 
			
		||||
#: ../js/ui/dateMenu.js:111
 | 
			
		||||
msgid "Open Calendar"
 | 
			
		||||
msgstr "Mở lịch"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is the time format with date used
 | 
			
		||||
#. in 24-hour mode.
 | 
			
		||||
#: ../js/ui/dateMenu.js:162
 | 
			
		||||
#: ../js/ui/dateMenu.js:164
 | 
			
		||||
msgid "%a %b %e, %R:%S"
 | 
			
		||||
msgstr "%R:%S, %a %b %e"
 | 
			
		||||
msgstr "%a %R:%S, %e %b"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:163
 | 
			
		||||
#: ../js/ui/dateMenu.js:165
 | 
			
		||||
msgid "%a %b %e, %R"
 | 
			
		||||
msgstr "%R, %a %b %e"
 | 
			
		||||
msgstr "%a %R, %e %b"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is the time format without date used
 | 
			
		||||
#. in 24-hour mode.
 | 
			
		||||
#: ../js/ui/dateMenu.js:167
 | 
			
		||||
#: ../js/ui/dateMenu.js:169
 | 
			
		||||
msgid "%a %R:%S"
 | 
			
		||||
msgstr "%R:%S %a"
 | 
			
		||||
msgstr "%a %R:%S"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:168
 | 
			
		||||
#: ../js/ui/dateMenu.js:170
 | 
			
		||||
msgid "%a %R"
 | 
			
		||||
msgstr "%R %a"
 | 
			
		||||
msgstr "%a %R"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is a time format with date used
 | 
			
		||||
#. for AM/PM.
 | 
			
		||||
#: ../js/ui/dateMenu.js:175
 | 
			
		||||
#: ../js/ui/dateMenu.js:177
 | 
			
		||||
msgid "%a %b %e, %l:%M:%S %p"
 | 
			
		||||
msgstr "%a %b %e, %l:%M:%S %p"
 | 
			
		||||
msgstr "%a %e %b, %l:%M:%S %p"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:176
 | 
			
		||||
#: ../js/ui/dateMenu.js:178
 | 
			
		||||
msgid "%a %b %e, %l:%M %p"
 | 
			
		||||
msgstr "%a %b %e, %l:%M %p"
 | 
			
		||||
msgstr "%a %e %b, %l:%M %p"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is a time format without date used
 | 
			
		||||
#. for AM/PM.
 | 
			
		||||
#: ../js/ui/dateMenu.js:180
 | 
			
		||||
#: ../js/ui/dateMenu.js:182
 | 
			
		||||
msgid "%a %l:%M:%S %p"
 | 
			
		||||
msgstr "%a %l:%M:%S %p"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/dateMenu.js:181
 | 
			
		||||
#: ../js/ui/dateMenu.js:183
 | 
			
		||||
msgid "%a %l:%M %p"
 | 
			
		||||
msgstr "%a %l:%M %p"
 | 
			
		||||
 | 
			
		||||
#. Translators: This is the date format to use when the calendar popup is
 | 
			
		||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
 | 
			
		||||
#.
 | 
			
		||||
#: ../js/ui/dateMenu.js:207
 | 
			
		||||
#: ../js/ui/dateMenu.js:194
 | 
			
		||||
msgid "%A %B %e, %Y"
 | 
			
		||||
msgstr "%A %e %B, %Y"
 | 
			
		||||
 | 
			
		||||
@@ -432,7 +430,7 @@ msgstr "MỤC GẦN ĐÂY"
 | 
			
		||||
msgid "Log Out %s"
 | 
			
		||||
msgstr "Đăng xuất %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:69
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:64 ../js/ui/endSessionDialog.js:70
 | 
			
		||||
msgid "Log Out"
 | 
			
		||||
msgstr "Đăng xuất"
 | 
			
		||||
 | 
			
		||||
@@ -454,46 +452,48 @@ msgstr "Bạn sẽ tự động đăng xuất sau %d giây."
 | 
			
		||||
msgid "Logging out of the system."
 | 
			
		||||
msgstr "Đang xuất khỏi hệ thống."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:74 ../js/ui/endSessionDialog.js:78
 | 
			
		||||
msgid "Shut Down"
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:75 ../js/ui/endSessionDialog.js:82
 | 
			
		||||
#| msgid "Power Off..."
 | 
			
		||||
msgid "Power Off"
 | 
			
		||||
msgstr "Tắt máy"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:75
 | 
			
		||||
msgid "Click Shut Down to quit these applications and shut down the system."
 | 
			
		||||
msgstr "Nhấn Tắt máy để thoát những ứng dụng này và tắt hệ thống."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:76
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The system will shut down automatically in %d seconds."
 | 
			
		||||
msgstr "Hệ thống sẽ tự động tắt sau %d giây."
 | 
			
		||||
#| msgid "Click Log Out to quit these applications and log out of the system."
 | 
			
		||||
msgid "Click Power Off to quit these applications and power off the system."
 | 
			
		||||
msgstr "Nhấn Tắt máy để thoát những ứng dụng này và tắt máy."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:77
 | 
			
		||||
msgid "Shutting down the system."
 | 
			
		||||
msgstr "Tắt hệ thống."
 | 
			
		||||
#, c-format
 | 
			
		||||
#| msgid "The system will restart automatically in %d seconds."
 | 
			
		||||
msgid "The system will power off automatically in %d seconds."
 | 
			
		||||
msgstr "Hệ thống sẽ tự động tắt sau %d giây."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:84 ../js/ui/endSessionDialog.js:88
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:78
 | 
			
		||||
#| msgid "Logging out of the system."
 | 
			
		||||
msgid "Powering off the system."
 | 
			
		||||
msgstr "Tắt máy."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:80 ../js/ui/endSessionDialog.js:88
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:93
 | 
			
		||||
msgid "Restart"
 | 
			
		||||
msgstr "Khởi động lại"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:85
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:89
 | 
			
		||||
msgid "Click Restart to quit these applications and restart the system."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Nhấn Khởi động lại để thoát những ứng dụng này và khởi động lại hệ thống."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:86
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:90
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The system will restart automatically in %d seconds."
 | 
			
		||||
msgstr "Hệ thống sẽ tự động khởi động lại sau %d giây."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:87
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:91
 | 
			
		||||
msgid "Restarting the system."
 | 
			
		||||
msgstr "Khởi động lại hệ thống."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:395
 | 
			
		||||
msgid "Confirm"
 | 
			
		||||
msgstr "Xác nhận"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:400 ../js/ui/status/bluetooth.js:470
 | 
			
		||||
#: ../js/ui/endSessionDialog.js:415 ../js/ui/polkitAuthenticationAgent.js:172
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:466
 | 
			
		||||
msgid "Cancel"
 | 
			
		||||
msgstr "Thôi"
 | 
			
		||||
 | 
			
		||||
@@ -507,7 +507,7 @@ msgstr "Bật"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The device has been disabled
 | 
			
		||||
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1087
 | 
			
		||||
#: ../js/ui/lookingGlass.js:627 ../src/gvc/gvc-mixer-control.c:1091
 | 
			
		||||
msgid "Disabled"
 | 
			
		||||
msgstr "Tắt"
 | 
			
		||||
 | 
			
		||||
@@ -527,34 +527,48 @@ msgstr "Xem mã nguồn"
 | 
			
		||||
msgid "Web Page"
 | 
			
		||||
msgstr "Trang Web"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/messageTray.js:1907
 | 
			
		||||
#: ../js/ui/messageTray.js:987
 | 
			
		||||
msgid "Open"
 | 
			
		||||
msgstr "Mở"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/messageTray.js:2145
 | 
			
		||||
msgid "System Information"
 | 
			
		||||
msgstr "Thông tin hệ thống"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/overview.js:88
 | 
			
		||||
#: ../js/ui/overview.js:91
 | 
			
		||||
msgid "Undo"
 | 
			
		||||
msgstr "Hoàn lại"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/overview.js:183
 | 
			
		||||
#: ../js/ui/overview.js:186
 | 
			
		||||
msgid "Windows"
 | 
			
		||||
msgstr "Cửa sổ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/overview.js:186
 | 
			
		||||
#: ../js/ui/overview.js:189
 | 
			
		||||
msgid "Applications"
 | 
			
		||||
msgstr "Ứng dụng"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is the name of the dock/favorites area on
 | 
			
		||||
#. the left of the overview
 | 
			
		||||
#: ../js/ui/overview.js:205
 | 
			
		||||
msgid "Dash"
 | 
			
		||||
msgstr "Khung ứng dụng"
 | 
			
		||||
 | 
			
		||||
#. TODO - _quit() doesn't really work on apps in state STARTING yet
 | 
			
		||||
#: ../js/ui/panel.js:531
 | 
			
		||||
#: ../js/ui/panel.js:515
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Quit %s"
 | 
			
		||||
msgstr "Thoát %s"
 | 
			
		||||
 | 
			
		||||
#. Button on the left side of the panel.
 | 
			
		||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
 | 
			
		||||
#: ../js/ui/panel.js:899
 | 
			
		||||
#: ../js/ui/panel.js:878
 | 
			
		||||
msgid "Activities"
 | 
			
		||||
msgstr "Hoạt động"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/panel.js:979
 | 
			
		||||
msgid "Top Bar"
 | 
			
		||||
msgstr "Thanh đỉnh"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/placeDisplay.js:122
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Failed to unmount '%s'"
 | 
			
		||||
@@ -568,65 +582,84 @@ msgstr "Thử lại"
 | 
			
		||||
msgid "Connect to..."
 | 
			
		||||
msgstr "Kết nối đến..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/placeDisplay.js:409
 | 
			
		||||
#: ../js/ui/placeDisplay.js:380
 | 
			
		||||
msgid "PLACES & DEVICES"
 | 
			
		||||
msgstr "ĐỊA ĐIỂM & THIẾT BỊ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:74
 | 
			
		||||
msgid "Authentication Required"
 | 
			
		||||
msgstr "Cần xác thực"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:108
 | 
			
		||||
msgid "Administrator"
 | 
			
		||||
msgstr "Quản trị"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:176
 | 
			
		||||
msgid "Authenticate"
 | 
			
		||||
msgstr "Xác thực"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:260
 | 
			
		||||
msgid "Sorry, that didn't work. Please try again."
 | 
			
		||||
msgstr "Rất tiếc, không được. Vui lòng thử lại."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/polkitAuthenticationAgent.js:272
 | 
			
		||||
msgid "Password:"
 | 
			
		||||
msgstr "Mật khẩu:"
 | 
			
		||||
 | 
			
		||||
#. Translators: this MUST be either "toggle-switch-us"
 | 
			
		||||
#. (for toggle switches containing the English words
 | 
			
		||||
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
 | 
			
		||||
#. switches containing "◯" and "|"). Other values will
 | 
			
		||||
#. simply result in invisible toggle switches.
 | 
			
		||||
#: ../js/ui/popupMenu.js:612
 | 
			
		||||
#: ../js/ui/popupMenu.js:679
 | 
			
		||||
msgid "toggle-switch-us"
 | 
			
		||||
msgstr "toggle-switch-intl"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/runDialog.js:201
 | 
			
		||||
#: ../js/ui/runDialog.js:205
 | 
			
		||||
msgid "Please enter a command:"
 | 
			
		||||
msgstr "Vui lòng nhập lệnh:"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/searchDisplay.js:283
 | 
			
		||||
#: ../js/ui/searchDisplay.js:310
 | 
			
		||||
msgid "Searching..."
 | 
			
		||||
msgstr "Đang tìm..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/searchDisplay.js:297
 | 
			
		||||
#: ../js/ui/searchDisplay.js:324
 | 
			
		||||
msgid "No matching results."
 | 
			
		||||
msgstr "Không tìm thấy."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:102 ../js/ui/statusMenu.js:166
 | 
			
		||||
#: ../js/ui/statusMenu.js:161 ../js/ui/statusMenu.js:228
 | 
			
		||||
msgid "Power Off..."
 | 
			
		||||
msgstr "Tắt máy..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:104 ../js/ui/statusMenu.js:165
 | 
			
		||||
#| msgid "Suspend..."
 | 
			
		||||
#: ../js/ui/statusMenu.js:163 ../js/ui/statusMenu.js:227
 | 
			
		||||
msgid "Suspend"
 | 
			
		||||
msgstr "Ngưng"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:125
 | 
			
		||||
#: ../js/ui/statusMenu.js:184
 | 
			
		||||
msgid "Available"
 | 
			
		||||
msgstr "Có mặt"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:130
 | 
			
		||||
#: ../js/ui/statusMenu.js:189
 | 
			
		||||
msgid "Busy"
 | 
			
		||||
msgstr "Bận"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:138
 | 
			
		||||
#: ../js/ui/statusMenu.js:197
 | 
			
		||||
msgid "My Account"
 | 
			
		||||
msgstr "Tài khoản"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:142
 | 
			
		||||
#: ../js/ui/statusMenu.js:201
 | 
			
		||||
msgid "System Settings"
 | 
			
		||||
msgstr "Thiết lập hệ thống"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:149
 | 
			
		||||
#: ../js/ui/statusMenu.js:208
 | 
			
		||||
msgid "Lock Screen"
 | 
			
		||||
msgstr "Khoá màn hình"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:153
 | 
			
		||||
#: ../js/ui/statusMenu.js:213
 | 
			
		||||
msgid "Switch User"
 | 
			
		||||
msgstr "Chuyển người dùng"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/statusMenu.js:158
 | 
			
		||||
#: ../js/ui/statusMenu.js:218
 | 
			
		||||
msgid "Log Out..."
 | 
			
		||||
msgstr "Đăng xuất..."
 | 
			
		||||
 | 
			
		||||
@@ -634,14 +667,12 @@ msgstr "Đăng xuất..."
 | 
			
		||||
msgid "Zoom"
 | 
			
		||||
msgstr "Phóng to"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:69
 | 
			
		||||
msgid "Screen Reader"
 | 
			
		||||
msgstr "Trình đọc màn hình"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:73
 | 
			
		||||
msgid "Screen Keyboard"
 | 
			
		||||
msgstr "Bàn phím màn hình"
 | 
			
		||||
 | 
			
		||||
#. let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
 | 
			
		||||
#. 'screen-reader-enabled');
 | 
			
		||||
#. this.menu.addMenuItem(screenReader);
 | 
			
		||||
#. let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
 | 
			
		||||
#. 'screen-keyboard-enabled');
 | 
			
		||||
#. this.menu.addMenuItem(screenKeyboard);
 | 
			
		||||
#: ../js/ui/status/accessibility.js:77
 | 
			
		||||
msgid "Visual Alerts"
 | 
			
		||||
msgstr "Cảnh báo trực quan"
 | 
			
		||||
@@ -666,17 +697,17 @@ msgstr "Phím chuột"
 | 
			
		||||
msgid "Universal Access Settings"
 | 
			
		||||
msgstr "Thiết lập hỗ trợ truy cập"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:145
 | 
			
		||||
#: ../js/ui/status/accessibility.js:146
 | 
			
		||||
msgid "High Contrast"
 | 
			
		||||
msgstr "Tương phản cao"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/accessibility.js:182
 | 
			
		||||
#: ../js/ui/status/accessibility.js:183
 | 
			
		||||
msgid "Large Text"
 | 
			
		||||
msgstr "Chữ lớn"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:241
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:337 ../js/ui/status/bluetooth.js:371
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:411 ../js/ui/status/bluetooth.js:444
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:42 ../js/ui/status/bluetooth.js:237
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:333 ../js/ui/status/bluetooth.js:367
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:407 ../js/ui/status/bluetooth.js:440
 | 
			
		||||
msgid "Bluetooth"
 | 
			
		||||
msgstr "Bluetooth"
 | 
			
		||||
 | 
			
		||||
@@ -696,94 +727,94 @@ msgstr "Thiết lập thiết bị mới..."
 | 
			
		||||
msgid "Bluetooth Settings"
 | 
			
		||||
msgstr "Thiết lập Bluetooth"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:192
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:188
 | 
			
		||||
msgid "Connection"
 | 
			
		||||
msgstr "Kết nối"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:228
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:224
 | 
			
		||||
msgid "Send Files..."
 | 
			
		||||
msgstr "Gửi tập tin..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:233
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:229
 | 
			
		||||
msgid "Browse Files..."
 | 
			
		||||
msgstr "Duyệt tập tin..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:242
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:238
 | 
			
		||||
msgid "Error browsing device"
 | 
			
		||||
msgstr "Lỗi duyệt tập tin"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:243
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:239
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "The requested device cannot be browsed, error is '%s'"
 | 
			
		||||
msgstr "Không thể duyệt thiết bị yêu cầu , lỗi là '%s'"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:251
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:247
 | 
			
		||||
msgid "Keyboard Settings"
 | 
			
		||||
msgstr "Thiết lập bàn phím"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:256
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:252
 | 
			
		||||
msgid "Mouse Settings"
 | 
			
		||||
msgstr "Thiết lập chuột"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:263 ../js/ui/status/volume.js:65
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:259 ../js/ui/status/volume.js:66
 | 
			
		||||
msgid "Sound Settings"
 | 
			
		||||
msgstr "Thiết lập âm thanh"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:372
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:368
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Authorization request from %s"
 | 
			
		||||
msgstr "Yêu cầu cấp quyền từ %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:378
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:374
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Device %s wants access to the service '%s'"
 | 
			
		||||
msgstr "Thiết bị %s muốn truy cập dịch vụ '%s'"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:380
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:376
 | 
			
		||||
msgid "Always grant access"
 | 
			
		||||
msgstr "Luôn cho phép"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:381
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:377
 | 
			
		||||
msgid "Grant this time only"
 | 
			
		||||
msgstr "Chỉ cho phép lần này"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:382
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:378
 | 
			
		||||
msgid "Reject"
 | 
			
		||||
msgstr "Từ chối"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:412
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:408
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Pairing confirmation for %s"
 | 
			
		||||
msgstr "Xác nhận kết nối cho %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:418 ../js/ui/status/bluetooth.js:452
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:414 ../js/ui/status/bluetooth.js:448
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Device %s wants to pair with this computer"
 | 
			
		||||
msgstr "Thiết bị %s muốn kết nối với máy tính này"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:419
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:415
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Please confirm whether the PIN '%s' matches the one on the device."
 | 
			
		||||
msgstr "Vui lòng xác nhận PIN '%s' khớp với số trên thiết bị."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:421
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:417
 | 
			
		||||
msgid "Matches"
 | 
			
		||||
msgstr "Khớp"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:422
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:418
 | 
			
		||||
msgid "Does not match"
 | 
			
		||||
msgstr "Không khớp"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:445
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:441
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Pairing request for %s"
 | 
			
		||||
msgstr "Yêu cầu kết nối cho %s"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:453
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:449
 | 
			
		||||
msgid "Please enter the PIN mentioned on the device."
 | 
			
		||||
msgstr "Vui lòng nhập số PIN ghi trên thiết bị."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:469
 | 
			
		||||
#: ../js/ui/status/bluetooth.js:465
 | 
			
		||||
msgid "OK"
 | 
			
		||||
msgstr "OK"
 | 
			
		||||
 | 
			
		||||
@@ -795,116 +826,262 @@ msgstr "Hiện bố trí bàn phím..."
 | 
			
		||||
msgid "Localization Settings"
 | 
			
		||||
msgstr "Thiết lập bản địa hoá"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:102 ../js/ui/status/network.js:1393
 | 
			
		||||
#| msgid "Unknown"
 | 
			
		||||
msgid "<unknown>"
 | 
			
		||||
msgstr "<không rõ>"
 | 
			
		||||
 | 
			
		||||
#. Translators: this indicates that wireless or wwan is disabled by hardware killswitch
 | 
			
		||||
#: ../js/ui/status/network.js:295
 | 
			
		||||
#| msgid "Disabled"
 | 
			
		||||
msgid "disabled"
 | 
			
		||||
msgstr "tắt"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:476
 | 
			
		||||
#| msgid "Connection"
 | 
			
		||||
msgid "connecting..."
 | 
			
		||||
msgstr "đang kết nối..."
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for network connections that require some kind of key or password
 | 
			
		||||
#: ../js/ui/status/network.js:479
 | 
			
		||||
msgid "authentication required"
 | 
			
		||||
msgstr "cần xác thực"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for devices that require some kind of firmware or kernel
 | 
			
		||||
#. module, which is missing
 | 
			
		||||
#: ../js/ui/status/network.js:491
 | 
			
		||||
msgid "firmware missing"
 | 
			
		||||
msgstr "thiếu firmware"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for wired network devices that are physically disconnected
 | 
			
		||||
#: ../js/ui/status/network.js:485
 | 
			
		||||
msgid "cable unplugged"
 | 
			
		||||
msgstr "cáp bị tháo"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is for a network device that cannot be activated (for example it
 | 
			
		||||
#. is disabled by rfkill, or it has no coverage
 | 
			
		||||
#: ../js/ui/status/network.js:489
 | 
			
		||||
#| msgid "Available"
 | 
			
		||||
msgid "unavailable"
 | 
			
		||||
msgstr "không có mặt"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:491
 | 
			
		||||
#| msgid "Connection"
 | 
			
		||||
msgid "connection failed"
 | 
			
		||||
msgstr "lỗi kết nối"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
 | 
			
		||||
#. and we cannot access its settings (including the name)
 | 
			
		||||
#: ../js/ui/status/network.js:571 ../js/ui/status/network.js:1341
 | 
			
		||||
msgid "Connected (private)"
 | 
			
		||||
msgstr "Đã kết nối (riêng)"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:636
 | 
			
		||||
msgid "Auto Ethernet"
 | 
			
		||||
msgstr "Ethernet tự động"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:697
 | 
			
		||||
msgid "Auto broadband"
 | 
			
		||||
msgstr "Băng thông rộng tự động"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:700
 | 
			
		||||
msgid "Auto dial-up"
 | 
			
		||||
msgstr "Quay số tự động"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this the automatic wireless connection name (including the network name)
 | 
			
		||||
#: ../js/ui/status/network.js:843 ../js/ui/status/network.js:1353
 | 
			
		||||
#, c-format
 | 
			
		||||
#| msgid "Quit %s"
 | 
			
		||||
msgid "Auto %s"
 | 
			
		||||
msgstr "%s tự động"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:845
 | 
			
		||||
#| msgid "Bluetooth"
 | 
			
		||||
msgid "Auto bluetooth"
 | 
			
		||||
msgstr "Bluetooth tự động"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1355
 | 
			
		||||
msgid "Auto wireless"
 | 
			
		||||
msgstr "Mạng không dây tự động"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1413
 | 
			
		||||
msgid "More..."
 | 
			
		||||
msgstr "Nữa..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1436
 | 
			
		||||
msgid "Enable networking"
 | 
			
		||||
msgstr "Bật nối mạng"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1448
 | 
			
		||||
msgid "Wired"
 | 
			
		||||
msgstr "Mạng dây"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1459
 | 
			
		||||
msgid "Wireless"
 | 
			
		||||
msgstr "Mạng không dây"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1469
 | 
			
		||||
msgid "Mobile broadband"
 | 
			
		||||
msgstr "Mạng băng thông rộng"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1479
 | 
			
		||||
#| msgid "Connection"
 | 
			
		||||
msgid "VPN Connections"
 | 
			
		||||
msgstr "Kết nối VPN"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1488
 | 
			
		||||
#| msgid "Power Settings"
 | 
			
		||||
msgid "Network Settings"
 | 
			
		||||
msgstr "Thiết lập mạng"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1783
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to mobile broadband connection '%s'"
 | 
			
		||||
msgstr "Bạn đã kết nối vào mạng băng thông rộng '%s'"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1787
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to wireless network '%s'"
 | 
			
		||||
msgstr "Bạn đã kết nối vào mạng không dây '%s'"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1791
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to wired network '%s'"
 | 
			
		||||
msgstr "Bạn đã kết nối vào mạng (dây) '%s'"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1795
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to VPN network '%s'"
 | 
			
		||||
msgstr "Bạn đã kết nối vào mạng VPN '%s'"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1800
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "You're now connected to '%s'"
 | 
			
		||||
msgstr "Bạn đã kết nối vào '%s'"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1808
 | 
			
		||||
#| msgid "Connection"
 | 
			
		||||
msgid "Connection established"
 | 
			
		||||
msgstr "Đã tạo kết nối"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:1930
 | 
			
		||||
msgid "Networking is disabled"
 | 
			
		||||
msgstr "Mạng bị tắt"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/network.js:2055
 | 
			
		||||
msgid "Network Manager"
 | 
			
		||||
msgstr "Trình quản lý mạng"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:85
 | 
			
		||||
msgid "Power Settings"
 | 
			
		||||
msgstr "Thiết lập năng lượng"
 | 
			
		||||
 | 
			
		||||
#. 0 is reported when UPower does not have enough data
 | 
			
		||||
#. to estimate battery life
 | 
			
		||||
#: ../js/ui/status/power.js:110
 | 
			
		||||
#: ../js/ui/status/power.js:111
 | 
			
		||||
msgid "Estimating..."
 | 
			
		||||
msgstr "Ước lượng..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:117
 | 
			
		||||
#: ../js/ui/status/power.js:118
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d hour remaining"
 | 
			
		||||
msgid_plural "%d hours remaining"
 | 
			
		||||
msgstr[0] "%d giờ còn lại"
 | 
			
		||||
 | 
			
		||||
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
 | 
			
		||||
#: ../js/ui/status/power.js:120
 | 
			
		||||
#: ../js/ui/status/power.js:121
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d %s %d %s remaining"
 | 
			
		||||
msgstr "%d %s %d %s còn lại"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:122
 | 
			
		||||
#: ../js/ui/status/power.js:123
 | 
			
		||||
msgid "hour"
 | 
			
		||||
msgid_plural "hours"
 | 
			
		||||
msgstr[0] "giờ"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:122
 | 
			
		||||
#: ../js/ui/status/power.js:123
 | 
			
		||||
msgid "minute"
 | 
			
		||||
msgid_plural "minutes"
 | 
			
		||||
msgstr[0] "%d phút"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:125
 | 
			
		||||
#: ../js/ui/status/power.js:126
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d minute remaining"
 | 
			
		||||
msgid_plural "%d minutes remaining"
 | 
			
		||||
msgstr[0] "%d phút còn lại"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:227
 | 
			
		||||
#: ../js/ui/status/power.js:228
 | 
			
		||||
msgid "AC adapter"
 | 
			
		||||
msgstr "Bộ đổi điện AC"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:229
 | 
			
		||||
#: ../js/ui/status/power.js:230
 | 
			
		||||
msgid "Laptop battery"
 | 
			
		||||
msgstr "Pin laptop"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:231
 | 
			
		||||
#: ../js/ui/status/power.js:232
 | 
			
		||||
msgid "UPS"
 | 
			
		||||
msgstr "UPS"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:233
 | 
			
		||||
#: ../js/ui/status/power.js:234
 | 
			
		||||
msgid "Monitor"
 | 
			
		||||
msgstr "Màn hình"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:235
 | 
			
		||||
#: ../js/ui/status/power.js:236
 | 
			
		||||
msgid "Mouse"
 | 
			
		||||
msgstr "Chuột"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:237
 | 
			
		||||
#: ../js/ui/status/power.js:238
 | 
			
		||||
msgid "Keyboard"
 | 
			
		||||
msgstr "Bàn phím"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:239
 | 
			
		||||
#: ../js/ui/status/power.js:240
 | 
			
		||||
msgid "PDA"
 | 
			
		||||
msgstr "PDA"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:241
 | 
			
		||||
#: ../js/ui/status/power.js:242
 | 
			
		||||
msgid "Cell phone"
 | 
			
		||||
msgstr "Điện thoại cầm tay"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:243
 | 
			
		||||
#: ../js/ui/status/power.js:244
 | 
			
		||||
msgid "Media player"
 | 
			
		||||
msgstr "Máy phát"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:245
 | 
			
		||||
#: ../js/ui/status/power.js:246
 | 
			
		||||
msgid "Tablet"
 | 
			
		||||
msgstr "Bảng"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:247
 | 
			
		||||
#: ../js/ui/status/power.js:248
 | 
			
		||||
msgid "Computer"
 | 
			
		||||
msgstr "Máy tính"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/power.js:249 ../src/shell-app-system.c:1013
 | 
			
		||||
#: ../js/ui/status/power.js:250 ../src/shell-app-system.c:1088
 | 
			
		||||
msgid "Unknown"
 | 
			
		||||
msgstr "Không biết"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/volume.js:44
 | 
			
		||||
#: ../js/ui/status/volume.js:45
 | 
			
		||||
msgid "Volume"
 | 
			
		||||
msgstr "Âm lượng"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/status/volume.js:57
 | 
			
		||||
#: ../js/ui/status/volume.js:58
 | 
			
		||||
msgid "Microphone"
 | 
			
		||||
msgstr "Micrô"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:239
 | 
			
		||||
#: ../js/ui/telepathyClient.js:332
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is online."
 | 
			
		||||
msgstr "%s trực tuyến."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:244
 | 
			
		||||
#: ../js/ui/telepathyClient.js:337
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is offline."
 | 
			
		||||
msgstr "%s ngoại tuyến."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:247
 | 
			
		||||
#: ../js/ui/telepathyClient.js:340
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is away."
 | 
			
		||||
msgstr "%s đi vắng."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/telepathyClient.js:250
 | 
			
		||||
#: ../js/ui/telepathyClient.js:343
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is busy."
 | 
			
		||||
msgstr "%s bận."
 | 
			
		||||
@@ -912,7 +1089,7 @@ msgstr "%s bận."
 | 
			
		||||
#. Translators: this is a time format string followed by a date.
 | 
			
		||||
#. If applicable, replace %X with a strftime format valid for your
 | 
			
		||||
#. locale, without seconds.
 | 
			
		||||
#: ../js/ui/telepathyClient.js:348
 | 
			
		||||
#: ../js/ui/telepathyClient.js:474
 | 
			
		||||
#, no-c-format
 | 
			
		||||
msgid "Sent at %X on %A"
 | 
			
		||||
msgstr "Đã gửi %X lúc %A"
 | 
			
		||||
@@ -921,10 +1098,14 @@ msgstr "Đã gửi %X lúc %A"
 | 
			
		||||
#. in the search entry when no search is
 | 
			
		||||
#. active; it should not exceed ~30
 | 
			
		||||
#. characters.
 | 
			
		||||
#: ../js/ui/viewSelector.js:103
 | 
			
		||||
#: ../js/ui/viewSelector.js:122
 | 
			
		||||
msgid "Type to search..."
 | 
			
		||||
msgstr "Nhập để tìm..."
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/viewSelector.js:142 ../src/shell-util.c:250
 | 
			
		||||
msgid "Search"
 | 
			
		||||
msgstr "Tìm"
 | 
			
		||||
 | 
			
		||||
#: ../js/ui/windowAttentionHandler.js:42
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s has finished starting"
 | 
			
		||||
@@ -937,7 +1118,7 @@ msgstr "'%s' đã sẵn sàng"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The number of sound outputs on a particular device
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1094
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1098
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%u Output"
 | 
			
		||||
msgid_plural "%u Outputs"
 | 
			
		||||
@@ -945,44 +1126,62 @@ msgstr[0] "%u đầu ra"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The number of sound inputs on a particular device
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1104
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1108
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%u Input"
 | 
			
		||||
msgid_plural "%u Inputs"
 | 
			
		||||
msgstr[0] "%u đầu vào"
 | 
			
		||||
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1402
 | 
			
		||||
#: ../src/gvc/gvc-mixer-control.c:1406
 | 
			
		||||
msgid "System Sounds"
 | 
			
		||||
msgstr "Âm thanh hệ thống"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1298
 | 
			
		||||
#: ../src/main.c:446
 | 
			
		||||
msgid "Print version"
 | 
			
		||||
msgstr "In phiên bản"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-app.c:454
 | 
			
		||||
#, c-format
 | 
			
		||||
#| msgid "Failed to unmount '%s'"
 | 
			
		||||
msgid "Failed to launch '%s'"
 | 
			
		||||
msgstr "Lỗi chạy '%s'"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1395
 | 
			
		||||
msgid "Less than a minute ago"
 | 
			
		||||
msgstr "Chưa đến một phút"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1302
 | 
			
		||||
#: ../src/shell-global.c:1399
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d minute ago"
 | 
			
		||||
msgid_plural "%d minutes ago"
 | 
			
		||||
msgstr[0] "%d phút trước"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1307
 | 
			
		||||
#: ../src/shell-global.c:1404
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d hour ago"
 | 
			
		||||
msgid_plural "%d hours ago"
 | 
			
		||||
msgstr[0] "%d giờ trước"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1312
 | 
			
		||||
#: ../src/shell-global.c:1409
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d day ago"
 | 
			
		||||
msgid_plural "%d days ago"
 | 
			
		||||
msgstr[0] "%d ngày trước"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-global.c:1317
 | 
			
		||||
#: ../src/shell-global.c:1414
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d week ago"
 | 
			
		||||
msgid_plural "%d weeks ago"
 | 
			
		||||
msgstr[0] "%d tuần trước"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-mobile-providers.c:80
 | 
			
		||||
msgid "United Kingdom"
 | 
			
		||||
msgstr "Vương quốc Anh"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-mobile-providers.c:526
 | 
			
		||||
msgid "Default"
 | 
			
		||||
msgstr "Mặc định"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-polkit-authentication-agent.c:334
 | 
			
		||||
msgid "Authentication dialog was dismissed by the user"
 | 
			
		||||
msgstr "Hộp thoại xác thực bị người dùng bỏ qua"
 | 
			
		||||
@@ -997,10 +1196,6 @@ msgstr "Thư mục chính"
 | 
			
		||||
msgid "File System"
 | 
			
		||||
msgstr "Hệ tập tin"
 | 
			
		||||
 | 
			
		||||
#: ../src/shell-util.c:250
 | 
			
		||||
msgid "Search"
 | 
			
		||||
msgstr "Tìm"
 | 
			
		||||
 | 
			
		||||
#. Translators: the first string is the name of a gvfs
 | 
			
		||||
#. * method, and the second string is a path. For
 | 
			
		||||
#. * example, "Trash: some-directory". It means that the
 | 
			
		||||
@@ -1011,6 +1206,30 @@ msgstr "Tìm"
 | 
			
		||||
msgid "%1$s: %2$s"
 | 
			
		||||
msgstr "%1$s: %2$s"
 | 
			
		||||
 | 
			
		||||
#~ msgid "No such application"
 | 
			
		||||
#~ msgstr "Không có ứng dụng đó"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Shut Down"
 | 
			
		||||
#~ msgstr "Tắt máy"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Click Shut Down to quit these applications and shut down the system."
 | 
			
		||||
#~ msgstr "Nhấn Tắt máy để thoát những ứng dụng này và tắt hệ thống."
 | 
			
		||||
 | 
			
		||||
#~ msgid "The system will shut down automatically in %d seconds."
 | 
			
		||||
#~ msgstr "Hệ thống sẽ tự động tắt sau %d giây."
 | 
			
		||||
 | 
			
		||||
#~ msgid "Shutting down the system."
 | 
			
		||||
#~ msgstr "Tắt hệ thống."
 | 
			
		||||
 | 
			
		||||
#~ msgid "Confirm"
 | 
			
		||||
#~ msgstr "Xác nhận"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Screen Reader"
 | 
			
		||||
#~ msgstr "Trình đọc màn hình"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Screen Keyboard"
 | 
			
		||||
#~ msgstr "Bàn phím màn hình"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Clip the crosshairs at the center"
 | 
			
		||||
#~ msgstr "Cắt lưới chéo ở giữa"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user