Compare commits
	
		
			27 Commits
		
	
	
		
			3.7.3
			...
			wip/re-sea
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					3124e82838 | ||
| 
						 | 
					6c4daaaa71 | ||
| 
						 | 
					3768e85673 | ||
| 
						 | 
					d1c72e1e4c | ||
| 
						 | 
					2498497cc1 | ||
| 
						 | 
					7c3c6da368 | ||
| 
						 | 
					09e7ab5611 | ||
| 
						 | 
					53cff07eef | ||
| 
						 | 
					cfed6e401d | ||
| 
						 | 
					12b041a569 | ||
| 
						 | 
					f2dd94776c | ||
| 
						 | 
					c0f9c52ba6 | ||
| 
						 | 
					2ee8b0e427 | ||
| 
						 | 
					b250a72fcf | ||
| 
						 | 
					cf08745f6c | ||
| 
						 | 
					58023c81ad | ||
| 
						 | 
					7e8968da52 | ||
| 
						 | 
					fce1d8157e | ||
| 
						 | 
					3b5de01ed6 | ||
| 
						 | 
					a61da42aa7 | ||
| 
						 | 
					81acfdbfc3 | ||
| 
						 | 
					159b789443 | ||
| 
						 | 
					c07b715a3a | ||
| 
						 | 
					1bb09fd0f1 | ||
| 
						 | 
					4441541da6 | ||
| 
						 | 
					afee4d6925 | ||
| 
						 | 
					b62bd0e62f | 
@@ -16,7 +16,6 @@ EXTRA_DIST =		\
 | 
			
		||||
# These are files checked into Git that we don't want to distribute
 | 
			
		||||
DIST_EXCLUDE =					\
 | 
			
		||||
	.gitignore				\
 | 
			
		||||
	.gitmodules				\
 | 
			
		||||
	gnome-shell.doap			\
 | 
			
		||||
	HACKING					\
 | 
			
		||||
	MAINTAINERS				\
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										57
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								NEWS
									
									
									
									
									
								
							@@ -1,60 +1,3 @@
 | 
			
		||||
3.7.3
 | 
			
		||||
=====
 | 
			
		||||
* Add 'No Messages' label when message tray is empty [Victoria; #686738]
 | 
			
		||||
* Use better icons in Ctrl-Alt-Tab popup [Stéphane; #641303]
 | 
			
		||||
* Show the OSK on the monitor where the focused window lives [Giovanni; #685856]
 | 
			
		||||
* Highlight window clone and caption when hovered [Giovanni, Marc; #665310]
 | 
			
		||||
* Improve login process indication [Stéphane; #687113]
 | 
			
		||||
* Omit empty categories in apps view [Stéphane; #687970]
 | 
			
		||||
* Style panel differently according to mode [Florian; #684573]
 | 
			
		||||
* Make it possible to hide the user name [Matthias; #688577]
 | 
			
		||||
* Consolidate and improve chat connection notifications [Giovanni; #687213]
 | 
			
		||||
* Improve notification scrollbar appearance [Carlos; #688393]
 | 
			
		||||
* Fade scroll view fade near scrolling edges [Jasper; #689249]
 | 
			
		||||
* Add a read-only org.gnome.Shell.Mode property [Debarshi; #689300]
 | 
			
		||||
* Don't close message tray after using context menus [Giovanni; #689296]
 | 
			
		||||
* Port swipe-scrolling to ClutterPanAction [Jasper, Florian; #689062, #689552]
 | 
			
		||||
* Remember state of 'Remember Password' checkbox [Ron; #688039]
 | 
			
		||||
* Improve timestamp format in chat notifications [Carlos; #680989]
 | 
			
		||||
* Improve style of missed-messages counter [Carlos; #686472]
 | 
			
		||||
* Omit connection failure notifications if cancelled by user [Giovanni; #684823]
 | 
			
		||||
* Add window-based Alt-Tab popup [Florian; #688913]
 | 
			
		||||
* Support external session mode definitions [Florian; #689304]
 | 
			
		||||
* Support session-mode-specific extensions [Florian; #689305]
 | 
			
		||||
* Support 'parentMode' property in session modes [Florian; #689308]
 | 
			
		||||
* Support a new org.gnome.ShellSearchProvider2 DBus interface
 | 
			
		||||
  [Cosimo; #689735, #690009]
 | 
			
		||||
* Add "windows" to Ctrl-Alt-Tab popup [Jasper; #689653]
 | 
			
		||||
* Port PopupMenu to GrabHelper [Jasper; #689109, #689954]
 | 
			
		||||
* Show headphone icon when headphones are plugged in [Giovanni; #675902]
 | 
			
		||||
* Display (non-app) search results as list [Tanner, Cosimo; #681797]
 | 
			
		||||
* Skip diacritical marks in search terms [Aleksander; #648587]
 | 
			
		||||
* Expose all engine options in input sources [Giovanni, Rui; #682318]
 | 
			
		||||
* Add input source switcher popup [Rui; #682315]
 | 
			
		||||
* Add minimal support for InfiniBand in network menu [Dan; #677150]
 | 
			
		||||
* Misc bug fixes and cleanups [Sebastian, Aleksander, Giovanni, Tim, Cosimo,
 | 
			
		||||
  Florian, Matthias, Rui, Lionel, Colin, Piotr, Guillaume, Bastien, Tanner,
 | 
			
		||||
  Carlos, Stéphane, Jakub; #688422, #688379, #688750, #688771, #686800,
 | 
			
		||||
  #688133, #688895, #688966, #683986, #688004, #689108, #689029, #683449,
 | 
			
		||||
  #688196, #689304, #689243, #689295, #689325, #689400, #679168, #689568,
 | 
			
		||||
  #689537, #689528, #689749, #689789, #689353, #689820, #689868, #689778,
 | 
			
		||||
  #689959, #688589, #688589, #689955, #687250, #689965, #690046, #690049,
 | 
			
		||||
  #689884, #682286, #690173, #690174, #672941, #689876, #687881, #690171,
 | 
			
		||||
  #690241, #690312, #690175, #687955, #650843, #688234, #690427
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Giovanni Campagna, Cosimo Cecchi, Matthias Clasen, Stéphane Démurget,
 | 
			
		||||
  Guillaume Desmottes, Tanner Doshier, Piotr Drąg, Sebastian Keller,
 | 
			
		||||
  Lionel Landwerlin, Tim Lunn, Victoria Martínez de la Cruz, Aleksander Morgado,
 | 
			
		||||
  Florian Müllner, Bastien Nocera, Marc Plano-Lesay, Carlos Soriano Sánchez,
 | 
			
		||||
  Jakub Steiner, Jasper St. Pierre, Colin Walters, Dan Winship, Ron Yorston
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Yuri Myasoedov [ru], Wouter Bolsterlee [nl], Yaron Shahrabani [he],
 | 
			
		||||
  Nilamdyuti Goswami [as], Ani Peter [ml], Kjartan Maraas [nb],
 | 
			
		||||
  Dr.T.Vasudevan [ta], A S Alam [pa], Shankar Prasad [kn], Khaled Hosny [ar],
 | 
			
		||||
  Daniel Mustieles [es], Dušan Kazik [sk]
 | 
			
		||||
 | 
			
		||||
3.7.2
 | 
			
		||||
=====
 | 
			
		||||
* Enforce RTL in he for messages that might end up as LTR [Florian; #686630]
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
AC_PREREQ(2.63)
 | 
			
		||||
AC_INIT([gnome-shell],[3.7.3],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
 | 
			
		||||
AC_INIT([gnome-shell],[3.7.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
 | 
			
		||||
 | 
			
		||||
AC_CONFIG_HEADERS([config.h])
 | 
			
		||||
AC_CONFIG_SRCDIR([src/shell-global.c])
 | 
			
		||||
@@ -65,7 +65,7 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
 | 
			
		||||
CLUTTER_MIN_VERSION=1.11.11
 | 
			
		||||
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
 | 
			
		||||
GJS_MIN_VERSION=1.33.2
 | 
			
		||||
MUTTER_MIN_VERSION=3.7.3
 | 
			
		||||
MUTTER_MIN_VERSION=3.7.2
 | 
			
		||||
GTK_MIN_VERSION=3.3.9
 | 
			
		||||
GIO_MIN_VERSION=2.35.0
 | 
			
		||||
LIBECAL_MIN_VERSION=3.5.3
 | 
			
		||||
@@ -79,7 +79,6 @@ GCR_MIN_VERSION=3.3.90
 | 
			
		||||
GNOME_DESKTOP_REQUIRED_VERSION=3.7.1
 | 
			
		||||
GNOME_MENUS_REQUIRED_VERSION=3.5.3
 | 
			
		||||
NETWORKMANAGER_MIN_VERSION=0.9.7
 | 
			
		||||
PULSE_MIN_VERS=2.0
 | 
			
		||||
 | 
			
		||||
# Collect more than 20 libraries for a prize!
 | 
			
		||||
PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
 | 
			
		||||
@@ -126,8 +125,8 @@ LIBS=$saved_LIBS
 | 
			
		||||
PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
 | 
			
		||||
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
 | 
			
		||||
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
 | 
			
		||||
PKG_CHECK_MODULES(GVC, libpulse >= $PULSE_MIN_VERS libpulse-mainloop-glib gobject-2.0)
 | 
			
		||||
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.7.2.2)
 | 
			
		||||
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
 | 
			
		||||
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.7.2)
 | 
			
		||||
 | 
			
		||||
AC_MSG_CHECKING([for bluetooth support])
 | 
			
		||||
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],
 | 
			
		||||
 
 | 
			
		||||
@@ -558,10 +558,6 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
    spacing: 4px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.lock-screen-status-button-box {
 | 
			
		||||
    spacing: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* User Menu */
 | 
			
		||||
 | 
			
		||||
#panelUserMenu {
 | 
			
		||||
@@ -617,25 +613,17 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
/* Overview */
 | 
			
		||||
 | 
			
		||||
#overview {
 | 
			
		||||
    spacing: 24px;
 | 
			
		||||
    spacing: 40px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#overview-group {
 | 
			
		||||
    spacing: 32px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.workspaces-display {
 | 
			
		||||
    spacing: 32px; /* needs to be the same value as #overview-group */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.window-caption {
 | 
			
		||||
    spacing: 25px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.workspace-controls {
 | 
			
		||||
    visible-width: 32px; /* Amount visible before hovering */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.workspace-thumbnails-background {
 | 
			
		||||
    border: 1px solid rgba(128, 128, 128, 0.4);
 | 
			
		||||
    border-right: 0px;
 | 
			
		||||
@@ -653,6 +641,7 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
 | 
			
		||||
.workspace-thumbnails {
 | 
			
		||||
    spacing: 11px;
 | 
			
		||||
    visible-width: 96px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.workspace-thumbnail-indicator {
 | 
			
		||||
@@ -714,8 +703,8 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.window-picker {
 | 
			
		||||
    -horizontal-spacing: 32px;
 | 
			
		||||
    -vertical-spacing: 32px;
 | 
			
		||||
    -horizontal-spacing: 40px;
 | 
			
		||||
    -vertical-spacing: 40px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Dash */
 | 
			
		||||
@@ -766,18 +755,15 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
/* Search Results */
 | 
			
		||||
 | 
			
		||||
#searchResults {
 | 
			
		||||
    padding: 20px 10px 10px 10px;
 | 
			
		||||
    spacing: 18px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#searchResultsContent {
 | 
			
		||||
    padding-right: 20px;
 | 
			
		||||
    spacing: 16px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#searchResultsContent:rtl {
 | 
			
		||||
    padding-right: 0px;
 | 
			
		||||
    /* for scrollbars */
 | 
			
		||||
    padding-left: 20px;
 | 
			
		||||
    padding-right: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.search-section {
 | 
			
		||||
@@ -847,15 +833,10 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.all-app {
 | 
			
		||||
    padding: 16px 25px 16px 16px;
 | 
			
		||||
    padding: 16px;
 | 
			
		||||
    spacing: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.all-app:rtl {
 | 
			
		||||
    padding-right: 16px;
 | 
			
		||||
    padding-left: 25px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.app-filter {
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    height: 2.85em;
 | 
			
		||||
@@ -1317,10 +1298,6 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
    outline: 1px solid rgba(128, 128, 128, 0.3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.message-tray-summary {
 | 
			
		||||
    height: 72px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.no-messages-label {
 | 
			
		||||
    font-family: cantarell, sans-serif;
 | 
			
		||||
    font-size: 11pt;
 | 
			
		||||
@@ -1329,7 +1306,7 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
 | 
			
		||||
.notification {
 | 
			
		||||
    border-radius: 10px 10px 0px 0px;
 | 
			
		||||
    background: rgba(0,0,0,0.9);
 | 
			
		||||
    background: rgba(0,0,0,0.8);
 | 
			
		||||
    padding: 8px 8px 4px 8px;
 | 
			
		||||
    spacing-rows: 10px;
 | 
			
		||||
    spacing-columns: 10px;
 | 
			
		||||
@@ -1361,7 +1338,7 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
 | 
			
		||||
.summary-boxpointer {
 | 
			
		||||
    -arrow-border-radius: 15px;
 | 
			
		||||
    -arrow-background-color: rgba(0,0,0,0.9);
 | 
			
		||||
    -arrow-background-color: rgba(0,0,0,0.8);
 | 
			
		||||
    -arrow-base: 36px;
 | 
			
		||||
    -arrow-rise: 18px;
 | 
			
		||||
    color: white;
 | 
			
		||||
@@ -1549,6 +1526,10 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#summary-mode {
 | 
			
		||||
    height: 72px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-source-button {
 | 
			
		||||
    padding: 6px 3px 6px 3px;
 | 
			
		||||
}
 | 
			
		||||
@@ -2435,8 +2416,3 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
    padding-bottom: 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.input-source-switcher-symbol {
 | 
			
		||||
   font-size: 42pt;
 | 
			
		||||
   width: 96px;
 | 
			
		||||
   height: 96px;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
   height="16"
 | 
			
		||||
   id="svg12430"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.48.3.1 r9886"
 | 
			
		||||
   inkscape:version="0.48+devel r11908 custom"
 | 
			
		||||
   sodipodi:docname="more-results.svg">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs12432" />
 | 
			
		||||
@@ -26,8 +26,8 @@
 | 
			
		||||
     inkscape:pageopacity="1"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="1"
 | 
			
		||||
     inkscape:cx="8.3155237"
 | 
			
		||||
     inkscape:cy="0.89548874"
 | 
			
		||||
     inkscape:cx="7.4498765"
 | 
			
		||||
     inkscape:cy="9.9072581"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="g14642-3-0"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
@@ -35,8 +35,8 @@
 | 
			
		||||
     inkscape:showpageshadow="false"
 | 
			
		||||
     inkscape:window-width="2560"
 | 
			
		||||
     inkscape:window-height="1376"
 | 
			
		||||
     inkscape:window-x="1200"
 | 
			
		||||
     inkscape:window-y="187"
 | 
			
		||||
     inkscape:window-x="1600"
 | 
			
		||||
     inkscape:window-y="27"
 | 
			
		||||
     inkscape:window-maximized="1">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
@@ -50,7 +50,7 @@
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
@@ -69,27 +69,11 @@
 | 
			
		||||
         inkscape:radius="0"
 | 
			
		||||
         inkscape:original="M 145.1875 400 C 144.5248 400 144 400.54899 144 401.21875 L 144 410.78125 C 144 411.45101 144.5248 412 145.1875 412 L 154.8125 412 C 155.4752 412 156 411.45101 156 410.78125 L 156 401.21875 C 156 400.54899 155.4752 400 154.8125 400 L 145.1875 400 z M 149 403 L 151 403 L 151 405 L 153 405 L 153 407 L 151 407 L 151 409 L 149 409 L 149 407 L 147 407 L 147 405 L 149 405 L 149 403 z "
 | 
			
		||||
         xlink:href="#rect11749-5-0-1-8"
 | 
			
		||||
         style="color:#bebebe;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;opacity:0.8"
 | 
			
		||||
         style="color:#bebebe;fill:#000000;fill-opacity:0.38207546;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible"
 | 
			
		||||
         id="path13004"
 | 
			
		||||
         inkscape:href="#rect11749-5-0-1-8"
 | 
			
		||||
         d="M 145.1875,400 C 144.5248,400 144,400.54899 144,401.21875 l 0,9.5625 c 0,0.66976 0.5248,1.21875 1.1875,1.21875 l 9.625,0 c 0.6627,0 1.1875,-0.54899 1.1875,-1.21875 l 0,-9.5625 C 156,400.54899 155.4752,400 154.8125,400 L 145.1875,400 z m 3.8125,3 2,0 0,2 2,0 0,2 -2,0 0,2 -2,0 0,-2 -2,0 0,-2 2,0 L 149,403 Z"
 | 
			
		||||
         transform="translate(0,1)" />
 | 
			
		||||
      <use
 | 
			
		||||
         x="0"
 | 
			
		||||
         y="0"
 | 
			
		||||
         xlink:href="#path13004"
 | 
			
		||||
         id="use11960"
 | 
			
		||||
         transform="translate(1,-1)"
 | 
			
		||||
         width="16"
 | 
			
		||||
         height="16" />
 | 
			
		||||
      <use
 | 
			
		||||
         x="0"
 | 
			
		||||
         y="0"
 | 
			
		||||
         xlink:href="#use11960"
 | 
			
		||||
         id="use11962"
 | 
			
		||||
         transform="translate(-2,0)"
 | 
			
		||||
         width="16"
 | 
			
		||||
         height="16" />
 | 
			
		||||
      <path
 | 
			
		||||
         inkscape:connector-curvature="0"
 | 
			
		||||
         style="color:#bebebe;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible"
 | 
			
		||||
 
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 3.7 KiB  | 
@@ -41,6 +41,7 @@ nobase_dist_js_DATA = 	\
 | 
			
		||||
	ui/boxpointer.js	\
 | 
			
		||||
	ui/calendar.js		\
 | 
			
		||||
	ui/checkBox.js		\
 | 
			
		||||
	ui/centerLayout.js	\
 | 
			
		||||
	ui/ctrlAltTab.js	\
 | 
			
		||||
	ui/dash.js		\
 | 
			
		||||
	ui/dateMenu.js		\
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ const Mainloop = imports.mainloop;
 | 
			
		||||
const Shell = imports.gi.Shell;
 | 
			
		||||
 | 
			
		||||
const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
 | 
			
		||||
const WEEKDATE_HEADER_WIDTH_DIGITS = 3;
 | 
			
		||||
const SHOW_WEEKDATE_KEY = 'show-weekdate';
 | 
			
		||||
 | 
			
		||||
// in org.gnome.desktop.interface
 | 
			
		||||
@@ -94,6 +95,15 @@ function _getCalendarWeekForDate(date) {
 | 
			
		||||
    return weekNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _getDigitWidth(actor){
 | 
			
		||||
    let context = actor.get_pango_context();
 | 
			
		||||
    let themeNode = actor.get_theme_node();
 | 
			
		||||
    let font = themeNode.get_font();
 | 
			
		||||
    let metrics = context.get_metrics(font, context.get_language());
 | 
			
		||||
    let width = metrics.get_approximate_digit_width();
 | 
			
		||||
    return width;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _getCalendarDayAbbreviation(dayNumber) {
 | 
			
		||||
    let abbreviations = [
 | 
			
		||||
        /* Translators: Calendar grid abbreviation for Sunday.
 | 
			
		||||
@@ -335,6 +345,8 @@ const Calendar = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this._weekStart = Shell.util_get_week_start();
 | 
			
		||||
        this._weekdate = NaN;
 | 
			
		||||
        this._digitWidth = NaN;
 | 
			
		||||
        this._settings = new Gio.Settings({ schema: 'org.gnome.shell.calendar' });
 | 
			
		||||
 | 
			
		||||
        this._settings.connect('changed::' + SHOW_WEEKDATE_KEY, Lang.bind(this, this._onSettingsChange));
 | 
			
		||||
@@ -407,6 +419,8 @@ const Calendar = new Lang.Class({
 | 
			
		||||
        this.actor.add(this._topBox,
 | 
			
		||||
                       { row: 0, col: 0, col_span: offsetCols + 7 });
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('style-changed', Lang.bind(this, this._onStyleChange));
 | 
			
		||||
 | 
			
		||||
        let back = new St.Button({ style_class: 'calendar-change-month-back' });
 | 
			
		||||
        this._topBox.add(back);
 | 
			
		||||
        back.connect('clicked', Lang.bind(this, this._onPrevMonthButtonClicked));
 | 
			
		||||
@@ -443,6 +457,18 @@ const Calendar = new Lang.Class({
 | 
			
		||||
        this._firstDayIndex = this.actor.get_n_children();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onStyleChange: function(actor, event) {
 | 
			
		||||
        // width of a digit in pango units
 | 
			
		||||
        this._digitWidth = _getDigitWidth(this.actor) / Pango.SCALE;
 | 
			
		||||
        this._setWeekdateHeaderWidth();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setWeekdateHeaderWidth: function() {
 | 
			
		||||
        if (this.digitWidth != NaN && this._useWeekdate && this._weekdateHeader) {
 | 
			
		||||
            this._weekdateHeader.set_width (this._digitWidth * WEEKDATE_HEADER_WIDTH_DIGITS);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onScroll : function(actor, event) {
 | 
			
		||||
        switch (event.get_scroll_direction()) {
 | 
			
		||||
        case Clutter.ScrollDirection.UP:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										60
									
								
								js/ui/centerLayout.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								js/ui/centerLayout.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
 | 
			
		||||
const Lang = imports.lang;
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
 | 
			
		||||
const CenterLayout = new Lang.Class({
 | 
			
		||||
    Name: 'CenterLayout',
 | 
			
		||||
    Extends: Clutter.BoxLayout,
 | 
			
		||||
 | 
			
		||||
    vfunc_allocate: function(container, box, flags) {
 | 
			
		||||
        let rtl = container.get_text_direction() == Clutter.TextDirection.RTL;
 | 
			
		||||
 | 
			
		||||
        let availWidth = box.x2 - box.x1;
 | 
			
		||||
        let availHeight = box.y2 - box.y1;
 | 
			
		||||
 | 
			
		||||
        // Assume that these are the first three widgets and they are all visible.
 | 
			
		||||
        let [left, center, right] = container.get_children();
 | 
			
		||||
 | 
			
		||||
        // Only support horizontal layouts for now.
 | 
			
		||||
        let [leftMinWidth, leftNaturalWidth] = left.get_preferred_width(availHeight);
 | 
			
		||||
        let [centerMinWidth, centerNaturalWidth] = center.get_preferred_width(availHeight);
 | 
			
		||||
        let [rightMinWidth, rightNaturalWidth] = right.get_preferred_width(availHeight);
 | 
			
		||||
 | 
			
		||||
        let sideWidth = (availWidth - centerMinWidth) / 2;
 | 
			
		||||
 | 
			
		||||
        let childBox = new Clutter.ActorBox();
 | 
			
		||||
        childBox.y1 = box.y1;
 | 
			
		||||
        childBox.y2 = box.y1 + availHeight;
 | 
			
		||||
 | 
			
		||||
        let leftSide = Math.min(Math.floor(sideWidth), leftNaturalWidth);
 | 
			
		||||
        let rightSide = Math.min(Math.floor(sideWidth), rightNaturalWidth);
 | 
			
		||||
 | 
			
		||||
        if (rtl) {
 | 
			
		||||
            childBox.x1 = availWidth - leftSide;
 | 
			
		||||
            childBox.x2 = availWidth;
 | 
			
		||||
        } else {
 | 
			
		||||
            childBox.x1 = 0;
 | 
			
		||||
            childBox.x2 = leftSide;
 | 
			
		||||
        }
 | 
			
		||||
        childBox.x1 += box.x1;
 | 
			
		||||
        left.allocate(childBox, flags);
 | 
			
		||||
 | 
			
		||||
        let maxSide = Math.max(leftSide, rightSide);
 | 
			
		||||
        let sideWidth = Math.max((availWidth - centerNaturalWidth) / 2, maxSide);
 | 
			
		||||
 | 
			
		||||
        childBox.x1 = box.x1 + Math.ceil(sideWidth);
 | 
			
		||||
        childBox.x2 = box.x2 - Math.ceil(sideWidth);
 | 
			
		||||
        center.allocate(childBox, flags);
 | 
			
		||||
 | 
			
		||||
        if (rtl) {
 | 
			
		||||
            childBox.x1 = 0;
 | 
			
		||||
            childBox.x2 = rightSide;
 | 
			
		||||
        } else {
 | 
			
		||||
            childBox.x1 = availWidth - rightSide;
 | 
			
		||||
            childBox.x2 = availWidth;
 | 
			
		||||
        }
 | 
			
		||||
        childBox.x1 += box.x1;
 | 
			
		||||
        right.allocate(childBox, flags);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -613,8 +613,7 @@ const NetworkAgent = new Lang.Class({
 | 
			
		||||
        this._vpnRequests = { };
 | 
			
		||||
 | 
			
		||||
        this._native.auto_register = false;
 | 
			
		||||
        if (this._native.registered)
 | 
			
		||||
            this._native.unregister();
 | 
			
		||||
        this._native.unregister();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _newRequest:  function(agent, requestId, connection, settingName, hints, flags) {
 | 
			
		||||
 
 | 
			
		||||
@@ -102,7 +102,8 @@ const CtrlAltTabManager = new Lang.Class({
 | 
			
		||||
                    icon = app.create_icon_texture(POPUP_APPICON_SIZE);
 | 
			
		||||
                else
 | 
			
		||||
                    icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
 | 
			
		||||
                items.push({ name: windows[i].title,
 | 
			
		||||
                items.push({ window: windows[i],
 | 
			
		||||
                             name: windows[i].title,
 | 
			
		||||
                             iconActor: icon,
 | 
			
		||||
                             sortGroup: SortGroup.MIDDLE });
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -371,6 +371,7 @@ const Dash = new Lang.Class({
 | 
			
		||||
        this._maxHeight = -1;
 | 
			
		||||
        this.iconSize = 64;
 | 
			
		||||
        this._shownInitially = false;
 | 
			
		||||
        this._ignoreHeight = false;
 | 
			
		||||
 | 
			
		||||
        this._dragPlaceholder = null;
 | 
			
		||||
        this._dragPlaceholderPos = -1;
 | 
			
		||||
@@ -396,7 +397,10 @@ const Dash = new Lang.Class({
 | 
			
		||||
        this.actor = new St.Bin({ child: this._container });
 | 
			
		||||
        this.actor.connect('notify::height', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                if (this._maxHeight != this.actor.height)
 | 
			
		||||
                if (this._ignoreHeight)
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                if (this._maxHeight != this.actor.height);
 | 
			
		||||
                    this._queueRedisplay();
 | 
			
		||||
                this._maxHeight = this.actor.height;
 | 
			
		||||
            }));
 | 
			
		||||
@@ -421,6 +425,8 @@ const Dash = new Lang.Class({
 | 
			
		||||
                              Lang.bind(this, this._onDragCancelled));
 | 
			
		||||
        Main.overview.connect('window-drag-end',
 | 
			
		||||
                              Lang.bind(this, this._onDragEnd));
 | 
			
		||||
        Main.overview.connect('showing',
 | 
			
		||||
                              Lang.bind(this, this._onOverviewShowing));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragBegin: function() {
 | 
			
		||||
@@ -923,6 +929,65 @@ const Dash = new Lang.Class({
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _computeTranslation: function() {
 | 
			
		||||
        let rtl = (this.actor.get_text_direction() == Clutter.TextDirection.RTL);
 | 
			
		||||
 | 
			
		||||
        if (rtl)
 | 
			
		||||
            return this.actor.width;
 | 
			
		||||
        else
 | 
			
		||||
            return - this.actor.width;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onOverviewShowing: function() {
 | 
			
		||||
        // reset any translation and make sure the actor is visible when
 | 
			
		||||
        // entering the overview
 | 
			
		||||
        this.slideX = 0;
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get slideX() {
 | 
			
		||||
        return this._slideX;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    set slideX(value) {
 | 
			
		||||
        this._slideX = value;
 | 
			
		||||
        this.actor.translation_x = this._slideX;
 | 
			
		||||
 | 
			
		||||
        if (this._slideX > 0) {
 | 
			
		||||
            let rect = new Clutter.Rect();
 | 
			
		||||
            rect.size.width = this.actor.width - this._slideX;
 | 
			
		||||
            rect.size.height = this.actor.height;
 | 
			
		||||
            this.actor.clip_rect = rect;
 | 
			
		||||
        } else {
 | 
			
		||||
            this.actor.clip_rect = null;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    show: function() {
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
        Tweener.addTween(this, { slideX: 0,
 | 
			
		||||
                                 transition: 'easeOutQuad',
 | 
			
		||||
                                 time: DASH_ANIMATION_TIME,
 | 
			
		||||
                                 onComplete: Lang.bind(this,
 | 
			
		||||
                                     function() {
 | 
			
		||||
                                         this._ignoreHeight = false;
 | 
			
		||||
                                     })
 | 
			
		||||
                               });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hide: function() {
 | 
			
		||||
        this._ignoreHeight = true;
 | 
			
		||||
        let hiddenX = this._computeTranslation();
 | 
			
		||||
        Tweener.addTween(this, { slideX: hiddenX,
 | 
			
		||||
                                 transition: 'easeOutQuad',
 | 
			
		||||
                                 time: DASH_ANIMATION_TIME,
 | 
			
		||||
                                 onComplete: Lang.bind(this,
 | 
			
		||||
                                 function() {
 | 
			
		||||
                                     this.actor.hide();
 | 
			
		||||
                                 })
 | 
			
		||||
                               });
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -129,7 +129,6 @@ function logExtensionError(uuid, error) {
 | 
			
		||||
    extension.state = ExtensionState.ERROR;
 | 
			
		||||
    if (!extension.errors)
 | 
			
		||||
        extension.errors = [];
 | 
			
		||||
    extension.errors.push(message);
 | 
			
		||||
 | 
			
		||||
    log('Extension "%s" had error: %s'.format(uuid, message));
 | 
			
		||||
    _signals.emit('extension-state-changed', { uuid: uuid,
 | 
			
		||||
 
 | 
			
		||||
@@ -23,8 +23,6 @@ const BaseIcon = new Lang.Class({
 | 
			
		||||
        this.actor._delegate = this;
 | 
			
		||||
        this.actor.connect('style-changed',
 | 
			
		||||
                           Lang.bind(this, this._onStyleChanged));
 | 
			
		||||
        this.actor.connect('destroy',
 | 
			
		||||
                           Lang.bind(this, this._onDestroy));
 | 
			
		||||
 | 
			
		||||
        this._spacing = 0;
 | 
			
		||||
 | 
			
		||||
@@ -54,9 +52,6 @@ const BaseIcon = new Lang.Class({
 | 
			
		||||
        this._setSizeManually = params.setSizeManually;
 | 
			
		||||
 | 
			
		||||
        this.icon = null;
 | 
			
		||||
 | 
			
		||||
        let cache = St.TextureCache.get_default();
 | 
			
		||||
        this._iconThemeChangedId = cache.connect('icon-theme-changed', Lang.bind(this, this._onIconThemeChanged));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _allocate: function(actor, box, flags) {
 | 
			
		||||
@@ -151,22 +146,7 @@ const BaseIcon = new Lang.Class({
 | 
			
		||||
            size = found ? len : ICON_SIZE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.iconSize == size && this._iconBin.child)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._createIconTexture(size);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
        if (this._iconThemeChangedId > 0) {
 | 
			
		||||
            let cache = St.TextureCache.get_default();
 | 
			
		||||
            cache.disconnect(this._iconThemeChangedId);
 | 
			
		||||
            this._iconThemeChangedId = 0;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onIconThemeChanged: function() {
 | 
			
		||||
        this._createIconTexture(this.iconSize);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -325,7 +325,7 @@ const LayoutManager = new Lang.Class({
 | 
			
		||||
        } else {
 | 
			
		||||
            let focusWindow = global.display.focus_window;
 | 
			
		||||
            if (focusWindow)
 | 
			
		||||
                i = this._chrome.findIndexForWindow(focusWindow);
 | 
			
		||||
                i = this._chrome.findIndexForWindow(focusWindow.get_compositor_private());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return i;
 | 
			
		||||
@@ -513,11 +513,7 @@ const LayoutManager = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
    findMonitorForActor: function(actor) {
 | 
			
		||||
        return this.monitors[this._chrome.findIndexForActor(actor)];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    findMonitorForWindow: function(window) {
 | 
			
		||||
        return this.monitors[this._chrome.findIndexForWindow(window)];
 | 
			
		||||
    },
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
Signals.addSignalMethods(LayoutManager.prototype);
 | 
			
		||||
 | 
			
		||||
@@ -895,8 +891,7 @@ const Chrome = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    findIndexForWindow: function(window) {
 | 
			
		||||
        let rect = window.get_input_rect();
 | 
			
		||||
        let i = this._findMonitorForRect(rect.x, rect.y, rect.width, rect.height);
 | 
			
		||||
        let i = this._findMonitorForRect(window.x, window.y, window.width, window.height);
 | 
			
		||||
        if (i >= 0)
 | 
			
		||||
            return i;
 | 
			
		||||
        return this._primaryIndex; // Not on any monitor, pretend its on the primary
 | 
			
		||||
@@ -914,8 +909,7 @@ const Chrome = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    findMonitorForWindow: function(window) {
 | 
			
		||||
        let rect = window.get_input_rect();
 | 
			
		||||
        let i = this._findMonitorForRect(rect.x, rect.y, rect.width, rect.height);
 | 
			
		||||
        let i = this._findMonitorForRect(window.x, window.y, window.width, window.height);
 | 
			
		||||
        if (i >= 0)
 | 
			
		||||
            return this._monitors[i];
 | 
			
		||||
        else
 | 
			
		||||
@@ -964,15 +958,14 @@ const Chrome = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        for (let i = windows.length - 1; i > -1; i--) {
 | 
			
		||||
            let window = windows[i];
 | 
			
		||||
            let metaWindow = window.meta_window;
 | 
			
		||||
            let layer = metaWindow.get_layer();
 | 
			
		||||
            let layer = window.get_meta_window().get_layer();
 | 
			
		||||
 | 
			
		||||
            // Skip minimized windows
 | 
			
		||||
            if (!window.showing_on_its_workspace())
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            if (layer == Meta.StackLayer.FULLSCREEN) {
 | 
			
		||||
                let monitor = this.findMonitorForWindow(metaWindow);
 | 
			
		||||
                let monitor = this.findMonitorForWindow(window);
 | 
			
		||||
                if (monitor)
 | 
			
		||||
                    monitor.inFullscreen = true;
 | 
			
		||||
            }
 | 
			
		||||
@@ -989,7 +982,7 @@ const Chrome = new Lang.Class({
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Or whether it is monitor sized
 | 
			
		||||
                let monitor = this.findMonitorForWindow(metaWindow);
 | 
			
		||||
                let monitor = this.findMonitorForWindow(window);
 | 
			
		||||
                if (monitor &&
 | 
			
		||||
                    window.x <= monitor.x &&
 | 
			
		||||
                    window.x + window.width >= monitor.x + monitor.width &&
 | 
			
		||||
 
 | 
			
		||||
@@ -49,8 +49,7 @@ const KeybindingMode = {
 | 
			
		||||
    LOGIN_SCREEN:  1 << 4,
 | 
			
		||||
    MESSAGE_TRAY:  1 << 5,
 | 
			
		||||
    SYSTEM_MODAL:  1 << 6,
 | 
			
		||||
    LOOKING_GLASS: 1 << 7,
 | 
			
		||||
    ALL:           ~0,
 | 
			
		||||
    LOOKING_GLASS: 1 << 7
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
let componentManager = null;
 | 
			
		||||
@@ -161,13 +160,13 @@ function start() {
 | 
			
		||||
    xdndHandler = new XdndHandler.XdndHandler();
 | 
			
		||||
    ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
 | 
			
		||||
    overview = new Overview.Overview();
 | 
			
		||||
    wm = new WindowManager.WindowManager();
 | 
			
		||||
    magnifier = new Magnifier.Magnifier();
 | 
			
		||||
    if (UnlockDialog.isSupported())
 | 
			
		||||
        screenShield = new ScreenShield.ScreenShield();
 | 
			
		||||
    else
 | 
			
		||||
        screenShield = new ScreenShield.ScreenShieldFallback();
 | 
			
		||||
    panel = new Panel.Panel();
 | 
			
		||||
    wm = new WindowManager.WindowManager();
 | 
			
		||||
    messageTray = new MessageTray.MessageTray();
 | 
			
		||||
    keyboard = new Keyboard.Keyboard();
 | 
			
		||||
    notificationDaemon = new NotificationDaemon.NotificationDaemon();
 | 
			
		||||
 
 | 
			
		||||
@@ -1412,7 +1412,7 @@ const MessageTray = new Lang.Class({
 | 
			
		||||
            actor.grab_key_focus();
 | 
			
		||||
        }));
 | 
			
		||||
        global.focus_manager.add_group(this.actor);
 | 
			
		||||
        this._summary = new St.BoxLayout({ style_class: 'message-tray-summary',
 | 
			
		||||
        this._summary = new St.BoxLayout({ name: 'summary-mode',
 | 
			
		||||
                                           reactive: true,
 | 
			
		||||
                                           track_hover: true,
 | 
			
		||||
                                           x_align: Clutter.ActorAlign.END,
 | 
			
		||||
@@ -1507,7 +1507,7 @@ const MessageTray = new Lang.Class({
 | 
			
		||||
                this._overviewVisible = true;
 | 
			
		||||
                this._grabHelper.ungrab(); // drop modal grab if necessary
 | 
			
		||||
                this.actor.add_style_pseudo_class('overview');
 | 
			
		||||
                this._updateState();
 | 
			
		||||
                this.show();
 | 
			
		||||
            }));
 | 
			
		||||
        Main.overview.connect('hiding', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
@@ -1790,6 +1790,11 @@ const MessageTray = new Lang.Class({
 | 
			
		||||
        this._updateState();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    show: function() {
 | 
			
		||||
        this._traySummoned = true;
 | 
			
		||||
        this._updateState();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onNotify: function(source, notification) {
 | 
			
		||||
        if (this._summaryBoxPointerItem && this._summaryBoxPointerItem.source == source) {
 | 
			
		||||
            if (this._summaryBoxPointerState == State.HIDING) {
 | 
			
		||||
@@ -2036,14 +2041,14 @@ const MessageTray = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Summary
 | 
			
		||||
        let summarySummoned = this._pointerInSummary || this._overviewVisible ||  this._traySummoned;
 | 
			
		||||
        let summarySummoned = this._pointerInSummary ||  this._traySummoned;
 | 
			
		||||
        let summaryPinned = this._pointerInTray || summarySummoned || this._locked;
 | 
			
		||||
        let summaryHovered = this._pointerInTray || this._pointerInSummary;
 | 
			
		||||
 | 
			
		||||
        let notificationsVisible = this._notificationState != State.HIDDEN;
 | 
			
		||||
        let notificationsDone = !notificationsVisible && !notificationsPending;
 | 
			
		||||
 | 
			
		||||
        let summaryOptionalInOverview = this._overviewVisible && !this._locked && !summaryHovered;
 | 
			
		||||
        let summaryOptionalInOverview = !this._locked && !summaryHovered;
 | 
			
		||||
        let mustHideSummary = (notificationsPending && (notificationUrgent || summaryOptionalInOverview))
 | 
			
		||||
                              || notificationsVisible || !Main.sessionMode.hasNotifications;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ const St = imports.gi.St;
 | 
			
		||||
const Shell = imports.gi.Shell;
 | 
			
		||||
const Gdk = imports.gi.Gdk;
 | 
			
		||||
 | 
			
		||||
const CenterLayout = imports.ui.centerLayout;
 | 
			
		||||
const Dash = imports.ui.dash;
 | 
			
		||||
const DND = imports.ui.dnd;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
@@ -30,9 +31,9 @@ const GLSL_DIM_EFFECT_CODE = '\
 | 
			
		||||
   vec2 dist = cogl_tex_coord_in[0].xy - vec2(0.5, 0.5); \
 | 
			
		||||
   float elipse_radius = 0.5; \
 | 
			
		||||
   /* from https://bugzilla.gnome.org/show_bug.cgi?id=669798: \
 | 
			
		||||
      the alpha on the gradient goes from 250 at its darkest to 180 at its most transparent. */ \
 | 
			
		||||
   float y = 250.0 / 255.0; \
 | 
			
		||||
   float x = 180.0 / 255.0; \
 | 
			
		||||
      the alpha on the gradient goes from 165 at its darkest to 98 at its most transparent. */ \
 | 
			
		||||
   float y = 165.0 / 255.0; \
 | 
			
		||||
   float x = 98.0 / 255.0; \
 | 
			
		||||
   /* interpolate darkening value, based on distance from screen center */ \
 | 
			
		||||
   float val = min(length(dist), elipse_radius); \
 | 
			
		||||
   float a = mix(x, y, val / elipse_radius); \
 | 
			
		||||
@@ -97,6 +98,13 @@ const ShellInfo = new Lang.Class({
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const ControlsChange = {
 | 
			
		||||
    BEFORE_PAGE: 1,
 | 
			
		||||
    AFTER_PAGE: 2,
 | 
			
		||||
    DND_START: 3,
 | 
			
		||||
    DND_END: 4
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const Overview = new Lang.Class({
 | 
			
		||||
    Name: 'Overview',
 | 
			
		||||
 | 
			
		||||
@@ -141,7 +149,19 @@ const Overview = new Lang.Class({
 | 
			
		||||
                                            vertical: true });
 | 
			
		||||
        this._overview._delegate = this;
 | 
			
		||||
 | 
			
		||||
        this._group = new St.BoxLayout({ name: 'overview-group' });
 | 
			
		||||
        let layout = new CenterLayout.CenterLayout();
 | 
			
		||||
        this._group = new St.Widget({ name: 'overview-group',
 | 
			
		||||
                                      layout_manager: layout });
 | 
			
		||||
 | 
			
		||||
        this._spacing = 0;
 | 
			
		||||
        this._group.connect('style-changed',
 | 
			
		||||
            Lang.bind(this, function() {
 | 
			
		||||
                let node = this._group.get_theme_node();
 | 
			
		||||
                let spacing = node.get_length('spacing');
 | 
			
		||||
                if (spacing != this._spacing) {
 | 
			
		||||
                    this._spacing = spacing;
 | 
			
		||||
                }
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        this._capturedEventId = 0;
 | 
			
		||||
        this._buttonPressId = 0;
 | 
			
		||||
@@ -237,25 +257,97 @@ const Overview = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._viewSelector = new ViewSelector.ViewSelector(this._searchEntry,
 | 
			
		||||
                                                           this._dash.showAppsButton);
 | 
			
		||||
        this._group.add(this._viewSelector.actor, { x_fill: true,
 | 
			
		||||
                                                    expand: true });
 | 
			
		||||
        this._group.add_actor(this._viewSelector.actor);
 | 
			
		||||
 | 
			
		||||
        this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
 | 
			
		||||
        this._group.add_actor(this._thumbnailsBox.actor);
 | 
			
		||||
 | 
			
		||||
        Main.ctrlAltTabManager.addGroup(this._thumbnailsBox.actor, _("Workspaces"), 'view-list-symbolic');
 | 
			
		||||
 | 
			
		||||
        // Add our same-line elements after the search entry
 | 
			
		||||
        this._overview.add(this._group, { y_fill: true,
 | 
			
		||||
                                          expand: true });
 | 
			
		||||
        this._overview.add_actor(this._group);
 | 
			
		||||
 | 
			
		||||
        // Then account for message tray
 | 
			
		||||
        this._messageTrayGhost = new St.Bin({ style_class: 'message-tray-summary',
 | 
			
		||||
        this._messageTrayGhost = new St.Bin({ child: new Clutter.Clone({ source: Main.messageTray.actor }),
 | 
			
		||||
                                              reactive: false,
 | 
			
		||||
                                              opacity: 0,
 | 
			
		||||
                                              x_fill: true,
 | 
			
		||||
                                              y_fill: true });
 | 
			
		||||
        this._overview.add_actor(this._messageTrayGhost);
 | 
			
		||||
 | 
			
		||||
        this._viewSelector.connect('after-page-change', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                this._setSideControlsVisibility(ControlsChange.AFTER_PAGE);
 | 
			
		||||
            }));
 | 
			
		||||
        this._viewSelector.connect('before-page-change', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                this._setSideControlsVisibility(ControlsChange.BEFORE_PAGE);
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        this.connect('item-drag-begin', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                this._setSideControlsVisibility(ControlsChange.DND_START);
 | 
			
		||||
            }));
 | 
			
		||||
        this.connect('item-drag-cancelled', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                this._setSideControlsVisibility(ControlsChange.DND_END);
 | 
			
		||||
            }));
 | 
			
		||||
        this.connect('item-drag-end', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                this._setSideControlsVisibility(ControlsChange.DND_END);
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._relayout));
 | 
			
		||||
        this._relayout();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setSideControlsVisibility: function(changeType) {
 | 
			
		||||
        // Ignore the case when we're leaving the overview, since
 | 
			
		||||
        // actors will be made visible again when entering the overview
 | 
			
		||||
        // next time, and animating them while doing so is just
 | 
			
		||||
        // unnecesary noise
 | 
			
		||||
        if (!this.visible || this.animationInProgress)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let appsActive = this._viewSelector.getAppsActive();
 | 
			
		||||
        let searchActive = this._viewSelector.getSearchActive();
 | 
			
		||||
        let dashVisible = !searchActive || (changeType == ControlsChange.DND_START);
 | 
			
		||||
        let thumbnailsVisible = (!searchActive && !appsActive) || (changeType == ControlsChange.DND_START);
 | 
			
		||||
        let trayVisible = !searchActive;
 | 
			
		||||
        let trayGhostVisible = trayVisible || dashVisible;
 | 
			
		||||
 | 
			
		||||
        if ((changeType == ControlsChange.BEFORE_PAGE) ||
 | 
			
		||||
            (changeType == ControlsChange.DND_START)) {
 | 
			
		||||
            if (dashVisible)
 | 
			
		||||
                this._dash.show();
 | 
			
		||||
            if (thumbnailsVisible)
 | 
			
		||||
                this._thumbnailsBox.show();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ((changeType == ControlsChange.BEFORE_PAGE) ||
 | 
			
		||||
            (changeType == ControlsChange.DND_END)) {
 | 
			
		||||
            if (!dashVisible) {
 | 
			
		||||
                this._dash.hide();
 | 
			
		||||
            }
 | 
			
		||||
            if (!thumbnailsVisible)
 | 
			
		||||
                this._thumbnailsBox.hide();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (changeType == ControlsChange.BEFORE_PAGE ||
 | 
			
		||||
            changeType == ControlsChange.DND_START) {
 | 
			
		||||
            if (trayGhostVisible)
 | 
			
		||||
                this._messageTrayGhost.show();
 | 
			
		||||
            if (trayVisible)
 | 
			
		||||
                Main.messageTray.show();
 | 
			
		||||
            else
 | 
			
		||||
                Main.messageTray.hide();
 | 
			
		||||
        } else if (changeType == ControlsChange.AFTER_PAGE ||
 | 
			
		||||
                   changeType == ControlsChange.DND_END) {
 | 
			
		||||
            if (!trayGhostVisible)
 | 
			
		||||
                this._messageTrayGhost.hide();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addSearchProvider: function(provider) {
 | 
			
		||||
        this._viewSelector.addSearchProvider(provider);
 | 
			
		||||
    },
 | 
			
		||||
@@ -394,7 +486,7 @@ const Overview = new Lang.Class({
 | 
			
		||||
            stackIndices[stack[i].get_meta_window().get_stable_sequence()] = i;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.emit('windows-restacked', stackIndices);
 | 
			
		||||
        this.emit('sync-window-stacking', stackIndices);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    //// Public methods ////
 | 
			
		||||
@@ -478,6 +570,7 @@ const Overview = new Lang.Class({
 | 
			
		||||
        // Disable unredirection while in the overview
 | 
			
		||||
        Meta.disable_unredirect_for_screen(global.screen);
 | 
			
		||||
        global.window_group.hide();
 | 
			
		||||
        this._messageTrayGhost.show();
 | 
			
		||||
        this._overview.show();
 | 
			
		||||
        this._background.show();
 | 
			
		||||
        this._viewSelector.show();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										121
									
								
								js/ui/panel.js
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								js/ui/panel.js
									
									
									
									
									
								
							@@ -15,6 +15,7 @@ const Signals = imports.signals;
 | 
			
		||||
const Atk = imports.gi.Atk;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const CenterLayout = imports.ui.centerLayout;
 | 
			
		||||
const Config = imports.misc.config;
 | 
			
		||||
const CtrlAltTab = imports.ui.ctrlAltTab;
 | 
			
		||||
const DND = imports.ui.dnd;
 | 
			
		||||
@@ -937,12 +938,47 @@ try {
 | 
			
		||||
    log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const PanelLayout = new Lang.Class({
 | 
			
		||||
    Name: 'PanelLayout',
 | 
			
		||||
    Extends: CenterLayout.CenterLayout,
 | 
			
		||||
 | 
			
		||||
    vfunc_allocate: function(container, box, flags) {
 | 
			
		||||
        this.parent(container, box, flags);
 | 
			
		||||
 | 
			
		||||
        let availWidth = box.x2 - box.x1;
 | 
			
		||||
        let availHeight = box.y2 - box.y1;
 | 
			
		||||
 | 
			
		||||
        let [left, center, right, leftCorner, rightCorner] = container.get_children();
 | 
			
		||||
        let childBox = new Clutter.ActorBox();
 | 
			
		||||
 | 
			
		||||
        let cornerMinWidth, cornerMinHeight;
 | 
			
		||||
        let cornerWidth, cornerHeight;
 | 
			
		||||
 | 
			
		||||
        [cornerMinWidth, cornerWidth] = leftCorner.get_preferred_width(-1);
 | 
			
		||||
        [cornerMinHeight, cornerHeight] = leftCorner.get_preferred_height(-1);
 | 
			
		||||
        childBox.x1 = 0;
 | 
			
		||||
        childBox.x2 = cornerWidth;
 | 
			
		||||
        childBox.y1 = availHeight;
 | 
			
		||||
        childBox.y2 = availHeight + cornerHeight;
 | 
			
		||||
        leftCorner.allocate(childBox, flags);
 | 
			
		||||
 | 
			
		||||
        [cornerMinWidth, cornerWidth] = rightCorner.get_preferred_width(-1);
 | 
			
		||||
        [cornerMinHeight, cornerHeight] = rightCorner.get_preferred_height(-1);
 | 
			
		||||
        childBox.x1 = availWidth - cornerWidth;
 | 
			
		||||
        childBox.x2 = availWidth;
 | 
			
		||||
        childBox.y1 = availHeight;
 | 
			
		||||
        childBox.y2 = availHeight + cornerHeight;
 | 
			
		||||
        rightCorner.allocate(childBox, flags);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const Panel = new Lang.Class({
 | 
			
		||||
    Name: 'Panel',
 | 
			
		||||
 | 
			
		||||
    _init : function() {
 | 
			
		||||
        this.actor = new Shell.GenericContainer({ name: 'panel',
 | 
			
		||||
                                                  reactive: true });
 | 
			
		||||
        this.actor = new St.Widget({ name: 'panel',
 | 
			
		||||
                                     reactive: true,
 | 
			
		||||
                                     layoutManager: new PanelLayout() });
 | 
			
		||||
        this.actor._delegate = this;
 | 
			
		||||
 | 
			
		||||
        this._sessionStyle = null;
 | 
			
		||||
@@ -962,7 +998,6 @@ const Panel = new Lang.Class({
 | 
			
		||||
            this._leftCorner = new PanelCorner(this._rightBox, St.Side.LEFT);
 | 
			
		||||
        else
 | 
			
		||||
            this._leftCorner = new PanelCorner(this._leftBox, St.Side.LEFT);
 | 
			
		||||
 | 
			
		||||
        this.actor.add_actor(this._leftCorner.actor);
 | 
			
		||||
 | 
			
		||||
        if (this.actor.get_text_direction() == Clutter.TextDirection.RTL)
 | 
			
		||||
@@ -971,9 +1006,6 @@ const Panel = new Lang.Class({
 | 
			
		||||
            this._rightCorner = new PanelCorner(this._rightBox, St.Side.RIGHT);
 | 
			
		||||
        this.actor.add_actor(this._rightCorner.actor);
 | 
			
		||||
 | 
			
		||||
        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.connect('button-press-event', Lang.bind(this, this._onButtonPress));
 | 
			
		||||
 | 
			
		||||
        Main.layoutManager.panelBox.add(this.actor);
 | 
			
		||||
@@ -984,83 +1016,6 @@ const Panel = new Lang.Class({
 | 
			
		||||
        this._updatePanel();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getPreferredWidth: function(actor, forHeight, alloc) {
 | 
			
		||||
        alloc.min_size = -1;
 | 
			
		||||
        alloc.natural_size = Main.layoutManager.primaryMonitor.width;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getPreferredHeight: function(actor, forWidth, alloc) {
 | 
			
		||||
        // We don't need to implement this; it's forced by the CSS
 | 
			
		||||
        alloc.min_size = -1;
 | 
			
		||||
        alloc.natural_size = -1;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _allocate: function(actor, box, flags) {
 | 
			
		||||
        let allocWidth = box.x2 - box.x1;
 | 
			
		||||
        let allocHeight = box.y2 - box.y1;
 | 
			
		||||
 | 
			
		||||
        let [leftMinWidth, leftNaturalWidth] = this._leftBox.get_preferred_width(-1);
 | 
			
		||||
        let [centerMinWidth, centerNaturalWidth] = this._centerBox.get_preferred_width(-1);
 | 
			
		||||
        let [rightMinWidth, rightNaturalWidth] = this._rightBox.get_preferred_width(-1);
 | 
			
		||||
 | 
			
		||||
        let sideWidth, centerWidth;
 | 
			
		||||
        centerWidth = centerNaturalWidth;
 | 
			
		||||
        sideWidth = (allocWidth - centerWidth) / 2;
 | 
			
		||||
 | 
			
		||||
        let childBox = new Clutter.ActorBox();
 | 
			
		||||
 | 
			
		||||
        childBox.y1 = 0;
 | 
			
		||||
        childBox.y2 = allocHeight;
 | 
			
		||||
        if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
 | 
			
		||||
            childBox.x1 = allocWidth - Math.min(Math.floor(sideWidth),
 | 
			
		||||
                                                leftNaturalWidth);
 | 
			
		||||
            childBox.x2 = allocWidth;
 | 
			
		||||
        } else {
 | 
			
		||||
            childBox.x1 = 0;
 | 
			
		||||
            childBox.x2 = Math.min(Math.floor(sideWidth),
 | 
			
		||||
                                   leftNaturalWidth);
 | 
			
		||||
        }
 | 
			
		||||
        this._leftBox.allocate(childBox, flags);
 | 
			
		||||
 | 
			
		||||
        childBox.x1 = Math.ceil(sideWidth);
 | 
			
		||||
        childBox.y1 = 0;
 | 
			
		||||
        childBox.x2 = childBox.x1 + centerWidth;
 | 
			
		||||
        childBox.y2 = allocHeight;
 | 
			
		||||
        this._centerBox.allocate(childBox, flags);
 | 
			
		||||
 | 
			
		||||
        childBox.y1 = 0;
 | 
			
		||||
        childBox.y2 = allocHeight;
 | 
			
		||||
        if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
 | 
			
		||||
            childBox.x1 = 0;
 | 
			
		||||
            childBox.x2 = Math.min(Math.floor(sideWidth),
 | 
			
		||||
                                   rightNaturalWidth);
 | 
			
		||||
        } else {
 | 
			
		||||
            childBox.x1 = allocWidth - Math.min(Math.floor(sideWidth),
 | 
			
		||||
                                                rightNaturalWidth);
 | 
			
		||||
            childBox.x2 = allocWidth;
 | 
			
		||||
        }
 | 
			
		||||
        this._rightBox.allocate(childBox, flags);
 | 
			
		||||
 | 
			
		||||
        let cornerMinWidth, cornerMinHeight;
 | 
			
		||||
        let cornerWidth, cornerHeight;
 | 
			
		||||
 | 
			
		||||
        [cornerMinWidth, cornerWidth] = this._leftCorner.actor.get_preferred_width(-1);
 | 
			
		||||
        [cornerMinHeight, cornerHeight] = this._leftCorner.actor.get_preferred_height(-1);
 | 
			
		||||
        childBox.x1 = 0;
 | 
			
		||||
        childBox.x2 = cornerWidth;
 | 
			
		||||
        childBox.y1 = allocHeight;
 | 
			
		||||
        childBox.y2 = allocHeight + cornerHeight;
 | 
			
		||||
        this._leftCorner.actor.allocate(childBox, flags);
 | 
			
		||||
 | 
			
		||||
        [cornerMinWidth, cornerWidth] = this._rightCorner.actor.get_preferred_width(-1);
 | 
			
		||||
        [cornerMinHeight, cornerHeight] = this._rightCorner.actor.get_preferred_height(-1);
 | 
			
		||||
        childBox.x1 = allocWidth - cornerWidth;
 | 
			
		||||
        childBox.x2 = allocWidth;
 | 
			
		||||
        childBox.y1 = allocHeight;
 | 
			
		||||
        childBox.y2 = allocHeight + cornerHeight;
 | 
			
		||||
        this._rightCorner.actor.allocate(childBox, flags);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onButtonPress: function(actor, event) {
 | 
			
		||||
        if (event.get_source() != actor)
 | 
			
		||||
            return false;
 | 
			
		||||
 
 | 
			
		||||
@@ -80,7 +80,7 @@ const Indicator = new Lang.Class({
 | 
			
		||||
        this._applet.connect('notify::show-full-menu', Lang.bind(this, this._updateFullMenu));
 | 
			
		||||
        this._updateFullMenu();
 | 
			
		||||
 | 
			
		||||
        this.menu.addSettingsAction(_("Bluetooth Settings"), 'gnome-bluetooth-panel.desktop');
 | 
			
		||||
        this.menu.addSettingsAction(_("Bluetooth Settings"), 'bluetooth-properties.desktop');
 | 
			
		||||
 | 
			
		||||
        this._applet.connect('pincode-request', Lang.bind(this, this._pinRequest));
 | 
			
		||||
        this._applet.connect('confirm-request', Lang.bind(this, this._confirmRequest));
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,9 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
const Gio = imports.gi.Gio;
 | 
			
		||||
const GLib = imports.gi.GLib;
 | 
			
		||||
const GnomeDesktop = imports.gi.GnomeDesktop;
 | 
			
		||||
const Lang = imports.lang;
 | 
			
		||||
const Meta = imports.gi.Meta;
 | 
			
		||||
const Shell = imports.gi.Shell;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
const St = imports.gi.St;
 | 
			
		||||
@@ -23,7 +21,6 @@ try {
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const PopupMenu = imports.ui.popupMenu;
 | 
			
		||||
const PanelMenu = imports.ui.panelMenu;
 | 
			
		||||
const SwitcherPopup = imports.ui.switcherPopup;
 | 
			
		||||
const Util = imports.misc.util;
 | 
			
		||||
 | 
			
		||||
const DESKTOP_INPUT_SOURCES_SCHEMA = 'org.gnome.desktop.input-sources';
 | 
			
		||||
@@ -50,7 +47,6 @@ const IBusManager = new Lang.Class({
 | 
			
		||||
        this._engines = {};
 | 
			
		||||
        this._ready = false;
 | 
			
		||||
        this._registerPropertiesId = 0;
 | 
			
		||||
        this._currentEngineName = null;
 | 
			
		||||
 | 
			
		||||
        this._nameWatcherId = Gio.DBus.session.watch_name(IBus.SERVICE_IBUS,
 | 
			
		||||
                                                          Gio.BusNameWatcherFlags.NONE,
 | 
			
		||||
@@ -70,10 +66,6 @@ const IBusManager = new Lang.Class({
 | 
			
		||||
        this._engines = {};
 | 
			
		||||
        this._ready = false;
 | 
			
		||||
        this._registerPropertiesId = 0;
 | 
			
		||||
        this._currentEngineName = null;
 | 
			
		||||
 | 
			
		||||
        if (this._readyCallback)
 | 
			
		||||
            this._readyCallback(false);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onNameAppeared: function() {
 | 
			
		||||
@@ -97,10 +89,12 @@ const IBusManager = new Lang.Class({
 | 
			
		||||
                let name = enginesList[i].get_name();
 | 
			
		||||
                this._engines[name] = enginesList[i];
 | 
			
		||||
            }
 | 
			
		||||
            this._updateReadiness();
 | 
			
		||||
        } else {
 | 
			
		||||
            this._clear();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._updateReadiness();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _initPanelService: function(ibus, result) {
 | 
			
		||||
@@ -111,31 +105,27 @@ const IBusManager = new Lang.Class({
 | 
			
		||||
            this._candidatePopup.setPanelService(this._panelService);
 | 
			
		||||
            // Need to set this to get 'global-engine-changed' emitions
 | 
			
		||||
            this._ibus.set_watch_ibus_signal(true);
 | 
			
		||||
            this._ibus.connect('global-engine-changed', Lang.bind(this, this._engineChanged));
 | 
			
		||||
            this._ibus.connect('global-engine-changed', Lang.bind(this, this._resetProperties));
 | 
			
		||||
            this._panelService.connect('update-property', Lang.bind(this, this._updateProperty));
 | 
			
		||||
            // If an engine is already active we need to get its properties
 | 
			
		||||
            this._ibus.get_global_engine_async(-1, null, Lang.bind(this, function(i, result) {
 | 
			
		||||
                let engine = this._ibus.get_global_engine_async_finish(result);
 | 
			
		||||
                if (!engine)
 | 
			
		||||
                    return;
 | 
			
		||||
                this._engineChanged(this._ibus, engine.get_name());
 | 
			
		||||
            }));
 | 
			
		||||
            this._updateReadiness();
 | 
			
		||||
            this._resetProperties();
 | 
			
		||||
        } else {
 | 
			
		||||
            this._clear();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._updateReadiness();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateReadiness: function() {
 | 
			
		||||
        this._ready = (Object.keys(this._engines).length > 0 &&
 | 
			
		||||
                       this._panelService != null);
 | 
			
		||||
 | 
			
		||||
        if (this._readyCallback)
 | 
			
		||||
            this._readyCallback(this._ready);
 | 
			
		||||
        if (this._ready && this._readyCallback)
 | 
			
		||||
            this._readyCallback();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _engineChanged: function(bus, engineName) {
 | 
			
		||||
        this._currentEngineName = engineName;
 | 
			
		||||
    _resetProperties: function() {
 | 
			
		||||
        this.emit('properties-registered', null);
 | 
			
		||||
 | 
			
		||||
        if (this._registerPropertiesId != 0)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -148,18 +138,25 @@ const IBusManager = new Lang.Class({
 | 
			
		||||
                this._panelService.disconnect(this._registerPropertiesId);
 | 
			
		||||
                this._registerPropertiesId = 0;
 | 
			
		||||
 | 
			
		||||
                this.emit('properties-registered', this._currentEngineName, props);
 | 
			
		||||
                this.emit('properties-registered', props);
 | 
			
		||||
            }));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateProperty: function(panel, prop) {
 | 
			
		||||
        this.emit('property-updated', this._currentEngineName, prop);
 | 
			
		||||
        this.emit('property-updated', prop);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateProperty: function(key, state) {
 | 
			
		||||
        this._panelService.property_activate(key, state);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hasProperties: function(id) {
 | 
			
		||||
        if (id == 'anthy')
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getEngineDesc: function(id) {
 | 
			
		||||
        if (!IBus || !this._ready)
 | 
			
		||||
            return null;
 | 
			
		||||
@@ -184,127 +181,16 @@ const LayoutMenuItem = new Lang.Class({
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const InputSource = new Lang.Class({
 | 
			
		||||
    Name: 'InputSource',
 | 
			
		||||
 | 
			
		||||
    _init: function(type, id, displayName, shortName, index) {
 | 
			
		||||
        this.type = type;
 | 
			
		||||
        this.id = id;
 | 
			
		||||
        this.displayName = displayName;
 | 
			
		||||
        this._shortName = shortName;
 | 
			
		||||
        this.index = index;
 | 
			
		||||
 | 
			
		||||
        this._menuItem = new LayoutMenuItem(this.displayName, this._shortName);
 | 
			
		||||
        this._menuItem.connect('activate', Lang.bind(this, this.activate));
 | 
			
		||||
        this._indicatorLabel = new St.Label({ text: this._shortName });
 | 
			
		||||
 | 
			
		||||
        this.properties = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy: function() {
 | 
			
		||||
        this._menuItem.destroy();
 | 
			
		||||
        this._indicatorLabel.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get shortName() {
 | 
			
		||||
        return this._shortName;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    set shortName(v) {
 | 
			
		||||
        this._shortName = v;
 | 
			
		||||
        this._menuItem.indicator.set_text(v);
 | 
			
		||||
        this._indicatorLabel.set_text(v);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get menuItem() {
 | 
			
		||||
        return this._menuItem;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get indicatorLabel() {
 | 
			
		||||
        return this._indicatorLabel;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activate: function() {
 | 
			
		||||
        this.emit('activate');
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
Signals.addSignalMethods(InputSource.prototype);
 | 
			
		||||
 | 
			
		||||
const InputSourcePopup = new Lang.Class({
 | 
			
		||||
    Name: 'InputSourcePopup',
 | 
			
		||||
    Extends: SwitcherPopup.SwitcherPopup,
 | 
			
		||||
 | 
			
		||||
    _init: function(items, action, actionBackward) {
 | 
			
		||||
        this.parent(items);
 | 
			
		||||
 | 
			
		||||
        this._action = action;
 | 
			
		||||
        this._actionBackward = actionBackward;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createSwitcher: function() {
 | 
			
		||||
        this._switcherList = new InputSourceSwitcher(this._items);
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _initialSelection: function(backward, binding) {
 | 
			
		||||
        if (binding == 'switch-input-source') {
 | 
			
		||||
            if (backward)
 | 
			
		||||
                this._selectedIndex = this._items.length - 1;
 | 
			
		||||
        } else if (binding == 'switch-input-source-backward') {
 | 
			
		||||
            if (!backward)
 | 
			
		||||
                this._selectedIndex = this._items.length - 1;
 | 
			
		||||
        }
 | 
			
		||||
        this._select(this._selectedIndex);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _keyPressHandler: function(keysym, backwards, action) {
 | 
			
		||||
        if (action == this._action)
 | 
			
		||||
            this._select(backwards ? this._previous() : this._next());
 | 
			
		||||
        else if (action == this._actionBackward)
 | 
			
		||||
            this._select(backwards ? this._next() : this._previous());
 | 
			
		||||
        else if (keysym == Clutter.Left)
 | 
			
		||||
            this._select(this._previous());
 | 
			
		||||
        else if (keysym == Clutter.Right)
 | 
			
		||||
            this._select(this._next());
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _finish : function() {
 | 
			
		||||
        this.parent();
 | 
			
		||||
 | 
			
		||||
        this._items[this._selectedIndex].activate();
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const InputSourceSwitcher = new Lang.Class({
 | 
			
		||||
    Name: 'InputSourceSwitcher',
 | 
			
		||||
    Extends: SwitcherPopup.SwitcherList,
 | 
			
		||||
 | 
			
		||||
    _init: function(items) {
 | 
			
		||||
        this.parent(true);
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < items.length; i++)
 | 
			
		||||
            this._addIcon(items[i]);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _addIcon: function(item) {
 | 
			
		||||
        let box = new St.BoxLayout({ vertical: true });
 | 
			
		||||
 | 
			
		||||
        let bin = new St.Bin({ style_class: 'input-source-switcher-symbol' });
 | 
			
		||||
        let symbol = new St.Label({ text: item.shortName });
 | 
			
		||||
        bin.set_child(symbol);
 | 
			
		||||
        box.add(bin, { x_fill: false, y_fill: false } );
 | 
			
		||||
 | 
			
		||||
        let text = new St.Label({ text: item.displayName });
 | 
			
		||||
        box.add(text, { x_fill: false });
 | 
			
		||||
 | 
			
		||||
        this.addItem(box, text);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const InputSourceIndicator = new Lang.Class({
 | 
			
		||||
    Name: 'InputSourceIndicator',
 | 
			
		||||
    Extends: PanelMenu.Button,
 | 
			
		||||
 | 
			
		||||
    _propertiesWhitelist: [
 | 
			
		||||
        'InputMode',
 | 
			
		||||
        'TypingMode',
 | 
			
		||||
        'DictMode'
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent(0.0, _("Keyboard"));
 | 
			
		||||
 | 
			
		||||
@@ -315,36 +201,14 @@ const InputSourceIndicator = new Lang.Class({
 | 
			
		||||
        this.actor.add_actor(this._container);
 | 
			
		||||
        this.actor.add_style_class_name('panel-status-button');
 | 
			
		||||
 | 
			
		||||
        // All valid input sources currently in the gsettings
 | 
			
		||||
        // KEY_INPUT_SOURCES list indexed by their index there
 | 
			
		||||
        this._inputSources = {};
 | 
			
		||||
        // All valid input sources currently in the gsettings
 | 
			
		||||
        // KEY_INPUT_SOURCES list of type INPUT_SOURCE_TYPE_IBUS
 | 
			
		||||
        // indexed by the IBus ID
 | 
			
		||||
        this._ibusSources = {};
 | 
			
		||||
        this._labelActors = {};
 | 
			
		||||
        this._layoutItems = {};
 | 
			
		||||
 | 
			
		||||
        this._currentSource = null;
 | 
			
		||||
 | 
			
		||||
        // All valid input sources currently in the gsettings
 | 
			
		||||
        // KEY_INPUT_SOURCES list ordered by most recently used
 | 
			
		||||
        this._mruSources = [];
 | 
			
		||||
        this._keybindingAction =
 | 
			
		||||
            Main.wm.addKeybinding('switch-input-source',
 | 
			
		||||
                                  new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
 | 
			
		||||
                                  Meta.KeyBindingFlags.REVERSES,
 | 
			
		||||
                                  Main.KeybindingMode.ALL,
 | 
			
		||||
                                  Lang.bind(this, this._switchInputSource));
 | 
			
		||||
        this._keybindingActionBackward =
 | 
			
		||||
            Main.wm.addKeybinding('switch-input-source-backward',
 | 
			
		||||
                                  new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
 | 
			
		||||
                                  Meta.KeyBindingFlags.REVERSES |
 | 
			
		||||
                                  Meta.KeyBindingFlags.REVERSED,
 | 
			
		||||
                                  Main.KeybindingMode.ALL,
 | 
			
		||||
                                  Lang.bind(this, this._switchInputSource));
 | 
			
		||||
        this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
 | 
			
		||||
        this._settings.connect('changed::' + KEY_CURRENT_INPUT_SOURCE, Lang.bind(this, this._currentInputSourceChanged));
 | 
			
		||||
        this._settings.connect('changed::' + KEY_INPUT_SOURCES, Lang.bind(this, this._inputSourcesChanged));
 | 
			
		||||
 | 
			
		||||
        this._currentSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
 | 
			
		||||
        this._xkbInfo = new GnomeDesktop.XkbInfo();
 | 
			
		||||
 | 
			
		||||
        this._propSeparator = new PopupMenu.PopupSeparatorMenuItem();
 | 
			
		||||
@@ -353,8 +217,9 @@ const InputSourceIndicator = new Lang.Class({
 | 
			
		||||
        this.menu.addMenuItem(this._propSection);
 | 
			
		||||
        this._propSection.actor.hide();
 | 
			
		||||
 | 
			
		||||
        this._ibusReady = false;
 | 
			
		||||
        this._ibusManager = new IBusManager(Lang.bind(this, this._ibusReadyCallback));
 | 
			
		||||
        this._properties = null;
 | 
			
		||||
 | 
			
		||||
        this._ibusManager = new IBusManager(Lang.bind(this, this._inputSourcesChanged));
 | 
			
		||||
        this._ibusManager.connect('properties-registered', Lang.bind(this, this._ibusPropertiesRegistered));
 | 
			
		||||
        this._ibusManager.connect('property-updated', Lang.bind(this, this._ibusPropertyUpdated));
 | 
			
		||||
        this._inputSourcesChanged();
 | 
			
		||||
@@ -376,29 +241,18 @@ const InputSourceIndicator = new Lang.Class({
 | 
			
		||||
        this._showLayoutItem.actor.visible = Main.sessionMode.allowSettings;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _ibusReadyCallback: function(ready) {
 | 
			
		||||
        if (this._ibusReady == ready)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._ibusReady = ready;
 | 
			
		||||
        this._mruSources = [];
 | 
			
		||||
        this._inputSourcesChanged();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _switchInputSource: function(display, screen, window, binding) {
 | 
			
		||||
        let popup = new InputSourcePopup(this._mruSources, this._keybindingAction, this._keybindingActionBackward);
 | 
			
		||||
        let modifiers = binding.get_modifiers();
 | 
			
		||||
        let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK;
 | 
			
		||||
        if (!popup.show(backwards, binding.get_name(), binding.get_mask()))
 | 
			
		||||
            popup.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _currentInputSourceChanged: function() {
 | 
			
		||||
        let nVisibleSources = Object.keys(this._inputSources).length;
 | 
			
		||||
        let newSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
 | 
			
		||||
        let newSource = this._inputSources[newSourceIndex];
 | 
			
		||||
        let nVisibleSources = Object.keys(this._layoutItems).length;
 | 
			
		||||
        let newCurrentSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
 | 
			
		||||
        let newLayoutItem = this._layoutItems[newCurrentSourceIndex];
 | 
			
		||||
        let hasProperties;
 | 
			
		||||
 | 
			
		||||
        if (!newSource || (nVisibleSources < 2 && !newSource.properties)) {
 | 
			
		||||
        if (newLayoutItem)
 | 
			
		||||
            hasProperties = this._ibusManager.hasProperties(newLayoutItem.ibusEngineId);
 | 
			
		||||
        else
 | 
			
		||||
            hasProperties = false;
 | 
			
		||||
 | 
			
		||||
        if (!newLayoutItem || (nVisibleSources < 2 && !hasProperties)) {
 | 
			
		||||
            // This source index might be invalid if we weren't able
 | 
			
		||||
            // to build a menu item for it, so we hide ourselves since
 | 
			
		||||
            // we can't fix it here. *shrug*
 | 
			
		||||
@@ -412,121 +266,106 @@ const InputSourceIndicator = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
 | 
			
		||||
        let oldSource;
 | 
			
		||||
        [oldSource, this._currentSource] = [this._currentSource, newSource];
 | 
			
		||||
 | 
			
		||||
        if (oldSource) {
 | 
			
		||||
            oldSource.menuItem.setShowDot(false);
 | 
			
		||||
            this._container.set_skip_paint(oldSource.indicatorLabel, true);
 | 
			
		||||
        if (this._layoutItems[this._currentSourceIndex]) {
 | 
			
		||||
            this._layoutItems[this._currentSourceIndex].setShowDot(false);
 | 
			
		||||
            this._container.set_skip_paint(this._labelActors[this._currentSourceIndex], true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        newSource.menuItem.setShowDot(true);
 | 
			
		||||
        this._container.set_skip_paint(newSource.indicatorLabel, false);
 | 
			
		||||
        newLayoutItem.setShowDot(true);
 | 
			
		||||
 | 
			
		||||
        this._buildPropSection(newSource.properties);
 | 
			
		||||
        let newLabelActor = this._labelActors[newCurrentSourceIndex];
 | 
			
		||||
        this._container.set_skip_paint(newLabelActor, false);
 | 
			
		||||
 | 
			
		||||
        for (let i = 1; i < this._mruSources.length; ++i)
 | 
			
		||||
            if (this._mruSources[i] == newSource) {
 | 
			
		||||
                let currentSource = this._mruSources.splice(i, 1);
 | 
			
		||||
                this._mruSources = currentSource.concat(this._mruSources);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        if (hasProperties)
 | 
			
		||||
            newLabelActor.set_text(newLayoutItem.indicator.get_text());
 | 
			
		||||
 | 
			
		||||
        this._currentSourceIndex = newCurrentSourceIndex;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _inputSourcesChanged: function() {
 | 
			
		||||
        let sources = this._settings.get_value(KEY_INPUT_SOURCES);
 | 
			
		||||
        let nSources = sources.n_children();
 | 
			
		||||
 | 
			
		||||
        for (let i in this._inputSources)
 | 
			
		||||
            this._inputSources[i].destroy();
 | 
			
		||||
        for (let i in this._layoutItems)
 | 
			
		||||
            this._layoutItems[i].destroy();
 | 
			
		||||
 | 
			
		||||
        this._inputSources = {};
 | 
			
		||||
        this._ibusSources = {};
 | 
			
		||||
        for (let i in this._labelActors)
 | 
			
		||||
            this._labelActors[i].destroy();
 | 
			
		||||
 | 
			
		||||
        let inputSourcesByShortName = {};
 | 
			
		||||
        this._layoutItems = {};
 | 
			
		||||
        this._labelActors = {};
 | 
			
		||||
 | 
			
		||||
        let infos = [];
 | 
			
		||||
        let infosByShortName = {};
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < nSources; i++) {
 | 
			
		||||
            let displayName;
 | 
			
		||||
            let shortName;
 | 
			
		||||
            let info = { exists: false };
 | 
			
		||||
            let [type, id] = sources.get_child_value(i).deep_unpack();
 | 
			
		||||
            let exists = false;
 | 
			
		||||
 | 
			
		||||
            if (type == INPUT_SOURCE_TYPE_XKB) {
 | 
			
		||||
                [exists, displayName, shortName, , ] =
 | 
			
		||||
                [info.exists, info.displayName, info.shortName, , ] =
 | 
			
		||||
                    this._xkbInfo.get_layout_info(id);
 | 
			
		||||
            } else if (type == INPUT_SOURCE_TYPE_IBUS) {
 | 
			
		||||
                let engineDesc = this._ibusManager.getEngineDesc(id);
 | 
			
		||||
                if (engineDesc) {
 | 
			
		||||
                    let language = IBus.get_language_name(engineDesc.get_language());
 | 
			
		||||
                    exists = true;
 | 
			
		||||
                    displayName = language + ' (' + engineDesc.get_longname() + ')';
 | 
			
		||||
                    shortName = this._makeEngineShortName(engineDesc);
 | 
			
		||||
 | 
			
		||||
                    info.exists = true;
 | 
			
		||||
                    info.displayName = language + ' (' + engineDesc.get_longname() + ')';
 | 
			
		||||
                    info.shortName = this._makeEngineShortName(engineDesc);
 | 
			
		||||
                    info.ibusEngineId = id;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!exists)
 | 
			
		||||
            if (!info.exists)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            let is = new InputSource(type, id, displayName, shortName, i);
 | 
			
		||||
            info.sourceIndex = i;
 | 
			
		||||
 | 
			
		||||
            is.connect('activate', Lang.bind(this, function() {
 | 
			
		||||
                this._settings.set_value(KEY_CURRENT_INPUT_SOURCE,
 | 
			
		||||
                                         GLib.Variant.new_uint32(is.index));
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
            if (!(is.shortName in inputSourcesByShortName))
 | 
			
		||||
                inputSourcesByShortName[is.shortName] = [];
 | 
			
		||||
            inputSourcesByShortName[is.shortName].push(is);
 | 
			
		||||
 | 
			
		||||
            this._inputSources[is.index] = is;
 | 
			
		||||
 | 
			
		||||
            if (is.type == INPUT_SOURCE_TYPE_IBUS)
 | 
			
		||||
                this._ibusSources[is.id] = is;
 | 
			
		||||
            if (!(info.shortName in infosByShortName))
 | 
			
		||||
                infosByShortName[info.shortName] = [];
 | 
			
		||||
            infosByShortName[info.shortName].push(info);
 | 
			
		||||
            infos.push(info);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let menuIndex = 0;
 | 
			
		||||
        for (let i in this._inputSources) {
 | 
			
		||||
            let is = this._inputSources[i];
 | 
			
		||||
            if (inputSourcesByShortName[is.shortName].length > 1) {
 | 
			
		||||
                let sub = inputSourcesByShortName[is.shortName].indexOf(is) + 1;
 | 
			
		||||
                is.shortName += String.fromCharCode(0x2080 + sub);
 | 
			
		||||
        for (let i = 0; i < infos.length; i++) {
 | 
			
		||||
            let info = infos[i];
 | 
			
		||||
            if (infosByShortName[info.shortName].length > 1) {
 | 
			
		||||
                let sub = infosByShortName[info.shortName].indexOf(info) + 1;
 | 
			
		||||
                info.shortName += String.fromCharCode(0x2080 + sub);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.menu.addMenuItem(is.menuItem, menuIndex++);
 | 
			
		||||
            let item = new LayoutMenuItem(info.displayName, info.shortName);
 | 
			
		||||
            item.ibusEngineId = info.ibusEngineId;
 | 
			
		||||
            this._layoutItems[info.sourceIndex] = item;
 | 
			
		||||
            this.menu.addMenuItem(item, i);
 | 
			
		||||
            item.connect('activate', Lang.bind(this, function() {
 | 
			
		||||
                this._settings.set_value(KEY_CURRENT_INPUT_SOURCE,
 | 
			
		||||
                                         GLib.Variant.new_uint32(info.sourceIndex));
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
            this._container.add_actor(is.indicatorLabel);
 | 
			
		||||
            this._container.set_skip_paint(is.indicatorLabel, true);
 | 
			
		||||
            let shortLabel = new St.Label({ text: info.shortName });
 | 
			
		||||
            this._labelActors[info.sourceIndex] = shortLabel;
 | 
			
		||||
            this._container.add_actor(shortLabel);
 | 
			
		||||
            this._container.set_skip_paint(shortLabel, true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let sourcesList = [];
 | 
			
		||||
        for (let i in this._inputSources)
 | 
			
		||||
            sourcesList.push(this._inputSources[i]);
 | 
			
		||||
 | 
			
		||||
        let mruSources = [];
 | 
			
		||||
        for (let i = 0; i < this._mruSources.length; i++) {
 | 
			
		||||
            for (let j = 0; j < sourcesList.length; j++)
 | 
			
		||||
                if (this._mruSources[i].type == sourcesList[j].type &&
 | 
			
		||||
                    this._mruSources[i].id == sourcesList[j].id) {
 | 
			
		||||
                    mruSources = mruSources.concat(sourcesList.splice(j, 1));
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
        this._mruSources = mruSources.concat(sourcesList);
 | 
			
		||||
 | 
			
		||||
        this._currentInputSourceChanged();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _showLayout: function() {
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
 | 
			
		||||
        let source = this._currentSource;
 | 
			
		||||
        let sources = this._settings.get_value(KEY_INPUT_SOURCES);
 | 
			
		||||
        let current = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
 | 
			
		||||
        let [type, id] = sources.get_child_value(current).deep_unpack();
 | 
			
		||||
        let xkbLayout = '';
 | 
			
		||||
        let xkbVariant = '';
 | 
			
		||||
 | 
			
		||||
        if (source.type == INPUT_SOURCE_TYPE_XKB) {
 | 
			
		||||
            [, , , xkbLayout, xkbVariant] = this._xkbInfo.get_layout_info(source.id);
 | 
			
		||||
        } else if (source.type == INPUT_SOURCE_TYPE_IBUS) {
 | 
			
		||||
            let engineDesc = this._ibusManager.getEngineDesc(source.id);
 | 
			
		||||
        if (type == INPUT_SOURCE_TYPE_XKB) {
 | 
			
		||||
            [, , , xkbLayout, xkbVariant] = this._xkbInfo.get_layout_info(id);
 | 
			
		||||
        } else if (type == INPUT_SOURCE_TYPE_IBUS) {
 | 
			
		||||
            let engineDesc = this._ibusManager.getEngineDesc(id);
 | 
			
		||||
            if (engineDesc) {
 | 
			
		||||
                xkbLayout = engineDesc.get_layout();
 | 
			
		||||
                xkbVariant = '';
 | 
			
		||||
@@ -555,25 +394,26 @@ const InputSourceIndicator = new Lang.Class({
 | 
			
		||||
        return String.fromCharCode(0x2328); // keyboard glyph
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _ibusPropertiesRegistered: function(im, engineName, props) {
 | 
			
		||||
        let source = this._ibusSources[engineName];
 | 
			
		||||
        if (!source)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        source.properties = props;
 | 
			
		||||
 | 
			
		||||
        if (source == this._currentSource)
 | 
			
		||||
            this._currentInputSourceChanged();
 | 
			
		||||
    _propertyWhitelisted: function(prop) {
 | 
			
		||||
        for (let i = 0; i < this._propertiesWhitelist.length; ++i) {
 | 
			
		||||
            let key = prop.get_key();
 | 
			
		||||
            if (key.substr(0, this._propertiesWhitelist[i].length) == this._propertiesWhitelist[i])
 | 
			
		||||
                return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _ibusPropertyUpdated: function(im, engineName, prop) {
 | 
			
		||||
        let source = this._ibusSources[engineName];
 | 
			
		||||
        if (!source)
 | 
			
		||||
    _ibusPropertiesRegistered: function(im, props) {
 | 
			
		||||
        this._properties = props;
 | 
			
		||||
        this._buildPropSection();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _ibusPropertyUpdated: function(im, prop) {
 | 
			
		||||
        if (!this._propertyWhitelisted(prop))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (this._updateSubProperty(source.properties, prop) &&
 | 
			
		||||
            source == this._currentSource)
 | 
			
		||||
            this._currentInputSourceChanged();
 | 
			
		||||
        if (this._updateSubProperty(this._properties, prop))
 | 
			
		||||
            this._buildPropSection();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateSubProperty: function(props, prop) {
 | 
			
		||||
@@ -593,12 +433,25 @@ const InputSourceIndicator = new Lang.Class({
 | 
			
		||||
        return false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _buildPropSection: function(properties) {
 | 
			
		||||
    _updateIndicatorLabel: function(text) {
 | 
			
		||||
        let layoutItem = this._layoutItems[this._currentSourceIndex];
 | 
			
		||||
        let hasProperties;
 | 
			
		||||
 | 
			
		||||
        if (layoutItem)
 | 
			
		||||
            hasProperties = this._ibusManager.hasProperties(layoutItem.ibusEngineId);
 | 
			
		||||
        else
 | 
			
		||||
            hasProperties = false;
 | 
			
		||||
 | 
			
		||||
        if (hasProperties)
 | 
			
		||||
            this._labelActors[this._currentSourceIndex].set_text(text);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _buildPropSection: function() {
 | 
			
		||||
        this._propSeparator.actor.hide();
 | 
			
		||||
        this._propSection.actor.hide();
 | 
			
		||||
        this._propSection.removeAll();
 | 
			
		||||
 | 
			
		||||
        this._buildPropSubMenu(this._propSection, properties);
 | 
			
		||||
        this._buildPropSubMenu(this._propSection, this._properties);
 | 
			
		||||
 | 
			
		||||
        if (!this._propSection.isEmpty()) {
 | 
			
		||||
            this._propSection.actor.show();
 | 
			
		||||
@@ -615,7 +468,8 @@ const InputSourceIndicator = new Lang.Class({
 | 
			
		||||
        for (let i = 0; (p = props.get(i)) != null; ++i) {
 | 
			
		||||
            let prop = p;
 | 
			
		||||
 | 
			
		||||
            if (!prop.get_visible())
 | 
			
		||||
            if (!this._propertyWhitelisted(prop) ||
 | 
			
		||||
                !prop.get_visible())
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            if (prop.get_key() == 'InputMode') {
 | 
			
		||||
@@ -626,17 +480,15 @@ const InputSourceIndicator = new Lang.Class({
 | 
			
		||||
                    text = prop.get_label().get_text();
 | 
			
		||||
 | 
			
		||||
                if (text && text.length > 0 && text.length < 3)
 | 
			
		||||
                    this._currentSource.indicatorLabel.set_text(text);
 | 
			
		||||
                    this._updateIndicatorLabel(text);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let item;
 | 
			
		||||
            switch (prop.get_prop_type()) {
 | 
			
		||||
            case IBus.PropType.MENU:
 | 
			
		||||
            let type = prop.get_prop_type();
 | 
			
		||||
            if (type == IBus.PropType.MENU) {
 | 
			
		||||
                item = new PopupMenu.PopupSubMenuMenuItem(prop.get_label().get_text());
 | 
			
		||||
                this._buildPropSubMenu(item.menu, prop.get_sub_props());
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case IBus.PropType.RADIO:
 | 
			
		||||
            } else if (type == IBus.PropType.RADIO) {
 | 
			
		||||
                item = new PopupMenu.PopupMenuItem(prop.get_label().get_text());
 | 
			
		||||
                item.prop = prop;
 | 
			
		||||
                radioGroup.push(item);
 | 
			
		||||
@@ -661,39 +513,7 @@ const InputSourceIndicator = new Lang.Class({
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }));
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case IBus.PropType.TOGGLE:
 | 
			
		||||
                item = new PopupMenu.PopupSwitchMenuItem(prop.get_label().get_text(), prop.get_state() == IBus.PropState.CHECKED);
 | 
			
		||||
                item.prop = prop;
 | 
			
		||||
                item.connect('toggled', Lang.bind(this, function() {
 | 
			
		||||
                    if (item.state) {
 | 
			
		||||
                        item.prop.set_state(IBus.PropState.CHECKED);
 | 
			
		||||
                        this._ibusManager.activateProperty(item.prop.get_key(),
 | 
			
		||||
                                                           IBus.PropState.CHECKED);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        item.prop.set_state(IBus.PropState.UNCHECKED);
 | 
			
		||||
                        this._ibusManager.activateProperty(item.prop.get_key(),
 | 
			
		||||
                                                           IBus.PropState.UNCHECKED);
 | 
			
		||||
                    }
 | 
			
		||||
                }));
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case IBus.PropType.NORMAL:
 | 
			
		||||
                item = new PopupMenu.PopupMenuItem(prop.get_label().get_text());
 | 
			
		||||
                item.prop = prop;
 | 
			
		||||
                item.connect('activate', Lang.bind(this, function() {
 | 
			
		||||
                    this._ibusManager.activateProperty(item.prop.get_key(),
 | 
			
		||||
                                                       IBus.PropState.CHECKED);
 | 
			
		||||
                }));
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case IBus.PropType.SEPARATOR:
 | 
			
		||||
                item = new PopupMenu.PopupSeparatorMenuItem();
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                log ('IBus property %s has invalid type %d'.format(prop.get_key(), type));
 | 
			
		||||
            } else {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -708,9 +528,8 @@ const InputSourceIndicator = new Lang.Class({
 | 
			
		||||
        // for those we don't actually display.
 | 
			
		||||
        let max_min_width = 0, max_natural_width = 0;
 | 
			
		||||
 | 
			
		||||
        for (let i in this._inputSources) {
 | 
			
		||||
            let is = this._inputSources[i];
 | 
			
		||||
            let [min_width, natural_width] = is.indicatorLabel.get_preferred_width(for_height);
 | 
			
		||||
        for (let i in this._labelActors) {
 | 
			
		||||
            let [min_width, natural_width] = this._labelActors[i].get_preferred_width(for_height);
 | 
			
		||||
            max_min_width = Math.max(max_min_width, min_width);
 | 
			
		||||
            max_natural_width = Math.max(max_natural_width, natural_width);
 | 
			
		||||
        }
 | 
			
		||||
@@ -722,9 +541,8 @@ const InputSourceIndicator = new Lang.Class({
 | 
			
		||||
    _containerGetPreferredHeight: function(container, for_width, alloc) {
 | 
			
		||||
        let max_min_height = 0, max_natural_height = 0;
 | 
			
		||||
 | 
			
		||||
        for (let i in this._inputSources) {
 | 
			
		||||
            let is = this._inputSources[i];
 | 
			
		||||
            let [min_height, natural_height] = is.indicatorLabel.get_preferred_height(for_width);
 | 
			
		||||
        for (let i in this._labelActors) {
 | 
			
		||||
            let [min_height, natural_height] = this._labelActors[i].get_preferred_height(for_width);
 | 
			
		||||
            max_min_height = Math.max(max_min_height, min_height);
 | 
			
		||||
            max_natural_height = Math.max(max_natural_height, natural_height);
 | 
			
		||||
        }
 | 
			
		||||
@@ -740,9 +558,7 @@ const InputSourceIndicator = new Lang.Class({
 | 
			
		||||
        box.y2 -= box.y1;
 | 
			
		||||
        box.y1 = 0;
 | 
			
		||||
 | 
			
		||||
        for (let i in this._inputSources) {
 | 
			
		||||
            let is = this._inputSources[i];
 | 
			
		||||
            is.indicatorLabel.allocate_align_fill(box, 0.5, 0, false, false, flags);
 | 
			
		||||
        }
 | 
			
		||||
        for (let i in this._labelActors)
 | 
			
		||||
            this._labelActors[i].allocate_align_fill(box, 0.5, 0, false, false, flags);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,6 @@ const Indicator = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.parent(null, _("Volume, network, battery"));
 | 
			
		||||
        this._box.style_class = 'lock-screen-status-button-box';
 | 
			
		||||
 | 
			
		||||
        this._volume = Main.panel.statusArea.volume;
 | 
			
		||||
        if (this._volume) {
 | 
			
		||||
 
 | 
			
		||||
@@ -611,11 +611,12 @@ const NMDevice = new Lang.Class({
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const NMDeviceSimple = new Lang.Class({
 | 
			
		||||
    Name: 'NMDeviceSimple',
 | 
			
		||||
const NMDeviceWired = new Lang.Class({
 | 
			
		||||
    Name: 'NMDeviceWired',
 | 
			
		||||
    Extends: NMDevice,
 | 
			
		||||
 | 
			
		||||
    _init: function(client, device, connections) {
 | 
			
		||||
        this._autoConnectionName = _("Auto Ethernet");
 | 
			
		||||
        this.category = NMConnectionCategory.WIRED;
 | 
			
		||||
 | 
			
		||||
        this.parent(client, device, connections);
 | 
			
		||||
@@ -630,18 +631,6 @@ const NMDeviceSimple = new Lang.Class({
 | 
			
		||||
        // we can do it here because addConnection and removeConnection
 | 
			
		||||
        // both call _createSection at some point
 | 
			
		||||
        this.section.actor.visible = this._connections.length > 1;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const NMDeviceWired = new Lang.Class({
 | 
			
		||||
    Name: 'NMDeviceWired',
 | 
			
		||||
    Extends: NMDeviceSimple,
 | 
			
		||||
 | 
			
		||||
    _init: function(client, device, connections) {
 | 
			
		||||
        this._autoConnectionName = _("Auto Ethernet");
 | 
			
		||||
        this.category = NMConnectionCategory.WIRED;
 | 
			
		||||
 | 
			
		||||
        this.parent(client, device, connections);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createAutomaticConnection: function() {
 | 
			
		||||
@@ -1651,7 +1640,6 @@ const NMApplet = new Lang.Class({
 | 
			
		||||
        this._dtypes[NetworkManager.DeviceType.WIFI] = NMDeviceWireless;
 | 
			
		||||
        this._dtypes[NetworkManager.DeviceType.MODEM] = NMDeviceModem;
 | 
			
		||||
        this._dtypes[NetworkManager.DeviceType.BT] = NMDeviceBluetooth;
 | 
			
		||||
        this._dtypes[NetworkManager.DeviceType.INFINIBAND] = NMDeviceSimple;
 | 
			
		||||
        // TODO: WiMax support
 | 
			
		||||
 | 
			
		||||
        // Connection types
 | 
			
		||||
@@ -1663,7 +1651,6 @@ const NMApplet = new Lang.Class({
 | 
			
		||||
        this._ctypes[NetworkManager.SETTING_BLUETOOTH_SETTING_NAME] = NMConnectionCategory.WWAN;
 | 
			
		||||
        this._ctypes[NetworkManager.SETTING_CDMA_SETTING_NAME] = NMConnectionCategory.WWAN;
 | 
			
		||||
        this._ctypes[NetworkManager.SETTING_GSM_SETTING_NAME] = NMConnectionCategory.WWAN;
 | 
			
		||||
        this._ctypes[NetworkManager.SETTING_INFINIBAND_SETTING_NAME] = NMConnectionCategory.WIRED;
 | 
			
		||||
        this._ctypes[NetworkManager.SETTING_VPN_SETTING_NAME] = NMConnectionCategory.VPN;
 | 
			
		||||
 | 
			
		||||
        this._settings = NMClient.RemoteSettings.new(null);
 | 
			
		||||
 
 | 
			
		||||
@@ -593,7 +593,6 @@ const UserMenuButton = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this.setSensitive(!Main.sessionMode.isLocked);
 | 
			
		||||
        this._updatePresenceIcon();
 | 
			
		||||
        this._updateUserName();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
 
 | 
			
		||||
@@ -39,15 +39,20 @@ const ViewSelector = new Lang.Class({
 | 
			
		||||
    Name: 'ViewSelector',
 | 
			
		||||
 | 
			
		||||
    _init : function(searchEntry, showAppsButton) {
 | 
			
		||||
        this.actor = new Shell.Stack({ name: 'viewSelector' });
 | 
			
		||||
        this.actor = new St.BoxLayout({ name: 'viewSelector',
 | 
			
		||||
                                        vertical: true });
 | 
			
		||||
 | 
			
		||||
        this._showAppsButton = showAppsButton;
 | 
			
		||||
        this._showAppsButton.connect('notify::checked', Lang.bind(this, this._onShowAppsButtonToggled));
 | 
			
		||||
 | 
			
		||||
        this._pageArea = new Shell.Stack();
 | 
			
		||||
        this.actor.add(this._pageArea, { x_fill: true,
 | 
			
		||||
                                         y_fill: true,
 | 
			
		||||
                                         expand: true });
 | 
			
		||||
 | 
			
		||||
        this._activePage = null;
 | 
			
		||||
 | 
			
		||||
        this.active = false;
 | 
			
		||||
        this._searchPending = false;
 | 
			
		||||
        this._searchActive = false;
 | 
			
		||||
        this._searchTimeoutId = 0;
 | 
			
		||||
 | 
			
		||||
        this._searchSystem = new Search.SearchSystem();
 | 
			
		||||
@@ -113,9 +118,6 @@ const ViewSelector = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        global.focus_manager.add_group(this._searchResults.actor);
 | 
			
		||||
 | 
			
		||||
        Main.overview.connect('item-drag-begin',
 | 
			
		||||
                              Lang.bind(this, this._resetShowAppsButton));
 | 
			
		||||
 | 
			
		||||
        this._stageKeyPressId = 0;
 | 
			
		||||
        Main.overview.connect('showing', Lang.bind(this,
 | 
			
		||||
            function () {
 | 
			
		||||
@@ -185,7 +187,7 @@ const ViewSelector = new Lang.Class({
 | 
			
		||||
                                                      this._a11yFocusPage(page);
 | 
			
		||||
                                                  })
 | 
			
		||||
                                            });;
 | 
			
		||||
        this.actor.add_actor(page);
 | 
			
		||||
        this._pageArea.add_actor(page);
 | 
			
		||||
        return page;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -206,11 +208,16 @@ const ViewSelector = new Lang.Class({
 | 
			
		||||
                             });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.emit('before-page-change');
 | 
			
		||||
        page.show();
 | 
			
		||||
        Tweener.addTween(page,
 | 
			
		||||
                         { opacity: 255,
 | 
			
		||||
                           time: 0.1,
 | 
			
		||||
                           transition: 'easeOutQuad'
 | 
			
		||||
                           transition: 'easeOutQuad',
 | 
			
		||||
                           onComplete: Lang.bind(this,
 | 
			
		||||
                               function() {
 | 
			
		||||
                                   this.emit('after-page-change');
 | 
			
		||||
                               })
 | 
			
		||||
                         });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -220,7 +227,7 @@ const ViewSelector = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onShowAppsButtonToggled: function() {
 | 
			
		||||
        if (this.active)
 | 
			
		||||
        if (this._searchActive)
 | 
			
		||||
            this.reset();
 | 
			
		||||
        else
 | 
			
		||||
            this._showPage(this._showAppsButton.checked ? this._appsPage
 | 
			
		||||
@@ -241,7 +248,7 @@ const ViewSelector = new Lang.Class({
 | 
			
		||||
        let symbol = event.get_key_symbol();
 | 
			
		||||
 | 
			
		||||
        if (symbol == Clutter.Escape) {
 | 
			
		||||
            if (this.active)
 | 
			
		||||
            if (this._searchActive)
 | 
			
		||||
                this.reset();
 | 
			
		||||
            else if (this._showAppsButton.checked)
 | 
			
		||||
                this._resetShowAppsButton();
 | 
			
		||||
@@ -249,9 +256,9 @@ const ViewSelector = new Lang.Class({
 | 
			
		||||
                Main.overview.hide();
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if (Clutter.keysym_to_unicode(symbol) ||
 | 
			
		||||
                   (symbol == Clutter.BackSpace && this.active)) {
 | 
			
		||||
                   (symbol == Clutter.BackSpace && this._searchActive)) {
 | 
			
		||||
            this.startSearch(event);
 | 
			
		||||
        } else if (!this.active) {
 | 
			
		||||
        } else if (!this._searchActive) {
 | 
			
		||||
            if (symbol == Clutter.Tab || symbol == Clutter.Down) {
 | 
			
		||||
                this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
 | 
			
		||||
                return true;
 | 
			
		||||
@@ -325,13 +332,15 @@ const ViewSelector = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onTextChanged: function (se, prop) {
 | 
			
		||||
        let searchPreviouslyActive = this.active;
 | 
			
		||||
        this.active = this._entry.get_text() != '';
 | 
			
		||||
        this._searchPending = this.active && !searchPreviouslyActive;
 | 
			
		||||
        if (this._searchPending) {
 | 
			
		||||
        let searchPreviouslyActive = this._searchActive;
 | 
			
		||||
        this._searchActive = this._entry.get_text() != '';
 | 
			
		||||
 | 
			
		||||
        let startSearch = this._searchActive && !searchPreviouslyActive;
 | 
			
		||||
        if (startSearch) {
 | 
			
		||||
            this._searchResults.startingSearch();
 | 
			
		||||
        }
 | 
			
		||||
        if (this.active) {
 | 
			
		||||
 | 
			
		||||
        if (this._searchActive) {
 | 
			
		||||
            this._entry.set_secondary_icon(this._activeIcon);
 | 
			
		||||
 | 
			
		||||
            if (this._iconClickedId == 0) {
 | 
			
		||||
@@ -347,14 +356,14 @@ const ViewSelector = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
            this._entry.set_secondary_icon(this._inactiveIcon);
 | 
			
		||||
            this._searchCancelled();
 | 
			
		||||
        }
 | 
			
		||||
        if (!this.active) {
 | 
			
		||||
 | 
			
		||||
            if (this._searchTimeoutId > 0) {
 | 
			
		||||
                Mainloop.source_remove(this._searchTimeoutId);
 | 
			
		||||
                this._searchTimeoutId = 0;
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._searchTimeoutId > 0)
 | 
			
		||||
            return;
 | 
			
		||||
        this._searchTimeoutId = Mainloop.timeout_add(150, Lang.bind(this, this._doSearch));
 | 
			
		||||
@@ -376,7 +385,7 @@ const ViewSelector = new Lang.Class({
 | 
			
		||||
            }
 | 
			
		||||
            this._searchResults.activateDefault();
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if (this.active) {
 | 
			
		||||
        } else if (this._searchActive) {
 | 
			
		||||
            let arrowNext, nextDirection;
 | 
			
		||||
            if (entry.get_text_direction() == Clutter.TextDirection.RTL) {
 | 
			
		||||
                arrowNext = Clutter.Left;
 | 
			
		||||
@@ -450,6 +459,10 @@ const ViewSelector = new Lang.Class({
 | 
			
		||||
        RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getAppsActive: function() {
 | 
			
		||||
        return this._showAppsButton.checked;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addSearchProvider: function(provider) {
 | 
			
		||||
        if (!this._shouldUseSearchProvider(provider))
 | 
			
		||||
            return;
 | 
			
		||||
@@ -461,6 +474,10 @@ const ViewSelector = new Lang.Class({
 | 
			
		||||
    removeSearchProvider: function(provider) {
 | 
			
		||||
        this._searchSystem.unregisterProvider(provider);
 | 
			
		||||
        this._searchResults.destroyProviderMeta(provider);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getSearchActive: function() {
 | 
			
		||||
        return this._searchActive;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
Signals.addSignalMethods(ViewSelector.prototype);
 | 
			
		||||
 
 | 
			
		||||
@@ -191,10 +191,8 @@ const WindowManager = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addKeybinding: function(name, settings, flags, modes, handler) {
 | 
			
		||||
        let action = global.display.add_keybinding(name, settings, flags, handler);
 | 
			
		||||
        if (action != Meta.KeyBindingAction.NONE)
 | 
			
		||||
        if (global.display.add_keybinding(name, settings, flags, handler))
 | 
			
		||||
            this.allowKeybinding(name, modes);
 | 
			
		||||
        return action;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    removeKeybinding: function(name) {
 | 
			
		||||
@@ -221,9 +219,7 @@ const WindowManager = new Lang.Class({
 | 
			
		||||
    _shouldAnimateActor: function(actor) {
 | 
			
		||||
        if (!this._shouldAnimate())
 | 
			
		||||
            return false;
 | 
			
		||||
        let windowType = actor.meta_window.get_window_type();
 | 
			
		||||
        return windowType == Meta.WindowType.NORMAL ||
 | 
			
		||||
            windowType == Meta.WindowType.MODAL_DIALOG;
 | 
			
		||||
        return actor.meta_window.get_window_type() == Meta.WindowType.NORMAL;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _removeEffect : function(list, actor) {
 | 
			
		||||
@@ -249,17 +245,16 @@ const WindowManager = new Lang.Class({
 | 
			
		||||
         */
 | 
			
		||||
        this._minimizing.push(actor);
 | 
			
		||||
 | 
			
		||||
        let monitor = Main.layoutManager.findMonitorForWindow(actor.meta_window);
 | 
			
		||||
        let xDest = monitor.x;
 | 
			
		||||
        let yDest = monitor.y;
 | 
			
		||||
        let primary = Main.layoutManager.primaryMonitor;
 | 
			
		||||
        let xDest = primary.x;
 | 
			
		||||
        if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
 | 
			
		||||
            xDest += monitor.width;
 | 
			
		||||
            xDest += primary.width;
 | 
			
		||||
 | 
			
		||||
        Tweener.addTween(actor,
 | 
			
		||||
                         { scale_x: 0.0,
 | 
			
		||||
                           scale_y: 0.0,
 | 
			
		||||
                           x: xDest,
 | 
			
		||||
                           y: yDest,
 | 
			
		||||
                           y: 0,
 | 
			
		||||
                           time: WINDOW_ANIMATION_TIME,
 | 
			
		||||
                           transition: 'easeOutQuad',
 | 
			
		||||
                           onComplete: this._minimizeWindowDone,
 | 
			
		||||
@@ -374,56 +369,57 @@ const WindowManager = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
            actor._windowType = type;
 | 
			
		||||
        }));
 | 
			
		||||
        if (actor.meta_window.is_attached_dialog()) {
 | 
			
		||||
            this._checkDimming(actor.get_meta_window().get_transient_for());
 | 
			
		||||
            if (this._shouldAnimate()) {
 | 
			
		||||
                actor.set_scale(1.0, 0.0);
 | 
			
		||||
                actor.scale_gravity = Clutter.Gravity.CENTER;
 | 
			
		||||
                actor.show();
 | 
			
		||||
                this._mapping.push(actor);
 | 
			
		||||
 | 
			
		||||
                Tweener.addTween(actor,
 | 
			
		||||
                                 { scale_y: 1,
 | 
			
		||||
                                   time: WINDOW_ANIMATION_TIME,
 | 
			
		||||
                                   transition: "easeOutQuad",
 | 
			
		||||
                                   onComplete: this._mapWindowDone,
 | 
			
		||||
                                   onCompleteScope: this,
 | 
			
		||||
                                   onCompleteParams: [shellwm, actor],
 | 
			
		||||
                                   onOverwrite: this._mapWindowOverwrite,
 | 
			
		||||
                                   onOverwriteScope: this,
 | 
			
		||||
                                   onOverwriteParams: [shellwm, actor]
 | 
			
		||||
                                 });
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            shellwm.completed_map(actor);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (!this._shouldAnimateActor(actor)) {
 | 
			
		||||
            shellwm.completed_map(actor);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (actor.meta_window.is_attached_dialog()) {
 | 
			
		||||
            /* Scale the window from the center of the parent */
 | 
			
		||||
            this._checkDimming(actor.get_meta_window().get_transient_for());
 | 
			
		||||
            actor.set_scale(1.0, 0.0);
 | 
			
		||||
            actor.scale_gravity = Clutter.Gravity.CENTER;
 | 
			
		||||
            actor.show();
 | 
			
		||||
            this._mapping.push(actor);
 | 
			
		||||
        actor.opacity = 0;
 | 
			
		||||
        actor.show();
 | 
			
		||||
 | 
			
		||||
            Tweener.addTween(actor,
 | 
			
		||||
                             { scale_y: 1,
 | 
			
		||||
                               time: WINDOW_ANIMATION_TIME,
 | 
			
		||||
                               transition: "easeOutQuad",
 | 
			
		||||
                               onComplete: this._mapWindowDone,
 | 
			
		||||
                               onCompleteScope: this,
 | 
			
		||||
                               onCompleteParams: [shellwm, actor],
 | 
			
		||||
                               onOverwrite: this._mapWindowOverwrite,
 | 
			
		||||
                               onOverwriteScope: this,
 | 
			
		||||
                               onOverwriteParams: [shellwm, actor]
 | 
			
		||||
                             });
 | 
			
		||||
        } else {
 | 
			
		||||
            /* Fade window in */
 | 
			
		||||
            actor.opacity = 0;
 | 
			
		||||
            actor.show();
 | 
			
		||||
            this._mapping.push(actor);
 | 
			
		||||
 | 
			
		||||
            Tweener.addTween(actor,
 | 
			
		||||
                             { opacity: 255,
 | 
			
		||||
                               time: WINDOW_ANIMATION_TIME,
 | 
			
		||||
                               transition: 'easeOutQuad',
 | 
			
		||||
                               onComplete: this._mapWindowDone,
 | 
			
		||||
                               onCompleteScope: this,
 | 
			
		||||
                               onCompleteParams: [shellwm, actor],
 | 
			
		||||
                               onOverwrite: this._mapWindowOverwrite,
 | 
			
		||||
                               onOverwriteScope: this,
 | 
			
		||||
                               onOverwriteParams: [shellwm, actor]
 | 
			
		||||
                             });
 | 
			
		||||
        }
 | 
			
		||||
        /* Fade window in */
 | 
			
		||||
        this._mapping.push(actor);
 | 
			
		||||
        Tweener.addTween(actor,
 | 
			
		||||
                         { opacity: 255,
 | 
			
		||||
                           time: WINDOW_ANIMATION_TIME,
 | 
			
		||||
                           transition: 'easeOutQuad',
 | 
			
		||||
                           onComplete: this._mapWindowDone,
 | 
			
		||||
                           onCompleteScope: this,
 | 
			
		||||
                           onCompleteParams: [shellwm, actor],
 | 
			
		||||
                           onOverwrite: this._mapWindowOverwrite,
 | 
			
		||||
                           onOverwriteScope: this,
 | 
			
		||||
                           onOverwriteParams: [shellwm, actor]
 | 
			
		||||
                         });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _mapWindowDone : function(shellwm, actor) {
 | 
			
		||||
        if (this._removeEffect(this._mapping, actor)) {
 | 
			
		||||
            Tweener.removeTweens(actor);
 | 
			
		||||
            actor.opacity = 255;
 | 
			
		||||
            actor.scale_y = 1;
 | 
			
		||||
            shellwm.completed_map(actor);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
@@ -445,21 +441,18 @@ const WindowManager = new Lang.Class({
 | 
			
		||||
                                                                 return win != window;
 | 
			
		||||
                                                             });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!this._shouldAnimateActor(actor)) {
 | 
			
		||||
            shellwm.completed_destroy(actor);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._destroying.push(actor);
 | 
			
		||||
 | 
			
		||||
        if (window.is_attached_dialog()) {
 | 
			
		||||
            let parent = window.get_transient_for();
 | 
			
		||||
            this._checkDimming(parent, window);
 | 
			
		||||
            if (!this._shouldAnimate()) {
 | 
			
		||||
                shellwm.completed_destroy(actor);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            actor.set_scale(1.0, 1.0);
 | 
			
		||||
            actor.scale_gravity = Clutter.Gravity.CENTER;
 | 
			
		||||
            actor.show();
 | 
			
		||||
            this._destroying.push(actor);
 | 
			
		||||
 | 
			
		||||
            actor._parentDestroyId = parent.connect('unmanaged', Lang.bind(this, function () {
 | 
			
		||||
                Tweener.removeTweens(actor);
 | 
			
		||||
 
 | 
			
		||||
@@ -124,8 +124,6 @@ const WindowClone = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this.actor._delegate = this;
 | 
			
		||||
 | 
			
		||||
        this._slot = [0, 0, 0, 0];
 | 
			
		||||
        this._dragSlot = [0, 0, 0, 0];
 | 
			
		||||
        this._stackAbove = null;
 | 
			
		||||
 | 
			
		||||
        this._sizeChangedId = this.realWindow.connect('size-changed',
 | 
			
		||||
@@ -161,15 +159,22 @@ const WindowClone = new Lang.Class({
 | 
			
		||||
        this._selected = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    set slot(slot) {
 | 
			
		||||
        this._slot = slot;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get slot() {
 | 
			
		||||
        if (this.inDrag)
 | 
			
		||||
            return this._dragSlot;
 | 
			
		||||
        else
 | 
			
		||||
            return this._slot;
 | 
			
		||||
        let x, y, w, h;
 | 
			
		||||
 | 
			
		||||
        if (this.inDrag) {
 | 
			
		||||
            x = this.dragOrigX;
 | 
			
		||||
            y = this.dragOrigY;
 | 
			
		||||
            w = this.actor.width * this.dragOrigScale;
 | 
			
		||||
            h = this.actor.height * this.dragOrigScale;
 | 
			
		||||
        } else {
 | 
			
		||||
            x = this.actor.x;
 | 
			
		||||
            y = this.actor.y;
 | 
			
		||||
            w = this.actor.width * this.actor.scale_x;
 | 
			
		||||
            h = this.actor.height * this.actor.scale_y;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [x, y, w, h];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setStackAbove: function (actor) {
 | 
			
		||||
@@ -387,7 +392,6 @@ const WindowClone = new Lang.Class({
 | 
			
		||||
        if (this._zooming)
 | 
			
		||||
            this._zoomEnd();
 | 
			
		||||
 | 
			
		||||
        this._dragSlot = this._slot;
 | 
			
		||||
        [this.dragOrigX, this.dragOrigY] = this.actor.get_position();
 | 
			
		||||
        this.dragOrigScale = this.actor.scale_x;
 | 
			
		||||
        this.inDrag = true;
 | 
			
		||||
@@ -441,8 +445,6 @@ const WindowOverlay = new Lang.Class({
 | 
			
		||||
        this._parentActor = parentActor;
 | 
			
		||||
        this._hidden = false;
 | 
			
		||||
 | 
			
		||||
        this._settings = new Gio.Settings({ schema: BUTTON_LAYOUT_SCHEMA });
 | 
			
		||||
 | 
			
		||||
        this.borderSize = 0;
 | 
			
		||||
        this.border = new St.Bin({ style_class: 'window-clone-border' });
 | 
			
		||||
 | 
			
		||||
@@ -454,7 +456,11 @@ const WindowOverlay = new Lang.Class({
 | 
			
		||||
        this._updateCaptionId = metaWindow.connect('notify::title',
 | 
			
		||||
            Lang.bind(this, function(w) {
 | 
			
		||||
                this.title.text = w.title;
 | 
			
		||||
                this.relayout(false);
 | 
			
		||||
                // we need this for the next call to get_preferred_width
 | 
			
		||||
                // to return useful results
 | 
			
		||||
                this.title.set_size(-1, -1);
 | 
			
		||||
 | 
			
		||||
                this._repositionSelf();
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        let button = new St.Button({ style_class: 'window-close' });
 | 
			
		||||
@@ -529,13 +535,27 @@ const WindowOverlay = new Lang.Class({
 | 
			
		||||
        return [this.borderSize, this.borderSize];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    relayout: function(animate) {
 | 
			
		||||
    _repositionSelf: function() {
 | 
			
		||||
        let [cloneX, cloneY, cloneWidth, cloneHeight] = this._windowClone.slot;
 | 
			
		||||
        this.updatePositions(cloneX, cloneY, cloneWidth, cloneHeight, false);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @cloneX: x position of windowClone
 | 
			
		||||
     * @cloneY: y position of windowClone
 | 
			
		||||
     * @cloneWidth: width of windowClone
 | 
			
		||||
     * @cloneHeight height of windowClone
 | 
			
		||||
     */
 | 
			
		||||
    // These parameters are not the values retrieved with
 | 
			
		||||
    // get_transformed_position() and get_transformed_size(),
 | 
			
		||||
    // as windowClone might be moving.
 | 
			
		||||
    // See Workspace._showWindowOverlay
 | 
			
		||||
    updatePositions: function(cloneX, cloneY, cloneWidth, cloneHeight, animate) {
 | 
			
		||||
        let button = this.closeButton;
 | 
			
		||||
        let title = this.title;
 | 
			
		||||
 | 
			
		||||
        let layout = this._settings.get_string(BUTTON_LAYOUT_KEY);
 | 
			
		||||
        let settings = new Gio.Settings({ schema: BUTTON_LAYOUT_SCHEMA });
 | 
			
		||||
        let layout = settings.get_string(BUTTON_LAYOUT_KEY);
 | 
			
		||||
        let rtl = Clutter.get_default_text_direction() == Clutter.TextDirection.RTL;
 | 
			
		||||
 | 
			
		||||
        let split = layout.split(":");
 | 
			
		||||
@@ -557,16 +577,8 @@ const WindowOverlay = new Lang.Class({
 | 
			
		||||
        else
 | 
			
		||||
            button.set_position(Math.floor(buttonX), Math.floor(buttonY));
 | 
			
		||||
 | 
			
		||||
        // Clutter.Actor.get_preferred_width() will return the fixed width if one
 | 
			
		||||
        // is set, so we need to reset the width by calling set_width(-1), to forward
 | 
			
		||||
        // the call down to StLabel.
 | 
			
		||||
        // We also need to save and restore the current width, otherwise the animation
 | 
			
		||||
        // starts from the wrong point.
 | 
			
		||||
        let prevTitleWidth = title.width;
 | 
			
		||||
        title.set_width(-1);
 | 
			
		||||
        let [titleMinWidth, titleNatWidth] = title.get_preferred_width(-1);
 | 
			
		||||
        let titleWidth = Math.max(titleMinWidth, Math.min(titleNatWidth, cloneWidth));
 | 
			
		||||
        title.width = prevTitleWidth;
 | 
			
		||||
 | 
			
		||||
        let titleX = cloneX + (cloneWidth - titleWidth) / 2;
 | 
			
		||||
        let titleY = cloneY + cloneHeight + title._spacing;
 | 
			
		||||
@@ -1172,8 +1184,8 @@ const Workspace = new Lang.Class({
 | 
			
		||||
            let slot = slots[i];
 | 
			
		||||
            let clone = clones[i];
 | 
			
		||||
            let metaWindow = clone.metaWindow;
 | 
			
		||||
            let overlay = clone.overlay;
 | 
			
		||||
            clone.slotId = i;
 | 
			
		||||
            let mainIndex = this._lookupIndex(metaWindow);
 | 
			
		||||
            let overlay = this._windowOverlays[mainIndex];
 | 
			
		||||
 | 
			
		||||
            // Positioning a window currently being dragged must be avoided;
 | 
			
		||||
            // we'll just leave a blank spot in the layout for it.
 | 
			
		||||
@@ -1181,7 +1193,6 @@ const Workspace = new Lang.Class({
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            let [x, y, scale] = slot;
 | 
			
		||||
            clone.slot = [x, y, clone.actor.width * scale, clone.actor.height * scale];
 | 
			
		||||
 | 
			
		||||
            if (overlay && initialPositioning)
 | 
			
		||||
                overlay.hide();
 | 
			
		||||
@@ -1213,7 +1224,7 @@ const Workspace = new Lang.Class({
 | 
			
		||||
                Tweener.removeTweens(clone.actor);
 | 
			
		||||
                clone.actor.set_position(x, y);
 | 
			
		||||
                clone.actor.set_scale(scale, scale);
 | 
			
		||||
                clone.overlay.relayout(false);
 | 
			
		||||
                this._updateWindowOverlayPositions(clone, overlay, x, y, scale, false);
 | 
			
		||||
                this._showWindowOverlay(clone, overlay, isOnCurrentWorkspace);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -1248,7 +1259,15 @@ const Workspace = new Lang.Class({
 | 
			
		||||
                           })
 | 
			
		||||
                         });
 | 
			
		||||
 | 
			
		||||
        clone.overlay.relayout(true);
 | 
			
		||||
        this._updateWindowOverlayPositions(clone, overlay, x, y, scale, true);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateWindowOverlayPositions: function(clone, overlay, x, y, scale, animate) {
 | 
			
		||||
        if (!overlay)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let [cloneWidth, cloneHeight] = clone.actor.get_size();
 | 
			
		||||
        overlay.updatePositions(x, y, cloneWidth * scale, cloneHeight * scale, animate);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _showWindowOverlay: function(clone, overlay, fade) {
 | 
			
		||||
@@ -1383,10 +1402,9 @@ const Workspace = new Lang.Class({
 | 
			
		||||
            let scale = win._overviewHint.scale;
 | 
			
		||||
            delete win._overviewHint;
 | 
			
		||||
 | 
			
		||||
            clone.slot = [x, y, clone.actor.width * scale, clone.actor.height * scale];
 | 
			
		||||
            clone.actor.set_position (x, y);
 | 
			
		||||
            clone.actor.set_scale (scale, scale);
 | 
			
		||||
            clone.overlay.relayout(false);
 | 
			
		||||
            this._updateWindowOverlayPositions(clone, overlay, x, y, scale, false);
 | 
			
		||||
        } else {
 | 
			
		||||
            // Position new windows at the top corner of the workspace rather
 | 
			
		||||
            // than where they were placed for real to avoid the window
 | 
			
		||||
@@ -1551,7 +1569,6 @@ const Workspace = new Lang.Class({
 | 
			
		||||
    _addWindowClone : function(win) {
 | 
			
		||||
        let clone = new WindowClone(win, this);
 | 
			
		||||
        let overlay = new WindowOverlay(clone, this._windowOverlaysGroup);
 | 
			
		||||
        clone.overlay = overlay;
 | 
			
		||||
 | 
			
		||||
        clone.connect('selected',
 | 
			
		||||
                      Lang.bind(this, this._onCloneSelected));
 | 
			
		||||
 
 | 
			
		||||
@@ -496,6 +496,8 @@ const ThumbnailsBox = new Lang.Class({
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.actor = new Shell.GenericContainer({ reactive: true,
 | 
			
		||||
                                                  style_class: 'workspace-thumbnails',
 | 
			
		||||
                                                  can_focus: true,
 | 
			
		||||
                                                  track_hover: true,
 | 
			
		||||
                                                  request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT });
 | 
			
		||||
        this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
 | 
			
		||||
        this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
 | 
			
		||||
@@ -524,6 +526,7 @@ const ThumbnailsBox = new Lang.Class({
 | 
			
		||||
        this._indicator = indicator;
 | 
			
		||||
        this.actor.add_actor(indicator);
 | 
			
		||||
 | 
			
		||||
        this._inDrag = false;
 | 
			
		||||
        this._dropWorkspace = -1;
 | 
			
		||||
        this._dropPlaceholderPos = -1;
 | 
			
		||||
        this._dropPlaceholder = new St.Bin({ style_class: 'placeholder' });
 | 
			
		||||
@@ -544,7 +547,13 @@ const ThumbnailsBox = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('button-press-event', function() { return true; });
 | 
			
		||||
        this.actor.connect('button-release-event', Lang.bind(this, this._onButtonRelease));
 | 
			
		||||
        this.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
 | 
			
		||||
        this.actor.connect('scroll-event',
 | 
			
		||||
                           Lang.bind(this, this._onScrollEvent));
 | 
			
		||||
        this.actor.connect('key-release-event',
 | 
			
		||||
                           Lang.bind(this, this._onKeyRelease));
 | 
			
		||||
 | 
			
		||||
        Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._updateTranslation));
 | 
			
		||||
        this.actor.connect('notify::hover', Lang.bind(this, this._updateTranslation));
 | 
			
		||||
 | 
			
		||||
        Main.overview.connect('showing',
 | 
			
		||||
                              Lang.bind(this, this._createThumbnails));
 | 
			
		||||
@@ -569,6 +578,40 @@ const ThumbnailsBox = new Lang.Class({
 | 
			
		||||
            Lang.bind(this, this._updateSwitcherVisibility));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getInitialTranslation: function() {
 | 
			
		||||
        // Always show the pager when hover, during a drag, or if workspaces are
 | 
			
		||||
        // actually used, e.g. there are windows on more than one
 | 
			
		||||
        let alwaysZoomOut = this.actor.hover || this._inDrag || global.screen.n_workspaces > 2;
 | 
			
		||||
 | 
			
		||||
        if (!alwaysZoomOut) {
 | 
			
		||||
            let monitors = Main.layoutManager.monitors;
 | 
			
		||||
            let primary = Main.layoutManager.primaryMonitor;
 | 
			
		||||
 | 
			
		||||
            /* 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) {
 | 
			
		||||
                    alwaysZoomOut = true;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (alwaysZoomOut)
 | 
			
		||||
            return 0;
 | 
			
		||||
 | 
			
		||||
        let visibleWidth = this.actor.get_theme_node().get_length('visible-width');
 | 
			
		||||
        let rtl = (this.actor.get_text_direction() == Clutter.TextDirection.RTL);
 | 
			
		||||
        return rtl ? (visibleWidth - this.actor.width) : (this.actor.width - visibleWidth);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateTranslation: function() {
 | 
			
		||||
        Tweener.addTween(this, { slideX: this._getInitialTranslation(),
 | 
			
		||||
                                 time: SLIDE_ANIMATION_TIME,
 | 
			
		||||
                                 transition: 'easeOutQuad' });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateSwitcherVisibility: function() {
 | 
			
		||||
        this.actor.visible =
 | 
			
		||||
            this._settings.get_boolean('dynamic-workspaces') ||
 | 
			
		||||
@@ -592,6 +635,9 @@ const ThumbnailsBox = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragBegin: function() {
 | 
			
		||||
        this._inDrag = true;
 | 
			
		||||
        this._updateTranslation();
 | 
			
		||||
 | 
			
		||||
        this._dragCancelled = false;
 | 
			
		||||
        this._dragMonitor = {
 | 
			
		||||
            dragMotion: Lang.bind(this, this._onDragMotion)
 | 
			
		||||
@@ -614,6 +660,8 @@ const ThumbnailsBox = new Lang.Class({
 | 
			
		||||
    _endDrag: function() {
 | 
			
		||||
        this._clearDragPlaceholder();
 | 
			
		||||
        DND.removeDragMonitor(this._dragMonitor);
 | 
			
		||||
        this._inDrag = false;
 | 
			
		||||
        this._updateTranslation();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragMotion: function(dragEvent) {
 | 
			
		||||
@@ -746,7 +794,7 @@ const ThumbnailsBox = new Lang.Class({
 | 
			
		||||
            global.screen.connect('notify::n-workspaces',
 | 
			
		||||
                                  Lang.bind(this, this._workspacesChanged));
 | 
			
		||||
        this._syncStackingId =
 | 
			
		||||
            Main.overview.connect('windows-restacked',
 | 
			
		||||
            Main.overview.connect('sync-window-stacking',
 | 
			
		||||
                                  Lang.bind(this, this._syncStacking));
 | 
			
		||||
 | 
			
		||||
        this._targetScale = 0;
 | 
			
		||||
@@ -770,6 +818,11 @@ const ThumbnailsBox = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this.addThumbnails(0, global.screen.n_workspaces);
 | 
			
		||||
 | 
			
		||||
        // reset any translation and make sure the actor is visible when
 | 
			
		||||
        // entering the overview
 | 
			
		||||
        this.slideX = this._getInitialTranslation();
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
 | 
			
		||||
        this._updateSwitcherVisibility();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -782,7 +835,6 @@ const ThumbnailsBox = new Lang.Class({
 | 
			
		||||
            global.screen.disconnect(this._nWorkspacesNotifyId);
 | 
			
		||||
            this._nWorkspacesNotifyId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._syncStackingId > 0) {
 | 
			
		||||
            Main.overview.disconnect(this._syncStackingId);
 | 
			
		||||
            this._syncStackingId = 0;
 | 
			
		||||
@@ -793,6 +845,49 @@ const ThumbnailsBox = new Lang.Class({
 | 
			
		||||
        this._thumbnails = [];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _computeTranslation: function() {
 | 
			
		||||
        let rtl = (this.actor.get_text_direction() == Clutter.TextDirection.RTL);
 | 
			
		||||
 | 
			
		||||
        if (rtl)
 | 
			
		||||
            return - this.actor.width;
 | 
			
		||||
        else
 | 
			
		||||
            return this.actor.width;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get slideX() {
 | 
			
		||||
        return this._slideX;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    set slideX(value) {
 | 
			
		||||
        this._slideX = value;
 | 
			
		||||
        this.actor.translation_x = this._slideX;
 | 
			
		||||
 | 
			
		||||
        if (this._slideX > 0) {
 | 
			
		||||
            let rect = new Clutter.Rect();
 | 
			
		||||
            rect.size.width = this._background.width - this._slideX;
 | 
			
		||||
            rect.size.height = this._background.height;
 | 
			
		||||
            this.actor.clip_rect = rect;
 | 
			
		||||
        } else {
 | 
			
		||||
            this.actor.clip_rect = null;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    show: function() {
 | 
			
		||||
        this.actor.show();
 | 
			
		||||
        this._updateTranslation();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hide: function() {
 | 
			
		||||
        let hiddenX = this._computeTranslation();
 | 
			
		||||
        Tweener.addTween(this, { slideX: hiddenX,
 | 
			
		||||
                                 transition: 'easeOutQuad',
 | 
			
		||||
                                 time: SLIDE_ANIMATION_TIME,
 | 
			
		||||
                                 onComplete: Lang.bind(this, function () {
 | 
			
		||||
                                     this.actor.hide();
 | 
			
		||||
                                 })
 | 
			
		||||
                               });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _workspacesChanged: function() {
 | 
			
		||||
        let oldNumWorkspaces = this._thumbnails.length;
 | 
			
		||||
        let newNumWorkspaces = global.screen.n_workspaces;
 | 
			
		||||
@@ -862,7 +957,7 @@ const ThumbnailsBox = new Lang.Class({
 | 
			
		||||
        this._queueUpdateStates();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _syncStacking: function(overview, stackIndices) {
 | 
			
		||||
    _syncStacking: function(actor, stackIndices) {
 | 
			
		||||
        for (let i = 0; i < this._thumbnails.length; i++)
 | 
			
		||||
            this._thumbnails[i].syncStacking(stackIndices);
 | 
			
		||||
    },
 | 
			
		||||
@@ -1228,5 +1323,19 @@ const ThumbnailsBox = new Lang.Class({
 | 
			
		||||
            Main.wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onKeyRelease: function (actor, event) {
 | 
			
		||||
        switch (event.get_key_symbol()) {
 | 
			
		||||
        case Clutter.KEY_Up:
 | 
			
		||||
            Main.wm.actionMoveWorkspace(Meta.MotionDirection.UP);
 | 
			
		||||
            break;
 | 
			
		||||
        case Clutter.KEY_Down:
 | 
			
		||||
            Main.wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
 | 
			
		||||
            break;
 | 
			
		||||
        case Clutter.KEY_Return:
 | 
			
		||||
            Main.overview.toggle();
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -23,8 +23,6 @@ const MAX_WORKSPACES = 16;
 | 
			
		||||
 | 
			
		||||
const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
 | 
			
		||||
 | 
			
		||||
const CONTROLS_POP_IN_TIME = 0.1;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const WorkspacesView = new Lang.Class({
 | 
			
		||||
    Name: 'WorkspacesView',
 | 
			
		||||
@@ -69,7 +67,7 @@ const WorkspacesView = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        // Add workspace actors
 | 
			
		||||
        for (let w = 0; w < global.screen.n_workspaces; w++)
 | 
			
		||||
            this.actor.add_actor(this._workspaces[w].actor);
 | 
			
		||||
            this._workspaces[w].actor.reparent(this.actor);
 | 
			
		||||
        this._workspaces[activeWorkspaceIndex].actor.raise_top();
 | 
			
		||||
 | 
			
		||||
        this._extraWorkspaces = [];
 | 
			
		||||
@@ -129,10 +127,11 @@ const WorkspacesView = new Lang.Class({
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            let ws = new Workspace.Workspace(null, i);
 | 
			
		||||
            ws.setGeometry(monitors[i].x,
 | 
			
		||||
                           monitors[i].y,
 | 
			
		||||
                           monitors[i].width,
 | 
			
		||||
                           monitors[i].height);
 | 
			
		||||
            let overviewSpacing = Main.overview._spacing;
 | 
			
		||||
            ws.setGeometry(monitors[i].x + overviewSpacing/2,
 | 
			
		||||
                           monitors[i].y + overviewSpacing/2,
 | 
			
		||||
                           monitors[i].width - overviewSpacing,
 | 
			
		||||
                           monitors[i].height - overviewSpacing);
 | 
			
		||||
            global.overlay_group.add_actor(ws.actor);
 | 
			
		||||
            this._extraWorkspaces.push(ws);
 | 
			
		||||
        }
 | 
			
		||||
@@ -437,24 +436,11 @@ const WorkspacesDisplay = new Lang.Class({
 | 
			
		||||
    Name: 'WorkspacesDisplay',
 | 
			
		||||
 | 
			
		||||
    _init: function() {
 | 
			
		||||
        this.actor = new Shell.GenericContainer({ style_class: 'workspaces-display' });
 | 
			
		||||
        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 = new Shell.GenericContainer();
 | 
			
		||||
        this.actor.connect('allocate', Lang.bind(this, this._updateWorkspacesGeometry));
 | 
			
		||||
        this.actor.connect('parent-set', Lang.bind(this, this._parentSet));
 | 
			
		||||
        this.actor.set_clip_to_allocation(true);
 | 
			
		||||
 | 
			
		||||
        this._spacing = 0;
 | 
			
		||||
        this.actor.connect('style-changed', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                let node = this.actor.get_theme_node();
 | 
			
		||||
                let spacing = node.get_length('spacing');
 | 
			
		||||
                if (spacing != this._spacing) {
 | 
			
		||||
                    this._spacing = spacing;
 | 
			
		||||
                    this._updateWorkspacesGeometry();
 | 
			
		||||
                }
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        let clickAction = new Clutter.ClickAction()
 | 
			
		||||
        clickAction.connect('clicked', Lang.bind(this, function(action) {
 | 
			
		||||
            // Only switch to the workspace when there's no application
 | 
			
		||||
@@ -482,25 +468,9 @@ const WorkspacesDisplay = new Lang.Class({
 | 
			
		||||
        Main.overview.addAction(panAction);
 | 
			
		||||
        this.actor.bind_property('mapped', panAction, 'enabled', GObject.BindingFlags.SYNC_CREATE);
 | 
			
		||||
 | 
			
		||||
        let controls = new St.Bin({ style_class: 'workspace-controls',
 | 
			
		||||
                                    request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT,
 | 
			
		||||
                                    y_align: St.Align.START,
 | 
			
		||||
                                    y_fill: true });
 | 
			
		||||
        this._controls = controls;
 | 
			
		||||
        this.actor.add_actor(controls);
 | 
			
		||||
 | 
			
		||||
        controls.reactive = true;
 | 
			
		||||
        controls.track_hover = true;
 | 
			
		||||
        controls.connect('notify::hover',
 | 
			
		||||
                         Lang.bind(this, this._onControlsHoverChanged));
 | 
			
		||||
 | 
			
		||||
        this._primaryIndex = Main.layoutManager.primaryIndex;
 | 
			
		||||
 | 
			
		||||
        this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
 | 
			
		||||
        controls.add_actor(this._thumbnailsBox.actor);
 | 
			
		||||
 | 
			
		||||
        this._workspacesViews = [];
 | 
			
		||||
        this._workspaces = [];
 | 
			
		||||
        this._workspacesViews = null;
 | 
			
		||||
        this._primaryScrollAdjustment = null;
 | 
			
		||||
 | 
			
		||||
        this._settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA });
 | 
			
		||||
@@ -512,26 +482,6 @@ const WorkspacesDisplay = new Lang.Class({
 | 
			
		||||
        this._inDrag = false;
 | 
			
		||||
        this._cancelledDrag = false;
 | 
			
		||||
 | 
			
		||||
        this._controlsInitiallyHovered = false;
 | 
			
		||||
        this._alwaysZoomOut = false;
 | 
			
		||||
        this._zoomOut = false;
 | 
			
		||||
        this._zoomFraction = 0;
 | 
			
		||||
 | 
			
		||||
        this._updateAlwaysZoom();
 | 
			
		||||
 | 
			
		||||
        // If we stop hiding the overview on layout changes, we will need to
 | 
			
		||||
        // update the _workspacesViews here
 | 
			
		||||
        Main.layoutManager.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();
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        global.screen.connect('notify::n-workspaces',
 | 
			
		||||
                              Lang.bind(this, this._workspacesChanged));
 | 
			
		||||
 | 
			
		||||
@@ -556,29 +506,10 @@ const WorkspacesDisplay = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    show: function() {
 | 
			
		||||
        if(!this._alwaysZoomOut) {
 | 
			
		||||
            let [mouseX, mouseY] = global.get_pointer();
 | 
			
		||||
            let [x, y] = this._controls.get_transformed_position();
 | 
			
		||||
            let [width, height] = this._controls.get_transformed_size();
 | 
			
		||||
            let visibleWidth = this._controls.get_theme_node().get_length('visible-width');
 | 
			
		||||
            let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
 | 
			
		||||
            if(rtl)
 | 
			
		||||
                x = x + width - visibleWidth;
 | 
			
		||||
            if(mouseX > x - 0.5 && mouseX < x + visibleWidth + 0.5 &&
 | 
			
		||||
               mouseY > y - 0.5 && mouseY < y + height + 0.5)
 | 
			
		||||
                this._controlsInitiallyHovered = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._zoomOut = this._alwaysZoomOut;
 | 
			
		||||
        this._zoomFraction = this._alwaysZoomOut ? 1 : 0;
 | 
			
		||||
        this._updateZoom();
 | 
			
		||||
 | 
			
		||||
        this._controls.show();
 | 
			
		||||
 | 
			
		||||
        this._updateWorkspacesViews();
 | 
			
		||||
 | 
			
		||||
        this._restackedNotifyId =
 | 
			
		||||
            Main.overview.connect('windows-restacked',
 | 
			
		||||
            Main.overview.connect('sync-window-stacking',
 | 
			
		||||
                                  Lang.bind(this, this._onRestacked));
 | 
			
		||||
 | 
			
		||||
        if (this._itemDragBeginId == 0)
 | 
			
		||||
@@ -608,11 +539,6 @@ const WorkspacesDisplay = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hide: function() {
 | 
			
		||||
        this._controls.hide();
 | 
			
		||||
 | 
			
		||||
        if (!this._alwaysZoomOut)
 | 
			
		||||
            this.zoomFraction = 0;
 | 
			
		||||
 | 
			
		||||
        if (this._restackedNotifyId > 0){
 | 
			
		||||
            Main.overview.disconnect(this._restackedNotifyId);
 | 
			
		||||
            this._restackedNotifyId = 0;
 | 
			
		||||
@@ -644,7 +570,7 @@ const WorkspacesDisplay = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < this._workspacesViews.length; i++)
 | 
			
		||||
            this._workspacesViews[i].destroy();
 | 
			
		||||
        this._workspacesViews = [];
 | 
			
		||||
        this._workspacesViews = null;
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < this._workspaces.length; i++)
 | 
			
		||||
            for (let w = 0; w < this._workspaces[i].length; w++) {
 | 
			
		||||
@@ -663,12 +589,14 @@ const WorkspacesDisplay = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateWorkspacesViews: function() {
 | 
			
		||||
        for (let i = 0; i < this._workspacesViews.length; i++)
 | 
			
		||||
            this._workspacesViews[i].destroy();
 | 
			
		||||
        if (this._workspacesViews)
 | 
			
		||||
            for (let i = 0; i < this._workspacesViews.length; i++)
 | 
			
		||||
                this._workspacesViews[i].destroy();
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < this._workspaces.length; i++)
 | 
			
		||||
            for (let w = 0; w < this._workspaces[i].length; w++)
 | 
			
		||||
                this._workspaces[i][w].destroy();
 | 
			
		||||
        if (this._workspaces)
 | 
			
		||||
            for (let i = 0; i < this._workspaces.length; i++)
 | 
			
		||||
                for (let w = 0; w < this._workspaces[i].length; w++)
 | 
			
		||||
                    this._workspaces[i][w].destroy();
 | 
			
		||||
 | 
			
		||||
        this._workspacesViews = [];
 | 
			
		||||
        this._workspaces = [];
 | 
			
		||||
@@ -716,7 +644,7 @@ const WorkspacesDisplay = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getPrimaryView: function() {
 | 
			
		||||
        if (!this._workspacesViews.length)
 | 
			
		||||
        if (!this._workspacesViews)
 | 
			
		||||
            return null;
 | 
			
		||||
        if (this._workspacesOnlyOnPrimary)
 | 
			
		||||
            return this._workspacesViews[0];
 | 
			
		||||
@@ -728,76 +656,6 @@ const WorkspacesDisplay = new Lang.Class({
 | 
			
		||||
        return this._getPrimaryView().getActiveWorkspace().hasMaximizedWindows();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // zoomFraction property allows us to tween the controls sliding in and out
 | 
			
		||||
    set zoomFraction(fraction) {
 | 
			
		||||
        this._zoomFraction = fraction;
 | 
			
		||||
        this.actor.queue_relayout();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get zoomFraction() {
 | 
			
		||||
        return this._zoomFraction;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateAlwaysZoom: function()  {
 | 
			
		||||
        // Always show the pager if workspaces are actually used,
 | 
			
		||||
        // e.g. there are windows on more than one
 | 
			
		||||
        this._alwaysZoomOut = global.screen.n_workspaces > 2;
 | 
			
		||||
 | 
			
		||||
        if (this._alwaysZoomOut)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let monitors = Main.layoutManager.monitors;
 | 
			
		||||
        let primary = Main.layoutManager.primaryMonitor;
 | 
			
		||||
 | 
			
		||||
        /* 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);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getPreferredHeight: function (actor, forWidth, alloc) {
 | 
			
		||||
        // pass through the call in case the child needs it, but report 0x0
 | 
			
		||||
        this._controls.get_preferred_height(forWidth);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _allocate: function (actor, box, flags) {
 | 
			
		||||
        let childBox = new Clutter.ActorBox();
 | 
			
		||||
 | 
			
		||||
        let totalWidth = box.x2 - box.x1;
 | 
			
		||||
 | 
			
		||||
        // width of the controls
 | 
			
		||||
        let [controlsMin, controlsNatural] = this._controls.get_preferred_width(box.y2 - box.y1);
 | 
			
		||||
 | 
			
		||||
        // Amount of space on the screen we reserve for the visible control
 | 
			
		||||
        let controlsVisible = this._controls.get_theme_node().get_length('visible-width');
 | 
			
		||||
        let controlsReserved = controlsVisible * (1 - this._zoomFraction) + controlsNatural * this._zoomFraction;
 | 
			
		||||
 | 
			
		||||
        let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
 | 
			
		||||
        if (rtl) {
 | 
			
		||||
            childBox.x2 = controlsReserved;
 | 
			
		||||
            childBox.x1 = childBox.x2 - controlsNatural;
 | 
			
		||||
        } else {
 | 
			
		||||
            childBox.x1 = totalWidth - controlsReserved;
 | 
			
		||||
            childBox.x2 = childBox.x1 + controlsNatural;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        childBox.y1 = 0;
 | 
			
		||||
        childBox.y2 = box.y2- box.y1;
 | 
			
		||||
        this._controls.allocate(childBox, flags);
 | 
			
		||||
 | 
			
		||||
        this._updateWorkspacesGeometry();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _parentSet: function(actor, oldParent) {
 | 
			
		||||
        if (oldParent && this._notifyOpacityId)
 | 
			
		||||
            oldParent.disconnect(this._notifyOpacityId);
 | 
			
		||||
@@ -825,7 +683,7 @@ const WorkspacesDisplay = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateWorkspacesGeometry: function() {
 | 
			
		||||
        if (!this._workspacesViews.length)
 | 
			
		||||
        if (!this._workspacesViews)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let fullWidth = this.actor.allocation.x2 - this.actor.allocation.x1;
 | 
			
		||||
@@ -834,23 +692,19 @@ const WorkspacesDisplay = new Lang.Class({
 | 
			
		||||
        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 [x, y] = this.actor.get_transformed_position();
 | 
			
		||||
 | 
			
		||||
        let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
 | 
			
		||||
 | 
			
		||||
        let clipWidth = width - controlsVisible;
 | 
			
		||||
        let clipWidth = width;
 | 
			
		||||
        let clipHeight = fullHeight;
 | 
			
		||||
        let clipX = rtl ? x + controlsVisible : x;
 | 
			
		||||
        let clipX = x;
 | 
			
		||||
        let clipY = y + (fullHeight - clipHeight) / 2;
 | 
			
		||||
 | 
			
		||||
        let widthAdjust = this._zoomOut ? controlsNatural : controlsVisible;
 | 
			
		||||
        widthAdjust += this._spacing;
 | 
			
		||||
        width -= widthAdjust;
 | 
			
		||||
        let overviewSpacing = Main.overview._spacing;
 | 
			
		||||
        width -= overviewSpacing;
 | 
			
		||||
        if (rtl)
 | 
			
		||||
            x += widthAdjust;
 | 
			
		||||
            x += overviewSpacing;
 | 
			
		||||
 | 
			
		||||
        let monitors = Main.layoutManager.monitors;
 | 
			
		||||
        let m = 0;
 | 
			
		||||
@@ -865,25 +719,22 @@ const WorkspacesDisplay = new Lang.Class({
 | 
			
		||||
                                                     monitors[i].y,
 | 
			
		||||
                                                     monitors[i].width,
 | 
			
		||||
                                                     monitors[i].height);
 | 
			
		||||
                this._workspacesViews[m].setGeometry(monitors[i].x,
 | 
			
		||||
                                                     monitors[i].y,
 | 
			
		||||
                                                     monitors[i].width,
 | 
			
		||||
                                                     monitors[i].height);
 | 
			
		||||
                this._workspacesViews[m].setGeometry(monitors[i].x + overviewSpacing/2,
 | 
			
		||||
                                                     monitors[i].y + overviewSpacing/2,
 | 
			
		||||
                                                     monitors[i].width - overviewSpacing,
 | 
			
		||||
                                                     monitors[i].height - overviewSpacing);
 | 
			
		||||
                m++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onRestacked: function(overview, stackIndices) {
 | 
			
		||||
    _onRestacked: function(actor, stackIndices) {
 | 
			
		||||
        for (let i = 0; i < this._workspacesViews.length; i++)
 | 
			
		||||
            this._workspacesViews[i].syncStacking(stackIndices);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _workspacesChanged: function() {
 | 
			
		||||
        this._updateAlwaysZoom();
 | 
			
		||||
        this._updateZoom();
 | 
			
		||||
 | 
			
		||||
        if (!this._workspacesViews.length)
 | 
			
		||||
        if (this._workspacesViews == null)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let oldNumWorkspaces = this._workspaces[0].length;
 | 
			
		||||
@@ -936,35 +787,6 @@ const WorkspacesDisplay = new Lang.Class({
 | 
			
		||||
                                                      newNumWorkspaces);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateZoom : function() {
 | 
			
		||||
        if (Main.overview.animationInProgress)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let shouldZoom = this._alwaysZoomOut || this._controls.hover;
 | 
			
		||||
        if (shouldZoom != this._zoomOut) {
 | 
			
		||||
            this._zoomOut = shouldZoom;
 | 
			
		||||
            this._updateWorkspacesGeometry();
 | 
			
		||||
 | 
			
		||||
            if (!this._workspacesViews.length)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            Tweener.addTween(this,
 | 
			
		||||
                             { zoomFraction: this._zoomOut ? 1 : 0,
 | 
			
		||||
                               time: WORKSPACE_SWITCH_TIME,
 | 
			
		||||
                               transition: 'easeOutQuad' });
 | 
			
		||||
 | 
			
		||||
            for (let i = 0; i < this._workspacesViews.length; i++)
 | 
			
		||||
                this._workspacesViews[i].updateWindowPositions();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onControlsHoverChanged: function() {
 | 
			
		||||
        if(!this._controls.hover)
 | 
			
		||||
            this._controlsInitiallyHovered = false;
 | 
			
		||||
        if(!this._controlsInitiallyHovered)
 | 
			
		||||
            this._updateZoom();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _dragBegin: function() {
 | 
			
		||||
        this._inDrag = true;
 | 
			
		||||
        this._cancelledDrag = false;
 | 
			
		||||
@@ -980,22 +802,11 @@ const WorkspacesDisplay = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragMotion: function(dragEvent) {
 | 
			
		||||
        let controlsHovered = this._controls.contains(dragEvent.targetActor);
 | 
			
		||||
        this._controls.set_hover(controlsHovered);
 | 
			
		||||
 | 
			
		||||
        return DND.DragMotionResult.CONTINUE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _dragEnd: function() {
 | 
			
		||||
        this._inDrag = false;
 | 
			
		||||
 | 
			
		||||
        // We do this deferred because drag-end is emitted before dnd.js emits
 | 
			
		||||
        // event/leave events that were suppressed during the drag. If we didn't
 | 
			
		||||
        // defer this, we'd zoom out then immediately zoom in because of the
 | 
			
		||||
        // enter event we received. That would normally be invisible but we
 | 
			
		||||
        // might as well avoid it.
 | 
			
		||||
        Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
 | 
			
		||||
                       Lang.bind(this, this._updateZoom));
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
Signals.addSignalMethods(WorkspacesDisplay.prototype);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										173
									
								
								po/et.po
									
									
									
									
									
								
							
							
						
						
									
										173
									
								
								po/et.po
									
									
									
									
									
								
							@@ -13,8 +13,8 @@ msgstr ""
 | 
			
		||||
"Project-Id-Version: gnome-shell MASTER\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
 | 
			
		||||
"shell&keywords=I18N+L10N&component=general\n"
 | 
			
		||||
"POT-Creation-Date: 2012-12-09 13:03+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2012-12-18 17:13+0300\n"
 | 
			
		||||
"POT-Creation-Date: 2012-11-16 18:27+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2012-11-16 20:40+0300\n"
 | 
			
		||||
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
 | 
			
		||||
"Language-Team: Estonian <>\n"
 | 
			
		||||
"Language: et\n"
 | 
			
		||||
@@ -135,28 +135,6 @@ msgstr ""
 | 
			
		||||
"See võti keelab automaatse 'Logi välja' menüükirje peitmise, kui arvutis on "
 | 
			
		||||
"üks kasutaja ning avatud üks seanss."
 | 
			
		||||
 | 
			
		||||
msgid "Show full name in the user menu"
 | 
			
		||||
msgstr "Kasutajamenüüs näidatakse kasutaja tervet nime"
 | 
			
		||||
 | 
			
		||||
msgid "Whether the users full name is shown in the user menu or not."
 | 
			
		||||
msgstr "Kas kasutajamenüüs näidatakse kasutaja kogu nime või mitte."
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Whether to remember password for mounting encrypted or remote filesystems"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Kas pidada meeles krüpteeritud või kaugfailisüsteemide haakimise paroole."
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"The shell will request a password when an encrypted device or a remote "
 | 
			
		||||
"filesystem is mounted. If the password can be saved for future use a "
 | 
			
		||||
"'Remember Password' checkbox will be present. This key sets the default "
 | 
			
		||||
"state of the checkbox."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Shell küsib parooli, kui haagitakse krüpteeritud seade või kaugfailisüsteem. "
 | 
			
		||||
"Kui parooli on võimalik salvestada järgmise kasutuse jaoks, näidatakse "
 | 
			
		||||
"\"Jäta parool meelde\" märkeruutu. See võti määrab märkeruudu vaikimisi "
 | 
			
		||||
"oleku."
 | 
			
		||||
 | 
			
		||||
msgid "Show the week date in the calendar"
 | 
			
		||||
msgstr "Kalendris näidatakse kuupäeva nädalavormingus"
 | 
			
		||||
 | 
			
		||||
@@ -249,18 +227,6 @@ msgstr ""
 | 
			
		||||
"konteinervormingusse salvestades tuleks ka sellele vormingule vastav laiend "
 | 
			
		||||
"määrata."
 | 
			
		||||
 | 
			
		||||
msgid "The application icon mode."
 | 
			
		||||
msgstr "Rakenduste ikooni režiim."
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Configures how the windows are shown in the switcher. Valid possibilities "
 | 
			
		||||
"are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-"
 | 
			
		||||
"only' (shows only the application icon) or 'both'."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Seadistab, kuidas aknaid akendevahetajas kuvatakse. Sobivad väärtused on "
 | 
			
		||||
"'thumbnail-only' (näidatakse ainult pisipilti), 'app-icon-only' (näidatakse "
 | 
			
		||||
"ainult rakenduse ikooni) või 'both' (näidatakse mõlemaid)."
 | 
			
		||||
 | 
			
		||||
msgid "Attach modal dialog to the parent window"
 | 
			
		||||
msgstr "Modaaldialoog kuulub vanemakna juurde"
 | 
			
		||||
 | 
			
		||||
@@ -622,8 +588,11 @@ msgstr "Helista"
 | 
			
		||||
msgid "File Transfer"
 | 
			
		||||
msgstr "Failiülekanne"
 | 
			
		||||
 | 
			
		||||
msgid "Chat"
 | 
			
		||||
msgstr "Vestlus"
 | 
			
		||||
msgid "Subscription request"
 | 
			
		||||
msgstr "Tellimuse päring"
 | 
			
		||||
 | 
			
		||||
msgid "Connection error"
 | 
			
		||||
msgstr "Ühenduse viga"
 | 
			
		||||
 | 
			
		||||
msgid "Unmute"
 | 
			
		||||
msgstr "Heli peale"
 | 
			
		||||
@@ -631,25 +600,27 @@ msgstr "Heli peale"
 | 
			
		||||
msgid "Mute"
 | 
			
		||||
msgstr "Heli maha"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is the word "Yesterday" followed by a time string. i.e. "Yesterday, 14:30"
 | 
			
		||||
#. Translators: this is a time format string followed by the word "Yesterday". i.e. "14:30 on Yesterday"
 | 
			
		||||
#, no-c-format
 | 
			
		||||
msgid "<b>Yesterday</b>, <b>%H:%M</b>"
 | 
			
		||||
msgstr "<b>Eile</b> <b>%H:%M</b>"
 | 
			
		||||
msgid "<b>%H:%M</b> on Yesterday"
 | 
			
		||||
msgstr "Eile <b>%H:%M</b>"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is the week day name followed by a time string. i.e. "Monday, 14:30
 | 
			
		||||
#. Translators: this is a time format string followed by a week day name. i.e. "14:30 on Monday
 | 
			
		||||
#, no-c-format
 | 
			
		||||
msgid "<b>%A</b>, <b>%H:%M</b>"
 | 
			
		||||
msgstr "<b>%A</b>, <b>%H:%M</b>"
 | 
			
		||||
msgid "<b>%H:%M</b> on <b>%A</b>"
 | 
			
		||||
msgstr "<b>%H:%M</b>, <b>%A</b>"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is the month name and day number followed by a time string. i.e. "May 25, 14:30"
 | 
			
		||||
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25",
 | 
			
		||||
#. shown when you get a chat message in the same year
 | 
			
		||||
#, no-c-format
 | 
			
		||||
msgid "<b>%B</b> <b>%d</b>, <b>%H:%M</b>"
 | 
			
		||||
msgstr "<b>%d. %B</b>, <b>%H:%M</b>"
 | 
			
		||||
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>"
 | 
			
		||||
msgstr "<b>%H:%M</b>, <b>%A</b>, <b>%d. %B</b>"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is the month name, day number, year number followed by a time string. i.e. "May 25 2012, 14:30"
 | 
			
		||||
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25, 2012",
 | 
			
		||||
#. shown when you get a chat message in a different year
 | 
			
		||||
#, no-c-format
 | 
			
		||||
msgid "<b>%B</b> <b>%d</b> <b>%Y</b>, <b>%H:%M</b> "
 | 
			
		||||
msgstr "<b>%d. %B %Y</b>, <b>%H:%M</b>"
 | 
			
		||||
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>, %Y"
 | 
			
		||||
msgstr "<b>%H:%M</b>, <b>%A</b>, <b>%d. %B</b> %Y"
 | 
			
		||||
 | 
			
		||||
#. Translators: this is the other person changing their old IM name to their new
 | 
			
		||||
#. IM name.
 | 
			
		||||
@@ -786,18 +757,18 @@ msgstr "Sisemine viga"
 | 
			
		||||
#. translators: argument is the account name, like
 | 
			
		||||
#. * name@jabber.org for example.
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Unable to connect to %s"
 | 
			
		||||
msgstr "Pole võimalik ühenduda võrguga %s"
 | 
			
		||||
msgid "Connection to %s failed"
 | 
			
		||||
msgstr "Ühendus %s nurjus"
 | 
			
		||||
 | 
			
		||||
msgid "View account"
 | 
			
		||||
msgstr "Konto kuvamine"
 | 
			
		||||
msgid "Reconnect"
 | 
			
		||||
msgstr "Ühendu uuesti"
 | 
			
		||||
 | 
			
		||||
msgid "Edit account"
 | 
			
		||||
msgstr "Konto muutmine"
 | 
			
		||||
 | 
			
		||||
msgid "Unknown reason"
 | 
			
		||||
msgstr "Põhjus teadmata"
 | 
			
		||||
 | 
			
		||||
msgid "Windows"
 | 
			
		||||
msgstr "Aknad"
 | 
			
		||||
 | 
			
		||||
msgid "Show Applications"
 | 
			
		||||
msgstr "Rakenduste kuvamine"
 | 
			
		||||
 | 
			
		||||
@@ -920,6 +891,8 @@ msgstr "Näita vigu"
 | 
			
		||||
msgid "Enabled"
 | 
			
		||||
msgstr "Lubatud"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The device has been disabled
 | 
			
		||||
msgid "Disabled"
 | 
			
		||||
msgstr "Keelatud"
 | 
			
		||||
 | 
			
		||||
@@ -944,9 +917,6 @@ msgstr "Ava"
 | 
			
		||||
msgid "Remove"
 | 
			
		||||
msgstr "Eemalda"
 | 
			
		||||
 | 
			
		||||
msgid "No Messages"
 | 
			
		||||
msgstr "Teateid pole"
 | 
			
		||||
 | 
			
		||||
msgid "Message Tray"
 | 
			
		||||
msgstr "Teateala"
 | 
			
		||||
 | 
			
		||||
@@ -1017,9 +987,6 @@ msgid_plural "%d new notifications"
 | 
			
		||||
msgstr[0] "%d uus märguanne"
 | 
			
		||||
msgstr[1] "%d uut märguannet"
 | 
			
		||||
 | 
			
		||||
msgid "Lock"
 | 
			
		||||
msgstr "Lukusta"
 | 
			
		||||
 | 
			
		||||
msgid "Searching..."
 | 
			
		||||
msgstr "Otsimine..."
 | 
			
		||||
 | 
			
		||||
@@ -1140,7 +1107,6 @@ msgstr "Luba ainult seekord"
 | 
			
		||||
msgid "Reject"
 | 
			
		||||
msgstr "Lükka tagasi"
 | 
			
		||||
 | 
			
		||||
#. Translators: argument is the device short name
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Pairing confirmation for %s"
 | 
			
		||||
msgstr "Paardumise kinnitus seadmele %s"
 | 
			
		||||
@@ -1153,7 +1119,6 @@ msgstr "Seade '%s' tahab selle arvutiga paarduda"
 | 
			
		||||
msgid "Please confirm whether the PIN '%06d' matches the one on the device."
 | 
			
		||||
msgstr "Palun kontrolli, kas PIN-kood '%06d' kattub seadme parooliga."
 | 
			
		||||
 | 
			
		||||
#. Translators: this is the verb, not the noun
 | 
			
		||||
msgid "Matches"
 | 
			
		||||
msgstr "Kattub"
 | 
			
		||||
 | 
			
		||||
@@ -1243,8 +1208,14 @@ msgstr "Automaatne juhtmeta ühendus"
 | 
			
		||||
msgid "Enable networking"
 | 
			
		||||
msgstr "Luba võrguühendused"
 | 
			
		||||
 | 
			
		||||
msgid "Wi-Fi"
 | 
			
		||||
msgstr "Wi-Fi"
 | 
			
		||||
msgid "Wired"
 | 
			
		||||
msgstr "Juhtmega"
 | 
			
		||||
 | 
			
		||||
msgid "Wireless"
 | 
			
		||||
msgstr "Juhtmeta"
 | 
			
		||||
 | 
			
		||||
msgid "Mobile broadband"
 | 
			
		||||
msgstr "Mobiiliühendus"
 | 
			
		||||
 | 
			
		||||
msgid "Network Settings"
 | 
			
		||||
msgstr "Võrgusätted"
 | 
			
		||||
@@ -1348,9 +1319,6 @@ msgstr "Mikrofon"
 | 
			
		||||
msgid "Log in as another user"
 | 
			
		||||
msgstr "Logi sisse teise kasutajana"
 | 
			
		||||
 | 
			
		||||
msgid "Unlock Window"
 | 
			
		||||
msgstr "Võta aken lukust lahti"
 | 
			
		||||
 | 
			
		||||
msgid "Available"
 | 
			
		||||
msgstr "Saadaval"
 | 
			
		||||
 | 
			
		||||
@@ -1381,6 +1349,9 @@ msgstr "Vaheta kasutajat"
 | 
			
		||||
msgid "Log Out"
 | 
			
		||||
msgstr "Logi välja"
 | 
			
		||||
 | 
			
		||||
msgid "Lock"
 | 
			
		||||
msgstr "Lukusta"
 | 
			
		||||
 | 
			
		||||
msgid "Install Updates & Restart"
 | 
			
		||||
msgstr "Paigalda uuendused ja taaskäivita"
 | 
			
		||||
 | 
			
		||||
@@ -1394,6 +1365,9 @@ msgstr ""
 | 
			
		||||
"Märguanded on nüüd keelatud, sealhulgas vestlusteated. Sinu netiolekut "
 | 
			
		||||
"muudeti, et teised teaksid, et sa ei pruugi nende teateid näha."
 | 
			
		||||
 | 
			
		||||
msgid "Windows"
 | 
			
		||||
msgstr "Aknad"
 | 
			
		||||
 | 
			
		||||
msgid "Applications"
 | 
			
		||||
msgstr "Rakendused"
 | 
			
		||||
 | 
			
		||||
@@ -1422,6 +1396,25 @@ msgstr "'%s' on valmis"
 | 
			
		||||
msgid "Evolution Calendar"
 | 
			
		||||
msgstr "Evolutioni kalender"
 | 
			
		||||
 | 
			
		||||
#. translators:
 | 
			
		||||
#. * The number of sound outputs on a particular device
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%u Output"
 | 
			
		||||
msgid_plural "%u Outputs"
 | 
			
		||||
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] "%u sisend"
 | 
			
		||||
msgstr[1] "%u sisendit"
 | 
			
		||||
 | 
			
		||||
msgid "System Sounds"
 | 
			
		||||
msgstr "Süsteemi helid"
 | 
			
		||||
 | 
			
		||||
msgid "Print version"
 | 
			
		||||
msgstr "Printimise versioon"
 | 
			
		||||
 | 
			
		||||
@@ -1453,46 +1446,6 @@ msgstr "Vaikimisi"
 | 
			
		||||
msgid "Authentication dialog was dismissed by the user"
 | 
			
		||||
msgstr "Kasutaja katkestas autentimisdialoogi"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Subscription request"
 | 
			
		||||
#~ msgstr "Tellimuse päring"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Connection error"
 | 
			
		||||
#~ msgstr "Ühenduse viga"
 | 
			
		||||
 | 
			
		||||
#~ msgid "<b>%H:%M</b> on Yesterday"
 | 
			
		||||
#~ msgstr "Eile <b>%H:%M</b>"
 | 
			
		||||
 | 
			
		||||
#~ msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>, %Y"
 | 
			
		||||
#~ msgstr "<b>%H:%M</b>, <b>%A</b>, <b>%d. %B</b> %Y"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Connection to %s failed"
 | 
			
		||||
#~ msgstr "Ühendus %s nurjus"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Reconnect"
 | 
			
		||||
#~ msgstr "Ühendu uuesti"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Wired"
 | 
			
		||||
#~ msgstr "Juhtmega"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Wireless"
 | 
			
		||||
#~ msgstr "Juhtmeta"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Mobile broadband"
 | 
			
		||||
#~ msgstr "Mobiiliühendus"
 | 
			
		||||
 | 
			
		||||
#~ msgid "%u Output"
 | 
			
		||||
#~ msgid_plural "%u Outputs"
 | 
			
		||||
#~ msgstr[0] "%u väljund"
 | 
			
		||||
#~ msgstr[1] "%u väljundit"
 | 
			
		||||
 | 
			
		||||
#~ msgid "%u Input"
 | 
			
		||||
#~ msgid_plural "%u Inputs"
 | 
			
		||||
#~ msgstr[0] "%u sisend"
 | 
			
		||||
#~ msgstr[1] "%u sisendit"
 | 
			
		||||
 | 
			
		||||
#~ msgid "System Sounds"
 | 
			
		||||
#~ msgstr "Süsteemi helid"
 | 
			
		||||
 | 
			
		||||
#~ msgid "disabled OpenSearch providers"
 | 
			
		||||
#~ msgstr "keelatud OpenSearch pakkujad"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								src/gvc
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								src/gvc
									
									
									
									
									
								
							 Submodule src/gvc updated: 03894efbcd...40cdff2479
									
								
							@@ -738,8 +738,7 @@ normalize_terms (GSList *terms)
 | 
			
		||||
  for (iter = terms; iter; iter = iter->next)
 | 
			
		||||
    {
 | 
			
		||||
      const char *term = iter->data;
 | 
			
		||||
      normalized_terms = g_slist_prepend (normalized_terms,
 | 
			
		||||
                                          shell_util_normalize_casefold_and_unaccent (term));
 | 
			
		||||
      normalized_terms = g_slist_prepend (normalized_terms, shell_util_normalize_and_casefold (term));
 | 
			
		||||
    }
 | 
			
		||||
  return normalized_terms;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1319,16 +1319,16 @@ shell_app_init_search_data (ShellApp *app)
 | 
			
		||||
 | 
			
		||||
  appinfo = gmenu_tree_entry_get_app_info (app->entry);
 | 
			
		||||
  name = g_app_info_get_name (G_APP_INFO (appinfo));
 | 
			
		||||
  app->casefolded_name = shell_util_normalize_casefold_and_unaccent (name);
 | 
			
		||||
  app->casefolded_name = shell_util_normalize_and_casefold (name);
 | 
			
		||||
 | 
			
		||||
  generic_name = g_desktop_app_info_get_generic_name (appinfo);
 | 
			
		||||
  if (generic_name)
 | 
			
		||||
    app->casefolded_generic_name = shell_util_normalize_casefold_and_unaccent (generic_name);
 | 
			
		||||
    app->casefolded_generic_name = shell_util_normalize_and_casefold (generic_name);
 | 
			
		||||
  else
 | 
			
		||||
    app->casefolded_generic_name = NULL;
 | 
			
		||||
 | 
			
		||||
  exec = g_app_info_get_executable (G_APP_INFO (appinfo));
 | 
			
		||||
  normalized_exec = shell_util_normalize_casefold_and_unaccent (exec);
 | 
			
		||||
  normalized_exec = shell_util_normalize_and_casefold (exec);
 | 
			
		||||
  app->casefolded_exec = trim_exec_line (normalized_exec);
 | 
			
		||||
  g_free (normalized_exec);
 | 
			
		||||
 | 
			
		||||
@@ -1343,7 +1343,7 @@ shell_app_init_search_data (ShellApp *app)
 | 
			
		||||
      i = 0;
 | 
			
		||||
      while (keywords[i])
 | 
			
		||||
        {
 | 
			
		||||
          app->casefolded_keywords[i] = shell_util_normalize_casefold_and_unaccent (keywords[i]);
 | 
			
		||||
          app->casefolded_keywords[i] = shell_util_normalize_and_casefold (keywords[i]);
 | 
			
		||||
          ++i;
 | 
			
		||||
        }
 | 
			
		||||
      app->casefolded_keywords[i] = NULL;
 | 
			
		||||
 
 | 
			
		||||
@@ -122,90 +122,12 @@ shell_util_normalize_and_casefold (const char *str)
 | 
			
		||||
  if (str == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  /* NOTE: 'ALL' is equivalent to 'NFKD'. If this is ever updated, please
 | 
			
		||||
   * update the unaccenting mechanism as well. */
 | 
			
		||||
  normalized = g_utf8_normalize (str, -1, G_NORMALIZE_ALL);
 | 
			
		||||
  result = g_utf8_casefold (normalized, -1);
 | 
			
		||||
  g_free (normalized);
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Combining diacritical mark?
 | 
			
		||||
 *  Basic range: [0x0300,0x036F]
 | 
			
		||||
 *  Supplement:  [0x1DC0,0x1DFF]
 | 
			
		||||
 *  For Symbols: [0x20D0,0x20FF]
 | 
			
		||||
 *  Half marks:  [0xFE20,0xFE2F]
 | 
			
		||||
 */
 | 
			
		||||
#define IS_CDM_UCS4(c) (((c) >= 0x0300 && (c) <= 0x036F)  || \
 | 
			
		||||
                        ((c) >= 0x1DC0 && (c) <= 0x1DFF)  || \
 | 
			
		||||
                        ((c) >= 0x20D0 && (c) <= 0x20FF)  || \
 | 
			
		||||
                        ((c) >= 0xFE20 && (c) <= 0xFE2F))
 | 
			
		||||
 | 
			
		||||
/* Copied from tracker/src/libtracker-fts/tracker-parser-glib.c under the GPL
 | 
			
		||||
 * Originally written by Aleksander Morgado <aleksander@gnu.org>
 | 
			
		||||
 */
 | 
			
		||||
char *
 | 
			
		||||
shell_util_normalize_casefold_and_unaccent (const char *str)
 | 
			
		||||
{
 | 
			
		||||
  char *tmp;
 | 
			
		||||
  gsize i = 0, j = 0, ilen;
 | 
			
		||||
 | 
			
		||||
  if (str == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  /* Get the NFKD-normalized and casefolded string */
 | 
			
		||||
  tmp = shell_util_normalize_and_casefold (str);
 | 
			
		||||
  ilen = strlen (tmp);
 | 
			
		||||
 | 
			
		||||
  while (i < ilen)
 | 
			
		||||
    {
 | 
			
		||||
      gunichar unichar;
 | 
			
		||||
      gchar *next_utf8;
 | 
			
		||||
      gint utf8_len;
 | 
			
		||||
 | 
			
		||||
      /* Get next character of the word as UCS4 */
 | 
			
		||||
      unichar = g_utf8_get_char_validated (&tmp[i], -1);
 | 
			
		||||
 | 
			
		||||
      /* Invalid UTF-8 character or end of original string. */
 | 
			
		||||
      if (unichar == (gunichar) -1 ||
 | 
			
		||||
          unichar == (gunichar) -2)
 | 
			
		||||
        {
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      /* Find next UTF-8 character */
 | 
			
		||||
      next_utf8 = g_utf8_next_char (&tmp[i]);
 | 
			
		||||
      utf8_len = next_utf8 - &tmp[i];
 | 
			
		||||
 | 
			
		||||
      if (IS_CDM_UCS4 ((guint32) unichar))
 | 
			
		||||
        {
 | 
			
		||||
          /* If the given unichar is a combining diacritical mark,
 | 
			
		||||
           * just update the original index, not the output one */
 | 
			
		||||
          i += utf8_len;
 | 
			
		||||
          continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      /* If already found a previous combining
 | 
			
		||||
       * diacritical mark, indexes are different so
 | 
			
		||||
       * need to copy characters. As output and input
 | 
			
		||||
       * buffers may overlap, need to use memmove
 | 
			
		||||
       * instead of memcpy */
 | 
			
		||||
      if (i != j)
 | 
			
		||||
        {
 | 
			
		||||
          memmove (&tmp[j], &tmp[i], utf8_len);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      /* Update both indexes */
 | 
			
		||||
      i += utf8_len;
 | 
			
		||||
      j += utf8_len;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Force proper string end */
 | 
			
		||||
  tmp[j] = '\0';
 | 
			
		||||
 | 
			
		||||
  return tmp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * shell_util_format_date:
 | 
			
		||||
 * @format: a strftime-style string format, as parsed by
 | 
			
		||||
 
 | 
			
		||||
@@ -20,8 +20,6 @@ int      shell_util_get_week_start             (void);
 | 
			
		||||
 | 
			
		||||
char    *shell_util_normalize_and_casefold     (const char       *str);
 | 
			
		||||
 | 
			
		||||
char    *shell_util_normalize_casefold_and_unaccent (const char  *str);
 | 
			
		||||
 | 
			
		||||
char    *shell_util_format_date                (const char       *format,
 | 
			
		||||
                                                gint64            time_ms);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1738,19 +1738,15 @@ _st_theme_node_ensure_background (StThemeNode *node)
 | 
			
		||||
              else if (term->type == TERM_URI)
 | 
			
		||||
                {
 | 
			
		||||
                  CRStyleSheet *base_stylesheet;
 | 
			
		||||
                  GFile *file;
 | 
			
		||||
 | 
			
		||||
                  if (decl->parent_statement != NULL)
 | 
			
		||||
                    base_stylesheet = decl->parent_statement->parent_sheet;
 | 
			
		||||
                  else
 | 
			
		||||
                    base_stylesheet = NULL;
 | 
			
		||||
 | 
			
		||||
                  file = _st_theme_resolve_url (node->theme,
 | 
			
		||||
                                                base_stylesheet,
 | 
			
		||||
                                                term->content.str->stryng->str);
 | 
			
		||||
 | 
			
		||||
                  node->background_image = g_file_get_path (file);
 | 
			
		||||
                  g_object_unref (file);
 | 
			
		||||
                  node->background_image = _st_theme_resolve_url (node->theme,
 | 
			
		||||
                                                                  base_stylesheet,
 | 
			
		||||
                                                                  term->content.str->stryng->str);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -1847,7 +1843,6 @@ _st_theme_node_ensure_background (StThemeNode *node)
 | 
			
		||||
          if (decl->value->type == TERM_URI)
 | 
			
		||||
            {
 | 
			
		||||
              CRStyleSheet *base_stylesheet;
 | 
			
		||||
              GFile *file;
 | 
			
		||||
 | 
			
		||||
              if (decl->parent_statement != NULL)
 | 
			
		||||
                base_stylesheet = decl->parent_statement->parent_sheet;
 | 
			
		||||
@@ -1855,12 +1850,9 @@ _st_theme_node_ensure_background (StThemeNode *node)
 | 
			
		||||
                base_stylesheet = NULL;
 | 
			
		||||
 | 
			
		||||
              g_free (node->background_image);
 | 
			
		||||
              file = _st_theme_resolve_url (node->theme,
 | 
			
		||||
                                            base_stylesheet,
 | 
			
		||||
                                            decl->value->content.str->stryng->str);
 | 
			
		||||
 | 
			
		||||
              node->background_image = g_file_get_path (file);
 | 
			
		||||
              g_object_unref (file);
 | 
			
		||||
              node->background_image = _st_theme_resolve_url (node->theme,
 | 
			
		||||
                                                              base_stylesheet,
 | 
			
		||||
                                                              decl->value->content.str->stryng->str);
 | 
			
		||||
            }
 | 
			
		||||
          else if (term_is_inherit (decl->value))
 | 
			
		||||
            {
 | 
			
		||||
@@ -2676,7 +2668,6 @@ st_theme_node_get_border_image (StThemeNode *node)
 | 
			
		||||
          int border_bottom;
 | 
			
		||||
          int border_left;
 | 
			
		||||
 | 
			
		||||
          GFile *file;
 | 
			
		||||
          char *filename;
 | 
			
		||||
 | 
			
		||||
          /* Support border-image: none; to suppress a previously specified border image */
 | 
			
		||||
@@ -2755,10 +2746,7 @@ st_theme_node_get_border_image (StThemeNode *node)
 | 
			
		||||
          else
 | 
			
		||||
            base_stylesheet = NULL;
 | 
			
		||||
 | 
			
		||||
          file = _st_theme_resolve_url (node->theme, base_stylesheet, url);
 | 
			
		||||
          filename = g_file_get_path (file);
 | 
			
		||||
          g_object_unref (file);
 | 
			
		||||
 | 
			
		||||
          filename = _st_theme_resolve_url (node->theme, base_stylesheet, url);
 | 
			
		||||
          if (filename == NULL)
 | 
			
		||||
            goto next_property;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -29,10 +29,10 @@ G_BEGIN_DECLS
 | 
			
		||||
GPtrArray *_st_theme_get_matched_properties (StTheme       *theme,
 | 
			
		||||
                                             StThemeNode   *node);
 | 
			
		||||
 | 
			
		||||
/* Resolve an URL from the stylesheet to a file */
 | 
			
		||||
GFile *_st_theme_resolve_url (StTheme      *theme,
 | 
			
		||||
                              CRStyleSheet *base_stylesheet,
 | 
			
		||||
                              const char   *url);
 | 
			
		||||
/* Resolve an URL from the stylesheet to a filename */
 | 
			
		||||
char *_st_theme_resolve_url (StTheme      *theme,
 | 
			
		||||
                             CRStyleSheet *base_stylesheet,
 | 
			
		||||
                             const char   *url);
 | 
			
		||||
 | 
			
		||||
CRDeclaration *_st_theme_parse_declaration_list (const char *str);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -849,16 +849,9 @@ add_matched_properties (StTheme      *a_this,
 | 
			
		||||
                char *filename = NULL;
 | 
			
		||||
 | 
			
		||||
                if (import_rule->url->stryng && import_rule->url->stryng->str)
 | 
			
		||||
                  {
 | 
			
		||||
                    GFile *file;
 | 
			
		||||
 | 
			
		||||
                    file = _st_theme_resolve_url (a_this,
 | 
			
		||||
                                                  a_nodesheet,
 | 
			
		||||
                                                  import_rule->url->stryng->str);
 | 
			
		||||
                    filename = g_file_get_path (file);
 | 
			
		||||
 | 
			
		||||
                    g_object_unref (file);
 | 
			
		||||
                  }
 | 
			
		||||
                  filename = _st_theme_resolve_url (a_this,
 | 
			
		||||
                                                    a_nodesheet,
 | 
			
		||||
                                                    import_rule->url->stryng->str);
 | 
			
		||||
 | 
			
		||||
                if (filename)
 | 
			
		||||
                  import_rule->sheet = parse_stylesheet (filename, NULL);
 | 
			
		||||
@@ -1006,41 +999,84 @@ _st_theme_get_matched_properties (StTheme        *theme,
 | 
			
		||||
 * local filename, if possible. The resolution here is distinctly lame and
 | 
			
		||||
 * will fail on many examples.
 | 
			
		||||
 */
 | 
			
		||||
GFile *
 | 
			
		||||
char *
 | 
			
		||||
_st_theme_resolve_url (StTheme      *theme,
 | 
			
		||||
                       CRStyleSheet *base_stylesheet,
 | 
			
		||||
                       const char   *url)
 | 
			
		||||
{
 | 
			
		||||
  char *scheme;
 | 
			
		||||
  GFile *stylesheet, *resource;
 | 
			
		||||
  const char *base_filename = NULL;
 | 
			
		||||
  char *dirname;
 | 
			
		||||
  char *filename;
 | 
			
		||||
  char *canonicalized_path;
 | 
			
		||||
 | 
			
		||||
  if ((scheme = g_uri_parse_scheme (url)))
 | 
			
		||||
  /* Handle absolute file:/ URLs */
 | 
			
		||||
  if (g_str_has_prefix (url, "file:") ||
 | 
			
		||||
      g_str_has_prefix (url, "File:") ||
 | 
			
		||||
      g_str_has_prefix (url, "FILE:"))
 | 
			
		||||
    {
 | 
			
		||||
      g_free (scheme);
 | 
			
		||||
      resource = g_file_new_for_uri (url);
 | 
			
		||||
      GError *error = NULL;
 | 
			
		||||
      char *filename;
 | 
			
		||||
 | 
			
		||||
      filename = g_filename_from_uri (url, NULL, &error);
 | 
			
		||||
      if (filename == NULL)
 | 
			
		||||
        {
 | 
			
		||||
          g_warning ("%s", error->message);
 | 
			
		||||
          g_error_free (error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      return filename;
 | 
			
		||||
    }
 | 
			
		||||
  else if (base_stylesheet != NULL)
 | 
			
		||||
 | 
			
		||||
  /* Guard against http:/ URLs */
 | 
			
		||||
 | 
			
		||||
  if (g_str_has_prefix (url, "http:") ||
 | 
			
		||||
      g_str_has_prefix (url, "Http:") ||
 | 
			
		||||
      g_str_has_prefix (url, "HTTP:"))
 | 
			
		||||
    {
 | 
			
		||||
      const char *base_filename = NULL;
 | 
			
		||||
      char *dirname;
 | 
			
		||||
      g_warning ("Http URL '%s' in theme stylesheet is not supported", url);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
      base_filename = g_hash_table_lookup (theme->filenames_by_stylesheet, base_stylesheet);
 | 
			
		||||
  /* Assume anything else is a relative URL, and "resolve" it
 | 
			
		||||
   */
 | 
			
		||||
  if (url[0] == '/')
 | 
			
		||||
    {
 | 
			
		||||
      canonicalized_path = realpath (url, NULL);
 | 
			
		||||
      if (g_mem_is_system_malloc ())
 | 
			
		||||
        {
 | 
			
		||||
          filename = canonicalized_path;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          filename = g_strdup (canonicalized_path);
 | 
			
		||||
          free (canonicalized_path);
 | 
			
		||||
        }
 | 
			
		||||
      return filename;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
      /* This is an internal function, if we get here with
 | 
			
		||||
         a bad @base_stylesheet we have a problem. */
 | 
			
		||||
      g_assert (base_filename);
 | 
			
		||||
  base_filename = g_hash_table_lookup (theme->filenames_by_stylesheet, base_stylesheet);
 | 
			
		||||
 | 
			
		||||
      dirname = g_path_get_dirname (base_filename);
 | 
			
		||||
      stylesheet = g_file_new_for_path (dirname);
 | 
			
		||||
      resource = g_file_resolve_relative_path (stylesheet, url);
 | 
			
		||||
  if (base_filename == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Can't get base to resolve url '%s'", url);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
      g_object_unref (stylesheet);
 | 
			
		||||
      g_free (dirname);
 | 
			
		||||
  dirname = g_path_get_dirname (base_filename);
 | 
			
		||||
  filename = g_build_filename (dirname, url, NULL);
 | 
			
		||||
  canonicalized_path = realpath (filename, NULL);
 | 
			
		||||
  g_free (dirname);
 | 
			
		||||
  g_free (filename);
 | 
			
		||||
 | 
			
		||||
  if (g_mem_is_system_malloc ())
 | 
			
		||||
    {
 | 
			
		||||
      filename = canonicalized_path;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      resource = g_file_new_for_path (url);
 | 
			
		||||
      filename = g_strdup (canonicalized_path);
 | 
			
		||||
      free (canonicalized_path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return resource;
 | 
			
		||||
  return filename;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								tests/interactive/center-layout.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								tests/interactive/center-layout.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
const St = imports.gi.St;
 | 
			
		||||
 | 
			
		||||
const CenterLayout = imports.ui.centerLayout;
 | 
			
		||||
const UI = imports.testcommon.ui;
 | 
			
		||||
 | 
			
		||||
function test() {
 | 
			
		||||
    let stage = new Clutter.Stage({ user_resizable: true });
 | 
			
		||||
    UI.init(stage);
 | 
			
		||||
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    let container = new St.Widget({ style: 'border: 2px solid black;',
 | 
			
		||||
                                    layout_manager: new CenterLayout.CenterLayout() });
 | 
			
		||||
    container.add_constraint(new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.SIZE, source: stage }));
 | 
			
		||||
    stage.add_actor(container);
 | 
			
		||||
 | 
			
		||||
    let left = new Clutter.Actor({ background_color: Clutter.Color.get_static(Clutter.StaticColor.RED), width: 300 });
 | 
			
		||||
    let center = new Clutter.Actor({ background_color: Clutter.Color.get_static(Clutter.StaticColor.BLUE), width: 100 });
 | 
			
		||||
    let right = new Clutter.Actor({ background_color: Clutter.Color.get_static(Clutter.StaticColor.YELLOW), width: 200 });
 | 
			
		||||
 | 
			
		||||
    container.add_actor(left);
 | 
			
		||||
    container.add_actor(center);
 | 
			
		||||
    container.add_actor(right);
 | 
			
		||||
 | 
			
		||||
    UI.main(stage);
 | 
			
		||||
}
 | 
			
		||||
test();
 | 
			
		||||
		Reference in New Issue
	
	Block a user