Compare commits
	
		
			118 Commits
		
	
	
		
			3.19.4
			...
			wip/tiling
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | ea901abd61 | ||
|   | 4e5e6aa7f8 | ||
|   | 8e587e2e42 | ||
|   | 93901dc32f | ||
|   | 7173937a7d | ||
|   | f44238a72f | ||
|   | 10a0114856 | ||
|   | aa7bc501d5 | ||
|   | 623eb6eacc | ||
|   | 12a3125132 | ||
|   | 2ca3d30485 | ||
|   | 0559b8fe03 | ||
|   | 0e0915ed79 | ||
|   | 1d56aac156 | ||
|   | f95f3b1ca5 | ||
|   | 3a4ae679ea | ||
|   | 190357c561 | ||
|   | 92c8a51ba6 | ||
|   | 8b1195be1a | ||
|   | e427aa3606 | ||
|   | 7517c91e99 | ||
|   | 7a94fa3be7 | ||
|   | f2ff0b6d42 | ||
|   | 4749bf0420 | ||
|   | 223bfb10a0 | ||
|   | 3d67bfda14 | ||
|   | 51e4491a9f | ||
|   | 82153ff23f | ||
|   | 9b39325244 | ||
|   | 868b3fd01e | ||
|   | 8b801aac77 | ||
|   | c380f2e03f | ||
|   | ca1b4382c0 | ||
|   | f6ba3bdfc2 | ||
|   | 99bba9e56c | ||
|   | 4af908a970 | ||
|   | 417cb2b213 | ||
|   | 9f1d1151b7 | ||
|   | fea1ddcd29 | ||
|   | 3b023ea994 | ||
|   | f8c70491b9 | ||
|   | 9df99d8bac | ||
|   | d4b0c21d06 | ||
|   | 517078d142 | ||
|   | 1c94d0e598 | ||
|   | b04747b174 | ||
|   | 6396974eae | ||
|   | 20908b9c2c | ||
|   | 4abfb299e2 | ||
|   | 62ac9df43d | ||
|   | 0882bce989 | ||
|   | 2d65b485fd | ||
|   | 613cadd19b | ||
|   | 9987185e20 | ||
|   | 2ff61a7d1b | ||
|   | ed686ab60b | ||
|   | a94e640b3f | ||
|   | da28d7a012 | ||
|   | 169f0e7324 | ||
|   | e6eb5c3ebc | ||
|   | 96927b3415 | ||
|   | ceae5dceea | ||
|   | d694244f29 | ||
|   | c52f716115 | ||
|   | 800c0c277e | ||
|   | ae3fad7155 | ||
|   | 1e0abc5279 | ||
|   | 1a3653765c | ||
|   | f0b8dadb7d | ||
|   | d340c3a6dd | ||
|   | 43bd057754 | ||
|   | 66be0387ee | ||
|   | 837836a722 | ||
|   | 2c71a35b4c | ||
|   | d3537c4dc6 | ||
|   | 7c114360d0 | ||
|   | c6aad6e735 | ||
|   | 741dd674f6 | ||
|   | 821d737e2c | ||
|   | 35da6a9078 | ||
|   | 00139755ff | ||
|   | 95dd681d47 | ||
|   | 2e5c8b3f11 | ||
|   | ad7e654a8b | ||
|   | b01926dbfa | ||
|   | 5001aa76d7 | ||
|   | f1730e488d | ||
|   | c22bee19e1 | ||
|   | 7fe2873750 | ||
|   | d6e32a6ac5 | ||
|   | 3f60a2e48a | ||
|   | 3729e592a6 | ||
|   | 56beedf9f2 | ||
|   | bed82427c6 | ||
|   | e097bc8353 | ||
|   | 4e82a751fb | ||
|   | acd50508dc | ||
|   | 9611661154 | ||
|   | a70a2c3744 | ||
|   | bc47b19c3f | ||
|   | bc1dd1cee4 | ||
|   | 495c89401a | ||
|   | e2efc85b08 | ||
|   | 020ae58fe4 | ||
|   | 525644059d | ||
|   | f0f638d2bd | ||
|   | bc8ec2d90d | ||
|   | 5b0eabec51 | ||
|   | 50099c4c10 | ||
|   | 55eef2deb3 | ||
|   | f9db65f47f | ||
|   | a809055470 | ||
|   | 247909e161 | ||
|   | e5ce6192f4 | ||
|   | 7adbb58736 | ||
|   | 0165cb6974 | ||
|   | 3cdcd3e9c1 | ||
|   | 6fc51e3723 | 
							
								
								
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -46,6 +46,7 @@ mutter | ||||
| mutter-restart-helper | ||||
| mutter-test-client | ||||
| mutter-test-runner | ||||
| mutter-test-unit-tests | ||||
| mutter-all.test | ||||
| org.gnome.mutter.gschema.valid | ||||
| org.gnome.mutter.gschema.xml | ||||
| @@ -62,12 +63,18 @@ src/stamp-meta-enum-types.h | ||||
| src/meta-dbus-display-config.[ch] | ||||
| src/meta-dbus-idle-monitor.[ch] | ||||
| src/meta-dbus-login1.[ch] | ||||
| src/gtk-primary-selection-protocol.c | ||||
| src/gtk-primary-selection-server-protocol.h | ||||
| src/gtk-shell-protocol.c | ||||
| src/gtk-shell-server-protocol.h | ||||
| src/xdg-shell-unstable-v*-protocol.c | ||||
| src/xdg-shell-unstable-v*-server-protocol.h | ||||
| src/pointer-gestures-unstable-v*-protocol.c | ||||
| src/pointer-gestures-unstable-v*-server-protocol.h | ||||
| src/relative-pointer-unstable-v*-protocol.c | ||||
| src/relative-pointer-unstable-v*-server-protocol.h | ||||
| src/pointer-constraints-unstable-v*-protocol.c | ||||
| src/pointer-constraints-unstable-v*-server-protocol.h | ||||
| src/meta/meta-version.h | ||||
| doc/reference/*.args | ||||
| doc/reference/*.bak | ||||
|   | ||||
							
								
								
									
										54
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								NEWS
									
									
									
									
									
								
							| @@ -1,3 +1,57 @@ | ||||
| 3.20.0 | ||||
| ====== | ||||
| * Fix crash when using visual bell [Jonas; #763858] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Jasper St. Pierre | ||||
|  | ||||
| Translations: | ||||
|   Milo Casagrande [it], Ask Hjorth Larsen [da] | ||||
|  | ||||
| 3.19.92 | ||||
| ======= | ||||
| * Add system bell support on wayland [Jonas; #763284] | ||||
| * Add gtk_surface.present to gtk-shell [Jonas; #763295] | ||||
| * Handle DND drops on the root window [Carlos; #762104] | ||||
| * Misc. bug fixes [Jonas, Carlos, Rui; #762828, #760745, #763125, #762763, | ||||
|   #762661, #762639, #763159] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Carlos Garnacho, Rui Matos, Florian Müllner | ||||
|  | ||||
| Translations: | ||||
|   Rūdolfs Mazurs [lv], Balázs Úr [hu], Claude Paroz [fr], Matej Urbančič [sl], | ||||
|   Мирослав Николић [sr, sr@latin], Sebastian Rasmussen [sv], Changwoo Ryu [ko], | ||||
|   Gil Forcada [ca], Tom Tryfonidis [el] | ||||
|  | ||||
| 3.19.91 | ||||
| ======= | ||||
| * Add --nested CLI argument to fix nested wayland session [Jonas; #758658] | ||||
| * Fix stack - scene graph stacking synchronization issues [Jonas; #755605] | ||||
| * Rate-limit last-device changes to fix freezes [Carlos; #753527] | ||||
| * Implement primary selection protocol [Carlos; #762560] | ||||
| * Misc. bug fixes [Carlos, Jonas; #762878, #762716] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Carlos Garnacho, Tim Lunn | ||||
|  | ||||
| Translations: | ||||
|   Piotr Drąg [pl], Artur de Aquino Morais [pt_BR], Marek Černocký [cs], | ||||
|   Cédric Valmary [oc], Mario Blättermann [de], Dušan Kazik [sk], | ||||
|   Fran Dieguez [gl], Aurimas Černius [lt], Daniel Mustieles [es], | ||||
|   Stas Solovey [ru], Yosef Or Boczko [he] | ||||
|  | ||||
| 3.19.90 | ||||
| ======= | ||||
| * Release buffer after processing commit [Ray; #761312, #761613] | ||||
| * Implement pointer motion, locks and confinement on wayland [Jonas; #744104] | ||||
| * Add basic startup notification support on wayland [Carlos; #762268] | ||||
| * Misc. bug fixes [Rui, Alberts, Florian; #760670, #761543, #752794, #761557] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Rui Matos, | ||||
|   Alberts Muktupāvels, Florian Müllner, Jasper St. Pierre, Ray Strode | ||||
|  | ||||
| 3.19.4 | ||||
| ====== | ||||
| * Fix updating stacking order when setting transient_for [Jonas; #755606] | ||||
|   | ||||
							
								
								
									
										10
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								configure.ac
									
									
									
									
									
								
							| @@ -1,8 +1,8 @@ | ||||
| AC_PREREQ(2.62) | ||||
|  | ||||
| m4_define([mutter_major_version], [3]) | ||||
| m4_define([mutter_minor_version], [19]) | ||||
| m4_define([mutter_micro_version], [4]) | ||||
| m4_define([mutter_minor_version], [20]) | ||||
| m4_define([mutter_micro_version], [0]) | ||||
|  | ||||
| m4_define([mutter_version], | ||||
|           [mutter_major_version.mutter_minor_version.mutter_micro_version]) | ||||
| @@ -59,12 +59,12 @@ CANBERRA_GTK_VERSION=0.26 | ||||
| CLUTTER_PACKAGE=clutter-1.0 | ||||
|  | ||||
| MUTTER_PC_MODULES=" | ||||
|    gtk+-3.0 >= 3.19.7 | ||||
|    gtk+-3.0 >= 3.19.8 | ||||
|    gio-unix-2.0 >= 2.35.1 | ||||
|    pango >= 1.2.0 | ||||
|    cairo >= 1.10.0 | ||||
|    gsettings-desktop-schemas >= 3.19.3 | ||||
|    $CLUTTER_PACKAGE >= 1.25.1 | ||||
|    $CLUTTER_PACKAGE >= 1.25.6 | ||||
|    cogl-1.0 >= 1.17.1 | ||||
|    upower-glib >= 0.99.0 | ||||
|    gnome-desktop-3.0 | ||||
| @@ -221,7 +221,7 @@ AS_IF([test "$have_wayland" = "yes"], [ | ||||
|   AC_SUBST([WAYLAND_SCANNER]) | ||||
|   AC_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support]) | ||||
|  | ||||
|   PKG_CHECK_MODULES(WAYLAND_PROTOCOLS, [wayland-protocols >= 1.0], | ||||
|   PKG_CHECK_MODULES(WAYLAND_PROTOCOLS, [wayland-protocols >= 1.1], | ||||
| 		    [ac_wayland_protocols_pkgdatadir=`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`]) | ||||
|   AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, $ac_wayland_protocols_pkgdatadir) | ||||
| ]) | ||||
|   | ||||
| @@ -29,6 +29,7 @@ eu | ||||
| fa | ||||
| fi | ||||
| fr | ||||
| fur | ||||
| ga | ||||
| gl | ||||
| gu | ||||
|   | ||||
							
								
								
									
										58
									
								
								po/ca.po
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								po/ca.po
									
									
									
									
									
								
							| @@ -6,21 +6,23 @@ | ||||
| # Jordi Mallach <jordi@sindominio.net>, 2003, 2004, 2005, 2006, 2007, 2008. | ||||
| # David Planella <david.planella@gmail.com>, 2008, 2009, 2011, 2012. | ||||
| # Jordi Serratosa <jordis@softcatala.cat>, 2012. | ||||
| # Gil Forcada <gilforcada@guifi.net>, 2012, 2013, 2014. | ||||
| # Gil Forcada <gilforcada@guifi.net>, 2012, 2013, 2014, 2016. | ||||
| # | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: metacity 2.24\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2015-03-10 17:33-0400\n" | ||||
| "PO-Revision-Date: 2015-03-10 17:33-0400\n" | ||||
| "Last-Translator: Jordi Mas <jmas@softcatala.org>\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2016-03-13 01:36+0000\n" | ||||
| "PO-Revision-Date: 2016-03-13 14:45+0100\n" | ||||
| "Last-Translator: Gil Forcada <gilforcada@guifi.net>\n" | ||||
| "Language-Team: Catalan <tradgnome@softcatala.org>\n" | ||||
| "Language: ca\n" | ||||
| "MIME-Version: 1.0\n" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| "Content-Transfer-Encoding: 8bits\n" | ||||
| "Plural-Forms: nplurals=2; plural=n != 1;\n" | ||||
| "X-Generator: Gtranslator 2.91.6\n" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:1 | ||||
| msgid "Navigation" | ||||
| @@ -465,22 +467,22 @@ msgstr "Canvia al terminal virtual 11" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Canvia al terminal virtual 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Pantalla integrada" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Desconeguda" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Pantalla desconeguda" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -496,7 +498,7 @@ msgstr "" | ||||
| "Ja s'està executant un altre gestor de composició a la pantalla %i a la " | ||||
| "visualització «%s»." | ||||
|  | ||||
| #: ../src/core/bell.c:185 | ||||
| #: ../src/core/bell.c:192 | ||||
| msgid "Bell event" | ||||
| msgstr "Esdeveniment de campana" | ||||
|  | ||||
| @@ -525,41 +527,51 @@ msgstr "_Espera" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Força'n la sortida" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "" | ||||
| "S'ha produït un error en obrir la pantalla del sistema de finestres X «%s»\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Inhabilita la connexió al gestor de sessions" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Reemplaça el gestor de finestres en execució" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Especifica l'ID de gestió de sessió" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Visualització X per usar" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Inicialitza la sessió des del fitxer desat" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Fes que les crides a l'X siguin síncrones" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Funciona com a compositor de Wayland" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| # Notes: | ||||
| # Afegeix una nota | ||||
| # | ||||
| # Camins: | ||||
| # ../src/core/main.c:223 | ||||
| #: ../src/core/main.c:223 | ||||
| #| msgid "Run as a wayland compositor" | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Funciona com a compositor imbricat" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Funciona com a servidor de pantalla completa, en comptes d'imbricat" | ||||
|  | ||||
| @@ -587,12 +599,12 @@ msgstr "Escriu versió" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Connector del Mutter a utilitzar" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Espai de treball %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -601,12 +613,12 @@ msgstr "" | ||||
| "La pantalla «%s» ja té un gestor de finestres; proveu l'opció --replace per " | ||||
| "reemplaçar el gestor de finestres actual." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "La pantalla %d en la visualització '%s' no és vàlida\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter es va compilar sense compatibilitat per al mode detallat\n" | ||||
|  | ||||
|   | ||||
							
								
								
									
										74
									
								
								po/cs.po
									
									
									
									
									
								
							
							
						
						
									
										74
									
								
								po/cs.po
									
									
									
									
									
								
							| @@ -12,7 +12,7 @@ msgstr "" | ||||
| "Project-Id-Version: mutter\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-03-24 23:25+0000\n" | ||||
| "POT-Creation-Date: 2016-02-27 13:36+0000\n" | ||||
| "PO-Revision-Date: 2014-09-22 15:01+0200\n" | ||||
| "Last-Translator: Petr Kovar <pknbe@volny.cz>\n" | ||||
| "Language-Team: Czech <gnome-cs-list@gnome.org>\n" | ||||
| @@ -238,8 +238,7 @@ msgstr "Přepnout okno na všechny/jednu pracovní plochu" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:13 | ||||
| msgid "Raise window if covered, otherwise lower it" | ||||
| msgstr "" | ||||
| "Když je okno zakryté vynést jej do popředí, jinak odsunout do pozadí" | ||||
| msgstr "Když je okno zakryté vynést jej do popředí, jinak odsunout do pozadí" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:14 | ||||
| msgid "Raise window above other windows" | ||||
| @@ -457,22 +456,22 @@ msgstr "Přepnout na VT 11" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Přepnout na VT 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Vestavěný displej" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Neznámý" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Neznámý displej" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -515,40 +514,44 @@ msgstr "_Počkat" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Vynutit ukončení" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Nelze otevřít displej X Window System „%s“\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Zakáže připojení ke správci sezení" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Nahradí běžícího správce oken" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Určení ID správy sezení" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Displej X, který použije" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Spustí sezení z uloženého souboru" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Provede volání X synchronně" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Spustit jako kompozitní program protokolu Wayland" | ||||
| msgstr "Spustit jako kompozitor protokolu Wayland" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Spustit jako podkladový kompozitor" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Spustit jako plnohodnotný server displeje, nikoliv vnořeně" | ||||
|  | ||||
| @@ -576,12 +579,12 @@ msgstr "Vypíše verzi" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Zásuvný modul Mutter, který se má použít" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Plocha %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -590,12 +593,12 @@ msgstr "" | ||||
| "Displej „%s“ již správce oken má; zkuste prosím nahradit aktuálního správce " | ||||
| "oken pomocí přepínače --replace." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Obrazovka %d na displeji „%s“ je neplatná\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter bylo přeloženo bez podpory podrobného režimu\n" | ||||
|  | ||||
| @@ -1272,32 +1275,3 @@ msgstr "%s (na %s)" | ||||
| #~ msgid "Move to Another _Workspace" | ||||
| #~ msgstr "Přes_unout na jinou plochu" | ||||
|  | ||||
| #~ msgid "Shift" | ||||
| #~ msgstr "Shift" | ||||
|  | ||||
| #~ msgid "Ctrl" | ||||
| #~ msgstr "Ctrl" | ||||
|  | ||||
| #~ msgid "Alt" | ||||
| #~ msgstr "Alt" | ||||
|  | ||||
| #~ msgid "Meta" | ||||
| #~ msgstr "Meta" | ||||
|  | ||||
| #~ msgid "Super" | ||||
| #~ msgstr "Super" | ||||
|  | ||||
| #~ msgid "Hyper" | ||||
| #~ msgstr "Hyper" | ||||
|  | ||||
| #~ msgid "Mod2" | ||||
| #~ msgstr "Mod2" | ||||
|  | ||||
| #~ msgid "Mod3" | ||||
| #~ msgstr "Mod3" | ||||
|  | ||||
| #~ msgid "Mod4" | ||||
| #~ msgstr "Mod4" | ||||
|  | ||||
| #~ msgid "Mod5" | ||||
| #~ msgstr "Mod5" | ||||
|   | ||||
							
								
								
									
										61
									
								
								po/da.po
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								po/da.po
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| # Danish translation of Mutter. | ||||
| # Copyright (C) 2002-2009, 2012-2015. | ||||
| # Copyright (C) 2002-2009, 2012-2016. | ||||
| # This file is distributed under the same license as the metacity package. | ||||
| # Kjartan Maraas <kmaraas@gnome.org>, 2002 | ||||
| # Keld simonsen <keld@dkuug.dk>, 2002 | ||||
| @@ -8,7 +8,7 @@ | ||||
| # Lasse Bang Mikkelsen <lbm@fatalerror.dk>, 2006. | ||||
| # Kenneth Nielsen <k.nielsen81@gmail.com>, 2008. | ||||
| # Joe Hansen <joedalton2@yahoo.dk>, 2011. | ||||
| # Ask Hjorth Larsen <asklarsen@gmail.com>, 2007, 09, 10, 12, 13, 14, 15. | ||||
| # Ask Hjorth Larsen <asklarsen@gmail.com>, 2007, 09, 10, 12, 13, 14, 15, 16. | ||||
| # | ||||
| # Konventioner: | ||||
| # | ||||
| @@ -20,8 +20,8 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: mutter\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2015-03-21 16:30+0100\n" | ||||
| "PO-Revision-Date: 2015-03-14 17:01+0100\n" | ||||
| "POT-Creation-Date: 2016-03-20 23:17+0100\n" | ||||
| "PO-Revision-Date: 2016-03-20 21:46+0100\n" | ||||
| "Last-Translator: Ask Hjorth Larsen <asklarsen@gmail.com>\n" | ||||
| "Language-Team: Danish <dansk@dansk-gruppen.dk>\n" | ||||
| "Language: da\n" | ||||
| @@ -291,7 +291,7 @@ msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:3 | ||||
| msgid "Attach modal dialogs" | ||||
| msgstr "Fastgør modaldialogvinduer" | ||||
| msgstr "Fastgør modaldialoger" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:4 | ||||
| msgid "" | ||||
| @@ -299,9 +299,8 @@ msgid "" | ||||
| "attached to the titlebar of the parent window and are moved together with " | ||||
| "the parent window." | ||||
| msgstr "" | ||||
| "Når sand, vil modaldialogvinduer hænge sammen med titellinjen af " | ||||
| "ophavsvinduet og flyttes sammen med dette, frem for at have uafhængige " | ||||
| "titellinjer." | ||||
| "Når sand, vil modaldialoger hænge sammen med titellinjen af ophavsvinduet og " | ||||
| "flyttes sammen med dette, frem for at have uafhængige titellinjer." | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:5 | ||||
| msgid "Enable edge tiling when dropping windows on screen edges" | ||||
| @@ -463,22 +462,22 @@ msgstr "Skift til VT 11" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Skift til VT 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Indbygget skærm" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Ukendt" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Ukendt skærm" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -493,7 +492,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "En anden komposithåndtering kører allerede på skærm %i på terminal \"%s\"." | ||||
|  | ||||
| #: ../src/core/bell.c:185 | ||||
| #: ../src/core/bell.c:192 | ||||
| msgid "Bell event" | ||||
| msgstr "Bip-hændelse" | ||||
|  | ||||
| @@ -522,40 +521,44 @@ msgstr "_Vent" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Tving til at afslutte" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Kunne ikke åbne X Window System-terminalen \"%s\"\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Deaktivér forbindelse til sessionshåndtering" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Erstat den kørende vindueshåndtering" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Angiv sessionhåndterings-id" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "X-skærm som bruges" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Initialisér session fra gemt fil" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Gør kald til X synkrone" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Kør som en wayland-kompositor" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Kør som en indlejret kompositor" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Kør som fuld displayserver, frem for indlejret" | ||||
|  | ||||
| @@ -582,12 +585,12 @@ msgstr "Vis version" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Mutter-udvidelsesmodul der skal bruges" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Arbejdsområde %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -596,12 +599,12 @@ msgstr "" | ||||
| "Terminalen \"%s\" har allerede en vindueshåndtering; prøv tilvalget --" | ||||
| "replace for at erstatte den aktuelle vindueshåndtering." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Skærm %d på terminal \"%s\" er ugyldig\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter blev kompileret uden understøttelse for uddybende tilstand\n" | ||||
|  | ||||
| @@ -1336,9 +1339,6 @@ msgstr "%s (på %s)" | ||||
| #~ msgid "_Dialog" | ||||
| #~ msgstr "_Dialog" | ||||
|  | ||||
| #~ msgid "_Modal dialog" | ||||
| #~ msgstr "_Modaldialogvindue" | ||||
|  | ||||
| #~ msgid "_Utility" | ||||
| #~ msgstr "_Værktøj" | ||||
|  | ||||
| @@ -1402,9 +1402,6 @@ msgstr "%s (på %s)" | ||||
| #~ msgid "Border" | ||||
| #~ msgstr "Ramme" | ||||
|  | ||||
| #~ msgid "Attached Modal Dialog" | ||||
| #~ msgstr "Fastgjort modaldialogvindue" | ||||
|  | ||||
| #~ msgid "Button layout test %d" | ||||
| #~ msgstr "Knaplayouttest %d" | ||||
|  | ||||
|   | ||||
							
								
								
									
										48
									
								
								po/de.po
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								po/de.po
									
									
									
									
									
								
							| @@ -3,7 +3,7 @@ | ||||
| # Matthias Warkus <mawarkus@gnome.org>, 2002. | ||||
| # Christian Neumair <chris@gnome-de.org>, 2002-2004. | ||||
| # Hendrik Richter <hendrikr@gnome.org>, 2005, 2006, 2007, 2008. | ||||
| # Mario Blättermann <mario.blaettermann@gmail.com>, 2010-2013. | ||||
| # Mario Blättermann <mario.blaettermann@gmail.com>, 2010-2013, 2016. | ||||
| # Christian Kirbach <Christian.Kirbach@googlemail.com>, 2009, 2011, 2012. | ||||
| # Wolfgang Stöggl <c72578@yahoo.de> 2011. | ||||
| # Tobias Endrigkeit <tobiasendrigkeit@googlemail.com>, 2012. | ||||
| @@ -13,16 +13,16 @@ msgstr "" | ||||
| "Project-Id-Version: mutter master\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-06-20 08:08+0000\n" | ||||
| "PO-Revision-Date: 2015-06-18 20:59+0100\n" | ||||
| "Last-Translator: Bernd Homuth <dev@hmt.im>\n" | ||||
| "POT-Creation-Date: 2016-02-28 13:37+0000\n" | ||||
| "PO-Revision-Date: 2016-02-28 19:15+0100\n" | ||||
| "Last-Translator: Mario Blättermann <mario.blaettermann@gmail.com>\n" | ||||
| "Language-Team: Deutsch <gnome-de@gnome.org>\n" | ||||
| "Language: de\n" | ||||
| "MIME-Version: 1.0\n" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "Plural-Forms: nplurals=2; plural=(n != 1);\n" | ||||
| "X-Generator: Poedit 1.8.1\n" | ||||
| "X-Generator: Poedit 1.8.7\n" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:1 | ||||
| msgid "Navigation" | ||||
| @@ -463,22 +463,22 @@ msgstr "Zum virtuellen Terminal 11 wechseln" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Zum virtuellen Terminal 12 wechseln" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Eingebaute Anzeige" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Unbekannt" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Unbekannte Anzeige" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -523,40 +523,44 @@ msgstr "_Warten" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Beenden erzwingen" | ||||
|  | ||||
| #: ../src/core/display.c:563 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "X-Window-Systemanzeige »%s« konnte nicht geöffnet werden\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Verbindung zur Sitzungsverwaltung deaktivieren" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Den aktuellen Fensterverwalter ersetzen" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Kennung der Sitzungsverwaltung angeben" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Zu verwendende X-Anzeige" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Sitzung anhand gespeicherter Datei starten" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "X-Aufrufe abgleichen" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Als Wayland-Compositor ausführen" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Als eingebetteten Compositor ausführen" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Als vollwertigen Display-Server verwenden (nicht eingebettet)" | ||||
|  | ||||
| @@ -586,12 +590,12 @@ msgstr "Version ausgeben" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Zu benutzendes Mutter-Plugin" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Arbeitsfläche %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -600,12 +604,12 @@ msgstr "" | ||||
| "Bildschirm »%s« hat bereits einen Fensterverwalter. Versuchen Sie die Option " | ||||
| "»--replace«, um den aktuellen Fensterverwalter zu ersetzen." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Bildschirm %d auf Anzeige »%s« ist ungültig\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter wurde ohne Unterstützung für den redseligen Modus kompiliert\n" | ||||
|  | ||||
|   | ||||
							
								
								
									
										58
									
								
								po/el.po
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								po/el.po
									
									
									
									
									
								
							| @@ -20,16 +20,16 @@ msgstr "" | ||||
| "Project-Id-Version: metacity.gnome-2-26\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-02-21 11:31+0000\n" | ||||
| "PO-Revision-Date: 2015-02-21 15:43+0200\n" | ||||
| "Last-Translator: Efstathios Iosifidis <iosifidis@opensuse.org>\n" | ||||
| "POT-Creation-Date: 2016-03-12 01:36+0000\n" | ||||
| "PO-Revision-Date: 2016-03-14 23:05+0200\n" | ||||
| "Last-Translator: Tom Tryfonidis <tomtryf@gmail.com>\n" | ||||
| "Language-Team: Greek, Modern (1453-) <opensuse-translation-el@opensuse.org>\n" | ||||
| "Language: el\n" | ||||
| "MIME-Version: 1.0\n" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "Plural-Forms: nplurals=2; plural=(n != 1);\n" | ||||
| "X-Generator: Gtranslator 2.91.6\n" | ||||
| "X-Generator: Poedit 1.8.7\n" | ||||
| "X-Project-Style: gnome\n" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:1 | ||||
| @@ -453,46 +453,41 @@ msgid "Switch to VT 7" | ||||
| msgstr "Εναλλαγή στο VT 7" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 8" | ||||
| msgstr "Εναλλαγή στο VT 8" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 9" | ||||
| msgstr "Εναλλαγή στο VT 9" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 10" | ||||
| msgstr "Εναλλαγή στο VT 10" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 11" | ||||
| msgstr "Εναλλαγή στο VT 11" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Εναλλαγή στο VT 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Ενσωματωμένη οθόνη" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Άγνωστη" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Άγνωστη οθόνη" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -507,7 +502,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Εκτελείται ένας άλλος διαχειριστής παραθύρων στην οθόνη %i προβολή \"%s\"." | ||||
|  | ||||
| #: ../src/core/bell.c:185 | ||||
| #: ../src/core/bell.c:192 | ||||
| msgid "Bell event" | ||||
| msgstr "Ηχητικό συμβάν κουδουνιού" | ||||
|  | ||||
| @@ -537,40 +532,44 @@ msgid "_Force Quit" | ||||
| msgstr "_Εξαναγκασμός σε τερματισμό" | ||||
|  | ||||
| # gconf/gconf-internals.c:2416 | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Αποτυχία ανοίγματος οθόνης του συστήματος παραθύρων Χ '%s'\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Απενεργοποίηση σύνδεσης στο διαχειριστή συνεδρίας" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Αντικατάσταση του τρέχοντος διαχειριστή παραθύρων" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Καθορισμός αναγνωριστικού διαχείρισης συνεδρίας" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Εμφάνιση Χ για χρήση" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Εκκίνηση συνεδρίας από savefile" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Να καταστούν σύγχρονες οι κλήσεις του X" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Εκτέλεση ως συνθετητής wayland" | ||||
| msgstr "Εκτέλεση ως wayland compositor" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Εκτέλεση ως ενσωματωμένος compositor" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Εκτέλεση ως διακομιστής πλήρους οθόνης, αντί ενσωματωμένης" | ||||
|  | ||||
| @@ -598,16 +597,13 @@ msgstr "Εμφάνιση έκδοσης" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Πρόσθετα του Mutter για χρήση" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Χώρος εργασίας %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| #| msgid "" | ||||
| #| "Screen %d on display \"%s\" already has a window manager; try using the --" | ||||
| #| "replace option to replace the current window manager.\n" | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| "to replace the current window manager." | ||||
| @@ -616,12 +612,12 @@ msgstr "" | ||||
| "χρησιμοποιήσετε την επιλογή --replace για να αντικαταστήσετε τον τρέχων " | ||||
| "διαχειριστή παραθύρων." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Η οθόνη %d στην προβολή '%s' δεν είναι έγκυρη\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "" | ||||
| "Το Mutter έχει μεταγλωττιστεί χωρίς υποστήριξη για λειτουργία εμφάνισης " | ||||
|   | ||||
							
								
								
									
										50
									
								
								po/es.po
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								po/es.po
									
									
									
									
									
								
							| @@ -7,15 +7,15 @@ | ||||
| # Pablo Gonzalo del Campo <pablodc@bigfoot.com>,2002,2003. | ||||
| # Francisco Javier F. Serrador <serrador@cvs.gnome.org>, 2004, 2005, 2006. | ||||
| # Jorge González <jorgegonz@svn.gnome.org>, 2007, 2008, 2009, 2010, 2011. | ||||
| # Daniel Mustieles <daniel.mustieles@gmail.com>, 2011, 2012, 2013, 2014, 2015. | ||||
| # Daniel Mustieles <daniel.mustieles@gmail.com>, 2011, 2012, 2013, 2014, 2015, 2016. | ||||
| # | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: mutter.master\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-02-23 11:10+0000\n" | ||||
| "PO-Revision-Date: 2015-02-23 19:07+0100\n" | ||||
| "POT-Creation-Date: 2016-02-28 13:37+0000\n" | ||||
| "PO-Revision-Date: 2016-02-29 16:02+0100\n" | ||||
| "Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n" | ||||
| "Language-Team: Español; Castellano <gnome-es-list@gnome.org>\n" | ||||
| "Language: \n" | ||||
| @@ -445,46 +445,41 @@ msgid "Switch to VT 7" | ||||
| msgstr "Cambiar al VT 7" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 8" | ||||
| msgstr "Cambiar al VT 8" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 9" | ||||
| msgstr "Cambiar al VT 9" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 10" | ||||
| msgstr "Cambiar al VT 10" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 11" | ||||
| msgstr "Cambiar al VT 11" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Cambiar al VT 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Pantalla integrada" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Desconocida" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Pantalla desconocida" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -529,40 +524,45 @@ msgstr "_Esperar" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Forzar la salida" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Ocurrió un error al abrir la pantalla de X Window System «%s»\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Desactivar conexión al gestor de sesión" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Reemplazar el gestor de ventanas en ejecución" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Especificar el ID se gestión de sesión" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Pantalla X que usar" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Inicializar sesión desde el archivo de salvaguarda" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Hacer que las llamadas a las X sean síncronas" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Ejecutar como compositor Wayland" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| #| msgid "Run as a wayland compositor" | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Ejecutar como compositor anidado" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Ejecutar como servidor completo, en lugar de anidado" | ||||
|  | ||||
| @@ -589,12 +589,12 @@ msgstr "Imprimir versión" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Complemento de mutter que usar" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Área de trabajo %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -603,12 +603,12 @@ msgstr "" | ||||
| "La pantalla «%s» ya tiene un gestor de ventanas; pruebe a usar la opción «--" | ||||
| "replace» para reemplazar el gestor de ventanas activo." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "La ventana %d en la pantalla «%s» no es válida\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter fue compilado sin soporte para modo prolijo\n" | ||||
|  | ||||
|   | ||||
							
								
								
									
										63
									
								
								po/eu.po
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								po/eu.po
									
									
									
									
									
								
							| @@ -2,24 +2,23 @@ | ||||
| # This file is distributed under the same license as the PACKAGE package. | ||||
| # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. | ||||
| # | ||||
| # | ||||
| # Hizkuntza Politikarako Sailburuordetza <hizpol@ej-gv.es>, 2004. | ||||
| # Iñaki Larrañaga Murgoitio <dooteo@zundan.com>, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011. | ||||
| # Iñaki Larrañaga Murgoitio <dooteo@zundan.com>, 2012, 2013, 2014, 2015. | ||||
| # | ||||
| # Iñaki Larrañaga Murgoitio <dooteo@zundan.com>, 2012, 2013, 2014, 2015, 2016. | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: mutter master\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-03-21 15:50+0100\n" | ||||
| "PO-Revision-Date: 2015-03-21 15:51+0100\n" | ||||
| "Last-Translator: Iñaki Larrañaga Murgoitio <dooteo@zundan.com>\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2016-03-23 17:05+0100\n" | ||||
| "PO-Revision-Date: 2016-03-23 17:06+0100\n" | ||||
| "Last-Translator: dooteo <dooteo@zundan.com>\n" | ||||
| "Language-Team: Basque <librezale@librezale.org>\n" | ||||
| "Language: eu\n" | ||||
| "MIME-Version: 1.0\n" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "X-Generator: Lokalize 1.4\n" | ||||
| "X-Generator: Lokalize 2.0\n" | ||||
| "Plural-Forms: nplurals=2; plural=(n != 1);\n" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:1 | ||||
| @@ -455,22 +454,22 @@ msgstr "Aldatu 11. TBra" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Aldatu 12. TBra" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Bertako pantaila" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Ezezaguna" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Pantaila ezezaguna" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -486,7 +485,7 @@ msgstr "" | ||||
| "Dagoeneko beste konposatze-kudeatzailea ari da exekutatzen \"%2$s\" " | ||||
| "pantailako %1$i. monitorean \"." | ||||
|  | ||||
| #: ../src/core/bell.c:185 | ||||
| #: ../src/core/bell.c:194 | ||||
| msgid "Bell event" | ||||
| msgstr "Soinuaren gertaera" | ||||
|  | ||||
| @@ -515,40 +514,44 @@ msgstr "_Itxaron" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Behartu ixtera" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Huts egin du X Window sistemaren '%s' pantaila irekitzean\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Desgaitu saio-kudeatzailearen konexioa" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Ordeztu exekutatzen dagoen leiho-kudeatzailea" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Zehaztu saio-kudeatzailearen IDa" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "X pantaila erabiltzeko" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Hasieratu saioa babes-fitxategitik" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Egin X deiak sinkronoak izatea" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Exekutatu wayland konposatzaile gisa" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Exekutatu habiaratutako konposatzaile gisa" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Exekutatu pantaila-zerbitzari oso bezala, habiaratuta baino" | ||||
|  | ||||
| @@ -575,12 +578,12 @@ msgstr "Erakutsi bertsioa" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Mutter-en osagaia erabiltzeko" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "%d. laneko area" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -589,12 +592,12 @@ msgstr "" | ||||
| "'%s' pantailak badu leiho-kudeatzailea; erabili --replace aukera uneko leiho-" | ||||
| "kudeatzailea ordezteko." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "'%2$s' bistaratzeko %1$d pantaila ez da baliozkoa\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter modu xehatuaren euskarririk gabe konpilatu da\n" | ||||
|  | ||||
| @@ -676,11 +679,11 @@ msgstr "%s (%s)" | ||||
| #~ "\" ez dator bat formatuarekin" | ||||
|  | ||||
| #~ msgid "" | ||||
| #~ "GTK color specification must have the state in brackets, e.g. gtk:fg" | ||||
| #~ "[NORMAL] where NORMAL is the state; could not parse \"%s\"" | ||||
| #~ "GTK color specification must have the state in brackets, e.g. gtk:" | ||||
| #~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" | ||||
| #~ msgstr "" | ||||
| #~ "GTK kolore-zehaztapenak egoera kortxete artean izan behar du, adib. gtk:fg" | ||||
| #~ "[NORMAL], NORMAL egoera izanik; \"%s\" ezin da analizatu" | ||||
| #~ "GTK kolore-zehaztapenak egoera kortxete artean izan behar du, adib. gtk:" | ||||
| #~ "fg[NORMAL], NORMAL egoera izanik; \"%s\" ezin da analizatu" | ||||
|  | ||||
| #~ msgid "" | ||||
| #~ "GTK color specification must have a close bracket after the state, e.g. " | ||||
|   | ||||
							
								
								
									
										46
									
								
								po/fr.po
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								po/fr.po
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| # French translation of mutter. | ||||
| # Copyright (C) 2002-2015 Free Software Foundation, Inc. | ||||
| # Copyright (C) 2002-2016 Free Software Foundation, Inc. | ||||
| # This file is distributed under the same license as the metacity package. | ||||
| # | ||||
| # Christophe Fergeau <teuf@users.sourceforge.net>, 2002. | ||||
| @@ -11,7 +11,7 @@ | ||||
| # Cyprien Le Pannérer <cyplp@free.fr>, 2006. | ||||
| # Robert-André Mauchin <zebob.m@gmail.com>, 2007.  | ||||
| # Stéphane Raimbault <stephane.raimbault@gmail.com>, 2007. | ||||
| # Claude Paroz <claude@2xlibre.net>, 2008-2015. | ||||
| # Claude Paroz <claude@2xlibre.net>, 2008-2016. | ||||
| # Bruno Brouard <annoa.b@gmail.com>, 2011-12. | ||||
| # | ||||
| msgid "" | ||||
| @@ -19,8 +19,8 @@ msgstr "" | ||||
| "Project-Id-Version: mutter master\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-02-23 23:11+0000\n" | ||||
| "PO-Revision-Date: 2015-02-24 10:08+0100\n" | ||||
| "POT-Creation-Date: 2016-03-05 13:41+0000\n" | ||||
| "PO-Revision-Date: 2016-03-05 17:57+0100\n" | ||||
| "Last-Translator: Claude Paroz <claude@2xlibre.net>\n" | ||||
| "Language-Team: GNOME French Team <gnomefr@traduc.org>\n" | ||||
| "Language: fr\n" | ||||
| @@ -468,22 +468,22 @@ msgstr "Passer à l'émulateur de terminal 11" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Passer à l'émulateur de terminal 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Affichage intégré" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Inconnu" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Affichage inconnu" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -528,40 +528,44 @@ msgstr "_Attendre" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Forcer à quitter" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Impossible d'ouvrir l'affichage « %s » du système X Window\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Désactiver la connexion au gestionnaire de sessions" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Remplacer le gestionnaire de fenêtres en cours de fonctionnement" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Indiquer l'ID de gestion de sessions" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Affichage X à utiliser" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Initialiser la session depuis le fichier de sauvegarde" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Rendre synchrones les appels à X" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Lancer comme un compositeur wayland" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Lancer comme un compositeur imbriqué" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Lancer comme un serveur d'affichage complet, plutôt qu'imbriqué" | ||||
|  | ||||
| @@ -589,12 +593,12 @@ msgstr "Afficher la version" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Greffon de Mutter à utiliser" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Espace de travail %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -603,12 +607,12 @@ msgstr "" | ||||
| "L'affichage « %s » a déjà un gestionnaire de fenêtres ; essayez d'utiliser " | ||||
| "l'option --replace pour remplacer le gestionnaire de fenêtres actuel." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "L'écran %d sur l'affichage « %s » n'est pas valide\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter a été compilé sans la prise en charge du mode bavard\n" | ||||
|  | ||||
|   | ||||
							
								
								
									
										583
									
								
								po/fur.po
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										583
									
								
								po/fur.po
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,583 @@ | ||||
| # Friulian translation for mutter. | ||||
| # Copyright (C) 2016 mutter's COPYRIGHT HOLDER | ||||
| # This file is distributed under the same license as the mutter package. | ||||
| # Fabio Tomat <f.t.public@gmail.com>, 2016. | ||||
| # | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: mutter master\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2016-03-25 01:58+0000\n" | ||||
| "PO-Revision-Date: 2016-03-25 17:54+0100\n" | ||||
| "Language-Team: Friulian <fur@li.org>\n" | ||||
| "Language: fur\n" | ||||
| "MIME-Version: 1.0\n" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n" | ||||
| "X-Generator: Poedit 1.8.5\n" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:1 | ||||
| msgid "Navigation" | ||||
| msgstr "Navigazion" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:2 | ||||
| msgid "Move window to workspace 1" | ||||
| msgstr "Sposte barcon tal spazi di lavôr 1" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:3 | ||||
| msgid "Move window to workspace 2" | ||||
| msgstr "Sposte barcon tal spazi di lavôr 2" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:4 | ||||
| msgid "Move window to workspace 3" | ||||
| msgstr "Sposte barcon tal spazi di lavôr 3" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:5 | ||||
| msgid "Move window to workspace 4" | ||||
| msgstr "Sposte barcon tal spazi di lavôr 4" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:6 | ||||
| msgid "Move window to last workspace" | ||||
| msgstr "Sposte barcon tal ultin spazi di lavôr" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:7 | ||||
| msgid "Move window one workspace to the left" | ||||
| msgstr "Sposte barcon tal spazi di lavôr a çampe" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:8 | ||||
| msgid "Move window one workspace to the right" | ||||
| msgstr "Sposte barcon tal spazi di lavôr a drete" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:9 | ||||
| msgid "Move window one workspace up" | ||||
| msgstr "Sposte barcon tal spazi di lavôr parsore" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:10 | ||||
| msgid "Move window one workspace down" | ||||
| msgstr "Sposte barcon tal spazi di lavôr sot" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:11 | ||||
| msgid "Move window one monitor to the left" | ||||
| msgstr "Sposte barcon tal visôr a çampe" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:12 | ||||
| msgid "Move window one monitor to the right" | ||||
| msgstr "Sposte barcon tal visôr a drete" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:13 | ||||
| msgid "Move window one monitor up" | ||||
| msgstr "Sposte barcon tal visôr parsore" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:14 | ||||
| msgid "Move window one monitor down" | ||||
| msgstr "Sposte barcon tal visôr sot" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:15 | ||||
| msgid "Switch applications" | ||||
| msgstr "Passâ di une aplicazion in chê altre" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:16 | ||||
| msgid "Switch to previous application" | ||||
| msgstr "Passe ae aplicazion prime" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:17 | ||||
| msgid "Switch windows" | ||||
| msgstr "Passâ di un barcon in chel altri" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:18 | ||||
| msgid "Switch to previous window" | ||||
| msgstr "Passe al barcon prime" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:19 | ||||
| msgid "Switch windows of an application" | ||||
| msgstr "Passâ di un barcon in chel altri di une aplicazion" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:20 | ||||
| msgid "Switch to previous window of an application" | ||||
| msgstr "Passe al barcon prime di une aplicazion" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:21 | ||||
| msgid "Switch system controls" | ||||
| msgstr "Passâ di un control di sisteme in chel altri" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:22 | ||||
| msgid "Switch to previous system control" | ||||
| msgstr "Passe al control di sisteme precedent" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:23 | ||||
| msgid "Switch windows directly" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:24 | ||||
| msgid "Switch directly to previous window" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:25 | ||||
| msgid "Switch windows of an app directly" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:26 | ||||
| msgid "Switch directly to previous window of an app" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:27 | ||||
| msgid "Switch system controls directly" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:28 | ||||
| msgid "Switch directly to previous system control" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:29 | ||||
| msgid "Hide all normal windows" | ||||
| msgstr "Plate ducj i barcons normâi" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:30 | ||||
| msgid "Switch to workspace 1" | ||||
| msgstr "Passe al spazi di lavôr 1" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:31 | ||||
| msgid "Switch to workspace 2" | ||||
| msgstr "Passe al spazi di lavôr 2" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:32 | ||||
| msgid "Switch to workspace 3" | ||||
| msgstr "Passe al spazi di lavôr 3" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:33 | ||||
| msgid "Switch to workspace 4" | ||||
| msgstr "Passe al spazi di lavôr 4" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:34 | ||||
| msgid "Switch to last workspace" | ||||
| msgstr "Passe al ultin spazi di lavôr" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:35 | ||||
| msgid "Move to workspace left" | ||||
| msgstr "Sposte il spazi di lavôr a çampe" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:36 | ||||
| msgid "Move to workspace right" | ||||
| msgstr "Sposte il spazi di lavôr a drete" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:37 | ||||
| msgid "Move to workspace above" | ||||
| msgstr "Sposte il spazi di lavôr parsore" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:38 | ||||
| msgid "Move to workspace below" | ||||
| msgstr "Sposte il spazi di lavôr sot" | ||||
|  | ||||
| #: ../data/50-mutter-system.xml.in.h:1 | ||||
| msgid "System" | ||||
| msgstr "Sisteme" | ||||
|  | ||||
| #: ../data/50-mutter-system.xml.in.h:2 | ||||
| msgid "Show the run command prompt" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/50-mutter-system.xml.in.h:3 | ||||
| msgid "Show the activities overview" | ||||
| msgstr "Mostre la panoramiche ativitâts" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:1 | ||||
| msgid "Windows" | ||||
| msgstr "Barcons" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:2 | ||||
| msgid "Activate the window menu" | ||||
| msgstr "Ative il menù dal barcon" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:3 | ||||
| msgid "Toggle fullscreen mode" | ||||
| msgstr "Ative/Disative modalitât plen visôr" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:4 | ||||
| msgid "Toggle maximization state" | ||||
| msgstr "Ative/Disative il stât slargjât" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:5 | ||||
| msgid "Maximize window" | ||||
| msgstr "Slargje il barcon" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:6 | ||||
| msgid "Restore window" | ||||
| msgstr "Ripristine barcon" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:7 | ||||
| msgid "Toggle shaded state" | ||||
| msgstr "Ative/Disative stât inrodolât" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:8 | ||||
| msgid "Close window" | ||||
| msgstr "Siere il barcon" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:9 | ||||
| msgid "Hide window" | ||||
| msgstr "Plate il barcon" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:10 | ||||
| msgid "Move window" | ||||
| msgstr "Sposte il barcon" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:11 | ||||
| msgid "Resize window" | ||||
| msgstr "Ridimensione barcon" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:12 | ||||
| msgid "Toggle window on all workspaces or one" | ||||
| msgstr "Ative/Disative barcon su ducj i spazis di lavôr o nome un" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:13 | ||||
| msgid "Raise window if covered, otherwise lower it" | ||||
| msgstr "Tire sù il barcon se al è cuviert, se no sbassilu" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:14 | ||||
| msgid "Raise window above other windows" | ||||
| msgstr "Met il barcon parsore di chei altris" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:15 | ||||
| msgid "Lower window below other windows" | ||||
| msgstr "Bute il barcon sot di chei altris" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:16 | ||||
| msgid "Maximize window vertically" | ||||
| msgstr "Slargje il barcon par verticâl" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:17 | ||||
| msgid "Maximize window horizontally" | ||||
| msgstr "Slargje il barcon par orizontâl" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:18 | ||||
| msgid "View split on left" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/50-mutter-windows.xml.in.h:19 | ||||
| msgid "View split on right" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/mutter.desktop.in.h:1 | ||||
| msgid "Mutter" | ||||
| msgstr "Mutter" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:1 | ||||
| msgid "Modifier to use for extended window management operations" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:2 | ||||
| msgid "" | ||||
| "This key will initiate the \"overlay\", which is a combination window " | ||||
| "overview and application launching system. The default is intended to be the " | ||||
| "\"Windows key\" on PC hardware. It's expected that this binding either the " | ||||
| "default or set to the empty string." | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:3 | ||||
| msgid "Attach modal dialogs" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:4 | ||||
| msgid "" | ||||
| "When true, instead of having independent titlebars, modal dialogs appear " | ||||
| "attached to the titlebar of the parent window and are moved together with " | ||||
| "the parent window." | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:5 | ||||
| msgid "Enable edge tiling when dropping windows on screen edges" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:6 | ||||
| msgid "" | ||||
| "If enabled, dropping windows on vertical screen edges maximizes them " | ||||
| "vertically and resizes them horizontally to cover half of the available " | ||||
| "area. Dropping windows on the top screen edge maximizes them completely." | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:7 | ||||
| msgid "Workspaces are managed dynamically" | ||||
| msgstr "I spazis di vore a son ministrât in maniere dinamiche" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:8 | ||||
| msgid "" | ||||
| "Determines whether workspaces are managed dynamically or whether there's a " | ||||
| "static number of workspaces (determined by the num-workspaces key in org." | ||||
| "gnome.desktop.wm.preferences)." | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:9 | ||||
| msgid "Workspaces only on primary" | ||||
| msgstr "Spazis di vore nome tal visôr primari" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:10 | ||||
| msgid "" | ||||
| "Determines whether workspace switching should happen for windows on all " | ||||
| "monitors or only for windows on the primary monitor." | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:11 | ||||
| msgid "No tab popup" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:12 | ||||
| msgid "" | ||||
| "Determines whether the use of popup and highlight frame should be disabled " | ||||
| "for window cycling." | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:13 | ||||
| msgid "Delay focus changes until the pointer stops moving" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:14 | ||||
| msgid "" | ||||
| "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " | ||||
| "the focus will not be changed immediately when entering a window, but only " | ||||
| "after the pointer stops moving." | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:15 | ||||
| msgid "Draggable border width" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:16 | ||||
| msgid "" | ||||
| "The amount of total draggable borders. If the theme's visible borders are " | ||||
| "not enough, invisible borders will be added to meet this value." | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:17 | ||||
| msgid "Auto maximize nearly monitor sized windows" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:18 | ||||
| msgid "" | ||||
| "If enabled, new windows that are initially the size of the monitor " | ||||
| "automatically get maximized." | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:19 | ||||
| msgid "Place new windows in the center" | ||||
| msgstr "Place i gnûfs barcons tal mieç" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:20 | ||||
| msgid "" | ||||
| "When true, the new windows will always be put in the center of the active " | ||||
| "screen of the monitor." | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:21 | ||||
| msgid "Select window from tab popup" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:22 | ||||
| msgid "Cancel tab popup" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1 | ||||
| msgid "Switch to VT 1" | ||||
| msgstr "Passe al VT 1" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2 | ||||
| msgid "Switch to VT 2" | ||||
| msgstr "Passe al VT 2" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3 | ||||
| msgid "Switch to VT 3" | ||||
| msgstr "Passe al VT 3" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4 | ||||
| msgid "Switch to VT 4" | ||||
| msgstr "Passe al VT 4" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5 | ||||
| msgid "Switch to VT 5" | ||||
| msgstr "Passe al VT 5" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6 | ||||
| msgid "Switch to VT 6" | ||||
| msgstr "Passe al VT 6" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7 | ||||
| msgid "Switch to VT 7" | ||||
| msgstr "Passe al VT 7" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8 | ||||
| msgid "Switch to VT 8" | ||||
| msgstr "Passe al VT 8" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9 | ||||
| msgid "Switch to VT 9" | ||||
| msgstr "Passe al VT 9" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10 | ||||
| msgid "Switch to VT 10" | ||||
| msgstr "Passe al VT 10" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11 | ||||
| msgid "Switch to VT 11" | ||||
| msgstr "Passe al VT 11" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12 | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Passe al VT 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Display integrât" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "No cognossût" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Display no cognossût" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
|  | ||||
| #. This probably means that a non-WM compositor like xcompmgr is running; | ||||
| #. * we have no way to get it to exit | ||||
| #: ../src/compositor/compositor.c:456 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Another compositing manager is already running on screen %i on display \"%s" | ||||
| "\"." | ||||
| msgstr "" | ||||
| "Un altri compositing manager al è za in esecuzion sul schermi %i sul display " | ||||
| "\"%s\"." | ||||
|  | ||||
| #: ../src/core/bell.c:194 | ||||
| msgid "Bell event" | ||||
| msgstr "Event cjampane" | ||||
|  | ||||
| #: ../src/core/delete.c:127 | ||||
| #, c-format | ||||
| msgid "“%s” is not responding." | ||||
| msgstr "“%s” nol rispuint." | ||||
|  | ||||
| #: ../src/core/delete.c:129 | ||||
| msgid "Application is not responding." | ||||
| msgstr "La aplicazion no rispuint." | ||||
|  | ||||
| #: ../src/core/delete.c:134 | ||||
| msgid "" | ||||
| "You may choose to wait a short while for it to continue or force the " | ||||
| "application to quit entirely." | ||||
| msgstr "" | ||||
|  | ||||
| #: ../src/core/delete.c:141 | ||||
| msgid "_Wait" | ||||
| msgstr "_Spiete" | ||||
|  | ||||
| #: ../src/core/delete.c:141 | ||||
| msgid "_Force Quit" | ||||
| msgstr "Sfuarce _Jessude" | ||||
|  | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Impussibil vierzi il display '%s' di X Window System\n" | ||||
|  | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Rimplace il window manager in vore" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "" | ||||
|  | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Display X di doprâ" | ||||
|  | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Inizialize session da file salvât" | ||||
|  | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Fâs lis clamadis X sincronis" | ||||
|  | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Eseguìs come compositor wayland" | ||||
|  | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Eseguìs come compositor nidiât" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Eseguìs come servidôr display complet, invezit che nidiât" | ||||
|  | ||||
| #: ../src/core/mutter.c:39 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "mutter %s\n" | ||||
| "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" | ||||
| "This is free software; see the source for copying conditions.\n" | ||||
| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " | ||||
| "PARTICULAR PURPOSE.\n" | ||||
| msgstr "" | ||||
| "mutter %s\n" | ||||
| "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., e altris\n" | ||||
| "Chest al è software libar; viodi i sorzints pes condizions di copie.\n" | ||||
| "No je NISSUNE garanzie; nancje di COMERCIABILITÂT o IDONEITÂT A UNE " | ||||
| "FINALITÂT PARTICOLÂR.\n" | ||||
|  | ||||
| #: ../src/core/mutter.c:53 | ||||
| msgid "Print version" | ||||
| msgstr "Stampe version" | ||||
|  | ||||
| #: ../src/core/mutter.c:59 | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Plugin Mutter di doprâ" | ||||
|  | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Spazi di lavôr %d" | ||||
|  | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| "to replace the current window manager." | ||||
| msgstr "" | ||||
| "Il display \"%s\" al à za un window manager; prove dopre la opzion --replace " | ||||
| "par rimplaçâ chel atuâl." | ||||
|  | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Schermi %d su display '%s' no valit\n" | ||||
|  | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter al è stât compilât cence supuart pe modalitât fetose\n" | ||||
|  | ||||
| #: ../src/x11/session.c:1815 | ||||
| msgid "" | ||||
| "These windows do not support "save current setup" and will have to " | ||||
| "be restarted manually next time you log in." | ||||
| msgstr "" | ||||
| "Chescj barcons no supuartin la funzion "salve impostazions atuâi" " | ||||
| "e si scugnarà tornâ a inviâlis a man tal prossim acès." | ||||
|  | ||||
| #: ../src/x11/window-props.c:549 | ||||
| #, c-format | ||||
| msgid "%s (on %s)" | ||||
| msgstr "%s (su %s)" | ||||
							
								
								
									
										49
									
								
								po/gl.po
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								po/gl.po
									
									
									
									
									
								
							| @@ -9,22 +9,21 @@ | ||||
| # Mancomún - Centro de Referencia e Servizos de Software Libre <g11n@mancomun.org>, 2009. | ||||
| # Fran Diéguez <frandieguez@gnome.org>, 2009, 2010, 2011, 2012. | ||||
| # Leandro Regueiro <leandro.regueiro@gmail.com>, 2012. | ||||
| # Fran Dieguez <frandieguez@gnome.org>, 2012, 2013, 2014, 2015. | ||||
| # | ||||
| # Fran Dieguez <frandieguez@gnome.org>, 2012, 2013, 2014, 2015, 2016. | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: gl\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2015-02-28 22:43+0100\n" | ||||
| "PO-Revision-Date: 2015-02-28 22:42+0100\n" | ||||
| "POT-Creation-Date: 2016-03-02 09:49+0100\n" | ||||
| "PO-Revision-Date: 2016-03-02 09:49+0200\n" | ||||
| "Last-Translator: Fran Dieguez <frandieguez@gnome.org>\n" | ||||
| "Language-Team: Galician <>\n" | ||||
| "Language-Team: gnome-l10n-gl@gnome.org\n" | ||||
| "Language: gl\n" | ||||
| "MIME-Version: 1.0\n" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "Plural-Forms: nplurals=2; plural=(n != 1);\n" | ||||
| "X-Generator: Gtranslator 2.91.6\n" | ||||
| "X-Generator: Virtaal 0.7.1\n" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:1 | ||||
| msgid "Navigation" | ||||
| @@ -461,22 +460,22 @@ msgstr "Cambiar á VT 11" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Cambiar á VT 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Pantalla embebida" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Descoñecido" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Pantalla descoñecida" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -521,40 +520,44 @@ msgstr "Espe_rar" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Forzar a saída" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Produciuse un erro ao abrir a visualización do X Window System «%s»\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Desactivar a conexión ao xestor de sesión" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Substituír o xestor de xanelas en execución" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Especificar o ID de xestión de sesión" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Pantalla X que se vai usar" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Inicializar sesión desde o ficheiro de salvagarda" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Facer que as chamadas a X sexan sincrónicas" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Executar como compositor de wayland" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Executar como compositor anidado" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Executar como un servidor de pantalla completo, fronte a un aniñado" | ||||
|  | ||||
| @@ -581,12 +584,12 @@ msgstr "Imprimir versión" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Engadido de mutter que usar" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Espazo de traballo %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -595,12 +598,12 @@ msgstr "" | ||||
| "A pantalla «%s» ten xa un xestor de xanelas, tente usar a opción --replace " | ||||
| "para substituír o xestor de xanelas." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "A pantalla %d na visualización «%s» non é válida\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter foi compilado sen compatibilidade para o modo detallado\n" | ||||
|  | ||||
|   | ||||
							
								
								
									
										42
									
								
								po/he.po
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								po/he.po
									
									
									
									
									
								
							| @@ -10,8 +10,8 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: metacity.HEAD.he\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2015-02-24 19:33+0200\n" | ||||
| "PO-Revision-Date: 2015-02-24 19:34+0200\n" | ||||
| "POT-Creation-Date: 2016-03-03 14:39+0200\n" | ||||
| "PO-Revision-Date: 2016-03-03 14:40+0200\n" | ||||
| "Last-Translator: Yosef Or Boczko <yoseforb@gmail.com>\n" | ||||
| "Language-Team: עברית <>\n" | ||||
| "Language: he\n" | ||||
| @@ -453,22 +453,22 @@ msgstr "מעבר ל־VT 11" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "מעבר ל־VT 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "תצוגה מובנית" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "לא ידוע" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "תצוגה לא ידועה" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -510,40 +510,44 @@ msgstr "ה_מתנה" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_אילוץ סגירה" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Failed to open X Window System display '%s'\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Disable connection to session manager" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Replace the running window manager" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Specify session management ID" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "X Display to use" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Initialize session from savefile" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Make X calls synchronous" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Run as a wayland compositor" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Run as a nested compositor" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Run as a full display server, rather than nested" | ||||
|  | ||||
| @@ -569,12 +573,12 @@ msgstr "Print version" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "תוסף ה־mutter לשימוש" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "מרחב עבודה %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -583,12 +587,12 @@ msgstr "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| "to replace the current window manager." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Screen %d on display '%s' is invalid\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter הודר ללא תמיכה במצב פירוט\n" | ||||
|  | ||||
|   | ||||
							
								
								
									
										52
									
								
								po/hu.po
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								po/hu.po
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| # Hungarian translation of mutter | ||||
| # Hungarian translation of mutter. | ||||
| # Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. | ||||
| # This file is distributed under the same license as the mutter package. | ||||
| # | ||||
| @@ -6,14 +6,14 @@ | ||||
| # Gabor Sari <saga at externet dot hu>, 2003. | ||||
| # Laszlo Dvornik <dvornik at gnome dot hu>, 2004. | ||||
| # Gabor Kelemen <kelemeng at gnome dot hu>, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013. | ||||
| # Balázs Úr <urbalazs at gmail dot com>, 2013, 2014, 2015. | ||||
| # Balázs Úr <urbalazs at gmail dot com>, 2013, 2014, 2015, 2016. | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: mutter master\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-02-22 11:10+0000\n" | ||||
| "PO-Revision-Date: 2015-02-22 20:52+0100\n" | ||||
| "POT-Creation-Date: 2016-03-04 13:42+0000\n" | ||||
| "PO-Revision-Date: 2016-03-04 20:43+0100\n" | ||||
| "Last-Translator: Balázs Úr <urbalazs@gmail.com>\n" | ||||
| "Language-Team: Hungarian <gnome-hu-list at gnome dot org>\n" | ||||
| "Language: hu\n" | ||||
| @@ -436,46 +436,41 @@ msgid "Switch to VT 7" | ||||
| msgstr "Váltás a 7. VT-re" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 8" | ||||
| msgstr "Váltás a 8. VT-re" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 9" | ||||
| msgstr "Váltás a 9. VT-re" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 10" | ||||
| msgstr "Váltás a 10. VT-re" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 11" | ||||
| msgstr "Váltás a 11. VT-re" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Váltás a 12. VT-re" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Beépített kijelző" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Ismeretlen" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Ismeretlen kijelző" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -519,40 +514,45 @@ msgstr "Vá_rakozás" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Erőltetett kilépés" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Nem sikerült megnyitni a(z) „%s” X Window rendszer képernyőt\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "A munkamenet-kezelőhöz való csatlakozás tiltása" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "A futó ablakkezelő helyettesítése" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "A munkamenet-kezelő azonosítójának megadása" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "A használandó X megjelenítő" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "A munkamenet előkészítése a mentési fájlból" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Az X-hívások szinkronná tétele" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Futtatás wayland betűszedőként" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| #| msgid "Run as a wayland compositor" | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Futtatás beágyazott betűszedőként" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "" | ||||
| "Futtatás teljes megjelenítő kiszolgálóként az egymásba ágyazott helyett" | ||||
| @@ -580,12 +580,12 @@ msgstr "Verzió kinyomtatása" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Használandó Mutter bővítmény" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "%d. munkaterület" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -594,12 +594,12 @@ msgstr "" | ||||
| "A(z) „%s” kijelző már rendelkezik ablakkezelővel; próbálja a --replace " | ||||
| "kapcsolóval helyettesíteni a jelenlegi ablakkezelőt." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "A(z) %d képernyő a(z) „%s” megjelenítőn érvénytelen\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "A Mutter ablakkezelőt a részletes mód támogatása nélkül fordították\n" | ||||
|  | ||||
|   | ||||
							
								
								
									
										48
									
								
								po/it.po
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								po/it.po
									
									
									
									
									
								
							| @@ -5,15 +5,15 @@ | ||||
| # Pier Luigi Fiorini <plfiorini@libero.it>, 2002. | ||||
| # Lapo Calamandrei <lapo.calamandrei@virgilio.it>, 2003. | ||||
| # Luca Ferretti <lferrett@gnome.org>, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012. | ||||
| # Milo Casagrande <milo@milo.name>, 2012, 2013, 2014, 2015. | ||||
| # Milo Casagrande <milo@milo.name>, 2012, 2013, 2014, 2015, 2016. | ||||
| # | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: mutter\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-03-04 23:11+0000\n" | ||||
| "PO-Revision-Date: 2015-03-05 09:16+0100\n" | ||||
| "POT-Creation-Date: 2016-03-17 13:44+0000\n" | ||||
| "PO-Revision-Date: 2016-03-17 21:24+0100\n" | ||||
| "Last-Translator: Milo Casagrande <milo@milo.name>\n" | ||||
| "Language-Team: Italian <tp@lists.linux.it>\n" | ||||
| "Language: it\n" | ||||
| @@ -21,7 +21,7 @@ msgstr "" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "Plural-Forms: nplurals=2; plural=(n!=1);\n" | ||||
| "X-Generator: Poedit 1.7.4\n" | ||||
| "X-Generator: Poedit 1.8.7\n" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:1 | ||||
| msgid "Navigation" | ||||
| @@ -466,22 +466,22 @@ msgstr "Passa al VT 11" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Passa al VT 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Display integrato" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Sconosciuto" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Display sconosciuto" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -497,7 +497,7 @@ msgstr "" | ||||
| "Un altro compositing manager è già in esecuzione sullo schermo %i sul " | ||||
| "display «%s»." | ||||
|  | ||||
| #: ../src/core/bell.c:185 | ||||
| #: ../src/core/bell.c:192 | ||||
| msgid "Bell event" | ||||
| msgstr "Evento campanella" | ||||
|  | ||||
| @@ -526,40 +526,44 @@ msgstr "_Attendi" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Forza uscita" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Apertura del display «%s» di X Window System non riuscita\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Disabilita la connessione al gestore di sessione" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Sostituisce il window manager in esecuzione" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Specifica l'ID di gestione sessione" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Display X da usare" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Inizializza la sessione da file salvato" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Rende le chiamate X sincrone" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Esegui come compositor Wayland" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Esegui come compositor annidato" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Esegui come display server invece che annidato" | ||||
|  | ||||
| @@ -586,12 +590,12 @@ msgstr "Stampa la versione" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Plugin Mutter da usare" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Spazio di lavoro %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -600,12 +604,12 @@ msgstr "" | ||||
| "Il display «%s» ha già un window manager; provare a utilizzare l'opzione --" | ||||
| "replace per sostituirlo." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Lo schermo %d nel display «%s» non è valido\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "" | ||||
| "Mutter è stato compilato escludendo il supporto per la modalità prolissa\n" | ||||
|   | ||||
							
								
								
									
										50
									
								
								po/ko.po
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								po/ko.po
									
									
									
									
									
								
							| @@ -6,7 +6,7 @@ | ||||
| # Changwoo Ryu <cwryu@debian.org>, 2003, 2004, 2005, 2006, 2007, 2008, 2009. | ||||
| # | ||||
| # Updated in mutter: | ||||
| # Changwoo Ryu <cwryu@debian.org>, 2011-2015. | ||||
| # Changwoo Ryu <cwryu@debian.org>, 2011-2016. | ||||
| # | ||||
| # | ||||
| # 주의: | ||||
| @@ -18,8 +18,8 @@ msgstr "" | ||||
| "Project-Id-Version: mutter\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-03-07 11:12+0000\n" | ||||
| "PO-Revision-Date: 2015-03-08 03:44+0900\n" | ||||
| "POT-Creation-Date: 2016-03-12 13:40+0000\n" | ||||
| "PO-Revision-Date: 2016-03-13 04:38+0900\n" | ||||
| "Last-Translator: Changwoo Ryu <cwryu@debian.org>\n" | ||||
| "Language-Team: GNOME Korea <gnome-kr@googlegroups.com>\n" | ||||
| "Language: Korean\n" | ||||
| @@ -453,22 +453,22 @@ msgstr "가상 터미널 11로 이동" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "가상 터미널 12로 이동" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "내장 디스플레이" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "알 수 없음" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "알 수 없는 디스플레이" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -484,7 +484,7 @@ msgstr "" | ||||
| "다른 창 구성 관리 프로그램이 이미 디스플레이 \"%2$s\" 화면 %1$i번에서 실행 중" | ||||
| "입니다." | ||||
|  | ||||
| #: ../src/core/bell.c:185 | ||||
| #: ../src/core/bell.c:192 | ||||
| msgid "Bell event" | ||||
| msgstr "삑소리 이벤트" | ||||
|  | ||||
| @@ -511,40 +511,44 @@ msgstr "기다리기(_W)" | ||||
| msgid "_Force Quit" | ||||
| msgstr "강제로 끝내기(_F)" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "X 윈도 시스템 디스플레이 '%s'을(를) 여는데 실패하였습니다\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "세션 관리자와 연결 하지 않습니다" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "실행 중인 창 관리자를 바꿉니다" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "세션 관리 ID를 지정합니다" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "사용할 X 디스플레이" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "저장 파일에서 세션을 초기화 합니다" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "동기 X 호출을 합니다" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "웨일랜드 컴포지터로 실행합니다" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "내장 컴포지터로 실행합니다" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "전체 디스플레이 서버로 실행, 내장 프로그램 아님" | ||||
|  | ||||
| @@ -571,24 +575,26 @@ msgstr "버전을 출력합니다" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "사용할 머터 플러그인" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "작업 공간 %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| "to replace the current window manager." | ||||
| msgstr "디스플레이 \"%s\"에 이미 창 관리자가 있습니다. 현재 창 관리자를 바꾸려면 --replace 옵션을 써보십시오." | ||||
| msgstr "" | ||||
| "디스플레이 \"%s\"에 이미 창 관리자가 있습니다. 현재 창 관리자를 바꾸려면 --" | ||||
| "replace 옵션을 써보십시오." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "디스플레이 '%2$s'의 화면 %1$d은(는) 잘못되었습니다\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "머터가 자세한 모드 지원 없이 컴파일 되었습니다\n" | ||||
|  | ||||
|   | ||||
							
								
								
									
										36
									
								
								po/lt.po
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								po/lt.po
									
									
									
									
									
								
							| @@ -13,8 +13,8 @@ msgstr "" | ||||
| "Project-Id-Version: lt\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2016-01-05 13:43+0000\n" | ||||
| "PO-Revision-Date: 2016-01-05 18:04+0200\n" | ||||
| "POT-Creation-Date: 2016-02-26 09:54+0000\n" | ||||
| "PO-Revision-Date: 2016-02-25 15:18+0200\n" | ||||
| "Last-Translator: Aurimas Černius <aurisc4@gmail.com>\n" | ||||
| "Language-Team: Lietuvių <gnome-lt@lists.akl.lt>\n" | ||||
| "Language: lt\n" | ||||
| @@ -23,7 +23,7 @@ msgstr "" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n" | ||||
| "%100<10 || n%100>=20) ? 1 : 2);\n" | ||||
| "X-Generator: Poedit 1.8.6\n" | ||||
| "X-Generator: Poedit 1.8.7\n" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:1 | ||||
| msgid "Navigation" | ||||
| @@ -513,42 +513,46 @@ msgstr "_Laukti" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Priverstinai išeiti" | ||||
|  | ||||
| #: ../src/core/display.c:563 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Nepavyko atverti X Window sistemos ekrano „%s“\n" | ||||
|  | ||||
| #: ../src/core/main.c:180 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Išjungti susijungimą su sesijos tvarkytuve" | ||||
|  | ||||
| #: ../src/core/main.c:186 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Pakeisti veikiančią langų tvarkytuvę" | ||||
|  | ||||
| #: ../src/core/main.c:192 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Nurodyti sesijos tvarkymo ID" | ||||
|  | ||||
| #: ../src/core/main.c:197 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Naudotinas X ekranas" | ||||
|  | ||||
| #: ../src/core/main.c:203 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Inicializuoti sesiją iš išsaugojimo failo" | ||||
|  | ||||
| #: ../src/core/main.c:209 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Sinchronizuoti X iškvietimus" | ||||
|  | ||||
| #: ../src/core/main.c:216 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Vykdyti kaip wayland kompozitorių" | ||||
|  | ||||
| #: ../src/core/main.c:224 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Vykdyti kaip įdėtinį kompozitorių" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Vykdyti kaip visą vaizduoklio serverį, o ne vidinį" | ||||
| msgstr "Vykdyti kaip visą vaizduoklio serverį, o ne įdėtinį" | ||||
|  | ||||
| #: ../src/core/mutter.c:39 | ||||
| #, c-format | ||||
| @@ -580,7 +584,7 @@ msgstr "Naudojamas Mutter įskiepis" | ||||
| msgid "Workspace %d" | ||||
| msgstr "Darbo sritis %d" | ||||
|  | ||||
| #: ../src/core/screen.c:526 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -589,12 +593,12 @@ msgstr "" | ||||
| "Vaizduoklis „%s“ jau turi langų tvarkytuvę; pabandykite pakeisti esamą langų " | ||||
| "tvarkytuvę, naudodami parametrą --replace." | ||||
|  | ||||
| #: ../src/core/screen.c:608 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Ekranas %d vaizduoklyje „%s“ netinkamas\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter buvo sukompiliuota be išsamaus veikimo veiksenos\n" | ||||
|  | ||||
|   | ||||
							
								
								
									
										64
									
								
								po/lv.po
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								po/lv.po
									
									
									
									
									
								
							| @@ -7,14 +7,14 @@ | ||||
| # Raivis Dejus <orvils@gmail.com>, 2006, 2007, 2009. | ||||
| # Rudolfs <rudolfs.mazurs@gmail.com>, 2011. | ||||
| # Rūdofls Mazurs <rudolfs.mazurs@gmail.com>, 2011, 2012. | ||||
| # Rūdolfs Mazurs <rudolfs.mazurs@gmail.com>, 2012, 2013, 2014, 2015. | ||||
| # Rūdolfs Mazurs <rudolfs.mazurs@gmail.com>, 2012, 2013, 2014, 2015, 2016. | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: lv\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-09-20 11:14+0000\n" | ||||
| "PO-Revision-Date: 2015-09-20 18:51+0300\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter&" | ||||
| "keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2016-03-03 13:37+0000\n" | ||||
| "PO-Revision-Date: 2016-03-03 22:19+0200\n" | ||||
| "Last-Translator: Rūdolfs Mazurs <rudolfs.mazurs@gmail.com>\n" | ||||
| "Language-Team: Latvian <lata-l10n@googlegroups.com>\n" | ||||
| "Language: lv\n" | ||||
| @@ -23,7 +23,7 @@ msgstr "" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : " | ||||
| "2);\n" | ||||
| "X-Generator: Lokalize 1.5\n" | ||||
| "X-Generator: Lokalize 2.0\n" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:1 | ||||
| msgid "Navigation" | ||||
| @@ -437,46 +437,41 @@ msgid "Switch to VT 7" | ||||
| msgstr "Pārslēgties uz VT 7" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 8" | ||||
| msgstr "Pārslēgties uz VT 8" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 9" | ||||
| msgstr "Pārslēgties uz VT 9" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 10" | ||||
| msgstr "Pārslēgties uz VT 10" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 11" | ||||
| msgstr "Pārslēgties uz VT 11" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Pārslēgties uz VT 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:500 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Iebūvēts displejs" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:526 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Nezināms" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:528 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Nezināms displejs" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:536 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -519,40 +514,45 @@ msgstr "_Gaidīt" | ||||
| msgid "_Force Quit" | ||||
| msgstr "Aizvērt _piespiedu kārtā" | ||||
|  | ||||
| #: ../src/core/display.c:563 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Neizdevās atvērt X logu sistēmas displeju “%s”\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Deaktivēt savienojumu ar sesiju pārvaldnieku" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Aizvietot darbojošos logu pārvaldnieku" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Norādiet sesiju pārvaldības ID" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Lietojamais X displejs" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Inicializēt sesiju no saglabātās datnes" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Padarīt X izsaukumus sinhronus" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Palaist kā wayland kompozitoru" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| #| msgid "Run as a wayland compositor" | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Palaist kā ligzdotu kompozitoru" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Palaist kā pilnu attēlošanas serveri, nevis iegultu" | ||||
|  | ||||
| @@ -579,29 +579,26 @@ msgstr "Parādīt versiju" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Izmantojamais mutter spraudnis" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Darbvieta %d" | ||||
|  | ||||
| #: ../src/core/screen.c:526 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| #| msgid "" | ||||
| #| "Screen %d on display \"%s\" already has a window manager; try using the --" | ||||
| #| "replace option to replace the current window manager.\n" | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| "to replace the current window manager." | ||||
| msgstr "" | ||||
| "Displejam “%s” jau ir logu pārvaldnieks; mēģiniet lietot --replace " | ||||
| "iespēju, lai aizvietotu pašreizējo logu pārvaldnieku." | ||||
| "Displejam “%s” jau ir logu pārvaldnieks; mēģiniet lietot --replace iespēju, " | ||||
| "lai aizvietotu pašreizējo logu pārvaldnieku." | ||||
|  | ||||
| #: ../src/core/screen.c:608 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Ekrāna %d displejs “%s“ nav derīgs\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter tika kompilēts bez detalizētas izvades režīma atbalsta\n" | ||||
|  | ||||
| @@ -617,3 +614,4 @@ msgstr "" | ||||
| #, c-format | ||||
| msgid "%s (on %s)" | ||||
| msgstr "%s (uz %s)" | ||||
|  | ||||
|   | ||||
							
								
								
									
										68
									
								
								po/pl.po
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								po/pl.po
									
									
									
									
									
								
							| @@ -9,14 +9,14 @@ | ||||
| # Marek Stępień <marcoos@aviary.pl>, 2007. | ||||
| # Wadim Dziedzic <wdziedzic@aviary.pl>, 2007. | ||||
| # Tomasz Dominikowski <dominikowski@gmail.com>, 2008-2009. | ||||
| # Piotr Drąg <piotrdrag@gmail.com>, 2010-2015. | ||||
| # Aviary.pl <gnomepl@aviary.pl>, 2007-2015. | ||||
| # Piotr Drąg <piotrdrag@gmail.com>, 2010-2016. | ||||
| # Aviary.pl <gnomepl@aviary.pl>, 2007-2016. | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: mutter\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2015-08-26 18:49+0200\n" | ||||
| "PO-Revision-Date: 2015-08-26 18:50+0200\n" | ||||
| "POT-Creation-Date: 2016-02-25 17:29+0100\n" | ||||
| "PO-Revision-Date: 2016-02-25 17:30+0100\n" | ||||
| "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n" | ||||
| "Language-Team: Polish <gnomepl@aviary.pl>\n" | ||||
| "Language: pl\n" | ||||
| @@ -285,10 +285,10 @@ msgid "" | ||||
| "\"Windows key\" on PC hardware. It's expected that this binding either the " | ||||
| "default or set to the empty string." | ||||
| msgstr "" | ||||
| "Ten klawisz inicjuje tryb „overlay”, który jest połączeniem podglądu okien i " | ||||
| "systemu uruchamiania programów. Domyślnie jest przeznaczony do powiązania z " | ||||
| "klawiszem „Windows” na komputerach typu PC. Ustawienie tego powiązania " | ||||
| "powinno być domyślne lub puste." | ||||
| "Ten klawisz inicjuje tryb „overlay” (nakładki), który jest połączeniem " | ||||
| "podglądu okien i systemu uruchamiania programów. Domyślnie jest przeznaczony " | ||||
| "do powiązania z klawiszem „Windows” na komputerach typu PC. Ustawienie tego " | ||||
| "powiązania powinno być domyślne lub puste." | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:3 | ||||
| msgid "Attach modal dialogs" | ||||
| @@ -332,8 +332,8 @@ msgid "" | ||||
| "gnome.desktop.wm.preferences)." | ||||
| msgstr "" | ||||
| "Określa, czy obszary robocze są zarządzane dynamicznie, czy istnieje " | ||||
| "statyczna liczba obszarów (określona przez klucz „num-workspaces” w org." | ||||
| "gnome.desktop.wm.preferences)." | ||||
| "statyczna liczba obszarów (określona przez klucz „num-workspaces” w „org." | ||||
| "gnome.desktop.wm.preferences”)." | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:9 | ||||
| msgid "Workspaces only on primary" | ||||
| @@ -468,22 +468,22 @@ msgstr "Przełączenie na 11. konsolę wirtualną" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Przełączenie na 12. konsolę wirtualną" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:500 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Wbudowany ekran" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:526 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Nieznany" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:528 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Nieznany ekran" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:536 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -525,42 +525,46 @@ msgstr "_Czekaj" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Zakończ" | ||||
|  | ||||
| #: ../src/core/display.c:563 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Otwarcie połączenia z ekranem „%s” systemu X Window się nie powiodło\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Rozłącza połączenie z menedżerem sesji" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Zastępuje uruchomionego menedżera okien" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Podaje identyfikator zarządzania sesją" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Używany ekran X" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Inicjuje sesję z zapisanego pliku" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Synchroniczne wywołania X" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Uruchamia jako menedżer składania Wayland" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Uruchamia jako osadzony menedżer składania" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Uruchamia pełny serwer wyświetlania zamiast osadzonego" | ||||
| msgstr "Uruchamia jako pełny serwer wyświetlania zamiast osadzonego" | ||||
|  | ||||
| #: ../src/core/mutter.c:39 | ||||
| #, c-format | ||||
| @@ -572,7 +576,7 @@ msgid "" | ||||
| "PARTICULAR PURPOSE.\n" | ||||
| msgstr "" | ||||
| "mutter %s\n" | ||||
| "Copyright (C) 2001—%d Havoc Pennington, Red Hat, Inc., oraz inni\n" | ||||
| "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., oraz inni\n" | ||||
| "Niniejszy program jest wolnym oprogramowaniem, aby poznać warunki, pod\n" | ||||
| "jakimi dopuszczalne jest kopiowanie programu, zajrzyj do jego źródeł.\n" | ||||
| "Na program nie udziela się ŻADNYCH GWARANCJI, nawet domyślnej gwarancji\n" | ||||
| @@ -584,23 +588,23 @@ msgstr "Wyświetla wersję" | ||||
|  | ||||
| #: ../src/core/mutter.c:59 | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Używana wtyczka programu Mutter" | ||||
| msgstr "Używana wtyczka menedżera Mutter" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Obszar roboczy %d" | ||||
| msgstr "%d. obszar roboczy" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| "to replace the current window manager." | ||||
| msgstr "" | ||||
| "Na ekranie „%s” działa już menedżer okien. Aby zastąpić działającego " | ||||
| "menedżera okien, proszę spróbować użyć opcji --replace." | ||||
| "menedżera okien, należy użyć opcji „--replace”." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Podekran %d ekranu „%s” jest nieprawidłowy\n" | ||||
| @@ -608,7 +612,7 @@ msgstr "Podekran %d ekranu „%s” jest nieprawidłowy\n" | ||||
| #: ../src/core/util.c:118 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "" | ||||
| "Program Mutter został skompilowany bez obsługi trybu z obszerną informacją\n" | ||||
| "Menedżer Mutter został skompilowany bez obsługi trybu z obszerną informacją\n" | ||||
|  | ||||
| #: ../src/x11/session.c:1815 | ||||
| msgid "" | ||||
|   | ||||
							
								
								
									
										45
									
								
								po/pt_BR.po
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								po/pt_BR.po
									
									
									
									
									
								
							| @@ -15,22 +15,23 @@ | ||||
| # Rodrigo Padula de Oliveira <contato@rodrigopadula.com>, 2011. | ||||
| # Rafael Ferreira <rafael.f.f1@gmail.com>, 2013, 2014. | ||||
| # Enrico Nicoletto <liverig@gmail.com>, 2012, 2014. | ||||
| # Artur de Aquino Morais <artur.morais93@outlook.com>, 2016. | ||||
| # | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: mutter\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-02-26 11:24+0000\n" | ||||
| "PO-Revision-Date: 2015-02-26 17:36-0300\n" | ||||
| "Last-Translator: Rafael Ferreira <rafael.f.f1@gmail.com>\n" | ||||
| "POT-Creation-Date: 2016-02-25 13:40+0000\n" | ||||
| "PO-Revision-Date: 2016-02-25 13:41-0300\n" | ||||
| "Last-Translator: Artur de Aquino Morais <artur.morais93@outlook.com>\n" | ||||
| "Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n" | ||||
| "Language: pt_BR\n" | ||||
| "MIME-Version: 1.0\n" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "Plural-Forms: nplurals=2; plural=(n > 1);\n" | ||||
| "X-Generator: Poedit 1.7.4\n" | ||||
| "X-Generator: Poedit 1.8.4\n" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:1 | ||||
| msgid "Navigation" | ||||
| @@ -472,22 +473,22 @@ msgstr "Trocar para o VT 11" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Trocar para o VT 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Tela embutida" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Desconhecido" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Monitor desconhecido" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s de %s" | ||||
| @@ -531,40 +532,44 @@ msgstr "_Esperar" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Forçar sair" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Falha ao abrir a exibição \"%s\" do sistema de janelas X\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Desabilitar a conexão com o gerenciador de sessões" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Substituir o gerenciador de janelas em execução" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Especificar o ID do gerenciador de sessões" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Exibição do X a ser utilizada" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Inicializar a sessão a partir do arquivo salvo" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Fazer X chamadas síncronas" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Executar como um compositor wayland" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Executar como um compositor aninhado" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Executar como um servidor de tela cheia, ao invés de aninhado" | ||||
|  | ||||
| @@ -592,12 +597,12 @@ msgstr "Versão impressa" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Plug-in do Mutter para usar" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Espaço de trabalho %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -606,7 +611,7 @@ msgstr "" | ||||
| "A exibição \"%s\" já possui um gerenciador de janelas; tente usar a opção --" | ||||
| "replace para substituir o gerenciador de janelas atual." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "A tela %d na exibição \"%s\" é inválida\n" | ||||
|   | ||||
							
								
								
									
										53
									
								
								po/ru.po
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								po/ru.po
									
									
									
									
									
								
							| @@ -9,15 +9,16 @@ | ||||
| # Yuri Kozlov <yuray@komyakino.ru>, 2011. | ||||
| # Yuri Myasoedov <ymyasoedov@yandex.ru>, 2012-2014, 2015. | ||||
| # Ivan Komaritsyn <vantu5z@mail.ru>, 2015. | ||||
| # Stas Solovey <whats_up@tut.by>, 2016. | ||||
| # | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: metacity ru\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-02-19 23:11+0000\n" | ||||
| "PO-Revision-Date: 2015-02-20 13:59+0300\n" | ||||
| "Last-Translator: Ivan Komaritsyn <vantu5z@mail.ru>\n" | ||||
| "POT-Creation-Date: 2016-03-03 01:44+0000\n" | ||||
| "PO-Revision-Date: 2016-03-03 13:51+0300\n" | ||||
| "Last-Translator: Stas Solovey <whats_up@tut.by>\n" | ||||
| "Language-Team: Русский <gnome-cyr@gnome.org>\n" | ||||
| "Language: ru\n" | ||||
| "MIME-Version: 1.0\n" | ||||
| @@ -25,7 +26,7 @@ msgstr "" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" | ||||
| "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" | ||||
| "X-Generator: Gtranslator 2.91.6\n" | ||||
| "X-Generator: Gtranslator 2.91.7\n" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:1 | ||||
| msgid "Navigation" | ||||
| @@ -441,46 +442,41 @@ msgid "Switch to VT 7" | ||||
| msgstr "Переключиться на виртуальный терминал 7" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 8" | ||||
| msgstr "Переключиться на виртуальный терминал 8" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 9" | ||||
| msgstr "Переключиться на виртуальный терминал 9" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 10" | ||||
| msgstr "Переключиться на виртуальный терминал 10" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 11" | ||||
| msgstr "Переключиться на виртуальный терминал 11" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Переключиться на виртуальный терминал 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Встроенный дисплей" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Неизвестный" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Неизвестный дисплей" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -521,40 +517,45 @@ msgstr "_Подождать" | ||||
| msgid "_Force Quit" | ||||
| msgstr "Завер_шить" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Не удалось открыть дисплей «%s» системы X Window\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Запретить подключение к менеджеру сеансов" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Заменить запущенный оконный менеджер" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Указать идентификатор управления сеансом" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Используемый дисплей X" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Инициализировать сеанс из сохранённого файла" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Сделать X-вызовы синхронными" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Запустить в качестве композитора wayland" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| #| msgid "Run as a wayland compositor" | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Запустить в качестве встроенного композитора" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Запустить в качестве полноэкранного сервера вместо встроенного" | ||||
|  | ||||
| @@ -583,12 +584,12 @@ msgstr "Вывести версию" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Использовать модуль mutter" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Рабочее место %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -597,12 +598,12 @@ msgstr "" | ||||
| "Дисплей «%s» уже использует менеджер окон; попробуйте использовать параметр " | ||||
| "--replace, чтобы заменить текущий менеджер окон." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Недопустимый экран %d дисплея «%s»\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter собран без поддержки режима подробных сообщений\n" | ||||
|  | ||||
|   | ||||
							
								
								
									
										45
									
								
								po/sk.po
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								po/sk.po
									
									
									
									
									
								
							| @@ -14,8 +14,8 @@ msgstr "" | ||||
| "Project-Id-Version: mutter\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-02-21 23:27+0000\n" | ||||
| "PO-Revision-Date: 2015-02-22 11:11+0100\n" | ||||
| "POT-Creation-Date: 2016-03-01 13:42+0000\n" | ||||
| "PO-Revision-Date: 2016-03-01 20:40+0100\n" | ||||
| "Last-Translator: Dušan Kazik <prescott66@gmail.com>\n" | ||||
| "Language-Team: Slovak <gnome-sk-list@gnome.org>\n" | ||||
| "Language: sk\n" | ||||
| @@ -23,7 +23,7 @@ msgstr "" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n" | ||||
| "X-Generator: Poedit 1.7.4\n" | ||||
| "X-Generator: Poedit 1.8.7\n" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:1 | ||||
| msgid "Navigation" | ||||
| @@ -542,22 +542,22 @@ msgstr "Prepnúť na VT č. 11" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Prepnúť na VT č. 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Vstavaný displej" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Neznámy" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Neznámy displej" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -602,46 +602,51 @@ msgid "_Force Quit" | ||||
| msgstr "_Vynútiť ukončenie" | ||||
|  | ||||
| # X window system preloz, napr. system na spravu okien X | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Zlyhalo otvorenie displeja systému na správu okien X „%s“\n" | ||||
|  | ||||
| # cmd desc | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Zakáže pripojenia k správcovi relácií" | ||||
|  | ||||
| # cmd desc | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Nahradí bežiaceho správcu okien" | ||||
|  | ||||
| # cmd desc | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Zadá identifikátor správy relácií" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "X displej, ktorý bude použitý" | ||||
|  | ||||
| # cmd desc | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Inicializuje reláciu z uloženého súboru" | ||||
|  | ||||
| # cmd desc | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Použije synchrónne volania X" | ||||
|  | ||||
| # cmd desc | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Spustí ako kompozitor protokolu wayland" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| # cmd desc | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Spustí ako kompozitor s vnoreným režimom" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Spustí ako plnohodnotný zobrazovací server, namiesto vnoreného režimu" | ||||
|  | ||||
| @@ -670,12 +675,12 @@ msgstr "Zobrazí verziu" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Použije zásuvný modul Mutter" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Pracovný priestor č. %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -684,12 +689,12 @@ msgstr "" | ||||
| "Displej „%s“ už má správcu okien. Skúste použiť prepínač --replace, aby sa " | ||||
| "aktuálny správca nahradil." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Obrazovka č. %d na displeji „%s“ nie je platná\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter bol skompilovaný bez výpisu podrobností pri behu\n" | ||||
|  | ||||
|   | ||||
							
								
								
									
										46
									
								
								po/sl.po
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								po/sl.po
									
									
									
									
									
								
							| @@ -4,15 +4,15 @@ | ||||
| # | ||||
| # Andraž Tori <andraz.tori1@guest.arnes.si>, 2000. | ||||
| # Matjaž Horvat <m@owca.info>, 2006. | ||||
| # Matej Urbančič <mateju@svn.gnome.org>, 2007-2015. | ||||
| # Matej Urbančič <mateju@svn.gnome.org>, 2007-2016. | ||||
| # | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: mutter master\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-03-15 11:07+0000\n" | ||||
| "PO-Revision-Date: 2015-03-15 14:36+0100\n" | ||||
| "POT-Creation-Date: 2016-03-05 21:12+0100\n" | ||||
| "PO-Revision-Date: 2016-03-05 21:12+0100\n" | ||||
| "Last-Translator: Matej Urbančič <mateju@svn.gnome.org>\n" | ||||
| "Language-Team: Slovenian GNOME Translation Team <gnome-si@googlegroups.com>\n" | ||||
| "Language: sl_SI\n" | ||||
| @@ -22,7 +22,7 @@ msgstr "" | ||||
| "Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n" | ||||
| "%100==4 ? 3 : 0);\n" | ||||
| "X-Poedit-SourceCharset: utf-8\n" | ||||
| "X-Generator: Poedit 1.5.4\n" | ||||
| "X-Generator: Poedit 1.8.4\n" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:1 | ||||
| msgid "Navigation" | ||||
| @@ -455,22 +455,22 @@ msgstr "Preklopi na VT 11" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Preklopi na VT 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Vgrajen zaslon" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Neznano" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Neznan zaslon" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -514,40 +514,44 @@ msgstr "_Počakaj" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Vsili konec" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Ni mogoče odpreti zaslona '%s' okenskega sistema X\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Onemogoči povezavo z upravljalnikom sej" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Zamenjaj trenutni upravljalnik oken" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Navedite ID upravljanja seje" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Zaslon X za uporabo" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Začni sejo iz shranjene datoteke" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Uskladi klice X" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Zaženi izbirnik wayland" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Zaženi kot gnezden vpisovalnik" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Zaženi kot polni strežnik zaslona in ne vstavljeno" | ||||
|  | ||||
| @@ -575,12 +579,12 @@ msgid "Mutter plugin to use" | ||||
| msgstr "Vstavek Mutter za uporabo" | ||||
|  | ||||
| # G:1 K:0 O:0 | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Delovna površina %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -589,12 +593,12 @@ msgstr "" | ||||
| "Zaslon \"%s\" že ima določen upravljalnik oken; poskušajte uporabiti možnost " | ||||
| "--replace za zamenjavo trenutnega upravljalnika zaslona." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Zaslon %d na prikazu '%s' ni veljaven\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "" | ||||
| "Program Mutter je kodno preveden brez podpore za podrobni način izpisovanja\n" | ||||
|   | ||||
							
								
								
									
										67
									
								
								po/sr.po
									
									
									
									
									
								
							
							
						
						
									
										67
									
								
								po/sr.po
									
									
									
									
									
								
							| @@ -1,19 +1,21 @@ | ||||
| # Serbian translation of mutter. | ||||
| # Courtesy of Prevod.org team (http://prevod.org/) -- 2003—2015. | ||||
| # Courtesy of Prevod.org team (http://prevod.org/) -- 2003—2016. | ||||
| # This file is distributed under the same license as the mutter package. | ||||
| # | ||||
| # Translators:  | ||||
| # Горан Ракић <grakic@devbase.net> | ||||
| # Данило Шеган <danilo@prevod.org>, 2005. | ||||
| # Милош Поповић <gpopac@gmail.com>, 2010. | ||||
| # Мирослав Николић <miroslavnikolic@rocketmail.com>, 2011—2015. | ||||
| # Мирослав Николић <miroslavnikolic@rocketmail.com>, 2011—2016. | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: mutter\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter&" | ||||
| "keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-03-04 11:14+0000\n" | ||||
| "PO-Revision-Date: 2015-03-04 19:46+0200\n" | ||||
| "POT-Creation-Date: 2016-03-09 01:41+0000\n" | ||||
| "PO-Revision-Date: 2016-03-09 09:52+0200\n" | ||||
| "Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n" | ||||
| "Language-Team: Serbian <gnom@prevod.org>\n" | ||||
| "Language-Team: Serbian <(nothing)>\n" | ||||
| "Language: sr\n" | ||||
| "MIME-Version: 1.0\n" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| @@ -436,46 +438,41 @@ msgid "Switch to VT 7" | ||||
| msgstr "Прелазак на ВТ 7" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 8" | ||||
| msgstr "Прелазак на ВТ 8" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 9" | ||||
| msgstr "Прелазак на ВТ 9" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 10" | ||||
| msgstr "Прелазак на ВТ 10" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 11" | ||||
| msgstr "Прелазак на ВТ 11" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Прелазак на ВТ 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Уграђени дисплеј" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Непознато" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Непознат дисплеј" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -519,40 +516,45 @@ msgstr "_Сачекај" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Приморај излаз" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Нисам успео да отворим екран „%s“ Икс система прозора\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Искључује везу са управником сесије" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Мења текућег управника прозорима" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Наводи ИБ управника сесије" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Икс екран који ће бити коришћен" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Покреће сесију из датотеке чувања" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Чини Икс позиве усклађеним" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Ради као вајландов саставник" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| #| msgid "Run as a wayland compositor" | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Ради као угнеждени саставник" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Ради као пуни сервер приказа, уместо као угнеждени" | ||||
|  | ||||
| @@ -566,8 +568,8 @@ msgid "" | ||||
| "PARTICULAR PURPOSE.\n" | ||||
| msgstr "" | ||||
| "матер %s\n" | ||||
| "Сва права задржана (C) 2001–%d Havoc Pennington, Red Hat, Inc., и остали\n" | ||||
| "Ово је слободан програм; погледајте изворни код за услове коришћења.\n" | ||||
| "Сва права задржана © 2001–%d Хевок Пенингтон, Ред Хет, Инк., и остали\n" | ||||
| "Ово је слободан програм; погледајте изворни кôд за услове коришћења.\n" | ||||
| "НЕ постоји никаква гаранција; чак ни гаранција о ТРЖИШНОЈ ВРЕДНОСТИ или " | ||||
| "ПРИЛАГОЂЕНОСТИ ОДРЕЂЕНОЈ НАМЕНИ.\n" | ||||
|  | ||||
| @@ -579,29 +581,26 @@ msgstr "Исписује издање" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Прикључци Матера за коришћење" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "%d. радни простор" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| #| msgid "" | ||||
| #| "Screen %d on display \"%s\" already has a window manager; try using the --" | ||||
| #| "replace option to replace the current window manager.\n" | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| "to replace the current window manager." | ||||
| msgstr "" | ||||
| "Приказ „%s“ већ има управника прозора; пробајте да користите опцију " | ||||
| "„--replace“ да замените тренутног управника прозора." | ||||
| "Приказ „%s“ већ има управника прозора; пробајте да користите опцију „--" | ||||
| "replace“ да замените тренутног управника прозора." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Приказ „%d“ на екрану „%s“ није исправан\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Матер је преведен без подршке за опширан режим\n" | ||||
|  | ||||
|   | ||||
| @@ -1,19 +1,21 @@ | ||||
| # Serbian translation of mutter. | ||||
| # Courtesy of Prevod.org team (http://prevod.org/) -- 2003—2015. | ||||
| # Courtesy of Prevod.org team (http://prevod.org/) -- 2003—2016. | ||||
| # This file is distributed under the same license as the mutter package. | ||||
| # | ||||
| # Translators:  | ||||
| # Goran Rakić <grakic@devbase.net> | ||||
| # Danilo Šegan <danilo@prevod.org>, 2005. | ||||
| # Miloš Popović <gpopac@gmail.com>, 2010. | ||||
| # Miroslav Nikolić <miroslavnikolic@rocketmail.com>, 2011—2015. | ||||
| # Miroslav Nikolić <miroslavnikolic@rocketmail.com>, 2011—2016. | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: mutter\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter&" | ||||
| "keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-03-04 11:14+0000\n" | ||||
| "PO-Revision-Date: 2015-03-04 19:46+0200\n" | ||||
| "POT-Creation-Date: 2016-03-09 01:41+0000\n" | ||||
| "PO-Revision-Date: 2016-03-09 09:52+0200\n" | ||||
| "Last-Translator: Miroslav Nikolić <miroslavnikolic@rocketmail.com>\n" | ||||
| "Language-Team: Serbian <gnom@prevod.org>\n" | ||||
| "Language-Team: Serbian <(nothing)>\n" | ||||
| "Language: sr\n" | ||||
| "MIME-Version: 1.0\n" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| @@ -436,46 +438,41 @@ msgid "Switch to VT 7" | ||||
| msgstr "Prelazak na VT 7" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 8" | ||||
| msgstr "Prelazak na VT 8" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 9" | ||||
| msgstr "Prelazak na VT 9" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 10" | ||||
| msgstr "Prelazak na VT 10" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 11" | ||||
| msgstr "Prelazak na VT 11" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12 | ||||
| #| msgid "Switch to VT 1" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Prelazak na VT 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Ugrađeni displej" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Nepoznato" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Nepoznat displej" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -519,40 +516,45 @@ msgstr "_Sačekaj" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Primoraj izlaz" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Nisam uspeo da otvorim ekran „%s“ Iks sistema prozora\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Isključuje vezu sa upravnikom sesije" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Menja tekućeg upravnika prozorima" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Navodi IB upravnika sesije" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Iks ekran koji će biti korišćen" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Pokreće sesiju iz datoteke čuvanja" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Čini Iks pozive usklađenim" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Radi kao vajlandov sastavnik" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| #| msgid "Run as a wayland compositor" | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Radi kao ugneždeni sastavnik" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Radi kao puni server prikaza, umesto kao ugneždeni" | ||||
|  | ||||
| @@ -566,8 +568,8 @@ msgid "" | ||||
| "PARTICULAR PURPOSE.\n" | ||||
| msgstr "" | ||||
| "mater %s\n" | ||||
| "Sva prava zadržana (C) 2001–%d Havoc Pennington, Red Hat, Inc., i ostali\n" | ||||
| "Ovo je slobodan program; pogledajte izvorni kod za uslove korišćenja.\n" | ||||
| "Sva prava zadržana © 2001–%d Hevok Penington, Red Het, Ink., i ostali\n" | ||||
| "Ovo je slobodan program; pogledajte izvorni kôd za uslove korišćenja.\n" | ||||
| "NE postoji nikakva garancija; čak ni garancija o TRŽIŠNOJ VREDNOSTI ili " | ||||
| "PRILAGOĐENOSTI ODREĐENOJ NAMENI.\n" | ||||
|  | ||||
| @@ -579,29 +581,26 @@ msgstr "Ispisuje izdanje" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Priključci Matera za korišćenje" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "%d. radni prostor" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| #| msgid "" | ||||
| #| "Screen %d on display \"%s\" already has a window manager; try using the --" | ||||
| #| "replace option to replace the current window manager.\n" | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| "to replace the current window manager." | ||||
| msgstr "" | ||||
| "Prikaz „%s“ već ima upravnika prozora; probajte da koristite opciju " | ||||
| "„--replace“ da zamenite trenutnog upravnika prozora." | ||||
| "Prikaz „%s“ već ima upravnika prozora; probajte da koristite opciju „--" | ||||
| "replace“ da zamenite trenutnog upravnika prozora." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Prikaz „%d“ na ekranu „%s“ nije ispravan\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mater je preveden bez podrške za opširan režim\n" | ||||
|  | ||||
|   | ||||
							
								
								
									
										162
									
								
								po/sv.po
									
									
									
									
									
								
							
							
						
						
									
										162
									
								
								po/sv.po
									
									
									
									
									
								
							| @@ -1,24 +1,25 @@ | ||||
| # Swedish messages for mutter. | ||||
| # Copyright © 2001-2015 Free Software Foundation, Inc. | ||||
| # Copyright © 2001-2016 Free Software Foundation, Inc. | ||||
| # Christian Rose <menthos@menthos.com>, 2001, 2002, 2003, 2004, 2005. | ||||
| # Daniel Nylander <po@danielnylander.se>, 2006, 2007, 2008, 2009, 2010, 2011, 2012. | ||||
| # Mattias Eriksson <snaggen@gmail.com>, 2014. | ||||
| # Anders Jonsson <anders.jonsson@norsjovallen.se>, 2015. | ||||
| # Sebastian Rasmussen <sebras@gmail.com>, 2016. | ||||
| # | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: mutter\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-02-19 21:45+0000\n" | ||||
| "PO-Revision-Date: 2015-02-24 17:54+0100\n" | ||||
| "Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n" | ||||
| "POT-Creation-Date: 2016-03-05 13:41+0000\n" | ||||
| "PO-Revision-Date: 2016-03-06 13:47+0100\n" | ||||
| "Last-Translator: Sebastian Rasmussen <sebras@gmail.com>\n" | ||||
| "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n" | ||||
| "Language: sv\n" | ||||
| "MIME-Version: 1.0\n" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "X-Generator: Poedit 1.7.3\n" | ||||
| "X-Generator: Poedit 1.8.7.1\n" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:1 | ||||
| msgid "Navigation" | ||||
| @@ -270,15 +271,15 @@ msgstr "Modifierare att använda för utökade fönsterhanteringsåtgärder" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:2 | ||||
| msgid "" | ||||
| "This key will initiate the \"overlay\", which is a combination window overview " | ||||
| "and application launching system. The default is intended to be the \"Windows key" | ||||
| "\" on PC hardware. It's expected that this binding either the default or set to " | ||||
| "the empty string." | ||||
| "This key will initiate the \"overlay\", which is a combination window " | ||||
| "overview and application launching system. The default is intended to be the " | ||||
| "\"Windows key\" on PC hardware. It's expected that this binding either the " | ||||
| "default or set to the empty string." | ||||
| msgstr "" | ||||
| "Denna nyckel kommer att initiera \"overlay\", som är en kombinerad " | ||||
| "fönsteröversikt och programstartare. Standard är tänkt att vara \"Windows-" | ||||
| "tangenten\" på PC-maskinvara. Det är förväntat att denna bindning antingen är " | ||||
| "standard eller inställd till en tom sträng." | ||||
| "tangenten\" på PC-maskinvara. Det är förväntat att denna bindning antingen " | ||||
| "är standard eller inställd till en tom sträng." | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:3 | ||||
| msgid "Attach modal dialogs" | ||||
| @@ -287,12 +288,12 @@ msgstr "Bifoga modala dialogfönster" | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:4 | ||||
| msgid "" | ||||
| "When true, instead of having independent titlebars, modal dialogs appear " | ||||
| "attached to the titlebar of the parent window and are moved together with the " | ||||
| "parent window." | ||||
| "attached to the titlebar of the parent window and are moved together with " | ||||
| "the parent window." | ||||
| msgstr "" | ||||
| "När true kommer, istället för att ha oberoende namnlister, modala dialogfönster " | ||||
| "att visas anslutna till namnlisten i föräldrafönstret och flyttas tillsammans " | ||||
| "med föräldrafönstret." | ||||
| "När true kommer, istället för att ha oberoende namnlister, modala " | ||||
| "dialogfönster att visas anslutna till namnlisten i föräldrafönstret och " | ||||
| "flyttas tillsammans med föräldrafönstret." | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:5 | ||||
| msgid "Enable edge tiling when dropping windows on screen edges" | ||||
| @@ -300,13 +301,13 @@ msgstr "Aktivera kantframhävning när fönster släpps på skärmkanter" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:6 | ||||
| msgid "" | ||||
| "If enabled, dropping windows on vertical screen edges maximizes them vertically " | ||||
| "and resizes them horizontally to cover half of the available area. Dropping " | ||||
| "windows on the top screen edge maximizes them completely." | ||||
| "If enabled, dropping windows on vertical screen edges maximizes them " | ||||
| "vertically and resizes them horizontally to cover half of the available " | ||||
| "area. Dropping windows on the top screen edge maximizes them completely." | ||||
| msgstr "" | ||||
| "Om aktiverad, släppa fönster på vertikala skärmkanter kommer att maximera dem " | ||||
| "vertikalt och storleksändra dem horisontellt till att täcka hälften av den " | ||||
| "tillgängliga ytan. Släppa fönster på övre skärmkanten maximerar dem helt." | ||||
| "Om aktiverad, släppa fönster på vertikala skärmkanter kommer att maximera " | ||||
| "dem vertikalt och storleksändra dem horisontellt till att täcka hälften av " | ||||
| "den tillgängliga ytan. Släppa fönster på övre skärmkanten maximerar dem helt." | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:7 | ||||
| msgid "Workspaces are managed dynamically" | ||||
| @@ -315,12 +316,12 @@ msgstr "Arbetsytor hanteras dynamiskt" | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:8 | ||||
| msgid "" | ||||
| "Determines whether workspaces are managed dynamically or whether there's a " | ||||
| "static number of workspaces (determined by the num-workspaces key in org.gnome." | ||||
| "desktop.wm.preferences)." | ||||
| "static number of workspaces (determined by the num-workspaces key in org." | ||||
| "gnome.desktop.wm.preferences)." | ||||
| msgstr "" | ||||
| "Bestämmer huruvida arbetsytor hanteras dynamiskt eller huruvida det finns ett " | ||||
| "fast antal arbetsytor (bestäms av nyckeln num-workspaces i org.gnome.desktop.wm." | ||||
| "preferences)." | ||||
| "Bestämmer huruvida arbetsytor hanteras dynamiskt eller huruvida det finns " | ||||
| "ett fast antal arbetsytor (bestäms av nyckeln num-workspaces i org.gnome." | ||||
| "desktop.wm.preferences)." | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:9 | ||||
| msgid "Workspaces only on primary" | ||||
| @@ -328,11 +329,11 @@ msgstr "Arbetsytor endast på primär" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:10 | ||||
| msgid "" | ||||
| "Determines whether workspace switching should happen for windows on all monitors " | ||||
| "or only for windows on the primary monitor." | ||||
| "Determines whether workspace switching should happen for windows on all " | ||||
| "monitors or only for windows on the primary monitor." | ||||
| msgstr "" | ||||
| "Bestämmer huruvida arbetsyteväxling ska hända för alla fönster på alla skärmar " | ||||
| "eller endast för fönster på den primära skärmen." | ||||
| "Bestämmer huruvida arbetsyteväxling ska hända för alla fönster på alla " | ||||
| "skärmar eller endast för fönster på den primära skärmen." | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:11 | ||||
| msgid "No tab popup" | ||||
| @@ -340,11 +341,11 @@ msgstr "Ingen flik-popup" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:12 | ||||
| msgid "" | ||||
| "Determines whether the use of popup and highlight frame should be disabled for " | ||||
| "window cycling." | ||||
| "Determines whether the use of popup and highlight frame should be disabled " | ||||
| "for window cycling." | ||||
| msgstr "" | ||||
| "Bestämmer huruvida användning av popup och framhävning av kontur ska inaktiveras " | ||||
| "vid fönsterväxling." | ||||
| "Bestämmer huruvida användning av popup och framhävning av kontur ska " | ||||
| "inaktiveras vid fönsterväxling." | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:13 | ||||
| msgid "Delay focus changes until the pointer stops moving" | ||||
| @@ -352,13 +353,13 @@ msgstr "Fördröj fokusändringar till muspekaren hålls still" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:14 | ||||
| msgid "" | ||||
| "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then the " | ||||
| "focus will not be changed immediately when entering a window, but only after the " | ||||
| "pointer stops moving." | ||||
| "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " | ||||
| "the focus will not be changed immediately when entering a window, but only " | ||||
| "after the pointer stops moving." | ||||
| msgstr "" | ||||
| "Om satt till \"true\", och fokusläget är antingen \"sloppy\" eller \"mouse\" " | ||||
| "kommer fokus inte att ändras omedelbart när muspekaren går in över ett fönster, " | ||||
| "utan först efter att muspekaren slutar röra sig." | ||||
| "kommer fokus inte att ändras omedelbart när muspekaren går in över ett " | ||||
| "fönster, utan först efter att muspekaren slutar röra sig." | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:15 | ||||
| msgid "Draggable border width" | ||||
| @@ -366,8 +367,8 @@ msgstr "Dragbar rambredd" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:16 | ||||
| msgid "" | ||||
| "The amount of total draggable borders. If the theme's visible borders are not " | ||||
| "enough, invisible borders will be added to meet this value." | ||||
| "The amount of total draggable borders. If the theme's visible borders are " | ||||
| "not enough, invisible borders will be added to meet this value." | ||||
| msgstr "" | ||||
| "Mängd av totalt dragbara ramar. Om temats synliga ramar inte är tillräckliga " | ||||
| "kommer osynliga ramar att läggas till för att möta detta värde." | ||||
| @@ -378,8 +379,8 @@ msgstr "Automatiskt maximera fönster vars storlek ligger nära skärmens storle | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:18 | ||||
| msgid "" | ||||
| "If enabled, new windows that are initially the size of the monitor automatically " | ||||
| "get maximized." | ||||
| "If enabled, new windows that are initially the size of the monitor " | ||||
| "automatically get maximized." | ||||
| msgstr "" | ||||
| "Om aktiverad kommer nya fönster med nästan samma storlek som skärmen att bli " | ||||
| "automatiskt maximerade." | ||||
| @@ -390,11 +391,11 @@ msgstr "Placera nya fönster centrerat" | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:20 | ||||
| msgid "" | ||||
| "When true, the new windows will always be put in the center of the active screen " | ||||
| "of the monitor." | ||||
| "When true, the new windows will always be put in the center of the active " | ||||
| "screen of the monitor." | ||||
| msgstr "" | ||||
| "När satt till \"true\", kommer nya fönster alltid att placeras centrerat på den " | ||||
| "aktiva skärmen." | ||||
| "När satt till \"true\", kommer nya fönster alltid att placeras centrerat på " | ||||
| "den aktiva skärmen." | ||||
|  | ||||
| #: ../data/org.gnome.mutter.gschema.xml.in.h:21 | ||||
| msgid "Select window from tab popup" | ||||
| @@ -452,22 +453,22 @@ msgstr "Växla till VT 11" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Växla till VT 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Inbyggd display" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Okänd" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Okänd display" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -477,8 +478,9 @@ msgstr "%s %s" | ||||
| #: ../src/compositor/compositor.c:456 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Another compositing manager is already running on screen %i on display \"%s\"." | ||||
| msgstr "En annan compositing-hanterare körs redan på skärm %i på display \"%s\"." | ||||
| "Another compositing manager is already running on screen %i on display \"%s" | ||||
| "\"." | ||||
| msgstr "En annan kompositionshanterare körs redan på skärm %i på display ”%s”." | ||||
|  | ||||
| #: ../src/core/bell.c:185 | ||||
| msgid "Bell event" | ||||
| @@ -495,8 +497,8 @@ msgstr "Programmet svarar inte." | ||||
|  | ||||
| #: ../src/core/delete.c:134 | ||||
| msgid "" | ||||
| "You may choose to wait a short while for it to continue or force the application " | ||||
| "to quit entirely." | ||||
| "You may choose to wait a short while for it to continue or force the " | ||||
| "application to quit entirely." | ||||
| msgstr "" | ||||
| "Du kan välja att vänta en kort stund på det för att fortsätta eller tvinga " | ||||
| "programmet att helt avslutas." | ||||
| @@ -509,40 +511,44 @@ msgstr "_Vänta" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Tvinga avslut" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Misslyckades med att öppna X Window System-displayen ”%s”\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Inaktivera anslutning till sessionshanteraren" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Ersätt körande fönsterhanteraren" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Ange sessionshanteringsid" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "X-display att använda" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Initiera session från sparandefil" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Gör X-anrop synkrona" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Kör som en wayland-compositor" | ||||
| msgstr "Kör som en wayland-kompositionshanterare" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Kör som en nästlad kompositionshanterare" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Kör som en full display-tjänst, i stället för nästlad" | ||||
|  | ||||
| @@ -552,8 +558,8 @@ msgid "" | ||||
| "mutter %s\n" | ||||
| "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" | ||||
| "This is free software; see the source for copying conditions.\n" | ||||
| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR " | ||||
| "PURPOSE.\n" | ||||
| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " | ||||
| "PARTICULAR PURPOSE.\n" | ||||
| msgstr "" | ||||
| "mutter %s\n" | ||||
| "Copyright © 2001-%d Havoc Pennington, Red Hat, Inc. och andra\n" | ||||
| @@ -569,33 +575,33 @@ msgstr "Skriv ut version" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Mutter-insticksmodul att använda" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Arbetsyta %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option to " | ||||
| "replace the current window manager." | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| "to replace the current window manager." | ||||
| msgstr "" | ||||
| "Display ”%s” har redan en fönsterhanterare; försök med flaggan --replace för att " | ||||
| "ersätta den aktuella fönsterhanteraren." | ||||
| "Display ”%s” har redan en fönsterhanterare; försök med flaggan --replace för " | ||||
| "att ersätta den aktuella fönsterhanteraren." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Skärm %d på display ”%s” är ogiltig\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter kompilerades utan stöd för utförligt läge\n" | ||||
|  | ||||
| #: ../src/x11/session.c:1815 | ||||
| msgid "" | ||||
| "These windows do not support "save current setup" and will have to be " | ||||
| "restarted manually next time you log in." | ||||
| "These windows do not support "save current setup" and will have to " | ||||
| "be restarted manually next time you log in." | ||||
| msgstr "" | ||||
| "Dessa fönster saknar stöd för "spara nuvarande inställningar" och " | ||||
| "kommer att behöva startas om manuellt nästa gång du loggar in." | ||||
|   | ||||
							
								
								
									
										52
									
								
								po/vi.po
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								po/vi.po
									
									
									
									
									
								
							| @@ -1,17 +1,17 @@ | ||||
| # Vietnamese translation for Metacity. | ||||
| # Copyright © 2015 GNOME i18n Project for Vietnamese. | ||||
| # Copyright © 2016 GNOME i18n Project for Vietnamese. | ||||
| # This file is distributed under the same license as the Metacity package. | ||||
| # Nguyễn Thái Ngọc Duy <pclouds@gmail.com>, 2002-2004, 2007, 2008, 2011-2013. | ||||
| # Clytie Siddall <clytie@riverland.net.au>, 2005-2009. | ||||
| # Trần Ngọc Quân <vnwildman@gmail.com>, 2014, 2015. | ||||
| # Trần Ngọc Quân <vnwildman@gmail.com>, 2014, 2015, 2016. | ||||
| # | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: metacity master\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2015-03-09 23:13+0000\n" | ||||
| "PO-Revision-Date: 2015-03-10 13:28+0700\n" | ||||
| "POT-Creation-Date: 2016-03-26 14:03+0000\n" | ||||
| "PO-Revision-Date: 2016-03-27 07:22+0700\n" | ||||
| "Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n" | ||||
| "Language-Team: Vietnamese <gnome-vi-list@gnome.org>\n" | ||||
| "Language: vi\n" | ||||
| @@ -19,11 +19,11 @@ msgstr "" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "Plural-Forms: nplurals=1; plural=0;\n" | ||||
| "X-Generator: LocFactoryEditor 1.8\n" | ||||
| "X-Generator: Gtranslator 2.91.7\n" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:1 | ||||
| msgid "Navigation" | ||||
| msgstr "Di chuyển" | ||||
| msgstr "Điều hướng" | ||||
|  | ||||
| #: ../data/50-mutter-navigation.xml.in.h:2 | ||||
| msgid "Move window to workspace 1" | ||||
| @@ -447,22 +447,22 @@ msgstr "Chuyển sang VT 11" | ||||
| msgid "Switch to VT 12" | ||||
| msgstr "Chuyển sang VT 12" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:364 | ||||
| #: ../src/backends/meta-monitor-manager.c:518 | ||||
| msgid "Built-in display" | ||||
| msgstr "Màn hình tích hợp" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:391 | ||||
| #: ../src/backends/meta-monitor-manager.c:544 | ||||
| msgid "Unknown" | ||||
| msgstr "Không rõ" | ||||
|  | ||||
| #: ../src/backends/meta-monitor-manager.c:393 | ||||
| #: ../src/backends/meta-monitor-manager.c:546 | ||||
| msgid "Unknown Display" | ||||
| msgstr "Không hiểu màn hình" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor vendor name, followed by a | ||||
| #. * size in inches, like 'Dell 15"' | ||||
| #. | ||||
| #: ../src/backends/meta-monitor-manager.c:401 | ||||
| #: ../src/backends/meta-monitor-manager.c:554 | ||||
| #, c-format | ||||
| msgid "%s %s" | ||||
| msgstr "%s %s" | ||||
| @@ -477,7 +477,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Bộ quản lý cửa sổ đã đang chạy trên Màn hình %i trên bộ trình bày \"%s\"." | ||||
|  | ||||
| #: ../src/core/bell.c:185 | ||||
| #: ../src/core/bell.c:194 | ||||
| msgid "Bell event" | ||||
| msgstr "Sự kiện chuông" | ||||
|  | ||||
| @@ -506,40 +506,44 @@ msgstr "_Chờ" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Buộc thoát" | ||||
|  | ||||
| #: ../src/core/display.c:562 | ||||
| #: ../src/core/display.c:555 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Gặp lỗi khi mở bộ trình bày Hệ thống Cửa sổ X \"%s\".\n" | ||||
|  | ||||
| #: ../src/core/main.c:176 | ||||
| #: ../src/core/main.c:181 | ||||
| msgid "Disable connection to session manager" | ||||
| msgstr "Vô hiệu hóa kết nối với bộ quản lý phiên làm việc" | ||||
|  | ||||
| #: ../src/core/main.c:182 | ||||
| #: ../src/core/main.c:187 | ||||
| msgid "Replace the running window manager" | ||||
| msgstr "Thay thế bộ quản lý cửa sổ đang chạy" | ||||
|  | ||||
| #: ../src/core/main.c:188 | ||||
| #: ../src/core/main.c:193 | ||||
| msgid "Specify session management ID" | ||||
| msgstr "Ghi rõ mã số quản lý phiên làm việc" | ||||
|  | ||||
| #: ../src/core/main.c:193 | ||||
| #: ../src/core/main.c:198 | ||||
| msgid "X Display to use" | ||||
| msgstr "Bộ trình bày X cần dùng" | ||||
|  | ||||
| #: ../src/core/main.c:199 | ||||
| #: ../src/core/main.c:204 | ||||
| msgid "Initialize session from savefile" | ||||
| msgstr "Khởi động phiên làm việc từ tập tin lưu" | ||||
|  | ||||
| #: ../src/core/main.c:205 | ||||
| #: ../src/core/main.c:210 | ||||
| msgid "Make X calls synchronous" | ||||
| msgstr "Khiến các lời gọi X đồng bộ với nhau" | ||||
|  | ||||
| #: ../src/core/main.c:212 | ||||
| #: ../src/core/main.c:217 | ||||
| msgid "Run as a wayland compositor" | ||||
| msgstr "Chạy như là một “wayland compositor”" | ||||
|  | ||||
| #: ../src/core/main.c:220 | ||||
| #: ../src/core/main.c:223 | ||||
| msgid "Run as a nested compositor" | ||||
| msgstr "Chạy như là một “nested compositor”" | ||||
|  | ||||
| #: ../src/core/main.c:231 | ||||
| msgid "Run as a full display server, rather than nested" | ||||
| msgstr "Chạy như là một dịch vụ hiển thị đầy đủ, thay cho lồng nhau" | ||||
|  | ||||
| @@ -567,12 +571,12 @@ msgstr "Hiển thị phiên bản" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Phần bổ sung Mutter cần dùng" | ||||
|  | ||||
| #: ../src/core/prefs.c:2004 | ||||
| #: ../src/core/prefs.c:1997 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Vùng làm việc %d" | ||||
|  | ||||
| #: ../src/core/screen.c:525 | ||||
| #: ../src/core/screen.c:521 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Display \"%s\" already has a window manager; try using the --replace option " | ||||
| @@ -581,12 +585,12 @@ msgstr "" | ||||
| "Màn hình \"%s\" đã có bộ quản lý cửa sổ rồi; hãy thử dùng tùy chọn “--" | ||||
| "replace” để thay thế bộ quản lý cửa sổ đang dùng." | ||||
|  | ||||
| #: ../src/core/screen.c:607 | ||||
| #: ../src/core/screen.c:603 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Màn hình %d trên bộ trình bày \"%s\" không hợp lệ.\n" | ||||
|  | ||||
| #: ../src/core/util.c:118 | ||||
| #: ../src/core/util.c:121 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter đã được biên dịch không hỗ trợ chế độ chi tiết\n" | ||||
|  | ||||
|   | ||||
| @@ -19,9 +19,9 @@ installedtestsdir = $(datadir)/installed-tests/mutter | ||||
| installedtests_DATA = mutter-all.test | ||||
|  | ||||
| installedtestsbindir = $(libexecdir)/installed-tests/mutter | ||||
| installedtestsbin_PROGRAMS = mutter-test-client mutter-test-runner | ||||
| installedtestsbin_PROGRAMS = mutter-test-client mutter-test-runner mutter-test-unit-tests | ||||
| else | ||||
| noinst_PROGRAMS += mutter-test-client mutter-test-runner | ||||
| noinst_PROGRAMS += mutter-test-client mutter-test-runner mutter-test-unit-tests | ||||
| endif | ||||
|  | ||||
| EXTRA_DIST += tests/mutter-all.test.in | ||||
| @@ -32,11 +32,19 @@ mutter_test_client_LDADD = $(MUTTER_LIBS) libmutter.la | ||||
| mutter_test_runner_SOURCES = tests/test-runner.c | ||||
| mutter_test_runner_LDADD = $(MUTTER_LIBS) libmutter.la | ||||
|  | ||||
| .PHONY: run-tests | ||||
| mutter_test_unit_tests_SOURCES = tests/unit-tests.c | ||||
| mutter_test_unit_tests_LDADD = $(MUTTER_LIBS) libmutter.la | ||||
|  | ||||
| run-tests: mutter-test-client mutter-test-runner | ||||
| .PHONY: run-tests run-test-runner-tests run-unit-tests | ||||
|  | ||||
| run-test-runner-tests: mutter-test-client mutter-test-runner | ||||
| 	./mutter-test-runner $(dist_stacking_DATA) | ||||
|  | ||||
| run-unit-tests: mutter-test-unit-tests | ||||
| 	./mutter-test-unit-tests | ||||
|  | ||||
| run-tests: run-test-runner-tests run-unit-tests | ||||
|  | ||||
| endif | ||||
|  | ||||
| # Some random test programs for bits of the code | ||||
|   | ||||
| @@ -49,13 +49,20 @@ mutter_built_sources += \ | ||||
| 	pointer-gestures-unstable-v1-server-protocol.h			\ | ||||
| 	gtk-shell-protocol.c			\ | ||||
| 	gtk-shell-server-protocol.h		\ | ||||
| 	gtk-primary-selection-protocol.c				\ | ||||
| 	gtk-primary-selection-server-protocol.h				\ | ||||
| 	xdg-shell-unstable-v5-protocol.c				\ | ||||
| 	xdg-shell-unstable-v5-server-protocol.h				\ | ||||
| 	relative-pointer-unstable-v1-protocol.c				\ | ||||
| 	relative-pointer-unstable-v1-server-protocol.h			\ | ||||
| 	pointer-constraints-unstable-v1-protocol.c			\ | ||||
| 	pointer-constraints-unstable-v1-server-protocol.h		\ | ||||
| 	$(NULL) | ||||
| endif | ||||
|  | ||||
| wayland_protocols =				\ | ||||
| 	wayland/protocol/gtk-shell.xml		\ | ||||
| 	wayland/protocol/gtk-primary-selection.xml	\ | ||||
| 	$(NULL) | ||||
|  | ||||
| libmutter_la_SOURCES =				\ | ||||
| @@ -84,6 +91,8 @@ libmutter_la_SOURCES =				\ | ||||
| 	backends/meta-monitor-manager-private.h	\ | ||||
| 	backends/meta-monitor-manager-dummy.c	\ | ||||
| 	backends/meta-monitor-manager-dummy.h	\ | ||||
| 	backends/meta-pointer-constraint.c	\ | ||||
| 	backends/meta-pointer-constraint.h	\ | ||||
| 	backends/meta-stage.h			\ | ||||
| 	backends/meta-stage.c			\ | ||||
| 	backends/edid-parse.c			\ | ||||
| @@ -110,6 +119,8 @@ libmutter_la_SOURCES =				\ | ||||
| 	core/boxes.c				\ | ||||
| 	core/boxes-private.h			\ | ||||
| 	meta/boxes.h				\ | ||||
| 	core/meta-border.c			\ | ||||
| 	core/meta-border.h			\ | ||||
| 	compositor/clutter-utils.c		\ | ||||
| 	compositor/clutter-utils.h		\ | ||||
| 	compositor/cogl-utils.c			\ | ||||
| @@ -190,6 +201,8 @@ libmutter_la_SOURCES =				\ | ||||
| 	core/screen.c				\ | ||||
| 	core/screen-private.h			\ | ||||
| 	meta/screen.h				\ | ||||
| 	core/startup-notification.c		\ | ||||
| 	core/startup-notification-private.h	\ | ||||
| 	meta/types.h				\ | ||||
| 	core/restart.c				\ | ||||
| 	core/stack.c				\ | ||||
| @@ -264,6 +277,12 @@ libmutter_la_SOURCES +=				\ | ||||
| 	wayland/meta-wayland-keyboard.h		\ | ||||
| 	wayland/meta-wayland-pointer.c		\ | ||||
| 	wayland/meta-wayland-pointer.h		\ | ||||
| 	wayland/meta-wayland-pointer-constraints.c	\ | ||||
| 	wayland/meta-wayland-pointer-constraints.h	\ | ||||
| 	wayland/meta-pointer-lock-wayland.c		\ | ||||
| 	wayland/meta-pointer-lock-wayland.h		\ | ||||
| 	wayland/meta-pointer-confinement-wayland.c	\ | ||||
| 	wayland/meta-pointer-confinement-wayland.h	\ | ||||
| 	wayland/meta-wayland-popup.c		\ | ||||
| 	wayland/meta-wayland-popup.h		\ | ||||
| 	wayland/meta-wayland-seat.c		\ | ||||
|   | ||||
| @@ -34,6 +34,7 @@ | ||||
| #include <meta/meta-idle-monitor.h> | ||||
| #include "meta-cursor-renderer.h" | ||||
| #include "meta-monitor-manager-private.h" | ||||
| #include "backends/meta-pointer-constraint.h" | ||||
|  | ||||
| #define DEFAULT_XKB_RULES_FILE "evdev" | ||||
| #define DEFAULT_XKB_MODEL "pc105+inet" | ||||
| @@ -51,6 +52,8 @@ struct _MetaBackend | ||||
|  | ||||
|   GHashTable *device_monitors; | ||||
|   gint current_device_id; | ||||
|  | ||||
|   MetaPointerConstraint *client_pointer_constraint; | ||||
| }; | ||||
|  | ||||
| struct _MetaBackendClass | ||||
| @@ -87,6 +90,13 @@ struct _MetaBackendClass | ||||
|  | ||||
|   void (* update_screen_size) (MetaBackend *backend, int width, int height); | ||||
|   void (* select_stage_events) (MetaBackend *backend); | ||||
|  | ||||
|   gboolean (* get_relative_motion_deltas) (MetaBackend *backend, | ||||
|                                            const        ClutterEvent *event, | ||||
|                                            double       *dx, | ||||
|                                            double       *dy, | ||||
|                                            double       *dx_unaccel, | ||||
|                                            double       *dy_unaccel); | ||||
| }; | ||||
|  | ||||
| MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend, | ||||
| @@ -110,4 +120,14 @@ struct xkb_keymap * meta_backend_get_keymap (MetaBackend *backend); | ||||
| void meta_backend_update_last_device (MetaBackend *backend, | ||||
|                                       int          device_id); | ||||
|  | ||||
| gboolean meta_backend_get_relative_motion_deltas (MetaBackend *backend, | ||||
|                                                   const        ClutterEvent *event, | ||||
|                                                   double       *dx, | ||||
|                                                   double       *dy, | ||||
|                                                   double       *dx_unaccel, | ||||
|                                                   double       *dy_unaccel); | ||||
|  | ||||
| void meta_backend_set_client_pointer_constraint (MetaBackend *backend, | ||||
|                                                  MetaPointerConstraint *constraint); | ||||
|  | ||||
| #endif /* META_BACKEND_PRIVATE_H */ | ||||
|   | ||||
| @@ -64,6 +64,8 @@ struct _MetaBackendPrivate | ||||
|   MetaInputSettings *input_settings; | ||||
|  | ||||
|   ClutterActor *stage; | ||||
|  | ||||
|   guint device_update_idle_id; | ||||
| }; | ||||
| typedef struct _MetaBackendPrivate MetaBackendPrivate; | ||||
|  | ||||
| @@ -78,6 +80,9 @@ meta_backend_finalize (GObject *object) | ||||
|   g_clear_object (&priv->monitor_manager); | ||||
|   g_clear_object (&priv->input_settings); | ||||
|  | ||||
|   if (priv->device_update_idle_id) | ||||
|     g_source_remove (priv->device_update_idle_id); | ||||
|  | ||||
|   g_hash_table_destroy (backend->device_monitors); | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object); | ||||
| @@ -353,6 +358,17 @@ meta_backend_real_select_stage_events (MetaBackend *backend) | ||||
|   /* Do nothing */ | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_backend_real_get_relative_motion_deltas (MetaBackend *backend, | ||||
|                                              const         ClutterEvent *event, | ||||
|                                              double        *dx, | ||||
|                                              double        *dy, | ||||
|                                              double        *dx_unaccel, | ||||
|                                              double        *dy_unaccel) | ||||
| { | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_backend_class_init (MetaBackendClass *klass) | ||||
| { | ||||
| @@ -366,6 +382,7 @@ meta_backend_class_init (MetaBackendClass *klass) | ||||
|   klass->ungrab_device = meta_backend_real_ungrab_device; | ||||
|   klass->update_screen_size = meta_backend_real_update_screen_size; | ||||
|   klass->select_stage_events = meta_backend_real_select_stage_events; | ||||
|   klass->get_relative_motion_deltas = meta_backend_real_get_relative_motion_deltas; | ||||
|  | ||||
|   g_signal_new ("keymap-changed", | ||||
|                 G_TYPE_FROM_CLASS (object_class), | ||||
| @@ -505,12 +522,44 @@ meta_backend_get_stage (MetaBackend *backend) | ||||
|   return priv->stage; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| update_last_device (MetaBackend *backend) | ||||
| { | ||||
|   MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL); | ||||
|   MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); | ||||
|   ClutterInputDeviceType device_type; | ||||
|   ClutterDeviceManager *manager; | ||||
|   ClutterInputDevice *device; | ||||
|  | ||||
|   priv->device_update_idle_id = 0; | ||||
|   manager = clutter_device_manager_get_default (); | ||||
|   device = clutter_device_manager_get_device (manager, | ||||
|                                               backend->current_device_id); | ||||
|   device_type = clutter_input_device_get_device_type (device); | ||||
|  | ||||
|   g_signal_emit_by_name (backend, "last-device-changed", | ||||
|                          backend->current_device_id); | ||||
|  | ||||
|   switch (device_type) | ||||
|     { | ||||
|     case CLUTTER_KEYBOARD_DEVICE: | ||||
|       break; | ||||
|     case CLUTTER_TOUCHSCREEN_DEVICE: | ||||
|       meta_cursor_tracker_set_pointer_visible (cursor_tracker, FALSE); | ||||
|       break; | ||||
|     default: | ||||
|       meta_cursor_tracker_set_pointer_visible (cursor_tracker, TRUE); | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   return G_SOURCE_REMOVE; | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_backend_update_last_device (MetaBackend *backend, | ||||
|                                  int          device_id) | ||||
| { | ||||
|   ClutterInputDeviceType device_type; | ||||
|   MetaCursorTracker *cursor_tracker; | ||||
|   MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); | ||||
|   ClutterDeviceManager *manager; | ||||
|   ClutterInputDevice *device; | ||||
|  | ||||
| @@ -524,26 +573,43 @@ meta_backend_update_last_device (MetaBackend *backend, | ||||
|       clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER) | ||||
|     return; | ||||
|  | ||||
|   device_type = clutter_input_device_get_device_type (device); | ||||
|  | ||||
|   cursor_tracker = meta_cursor_tracker_get_for_screen (NULL); | ||||
|   backend->current_device_id = device_id; | ||||
|   g_signal_emit_by_name (backend, "last-device-changed", device_id); | ||||
|  | ||||
|   if (device_type == CLUTTER_KEYBOARD_DEVICE) | ||||
|     return; | ||||
|  | ||||
|   switch (device_type) | ||||
|   if (priv->device_update_idle_id == 0) | ||||
|     { | ||||
|     case CLUTTER_TOUCHSCREEN_DEVICE: | ||||
|       meta_cursor_tracker_set_pointer_visible (cursor_tracker, FALSE); | ||||
|       break; | ||||
|     default: | ||||
|       meta_cursor_tracker_set_pointer_visible (cursor_tracker, TRUE); | ||||
|       break; | ||||
|       priv->device_update_idle_id = | ||||
|         g_idle_add ((GSourceFunc) update_last_device, backend); | ||||
|       g_source_set_name_by_id (priv->device_update_idle_id, | ||||
|                                "[mutter] update_last_device"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_backend_get_relative_motion_deltas (MetaBackend *backend, | ||||
|                                          const        ClutterEvent *event, | ||||
|                                          double       *dx, | ||||
|                                          double       *dy, | ||||
|                                          double       *dx_unaccel, | ||||
|                                          double       *dy_unaccel) | ||||
| { | ||||
|   MetaBackendClass *klass = META_BACKEND_GET_CLASS (backend); | ||||
|   return klass->get_relative_motion_deltas (backend, | ||||
|                                             event, | ||||
|                                             dx, dy, | ||||
|                                             dx_unaccel, dy_unaccel); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_backend_set_client_pointer_constraint (MetaBackend           *backend, | ||||
|                                             MetaPointerConstraint *constraint) | ||||
| { | ||||
|   g_assert (!constraint || (constraint && !backend->client_pointer_constraint)); | ||||
|  | ||||
|   g_clear_object (&backend->client_pointer_constraint); | ||||
|   if (constraint) | ||||
|     backend->client_pointer_constraint = g_object_ref (constraint); | ||||
| } | ||||
|  | ||||
| static GType | ||||
| get_backend_type (void) | ||||
| { | ||||
|   | ||||
| @@ -26,6 +26,8 @@ | ||||
| #ifndef META_BARRIER_PRIVATE_H | ||||
| #define META_BARRIER_PRIVATE_H | ||||
|  | ||||
| #include "core/meta-border.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define META_TYPE_BARRIER_IMPL            (meta_barrier_impl_get_type ()) | ||||
| @@ -67,14 +69,7 @@ G_END_DECLS | ||||
| struct _MetaBarrierPrivate | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   int x1; | ||||
|   int y1; | ||||
|   int x2; | ||||
|   int y2; | ||||
|  | ||||
|   MetaBarrierDirection directions; | ||||
|  | ||||
|   MetaBorder border; | ||||
|   MetaBarrierImpl *impl; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -61,19 +61,20 @@ meta_barrier_get_property (GObject    *object, | ||||
|       g_value_set_object (value, priv->display); | ||||
|       break; | ||||
|     case PROP_X1: | ||||
|       g_value_set_int (value, priv->x1); | ||||
|       g_value_set_int (value, priv->border.line.a.x); | ||||
|       break; | ||||
|     case PROP_Y1: | ||||
|       g_value_set_int (value, priv->y1); | ||||
|       g_value_set_int (value, priv->border.line.a.y); | ||||
|       break; | ||||
|     case PROP_X2: | ||||
|       g_value_set_int (value, priv->x2); | ||||
|       g_value_set_int (value, priv->border.line.b.x); | ||||
|       break; | ||||
|     case PROP_Y2: | ||||
|       g_value_set_int (value, priv->y2); | ||||
|       g_value_set_int (value, priv->border.line.b.y); | ||||
|       break; | ||||
|     case PROP_DIRECTIONS: | ||||
|       g_value_set_flags (value, priv->directions); | ||||
|       g_value_set_flags (value, | ||||
|                          meta_border_get_allows_directions (&priv->border)); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||||
| @@ -95,19 +96,20 @@ meta_barrier_set_property (GObject      *object, | ||||
|       priv->display = g_value_get_object (value); | ||||
|       break; | ||||
|     case PROP_X1: | ||||
|       priv->x1 = g_value_get_int (value); | ||||
|       priv->border.line.a.x = g_value_get_int (value); | ||||
|       break; | ||||
|     case PROP_Y1: | ||||
|       priv->y1 = g_value_get_int (value); | ||||
|       priv->border.line.a.y = g_value_get_int (value); | ||||
|       break; | ||||
|     case PROP_X2: | ||||
|       priv->x2 = g_value_get_int (value); | ||||
|       priv->border.line.b.x = g_value_get_int (value); | ||||
|       break; | ||||
|     case PROP_Y2: | ||||
|       priv->y2 = g_value_get_int (value); | ||||
|       priv->border.line.b.y = g_value_get_int (value); | ||||
|       break; | ||||
|     case PROP_DIRECTIONS: | ||||
|       priv->directions = g_value_get_flags (value); | ||||
|       meta_border_set_allows_directions (&priv->border, | ||||
|                                          g_value_get_flags (value)); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||||
| @@ -166,7 +168,8 @@ meta_barrier_constructed (GObject *object) | ||||
|   MetaBarrier *barrier = META_BARRIER (object); | ||||
|   MetaBarrierPrivate *priv = barrier->priv; | ||||
|  | ||||
|   g_return_if_fail (priv->x1 == priv->x2 || priv->y1 == priv->y2); | ||||
|   g_return_if_fail (priv->border.line.a.x == priv->border.line.b.x || | ||||
|                     priv->border.line.a.y == priv->border.line.b.y); | ||||
|  | ||||
| #if defined(HAVE_NATIVE_BACKEND) | ||||
|   if (META_IS_BACKEND_NATIVE (meta_get_backend ())) | ||||
|   | ||||
| @@ -27,8 +27,6 @@ | ||||
| #include "meta-cursor-renderer.h" | ||||
|  | ||||
| #include <meta/meta-backend.h> | ||||
| #include <backends/meta-backend-private.h> | ||||
| #include <backends/meta-monitor-manager-private.h> | ||||
| #include <meta/util.h> | ||||
|  | ||||
| #include <cogl/cogl.h> | ||||
| @@ -118,14 +116,6 @@ meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer, | ||||
|   }; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| is_cursor_in_monitors_area (int x, int y) | ||||
| { | ||||
|   MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (meta_get_backend ()); | ||||
|   return meta_monitor_manager_get_monitor_at_point (monitor_manager, | ||||
|                                                     (gfloat) x, (gfloat) y) >= 0; | ||||
| } | ||||
|  | ||||
| static void | ||||
| update_cursor (MetaCursorRenderer *renderer, | ||||
|                MetaCursorSprite   *cursor_sprite) | ||||
| @@ -134,11 +124,6 @@ update_cursor (MetaCursorRenderer *renderer, | ||||
|   gboolean handled_by_backend; | ||||
|   gboolean should_redraw = FALSE; | ||||
|  | ||||
|   /* do not render cursor if it is not on any monitor. Such situation | ||||
|    * can occur e. g. after monitor hot-plug */ | ||||
|   if (!is_cursor_in_monitors_area (priv->current_x, priv->current_y)) | ||||
|     return; | ||||
|  | ||||
|   if (cursor_sprite) | ||||
|     meta_cursor_sprite_prepare_at (cursor_sprite, | ||||
|                                    priv->current_x, | ||||
|   | ||||
							
								
								
									
										57
									
								
								src/backends/meta-pointer-constraint.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/backends/meta-pointer-constraint.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2015 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jonas Ådahl <jadahl@gmail.com> | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "backends/meta-pointer-constraint.h" | ||||
|  | ||||
| #include <glib-object.h> | ||||
|  | ||||
| G_DEFINE_TYPE (MetaPointerConstraint, meta_pointer_constraint, G_TYPE_OBJECT); | ||||
|  | ||||
| static void | ||||
| meta_pointer_constraint_init (MetaPointerConstraint *constraint) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_pointer_constraint_class_init (MetaPointerConstraintClass *klass) | ||||
| { | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_pointer_constraint_constrain (MetaPointerConstraint *constraint, | ||||
|                                    ClutterInputDevice    *device, | ||||
|                                    guint32                time, | ||||
|                                    float                  prev_x, | ||||
|                                    float                  prev_y, | ||||
|                                    float                  *x, | ||||
|                                    float                  *y) | ||||
| { | ||||
|   META_POINTER_CONSTRAINT_GET_CLASS (constraint)->constrain (constraint, | ||||
|                                                              device, | ||||
|                                                              time, | ||||
|                                                              prev_x, prev_y, | ||||
|                                                              x, y); | ||||
| } | ||||
							
								
								
									
										60
									
								
								src/backends/meta-pointer-constraint.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/backends/meta-pointer-constraint.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2015 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jonas Ådahl <jadahl@gmail.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef META_POINTER_CONSTRAINT_H | ||||
| #define META_POINTER_CONSTRAINT_H | ||||
|  | ||||
| #include <glib-object.h> | ||||
| #include <clutter/clutter.h> | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define META_TYPE_POINTER_CONSTRAINT (meta_pointer_constraint_get_type ()) | ||||
| G_DECLARE_DERIVABLE_TYPE (MetaPointerConstraint, meta_pointer_constraint, | ||||
|                           META, POINTER_CONSTRAINT, GObject); | ||||
|  | ||||
| struct _MetaPointerConstraintClass | ||||
| { | ||||
|   GObjectClass parent_class; | ||||
|  | ||||
|   void (*constrain) (MetaPointerConstraint *constraint, | ||||
|                      ClutterInputDevice *device, | ||||
|                      guint32 time, | ||||
|                      float prev_x, | ||||
|                      float prev_y, | ||||
|                      float *x, | ||||
|                      float *y); | ||||
| }; | ||||
|  | ||||
| void meta_pointer_constraint_constrain (MetaPointerConstraint *constraint, | ||||
|                                         ClutterInputDevice    *device, | ||||
|                                         guint32                time, | ||||
|                                         float                  prev_x, | ||||
|                                         float                  prev_y, | ||||
|                                         float                 *x, | ||||
|                                         float                 *y); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* META_POINTER_CONSTRAINT_H */ | ||||
| @@ -36,6 +36,8 @@ | ||||
| #include "meta-monitor-manager-kms.h" | ||||
| #include "meta-cursor-renderer-native.h" | ||||
| #include "meta-launcher.h" | ||||
| #include "backends/meta-cursor-tracker-private.h" | ||||
| #include "backends/meta-pointer-constraint.h" | ||||
|  | ||||
| #include <stdlib.h> | ||||
|  | ||||
| @@ -139,6 +141,24 @@ constrain_to_barriers (ClutterInputDevice *device, | ||||
|                                        new_x, new_y); | ||||
| } | ||||
|  | ||||
| static void | ||||
| constrain_to_client_constraint (ClutterInputDevice *device, | ||||
|                                 guint32             time, | ||||
|                                 float               prev_x, | ||||
|                                 float               prev_y, | ||||
|                                 float              *x, | ||||
|                                 float              *y) | ||||
| { | ||||
|   MetaBackend *backend = meta_get_backend (); | ||||
|   MetaPointerConstraint *constraint = backend->client_pointer_constraint; | ||||
|  | ||||
|   if (!constraint) | ||||
|     return; | ||||
|  | ||||
|   meta_pointer_constraint_constrain (constraint, device, | ||||
|                                      time, prev_x, prev_y, x, y); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * The pointer constrain code is mostly a rip-off of the XRandR code from Xorg. | ||||
|  * (from xserver/randr/rrcrtc.c, RRConstrainCursorHarder) | ||||
| @@ -193,10 +213,12 @@ constrain_all_screen_monitors (ClutterInputDevice *device, | ||||
|  | ||||
| static void | ||||
| pointer_constrain_callback (ClutterInputDevice *device, | ||||
| 			    guint32             time, | ||||
| 			    float              *new_x, | ||||
| 			    float              *new_y, | ||||
| 			    gpointer            user_data) | ||||
|                             guint32             time, | ||||
|                             float               prev_x, | ||||
|                             float               prev_y, | ||||
|                             float              *new_x, | ||||
|                             float              *new_y, | ||||
|                             gpointer            user_data) | ||||
| { | ||||
|   MetaMonitorManager *monitor_manager; | ||||
|   MetaMonitorInfo *monitors; | ||||
| @@ -205,6 +227,9 @@ pointer_constrain_callback (ClutterInputDevice *device, | ||||
|   /* Constrain to barriers */ | ||||
|   constrain_to_barriers (device, time, new_x, new_y); | ||||
|  | ||||
|   /* Constrain to pointer lock */ | ||||
|   constrain_to_client_constraint (device, time, prev_x, prev_y, new_x, new_y); | ||||
|  | ||||
|   monitor_manager = meta_monitor_manager_get (); | ||||
|   monitors = meta_monitor_manager_get_monitor_infos (monitor_manager, &n_monitors); | ||||
|  | ||||
| @@ -255,11 +280,16 @@ meta_backend_native_warp_pointer (MetaBackend *backend, | ||||
| { | ||||
|   ClutterDeviceManager *manager = clutter_device_manager_get_default (); | ||||
|   ClutterInputDevice *device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE); | ||||
|   MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (NULL); | ||||
|  | ||||
|   /* XXX */ | ||||
|   guint32 time_ = 0; | ||||
|  | ||||
|   /* Warp the input device pointer state. */ | ||||
|   clutter_evdev_warp_pointer (device, time_, x, y); | ||||
|  | ||||
|   /* Warp displayed pointer cursor. */ | ||||
|   meta_cursor_tracker_update_position (tracker, x, y); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -306,6 +336,19 @@ meta_backend_native_lock_layout_group (MetaBackend *backend, | ||||
|   g_signal_emit_by_name (backend, "keymap-layout-group-changed", idx, 0); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_backend_native_get_relative_motion_deltas (MetaBackend *backend, | ||||
|                                                 const        ClutterEvent *event, | ||||
|                                                 double       *dx, | ||||
|                                                 double       *dy, | ||||
|                                                 double       *dx_unaccel, | ||||
|                                                 double       *dy_unaccel) | ||||
| { | ||||
|   return clutter_evdev_event_get_relative_motion (event, | ||||
|                                                   dx, dy, | ||||
|                                                   dx_unaccel, dy_unaccel); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_backend_native_class_init (MetaBackendNativeClass *klass) | ||||
| { | ||||
| @@ -323,6 +366,7 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass) | ||||
|   backend_class->set_keymap = meta_backend_native_set_keymap; | ||||
|   backend_class->get_keymap = meta_backend_native_get_keymap; | ||||
|   backend_class->lock_layout_group = meta_backend_native_lock_layout_group; | ||||
|   backend_class->get_relative_motion_deltas = meta_backend_native_get_relative_motion_deltas; | ||||
| } | ||||
|  | ||||
| static void | ||||
|   | ||||
| @@ -93,126 +93,18 @@ next_serial (void) | ||||
|   return barrier_serial; | ||||
| } | ||||
|  | ||||
| typedef struct _Vector2 | ||||
| { | ||||
|   float x, y; | ||||
| } Vector2; | ||||
|  | ||||
| static float | ||||
| vector2_cross_product (Vector2 a, Vector2 b) | ||||
| { | ||||
|   return a.x * b.y - a.y * b.x; | ||||
| } | ||||
|  | ||||
| static Vector2 | ||||
| vector2_add (Vector2 a, Vector2 b) | ||||
| { | ||||
|   return (Vector2) { | ||||
|     .x = a.x + b.x, | ||||
|     .y = a.y + b.y, | ||||
|   }; | ||||
| } | ||||
|  | ||||
| static Vector2 | ||||
| vector2_subtract (Vector2 a, Vector2 b) | ||||
| { | ||||
|   return (Vector2) { | ||||
|     .x = a.x - b.x, | ||||
|     .y = a.y - b.y, | ||||
|   }; | ||||
| } | ||||
|  | ||||
| static Vector2 | ||||
| vector2_multiply_constant (float c, Vector2 a) | ||||
| { | ||||
|   return (Vector2) { | ||||
|     .x = c * a.x, | ||||
|     .y = c * a.y, | ||||
|   }; | ||||
| } | ||||
|  | ||||
| typedef struct _Line2 | ||||
| { | ||||
|   Vector2 a; | ||||
|   Vector2 b; | ||||
| } Line2; | ||||
|  | ||||
| static gboolean | ||||
| lines_intersect (Line2 *line1, Line2 *line2, Vector2 *intersection) | ||||
| { | ||||
|   Vector2 p = line1->a; | ||||
|   Vector2 r = vector2_subtract (line1->b, line1->a); | ||||
|   Vector2 q = line2->a; | ||||
|   Vector2 s = vector2_subtract (line2->b, line2->a); | ||||
|   float rxs; | ||||
|   float sxr; | ||||
|   float t; | ||||
|   float u; | ||||
|  | ||||
|   /* | ||||
|    * The line (p, r) and (q, s) intersects where | ||||
|    * | ||||
|    *   p + t r = q + u s | ||||
|    * | ||||
|    * Calculate t: | ||||
|    * | ||||
|    *   (p + t r) × s = (q + u s) × s | ||||
|    *   p × s + t (r × s) = q × s + u (s × s) | ||||
|    *   p × s + t (r × s) = q × s | ||||
|    *   t (r × s) = q × s - p × s | ||||
|    *   t (r × s) = (q - p) × s | ||||
|    *   t = ((q - p) × s) / (r × s) | ||||
|    * | ||||
|    * Using the same method, for u we get: | ||||
|    * | ||||
|    *   u = ((p - q) × r) / (s × r) | ||||
|    */ | ||||
|  | ||||
|   rxs = vector2_cross_product (r, s); | ||||
|   sxr = vector2_cross_product (s, r); | ||||
|  | ||||
|   /* If r × s = 0 then the lines are either parallel or collinear. */ | ||||
|   if (fabs ( rxs) < DBL_MIN) | ||||
|     return FALSE; | ||||
|  | ||||
|   t = vector2_cross_product (vector2_subtract (q, p), s) / rxs; | ||||
|   u = vector2_cross_product (vector2_subtract (p, q), r) / sxr; | ||||
|  | ||||
|  | ||||
|   /* The lines only intersect if 0 ≤ t ≤ 1 and 0 ≤ u ≤ 1. */ | ||||
|   if (t < 0.0 || t > 1.0 || u < 0.0 || u > 1.0) | ||||
|     return FALSE; | ||||
|  | ||||
|   *intersection = vector2_add (p, vector2_multiply_constant (t, r)); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| is_barrier_horizontal (MetaBarrier *barrier) | ||||
| { | ||||
|   return barrier->priv->y1 == barrier->priv->y2; | ||||
|   return meta_border_is_horizontal (&barrier->priv->border); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| is_barrier_blocking_directions (MetaBarrier         *barrier, | ||||
|                                 MetaBarrierDirection directions) | ||||
| { | ||||
|   /* Barriers doesn't block parallel motions. */ | ||||
|   if (is_barrier_horizontal (barrier)) | ||||
|     { | ||||
|       if ((directions & (META_BARRIER_DIRECTION_POSITIVE_Y | | ||||
|                          META_BARRIER_DIRECTION_NEGATIVE_Y)) == 0) | ||||
|         return FALSE; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if ((directions & (META_BARRIER_DIRECTION_POSITIVE_X | | ||||
|                          META_BARRIER_DIRECTION_NEGATIVE_X)) == 0) | ||||
|         return FALSE; | ||||
|     } | ||||
|  | ||||
|   return (barrier->priv->directions & directions) != directions; | ||||
|   return meta_border_is_blocking_directions (&barrier->priv->border, | ||||
|                                              directions); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -224,31 +116,16 @@ dismiss_pointer (MetaBarrierImplNative *self) | ||||
|   priv->state = META_BARRIER_STATE_LEFT; | ||||
| } | ||||
|  | ||||
| static Line2 | ||||
| barrier_to_line (MetaBarrier *barrier) | ||||
| { | ||||
|   return (Line2) { | ||||
|     .a = (Vector2) { | ||||
|       .x = MIN (barrier->priv->x1, barrier->priv->x2), | ||||
|       .y = MIN (barrier->priv->y1, barrier->priv->y2), | ||||
|     }, | ||||
|     .b = (Vector2) { | ||||
|       .x = MAX (barrier->priv->x1, barrier->priv->x2), | ||||
|       .y = MAX (barrier->priv->y1, barrier->priv->y2), | ||||
|     }, | ||||
|   }; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Calculate the hit box for a held motion. The hit box is a 2 px wide region | ||||
|  * in the opposite direction of every direction the barrier blocks. The purpose | ||||
|  * of this is to allow small movements without receiving a "left" signal. This | ||||
|  * heuristic comes from the X.org pointer barrier implementation. | ||||
|  */ | ||||
| static Line2 | ||||
| static MetaLine2 | ||||
| calculate_barrier_hit_box (MetaBarrier *barrier) | ||||
| { | ||||
|   Line2 hit_box = barrier_to_line (barrier); | ||||
|   MetaLine2 hit_box = barrier->priv->border.line; | ||||
|  | ||||
|   if (is_barrier_horizontal (barrier)) | ||||
|     { | ||||
| @@ -273,7 +150,8 @@ calculate_barrier_hit_box (MetaBarrier *barrier) | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| is_within_box (Line2 box, Vector2 point) | ||||
| is_within_box (MetaLine2   box, | ||||
|                MetaVector2 point) | ||||
| { | ||||
|   return (point.x >= box.a.x && point.x < box.b.x && | ||||
|           point.y >= box.a.y && point.y < box.b.y); | ||||
| @@ -288,8 +166,8 @@ maybe_release_barrier (gpointer key, | ||||
|   MetaBarrierImplNativePrivate *priv = | ||||
|     meta_barrier_impl_native_get_instance_private (self); | ||||
|   MetaBarrier *barrier = priv->barrier; | ||||
|   Line2 *motion = user_data; | ||||
|   Line2 hit_box; | ||||
|   MetaLine2 *motion = user_data; | ||||
|   MetaLine2 hit_box; | ||||
|  | ||||
|   if (priv->state != META_BARRIER_STATE_HELD) | ||||
|     return; | ||||
| @@ -297,8 +175,10 @@ maybe_release_barrier (gpointer key, | ||||
|   /* Release if we end up outside barrier end points. */ | ||||
|   if (is_barrier_horizontal (barrier)) | ||||
|     { | ||||
|       if (motion->b.x > MAX (barrier->priv->x1, barrier->priv->x2) || | ||||
|           motion->b.x < MIN (barrier->priv->x1, barrier->priv->x2)) | ||||
|       if (motion->b.x > MAX (barrier->priv->border.line.a.x, | ||||
|                              barrier->priv->border.line.b.x) || | ||||
|           motion->b.x < MIN (barrier->priv->border.line.a.x, | ||||
|                              barrier->priv->border.line.b.x)) | ||||
|         { | ||||
|           dismiss_pointer (self); | ||||
|           return; | ||||
| @@ -306,8 +186,10 @@ maybe_release_barrier (gpointer key, | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (motion->b.y > MAX (barrier->priv->y1, barrier->priv->y2) || | ||||
|           motion->b.y < MIN (barrier->priv->y1, barrier->priv->y2)) | ||||
|       if (motion->b.y > MAX (barrier->priv->border.line.a.y, | ||||
|                              barrier->priv->border.line.b.y) || | ||||
|           motion->b.y < MIN (barrier->priv->border.line.a.y, | ||||
|                              barrier->priv->border.line.b.y)) | ||||
|         { | ||||
|           dismiss_pointer (self); | ||||
|           return; | ||||
| @@ -330,7 +212,7 @@ maybe_release_barriers (MetaBarrierManagerNative *manager, | ||||
|                         float                     x, | ||||
|                         float                     y) | ||||
| { | ||||
|   Line2 motion = { | ||||
|   MetaLine2 motion = { | ||||
|     .a = { | ||||
|       .x = prev_x, | ||||
|       .y = prev_y, | ||||
| @@ -350,7 +232,7 @@ typedef struct _MetaClosestBarrierData | ||||
| { | ||||
|   struct | ||||
|   { | ||||
|     Line2                       motion; | ||||
|     MetaLine2                   motion; | ||||
|     MetaBarrierDirection        directions; | ||||
|   } in; | ||||
|  | ||||
| @@ -371,8 +253,7 @@ update_closest_barrier (gpointer key, | ||||
|     meta_barrier_impl_native_get_instance_private (self); | ||||
|   MetaBarrier *barrier = priv->barrier; | ||||
|   MetaClosestBarrierData *data = user_data; | ||||
|   Line2 barrier_line; | ||||
|   Vector2 intersection; | ||||
|   MetaVector2 intersection; | ||||
|   float dx, dy; | ||||
|   float distance_2; | ||||
|  | ||||
| @@ -391,17 +272,9 @@ update_closest_barrier (gpointer key, | ||||
|  | ||||
|   /* Check if the motion intersects with the barrier, and retrieve the | ||||
|    * intersection point if any. */ | ||||
|   barrier_line = (Line2) { | ||||
|     .a = { | ||||
|       .x = barrier->priv->x1, | ||||
|       .y = barrier->priv->y1 | ||||
|     }, | ||||
|     .b = { | ||||
|       .x = barrier->priv->x2, | ||||
|       .y = barrier->priv->y2 | ||||
|     }, | ||||
|   }; | ||||
|   if (!lines_intersect (&barrier_line, &data->in.motion, &intersection)) | ||||
|   if (!meta_line2_intersects_with (&barrier->priv->border.line, | ||||
|                                    &data->in.motion, | ||||
|                                    &intersection)) | ||||
|     return; | ||||
|  | ||||
|   /* Calculate the distance to the barrier and keep track of the closest | ||||
| @@ -570,9 +443,9 @@ clamp_to_barrier (MetaBarrierImplNative *self, | ||||
|   if (is_barrier_horizontal (barrier)) | ||||
|     { | ||||
|       if (*motion_dir & META_BARRIER_DIRECTION_POSITIVE_Y) | ||||
|         *y = barrier->priv->y1; | ||||
|         *y = barrier->priv->border.line.a.y; | ||||
|       else if (*motion_dir & META_BARRIER_DIRECTION_NEGATIVE_Y) | ||||
|         *y = barrier->priv->y1; | ||||
|         *y = barrier->priv->border.line.a.y; | ||||
|  | ||||
|       priv->blocked_dir = *motion_dir & (META_BARRIER_DIRECTION_POSITIVE_Y | | ||||
|                                          META_BARRIER_DIRECTION_NEGATIVE_Y); | ||||
| @@ -582,9 +455,9 @@ clamp_to_barrier (MetaBarrierImplNative *self, | ||||
|   else | ||||
|     { | ||||
|       if (*motion_dir & META_BARRIER_DIRECTION_POSITIVE_X) | ||||
|         *x = barrier->priv->x1; | ||||
|         *x = barrier->priv->border.line.a.x; | ||||
|       else if (*motion_dir & META_BARRIER_DIRECTION_NEGATIVE_X) | ||||
|         *x = barrier->priv->x1; | ||||
|         *x = barrier->priv->border.line.a.x; | ||||
|  | ||||
|       priv->blocked_dir = *motion_dir & (META_BARRIER_DIRECTION_POSITIVE_X | | ||||
|                                          META_BARRIER_DIRECTION_NEGATIVE_X); | ||||
|   | ||||
| @@ -102,9 +102,6 @@ meta_cursor_renderer_native_finalize (GObject *object) | ||||
|   if (priv->animation_timeout_id) | ||||
|     g_source_remove (priv->animation_timeout_id); | ||||
|  | ||||
|   if (priv->gbm) | ||||
|     gbm_device_destroy (priv->gbm); | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_cursor_renderer_native_parent_class)->finalize (object); | ||||
| } | ||||
|  | ||||
| @@ -672,7 +669,7 @@ meta_cursor_renderer_native_init (MetaCursorRendererNative *native) | ||||
|     { | ||||
|       CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (ctx)); | ||||
|       priv->drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer); | ||||
|       priv->gbm = gbm_create_device (priv->drm_fd); | ||||
|       priv->gbm = cogl_kms_renderer_get_gbm (cogl_renderer); | ||||
|  | ||||
|       uint64_t width, height; | ||||
|       if (drmGetCap (priv->drm_fd, DRM_CAP_CURSOR_WIDTH, &width) == 0 && | ||||
|   | ||||
| @@ -46,6 +46,12 @@ | ||||
| #include "meta-cursor-renderer-native.h" | ||||
| #include "meta-idle-monitor-native.h" | ||||
|  | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevClient, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevEnumerator, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC(Login1Session, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC(Login1Seat, g_object_unref) | ||||
|  | ||||
| struct _MetaLauncher | ||||
| { | ||||
|   Login1Session *session_proxy; | ||||
| @@ -58,8 +64,8 @@ static Login1Session * | ||||
| get_session_proxy (GCancellable *cancellable, | ||||
|                    GError      **error) | ||||
| { | ||||
|   char *proxy_path; | ||||
|   char *session_id; | ||||
|   g_autofree char *proxy_path = NULL; | ||||
|   g_autofree char *session_id = NULL; | ||||
|   Login1Session *session_proxy; | ||||
|  | ||||
|   if (sd_pid_get_session (getpid (), &session_id) < 0) | ||||
| @@ -81,8 +87,6 @@ get_session_proxy (GCancellable *cancellable, | ||||
|   if (!session_proxy) | ||||
|     g_prefix_error(error, "Could not get session proxy: "); | ||||
|  | ||||
|   free (proxy_path); | ||||
|  | ||||
|   return session_proxy; | ||||
| } | ||||
|  | ||||
| @@ -285,8 +289,8 @@ get_primary_gpu_path (const gchar *seat_name) | ||||
|   gchar *path = NULL; | ||||
|   GList *devices, *tmp; | ||||
|  | ||||
|   GUdevClient *gudev_client = g_udev_client_new (subsystems); | ||||
|   GUdevEnumerator *enumerator = g_udev_enumerator_new (gudev_client); | ||||
|   g_autoptr (GUdevClient) gudev_client = g_udev_client_new (subsystems); | ||||
|   g_autoptr (GUdevEnumerator) enumerator = g_udev_enumerator_new (gudev_client); | ||||
|  | ||||
|   g_udev_enumerator_add_match_name (enumerator, "card*"); | ||||
|   g_udev_enumerator_add_match_tag (enumerator, "seat"); | ||||
| @@ -297,7 +301,8 @@ get_primary_gpu_path (const gchar *seat_name) | ||||
|  | ||||
|   for (tmp = devices; tmp != NULL; tmp = tmp->next) | ||||
|     { | ||||
|       GUdevDevice *platform_device = NULL, *pci_device = NULL; | ||||
|       g_autoptr (GUdevDevice) platform_device = NULL; | ||||
|       g_autoptr (GUdevDevice) pci_device = NULL; | ||||
|       GUdevDevice *dev = tmp->data; | ||||
|       gint boot_vga; | ||||
|       const gchar *device_seat; | ||||
| @@ -328,7 +333,6 @@ get_primary_gpu_path (const gchar *seat_name) | ||||
|       if (platform_device != NULL) | ||||
|         { | ||||
|           path = g_strdup (g_udev_device_get_device_file (dev)); | ||||
|           g_object_unref (platform_device); | ||||
|           break; | ||||
|         } | ||||
|  | ||||
| @@ -343,17 +347,12 @@ get_primary_gpu_path (const gchar *seat_name) | ||||
|               path = g_strdup (g_udev_device_get_device_file (dev)); | ||||
|               break; | ||||
|             } | ||||
|  | ||||
|           g_object_unref (pci_device); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   g_list_free_full (devices, g_object_unref); | ||||
|  | ||||
| out: | ||||
|   g_object_unref (enumerator); | ||||
|   g_object_unref (gudev_client); | ||||
|  | ||||
|   return path; | ||||
| } | ||||
|  | ||||
| @@ -399,7 +398,8 @@ get_kms_fd (Login1Session *session_proxy, | ||||
| static gchar * | ||||
| get_seat_id (GError **error) | ||||
| { | ||||
|   char *session_id, *seat_id; | ||||
|   g_autofree char *session_id = NULL; | ||||
|   char *seat_id = NULL; | ||||
|   int r; | ||||
|  | ||||
|   r = sd_pid_get_session (0, &session_id); | ||||
| @@ -413,8 +413,6 @@ get_seat_id (GError **error) | ||||
|     } | ||||
|  | ||||
|   r = sd_session_get_seat (session_id, &seat_id); | ||||
|   free (session_id); | ||||
|  | ||||
|   if (r < 0) | ||||
|     { | ||||
|       g_set_error (error, | ||||
| @@ -431,9 +429,9 @@ MetaLauncher * | ||||
| meta_launcher_new (GError **error) | ||||
| { | ||||
|   MetaLauncher *self = NULL; | ||||
|   Login1Session *session_proxy = NULL; | ||||
|   Login1Seat *seat_proxy = NULL; | ||||
|   char *seat_id = NULL; | ||||
|   g_autoptr (Login1Session) session_proxy = NULL; | ||||
|   g_autoptr (Login1Seat) seat_proxy = NULL; | ||||
|   g_autofree char *seat_id = NULL; | ||||
|   gboolean have_control = FALSE; | ||||
|   int kms_fd; | ||||
|  | ||||
| @@ -460,11 +458,9 @@ meta_launcher_new (GError **error) | ||||
|   if (!get_kms_fd (session_proxy, seat_id, &kms_fd, error)) | ||||
|     goto fail; | ||||
|  | ||||
|   free (seat_id); | ||||
|  | ||||
|   self = g_slice_new0 (MetaLauncher); | ||||
|   self->session_proxy = session_proxy; | ||||
|   self->seat_proxy = seat_proxy; | ||||
|   self->session_proxy = g_object_ref (session_proxy); | ||||
|   self->seat_proxy = g_object_ref (seat_proxy); | ||||
|  | ||||
|   self->session_active = TRUE; | ||||
|  | ||||
| @@ -479,10 +475,6 @@ meta_launcher_new (GError **error) | ||||
|  fail: | ||||
|   if (have_control) | ||||
|     login1_session_call_release_control_sync (session_proxy, NULL, NULL); | ||||
|   g_clear_object (&session_proxy); | ||||
|   g_clear_object (&seat_proxy); | ||||
|   free (seat_id); | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -107,6 +107,7 @@ meta_barrier_impl_x11_new (MetaBarrier *barrier) | ||||
|   MetaDisplay *display = barrier->priv->display; | ||||
|   Display *dpy; | ||||
|   Window root; | ||||
|   unsigned int allowed_motion_dirs; | ||||
|  | ||||
|   if (display == NULL) | ||||
|     { | ||||
| @@ -121,12 +122,14 @@ meta_barrier_impl_x11_new (MetaBarrier *barrier) | ||||
|   dpy = display->xdisplay; | ||||
|   root = DefaultRootWindow (dpy); | ||||
|  | ||||
|   allowed_motion_dirs = | ||||
|     meta_border_get_allows_directions (&barrier->priv->border); | ||||
|   priv->xbarrier = XFixesCreatePointerBarrier (dpy, root, | ||||
|                                                barrier->priv->x1, | ||||
|                                                barrier->priv->y1, | ||||
|                                                barrier->priv->x2, | ||||
|                                                barrier->priv->y2, | ||||
|                                                barrier->priv->directions, | ||||
|                                                barrier->priv->border.line.a.x, | ||||
|                                                barrier->priv->border.line.a.y, | ||||
|                                                barrier->priv->border.line.b.x, | ||||
|                                                barrier->priv->border.line.b.y, | ||||
|                                                allowed_motion_dirs, | ||||
|                                                0, NULL); | ||||
|  | ||||
|   g_hash_table_insert (display->xids, &priv->xbarrier, barrier); | ||||
|   | ||||
| @@ -60,4 +60,7 @@ void     meta_end_modal_for_plugin   (MetaCompositor   *compositor, | ||||
| gint64 meta_compositor_monotonic_time_to_server_time (MetaDisplay *display, | ||||
|                                                       gint64       monotonic_time); | ||||
|  | ||||
| void meta_compositor_flash_window (MetaCompositor *compositor, | ||||
|                                    MetaWindow     *window); | ||||
|  | ||||
| #endif /* META_COMPOSITOR_PRIVATE_H */ | ||||
|   | ||||
| @@ -1249,6 +1249,48 @@ meta_compositor_flash_screen (MetaCompositor *compositor, | ||||
|   clutter_actor_restore_easing_state (flash); | ||||
| } | ||||
|  | ||||
| static void | ||||
| window_flash_out_completed (ClutterTimeline *timeline, | ||||
|                             gboolean         is_finished, | ||||
|                             gpointer         user_data) | ||||
| { | ||||
|   ClutterActor *flash = CLUTTER_ACTOR (user_data); | ||||
|   clutter_actor_destroy (flash); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_compositor_flash_window (MetaCompositor *compositor, | ||||
|                               MetaWindow     *window) | ||||
| { | ||||
|   ClutterActor *window_actor = | ||||
|     CLUTTER_ACTOR (meta_window_get_compositor_private (window)); | ||||
|   ClutterActor *flash; | ||||
|   ClutterTransition *transition; | ||||
|  | ||||
|   flash = clutter_actor_new (); | ||||
|   clutter_actor_set_background_color (flash, CLUTTER_COLOR_Black); | ||||
|   clutter_actor_set_size (flash, window->rect.width, window->rect.height); | ||||
|   clutter_actor_set_position (flash, | ||||
|                               window->custom_frame_extents.left, | ||||
|                               window->custom_frame_extents.top); | ||||
|   clutter_actor_set_opacity (flash, 0); | ||||
|   clutter_actor_add_child (window_actor, flash); | ||||
|  | ||||
|   clutter_actor_save_easing_state (flash); | ||||
|   clutter_actor_set_easing_mode (flash, CLUTTER_EASE_IN_QUAD); | ||||
|   clutter_actor_set_easing_duration (flash, FLASH_TIME_MS); | ||||
|   clutter_actor_set_opacity (flash, 192); | ||||
|  | ||||
|   transition = clutter_actor_get_transition (flash, "opacity"); | ||||
|   clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (transition), TRUE); | ||||
|   clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), 2); | ||||
|  | ||||
|   g_signal_connect (transition, "stopped", | ||||
|                     G_CALLBACK (window_flash_out_completed), flash); | ||||
|  | ||||
|   clutter_actor_restore_easing_state (flash); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_compositor_monotonic_time_to_server_time: | ||||
|  * @display: a #MetaDisplay | ||||
|   | ||||
| @@ -36,5 +36,6 @@ void meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex, | ||||
|                                             guint              fallback_width, | ||||
|                                             guint              fallback_height); | ||||
| gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self); | ||||
| cairo_region_t * meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -303,6 +303,7 @@ set_cogl_texture (MetaShapedTexture *stex, | ||||
|     { | ||||
|       priv->tex_width = width; | ||||
|       priv->tex_height = height; | ||||
|       meta_shaped_texture_set_mask_texture (stex, NULL); | ||||
|       clutter_actor_queue_relayout (CLUTTER_ACTOR (stex)); | ||||
|       g_signal_emit (stex, signals[SIZE_CHANGED], 0); | ||||
|     } | ||||
| @@ -789,6 +790,13 @@ meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex, | ||||
|     priv->opaque_region = NULL; | ||||
| } | ||||
|  | ||||
| cairo_region_t * | ||||
| meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex) | ||||
| { | ||||
|   MetaShapedTexturePrivate *priv = stex->priv; | ||||
|   return priv->opaque_region; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_shaped_texture_get_image: | ||||
|  * @stex: A #MetaShapedTexture | ||||
|   | ||||
| @@ -36,6 +36,14 @@ | ||||
|  | ||||
| #include "compositor/region-utils.h" | ||||
|  | ||||
| enum { | ||||
|   PAINTING, | ||||
|  | ||||
|   LAST_SIGNAL | ||||
| }; | ||||
|  | ||||
| static guint signals[LAST_SIGNAL]; | ||||
|  | ||||
| struct _MetaSurfaceActorWaylandPrivate | ||||
| { | ||||
|   MetaWaylandSurface *surface; | ||||
| @@ -128,7 +136,8 @@ meta_surface_actor_wayland_get_subsurface_rect (MetaSurfaceActorWayland *self, | ||||
|                                                 MetaRectangle           *rect) | ||||
| { | ||||
|   MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self); | ||||
|   CoglTexture *texture = surface->buffer->texture; | ||||
|   MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface); | ||||
|   CoglTexture *texture = buffer->texture; | ||||
|   MetaWindow *toplevel_window; | ||||
|   int monitor_scale; | ||||
|   float x, y; | ||||
| @@ -347,12 +356,13 @@ meta_surface_actor_wayland_paint (ClutterActor *actor) | ||||
|   if (priv->surface) | ||||
|     { | ||||
|       MetaWaylandCompositor *compositor = priv->surface->compositor; | ||||
|       meta_wayland_surface_update_outputs (priv->surface); | ||||
|  | ||||
|       wl_list_insert_list (&compositor->frame_callbacks, &priv->frame_callback_list); | ||||
|       wl_list_init (&priv->frame_callback_list); | ||||
|     } | ||||
|  | ||||
|   g_signal_emit (actor, signals[PAINTING], 0); | ||||
|  | ||||
|   CLUTTER_ACTOR_CLASS (meta_surface_actor_wayland_parent_class)->paint (actor); | ||||
| } | ||||
|  | ||||
| @@ -388,6 +398,13 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass) | ||||
|   surface_actor_class->get_window = meta_surface_actor_wayland_get_window; | ||||
|  | ||||
|   object_class->dispose = meta_surface_actor_wayland_dispose; | ||||
|  | ||||
|   signals[PAINTING] = g_signal_new ("painting", | ||||
|                                     G_TYPE_FROM_CLASS (object_class), | ||||
|                                     G_SIGNAL_RUN_LAST, | ||||
|                                     0, | ||||
|                                     NULL, NULL, NULL, | ||||
|                                     G_TYPE_NONE, 0); | ||||
| } | ||||
|  | ||||
| static void | ||||
|   | ||||
| @@ -238,6 +238,33 @@ meta_surface_actor_x11_is_visible (MetaSurfaceActor *actor) | ||||
|   return is_visible (self); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_surface_actor_x11_is_opaque (MetaSurfaceActor *actor) | ||||
| { | ||||
|   MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); | ||||
|   MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self); | ||||
|  | ||||
|   /* If we're not ARGB32, then we're opaque. */ | ||||
|   if (!meta_surface_actor_is_argb32 (actor)) | ||||
|     return TRUE; | ||||
|  | ||||
|   cairo_region_t *opaque_region = meta_surface_actor_get_opaque_region (actor); | ||||
|  | ||||
|   /* If we have no opaque region, then no pixels are opaque. */ | ||||
|   if (!opaque_region) | ||||
|     return FALSE; | ||||
|  | ||||
|   MetaWindow *window = priv->window; | ||||
|   cairo_rectangle_int_t client_area; | ||||
|   meta_window_get_client_area_rect (window, &client_area); | ||||
|  | ||||
|   /* Otherwise, check if our opaque region covers our entire surface. */ | ||||
|   if (cairo_region_contains_rectangle (opaque_region, &client_area) == CAIRO_REGION_OVERLAP_IN) | ||||
|     return TRUE; | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_surface_actor_x11_should_unredirect (MetaSurfaceActor *actor) | ||||
| { | ||||
| @@ -255,15 +282,15 @@ meta_surface_actor_x11_should_unredirect (MetaSurfaceActor *actor) | ||||
|   if (window->shape_region != NULL) | ||||
|     return FALSE; | ||||
|  | ||||
|   if (meta_surface_actor_is_argb32 (actor) && !meta_window_requested_bypass_compositor (window)) | ||||
|     return FALSE; | ||||
|  | ||||
|   if (!meta_window_is_monitor_sized (window)) | ||||
|     return FALSE; | ||||
|  | ||||
|   if (meta_window_requested_bypass_compositor (window)) | ||||
|     return TRUE; | ||||
|  | ||||
|   if (!meta_surface_actor_x11_is_opaque (actor)) | ||||
|     return FALSE; | ||||
|  | ||||
|   if (meta_window_is_override_redirect (window)) | ||||
|     return TRUE; | ||||
|  | ||||
|   | ||||
| @@ -235,6 +235,13 @@ meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, | ||||
|   meta_shaped_texture_set_opaque_region (priv->texture, region); | ||||
| } | ||||
|  | ||||
| cairo_region_t * | ||||
| meta_surface_actor_get_opaque_region (MetaSurfaceActor *actor) | ||||
| { | ||||
|   MetaSurfaceActorPrivate *priv = actor->priv; | ||||
|   return meta_shaped_texture_get_opaque_region (priv->texture); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| is_frozen (MetaSurfaceActor *self) | ||||
| { | ||||
|   | ||||
| @@ -60,6 +60,7 @@ void meta_surface_actor_set_input_region (MetaSurfaceActor *self, | ||||
|                                           cairo_region_t   *region); | ||||
| void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, | ||||
|                                            cairo_region_t   *region); | ||||
| cairo_region_t * meta_surface_actor_get_opaque_region (MetaSurfaceActor *self); | ||||
|  | ||||
| void meta_surface_actor_process_damage (MetaSurfaceActor *actor, | ||||
|                                         int x, int y, int width, int height); | ||||
|   | ||||
| @@ -817,13 +817,6 @@ meta_window_actor_has_shadow (MetaWindowActor *self) | ||||
|       meta_window_is_fullscreen (priv->window)) | ||||
|     return FALSE; | ||||
|  | ||||
|   /* | ||||
|    * If we have two snap-tiled windows, we don't want the shadow to obstruct | ||||
|    * the other window. | ||||
|    */ | ||||
|   if (meta_window_get_tile_match (priv->window)) | ||||
|     return FALSE; | ||||
|  | ||||
|   /* | ||||
|    * Always put a shadow around windows with a frame - This should override | ||||
|    * the restriction about not putting a shadow around ARGB windows. | ||||
|   | ||||
| @@ -52,6 +52,7 @@ | ||||
| #include "screen-private.h" | ||||
| #include "window-private.h" | ||||
| #include "util-private.h" | ||||
| #include "compositor/compositor-private.h" | ||||
| #include <meta/prefs.h> | ||||
| #include <meta/compositor.h> | ||||
| #ifdef HAVE_LIBCANBERRA | ||||
| @@ -131,6 +132,12 @@ bell_flash_window_frame (MetaWindow *window) | ||||
|   g_source_set_name_by_id (id, "[mutter] bell_unflash_frame"); | ||||
| } | ||||
|  | ||||
| static void | ||||
| bell_flash_window (MetaWindow *window) | ||||
| { | ||||
|   meta_compositor_flash_window (window->display->compositor, window); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * bell_flash_frame: | ||||
|  * @display:  The display the bell event came in on | ||||
| @@ -145,6 +152,8 @@ bell_flash_frame (MetaDisplay *display, | ||||
| { | ||||
|   if (window && window->frame) | ||||
|     bell_flash_window_frame (window); | ||||
|   else if (window) | ||||
|     bell_flash_window (window); | ||||
|   else | ||||
|     bell_flash_fullscreen (display); | ||||
| } | ||||
| @@ -203,33 +212,18 @@ bell_audible_notify (MetaDisplay *display, | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| void | ||||
| gboolean | ||||
| meta_bell_notify (MetaDisplay *display, | ||||
| 		  XkbAnyEvent *xkb_ev) | ||||
|                   MetaWindow  *window) | ||||
| { | ||||
|   MetaWindow *window; | ||||
|   XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent*) xkb_ev; | ||||
|  | ||||
|   window = meta_display_lookup_x_window (display, xkb_bell_event->window); | ||||
|   if (!window && display->focus_window && display->focus_window->frame) | ||||
|     window = display->focus_window; | ||||
|  | ||||
|   /* flash something */ | ||||
|   if (meta_prefs_get_visual_bell ()) | ||||
|     bell_visual_notify (display, window); | ||||
|  | ||||
|   if (meta_prefs_bell_is_audible ()) | ||||
|     { | ||||
|       if (!bell_audible_notify (display, window)) | ||||
|         { | ||||
|           /* Force a classic bell if the libcanberra bell failed. */ | ||||
|           XkbForceDeviceBell (display->xdisplay, | ||||
|                               xkb_bell_event->device, | ||||
|                               xkb_bell_event->bell_class, | ||||
|                               xkb_bell_event->bell_id, | ||||
|                               xkb_bell_event->percent); | ||||
|         } | ||||
|     } | ||||
|     return bell_audible_notify (display, window); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| void | ||||
|   | ||||
| @@ -25,15 +25,14 @@ | ||||
| /** | ||||
|  * meta_bell_notify: | ||||
|  * @display: The display the bell event came in on | ||||
|  * @xkb_ev: The bell event we just received | ||||
|  * @window: The window the bell event was received on | ||||
|  * | ||||
|  * Gives the user some kind of visual bell; in fact, this is our response | ||||
|  * to any kind of bell request, but we set it up so that we only get | ||||
|  * notified about visual bells, and X deals with audible ones. | ||||
|  * | ||||
|  * If the configure script found we had no XKB, this does not exist. | ||||
|  * Gives the user some kind of aural or visual feedback, such as a bell sound | ||||
|  * or flash. What type of feedback is invoked depends on the configuration. | ||||
|  * If the aural feedback could not be invoked, FALSE is returned. | ||||
|  */ | ||||
| void meta_bell_notify (MetaDisplay *display, XkbAnyEvent *xkb_ev); | ||||
| gboolean meta_bell_notify (MetaDisplay *display, | ||||
|                            MetaWindow  *window); | ||||
|  | ||||
| /** | ||||
|  * meta_bell_set_audible: | ||||
|   | ||||
| @@ -97,7 +97,7 @@ typedef enum | ||||
|   PRIORITY_ENTIRELY_VISIBLE_ON_WORKAREA = 1, | ||||
|   PRIORITY_SIZE_HINTS_INCREMENTS = 1, | ||||
|   PRIORITY_MAXIMIZATION = 2, | ||||
|   PRIORITY_TILING = 2, | ||||
|   PRIORITY_CONSTRAINED_EDGES = 2, | ||||
|   PRIORITY_FULLSCREEN = 2, | ||||
|   PRIORITY_SIZE_HINTS_LIMITS = 3, | ||||
|   PRIORITY_TITLEBAR_VISIBLE = 4, | ||||
| @@ -152,7 +152,7 @@ static gboolean constrain_maximization       (MetaWindow         *window, | ||||
|                                               ConstraintInfo     *info, | ||||
|                                               ConstraintPriority  priority, | ||||
|                                               gboolean            check_only); | ||||
| static gboolean constrain_tiling             (MetaWindow         *window, | ||||
| static gboolean constrain_constrained_edges  (MetaWindow         *window, | ||||
|                                               ConstraintInfo     *info, | ||||
|                                               ConstraintPriority  priority, | ||||
|                                               gboolean            check_only); | ||||
| @@ -213,7 +213,7 @@ typedef struct { | ||||
| static const Constraint all_constraints[] = { | ||||
|   {constrain_modal_dialog,       "constrain_modal_dialog"}, | ||||
|   {constrain_maximization,       "constrain_maximization"}, | ||||
|   {constrain_tiling,             "constrain_tiling"}, | ||||
|   {constrain_constrained_edges,  "constrain_constrained_edges"}, | ||||
|   {constrain_fullscreen,         "constrain_fullscreen"}, | ||||
|   {constrain_size_increments,    "constrain_size_increments"}, | ||||
|   {constrain_size_limits,        "constrain_size_limits"}, | ||||
| @@ -701,16 +701,11 @@ constrain_maximization (MetaWindow         *window, | ||||
|     return TRUE; | ||||
|  | ||||
|   /* Determine whether constraint applies; exit if it doesn't */ | ||||
|   if ((!window->maximized_horizontally && !window->maximized_vertically) || | ||||
|       META_WINDOW_TILED_SIDE_BY_SIDE (window)) | ||||
|   if (!window->maximized_horizontally && !window->maximized_vertically) | ||||
|     return TRUE; | ||||
|  | ||||
|   /* Calculate target_size = maximized size of (window + frame) */ | ||||
|   if (META_WINDOW_TILED_MAXIMIZED (window)) | ||||
|     { | ||||
|       meta_window_get_current_tile_area (window, &target_size); | ||||
|     } | ||||
|   else if (META_WINDOW_MAXIMIZED (window)) | ||||
|   if (META_WINDOW_MAXIMIZED (window)) | ||||
|     { | ||||
|       target_size = info->work_area_monitor; | ||||
|     } | ||||
| @@ -773,58 +768,6 @@ constrain_maximization (MetaWindow         *window, | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| constrain_tiling (MetaWindow         *window, | ||||
|                   ConstraintInfo     *info, | ||||
|                   ConstraintPriority  priority, | ||||
|                   gboolean            check_only) | ||||
| { | ||||
|   MetaRectangle target_size; | ||||
|   MetaRectangle min_size, max_size; | ||||
|   gboolean hminbad, vminbad; | ||||
|   gboolean horiz_equal, vert_equal; | ||||
|   gboolean constraint_already_satisfied; | ||||
|  | ||||
|   if (priority > PRIORITY_TILING) | ||||
|     return TRUE; | ||||
|  | ||||
|   /* Determine whether constraint applies; exit if it doesn't */ | ||||
|   if (!META_WINDOW_TILED_SIDE_BY_SIDE (window)) | ||||
|     return TRUE; | ||||
|  | ||||
|   /* Calculate target_size - as the tile previews need this as well, we | ||||
|    * use an external function for the actual calculation | ||||
|    */ | ||||
|   meta_window_get_current_tile_area (window, &target_size); | ||||
|  | ||||
|   /* Check min size constraints; max size constraints are ignored as for | ||||
|    * maximized windows. | ||||
|    */ | ||||
|   get_size_limits (window, &min_size, &max_size); | ||||
|   hminbad = target_size.width < min_size.width; | ||||
|   vminbad = target_size.height < min_size.height; | ||||
|   if (hminbad || vminbad) | ||||
|     return TRUE; | ||||
|  | ||||
|   /* Determine whether constraint is already satisfied; exit if it is */ | ||||
|   horiz_equal = target_size.x      == info->current.x && | ||||
|                 target_size.width  == info->current.width; | ||||
|   vert_equal  = target_size.y      == info->current.y && | ||||
|                 target_size.height == info->current.height; | ||||
|   constraint_already_satisfied = horiz_equal && vert_equal; | ||||
|   if (check_only || constraint_already_satisfied) | ||||
|     return constraint_already_satisfied; | ||||
|  | ||||
|   /*** Enforce constraint ***/ | ||||
|   info->current.x      = target_size.x; | ||||
|   info->current.width  = target_size.width; | ||||
|   info->current.y      = target_size.y; | ||||
|   info->current.height = target_size.height; | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
|  | ||||
| static gboolean | ||||
| constrain_fullscreen (MetaWindow         *window, | ||||
|                       ConstraintInfo     *info, | ||||
| @@ -860,6 +803,45 @@ constrain_fullscreen (MetaWindow         *window, | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| constrain_constrained_edges (MetaWindow         *window, | ||||
|                              ConstraintInfo     *info, | ||||
|                              ConstraintPriority  priority, | ||||
|                              gboolean            check_only) | ||||
| { | ||||
|   MetaRectangle monitor, new_rectangle; | ||||
|   gboolean constraint_already_satisfied; | ||||
|  | ||||
|   if (priority > PRIORITY_CONSTRAINED_EDGES) | ||||
|     return TRUE; | ||||
|  | ||||
|   /* Determine whether constraint applies; exit if it doesn't */ | ||||
|   if (!window->constrained_edges) | ||||
|     return TRUE; | ||||
|  | ||||
|   new_rectangle = info->current; | ||||
|   monitor = info->work_area_monitor; | ||||
|  | ||||
|   if (window->constrained_edges & META_DIRECTION_LEFT) | ||||
|     new_rectangle.x = monitor.x; | ||||
|   if (window->constrained_edges & META_DIRECTION_RIGHT) | ||||
|     new_rectangle.x = monitor.x + monitor.width - new_rectangle.width; | ||||
|   if (window->constrained_edges & META_DIRECTION_TOP) | ||||
|     new_rectangle.y = monitor.y; | ||||
|   if (window->constrained_edges & META_DIRECTION_BOTTOM) | ||||
|     new_rectangle.y = monitor.y + monitor.height - new_rectangle.height; | ||||
|  | ||||
|   constraint_already_satisfied = | ||||
|     meta_rectangle_equal (&info->current, &new_rectangle); | ||||
|  | ||||
|   if (check_only || constraint_already_satisfied) | ||||
|     return constraint_already_satisfied; | ||||
|  | ||||
|   /*** Enforce constraint ***/ | ||||
|   info->current = new_rectangle; | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| constrain_size_increments (MetaWindow         *window, | ||||
|                            ConstraintInfo     *info, | ||||
| @@ -877,7 +859,6 @@ constrain_size_increments (MetaWindow         *window, | ||||
|  | ||||
|   /* Determine whether constraint applies; exit if it doesn't */ | ||||
|   if (META_WINDOW_MAXIMIZED (window) || window->fullscreen || | ||||
|       META_WINDOW_TILED_SIDE_BY_SIDE (window) || | ||||
|       info->action_type == ACTION_MOVE) | ||||
|     return TRUE; | ||||
|  | ||||
| @@ -1020,7 +1001,6 @@ constrain_aspect_ratio (MetaWindow         *window, | ||||
|   constraints_are_inconsistent = minr > maxr; | ||||
|   if (constraints_are_inconsistent || | ||||
|       META_WINDOW_MAXIMIZED (window) || window->fullscreen || | ||||
|       META_WINDOW_TILED_SIDE_BY_SIDE (window) || | ||||
|       info->action_type == ACTION_MOVE) | ||||
|     return TRUE; | ||||
|  | ||||
|   | ||||
| @@ -35,6 +35,7 @@ | ||||
| #include <meta/boxes.h> | ||||
| #include <meta/display.h> | ||||
| #include "keybindings-private.h" | ||||
| #include "startup-notification-private.h" | ||||
| #include "meta-gesture-tracker-private.h" | ||||
| #include <meta/prefs.h> | ||||
| #include <meta/barrier.h> | ||||
| @@ -73,13 +74,6 @@ typedef enum { | ||||
|  */ | ||||
| #define N_IGNORED_CROSSING_SERIALS  10 | ||||
|  | ||||
| typedef enum { | ||||
|   META_TILE_NONE, | ||||
|   META_TILE_LEFT, | ||||
|   META_TILE_RIGHT, | ||||
|   META_TILE_MAXIMIZED | ||||
| } MetaTileMode; | ||||
|  | ||||
| typedef enum { | ||||
|   /* Normal interaction where you're interacting with windows. | ||||
|    * Events go to windows normally. */ | ||||
| @@ -210,8 +204,6 @@ struct _MetaDisplay | ||||
|   int         grab_anchor_root_x; | ||||
|   int         grab_anchor_root_y; | ||||
|   MetaRectangle grab_anchor_window_pos; | ||||
|   MetaTileMode  grab_tile_mode; | ||||
|   int           grab_tile_monitor_number; | ||||
|   int         grab_latest_motion_x; | ||||
|   int         grab_latest_motion_y; | ||||
|   guint       grab_have_pointer : 1; | ||||
| @@ -276,9 +268,8 @@ struct _MetaDisplay | ||||
|   int xinput_event_base; | ||||
|   int xinput_opcode; | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
|   SnDisplay *sn_display; | ||||
| #endif | ||||
|   MetaStartupNotification *startup_notification; | ||||
|  | ||||
|   int xsync_event_base; | ||||
|   int xsync_error_base; | ||||
|   int shape_event_base; | ||||
|   | ||||
| @@ -400,28 +400,6 @@ meta_display_remove_pending_pings_for_window (MetaDisplay *display, | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
| static void | ||||
| sn_error_trap_push (SnDisplay *sn_display, | ||||
|                     Display   *xdisplay) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   display = meta_display_for_x_display (xdisplay); | ||||
|   if (display != NULL) | ||||
|     meta_error_trap_push (display); | ||||
| } | ||||
|  | ||||
| static void | ||||
| sn_error_trap_pop (SnDisplay *sn_display, | ||||
|                    Display   *xdisplay) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   display = meta_display_for_x_display (xdisplay); | ||||
|   if (display != NULL) | ||||
|     meta_error_trap_pop (display); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static void | ||||
| enable_compositor (MetaDisplay *display) | ||||
| { | ||||
| @@ -527,6 +505,20 @@ gesture_tracker_state_changed (MetaGestureTracker   *tracker, | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| on_startup_notification_changed (MetaStartupNotification *sn, | ||||
|                                  gpointer                 sequence, | ||||
|                                  MetaDisplay             *display) | ||||
| { | ||||
|   if (!display->screen) | ||||
|     return; | ||||
|  | ||||
|   g_slist_free (display->screen->startup_sequences); | ||||
|   display->screen->startup_sequences = | ||||
|     meta_startup_notification_get_sequences (display->startup_notification); | ||||
|   g_signal_emit_by_name (display->screen, "startup-sequence-changed", sequence); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_display_open: | ||||
|  * | ||||
| @@ -630,12 +622,6 @@ meta_display_open (void) | ||||
|  | ||||
|   display->screen = NULL; | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
|   display->sn_display = sn_display_new (display->xdisplay, | ||||
|                                         sn_error_trap_push, | ||||
|                                         sn_error_trap_pop); | ||||
| #endif | ||||
|  | ||||
|   /* Get events */ | ||||
|   meta_display_init_events (display); | ||||
|   meta_display_init_events_x11 (display); | ||||
| @@ -663,8 +649,6 @@ meta_display_open (void) | ||||
|  | ||||
|   display->grab_op = META_GRAB_OP_NONE; | ||||
|   display->grab_window = NULL; | ||||
|   display->grab_tile_mode = META_TILE_NONE; | ||||
|   display->grab_tile_monitor_number = -1; | ||||
|  | ||||
|   display->grab_edge_resistance_data = NULL; | ||||
|  | ||||
| @@ -916,6 +900,10 @@ meta_display_open (void) | ||||
|  | ||||
|   display->screen = screen; | ||||
|  | ||||
|   display->startup_notification = meta_startup_notification_get (display); | ||||
|   g_signal_connect (display->startup_notification, "changed", | ||||
|                     G_CALLBACK (on_startup_notification_changed), display); | ||||
|  | ||||
|   meta_screen_init_workspaces (screen); | ||||
|  | ||||
|   enable_compositor (display); | ||||
| @@ -1100,6 +1088,7 @@ meta_display_close (MetaDisplay *display, | ||||
|  | ||||
|   meta_display_remove_autoraise_callback (display); | ||||
|  | ||||
|   g_clear_object (&display->startup_notification); | ||||
|   g_clear_object (&display->gesture_tracker); | ||||
|  | ||||
|   if (display->focus_timeout_id) | ||||
| @@ -1112,14 +1101,6 @@ meta_display_close (MetaDisplay *display, | ||||
|  | ||||
|   meta_screen_free (display->screen, timestamp); | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
|   if (display->sn_display) | ||||
|     { | ||||
|       sn_display_unref (display->sn_display); | ||||
|       display->sn_display = NULL; | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|   /* Must be after all calls to meta_window_unmanage() since they | ||||
|    * unregister windows | ||||
|    */ | ||||
| @@ -1229,7 +1210,7 @@ meta_grab_op_is_moving (MetaGrabOp op) | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_grab_op_windows_are_interactable: | ||||
|  * meta_display_windows_are_interactable: | ||||
|  * @op: A #MetaGrabOp | ||||
|  * | ||||
|  * Whether windows can be interacted with. | ||||
| @@ -1911,8 +1892,6 @@ meta_display_begin_grab_op (MetaDisplay *display, | ||||
|   display->grab_op = op; | ||||
|   display->grab_window = grab_window; | ||||
|   display->grab_button = button; | ||||
|   display->grab_tile_mode = grab_window->tile_mode; | ||||
|   display->grab_tile_monitor_number = grab_window->tile_monitor_number; | ||||
|   display->grab_anchor_root_x = root_x; | ||||
|   display->grab_anchor_root_y = root_y; | ||||
|   display->grab_latest_motion_x = root_x; | ||||
| @@ -2010,8 +1989,6 @@ meta_display_end_grab_op (MetaDisplay *display, | ||||
|  | ||||
|   display->event_route = META_EVENT_ROUTE_NORMAL; | ||||
|   display->grab_window = NULL; | ||||
|   display->grab_tile_mode = META_TILE_NONE; | ||||
|   display->grab_tile_monitor_number = -1; | ||||
|  | ||||
|   meta_display_update_cursor (display); | ||||
|  | ||||
|   | ||||
| @@ -274,12 +274,6 @@ meta_frame_get_flags (MetaFrame *frame) | ||||
|   if (META_WINDOW_MAXIMIZED (frame->window)) | ||||
|     flags |= META_FRAME_MAXIMIZED; | ||||
|  | ||||
|   if (META_WINDOW_TILED_LEFT (frame->window)) | ||||
|     flags |= META_FRAME_TILED_LEFT; | ||||
|  | ||||
|   if (META_WINDOW_TILED_RIGHT (frame->window)) | ||||
|     flags |= META_FRAME_TILED_RIGHT; | ||||
|  | ||||
|   if (frame->window->fullscreen) | ||||
|     flags |= META_FRAME_FULLSCREEN; | ||||
|  | ||||
| @@ -289,6 +283,18 @@ meta_frame_get_flags (MetaFrame *frame) | ||||
|   if (frame->window->wm_state_above) | ||||
|     flags |= META_FRAME_ABOVE; | ||||
|  | ||||
|   if (frame->window->constrained_edges & META_DIRECTION_LEFT) | ||||
|     flags |= META_FRAME_CONSTRAINED_LEFT_EDGE; | ||||
|  | ||||
|   if (frame->window->constrained_edges & META_DIRECTION_RIGHT) | ||||
|     flags |= META_FRAME_CONSTRAINED_RIGHT_EDGE; | ||||
|  | ||||
|   if (frame->window->constrained_edges & META_DIRECTION_TOP) | ||||
|     flags |= META_FRAME_CONSTRAINED_TOP_EDGE; | ||||
|  | ||||
|   if (frame->window->constrained_edges & META_DIRECTION_BOTTOM) | ||||
|     flags |= META_FRAME_CONSTRAINED_BOTTOM_EDGE; | ||||
|  | ||||
|   return flags; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -2001,23 +2001,13 @@ process_mouse_move_resize_grab (MetaDisplay     *display, | ||||
|  | ||||
|   if (event->keyval == CLUTTER_KEY_Escape) | ||||
|     { | ||||
|       /* Hide the tiling preview if necessary */ | ||||
|       if (window->tile_mode != META_TILE_NONE) | ||||
|         meta_screen_hide_tile_preview (screen); | ||||
|  | ||||
|       /* Restore the original tile mode */ | ||||
|       window->tile_mode = display->grab_tile_mode; | ||||
|       window->tile_monitor_number = display->grab_tile_monitor_number; | ||||
|  | ||||
|       /* End move or resize and restore to original state.  If the | ||||
|        * window was a maximized window that had been "shaken loose" we | ||||
|        * need to remaximize it.  In normal cases, we need to do a | ||||
|        * moveresize now to get the position back to the original. | ||||
|        */ | ||||
|       if (window->shaken_loose || window->tile_mode == META_TILE_MAXIMIZED) | ||||
|       if (window->shaken_loose) | ||||
|         meta_window_maximize (window, META_MAXIMIZE_BOTH); | ||||
|       else if (window->tile_mode != META_TILE_NONE) | ||||
|         meta_window_tile (window); | ||||
|       else | ||||
|         meta_window_move_resize_frame (display->grab_window, | ||||
|                                        TRUE, | ||||
| @@ -2939,41 +2929,25 @@ handle_toggle_above       (MetaDisplay     *display, | ||||
| } | ||||
|  | ||||
| static void | ||||
| handle_toggle_tiled (MetaDisplay     *display, | ||||
|                      MetaScreen      *screen, | ||||
|                      MetaWindow      *window, | ||||
|                      ClutterKeyEvent *event, | ||||
|                      MetaKeyBinding  *binding, | ||||
|                      gpointer         dummy) | ||||
| handle_toggle_tiled_left (MetaDisplay     *display, | ||||
|                           MetaScreen      *screen, | ||||
|                           MetaWindow      *window, | ||||
|                           ClutterKeyEvent *event, | ||||
|                           MetaKeyBinding  *binding, | ||||
|                           gpointer         dummy) | ||||
| { | ||||
|   MetaTileMode mode = binding->handler->data; | ||||
|   meta_window_toggle_tile (window, META_TILE_ZONE_W); | ||||
| } | ||||
|  | ||||
|   if ((META_WINDOW_TILED_LEFT (window) && mode == META_TILE_LEFT) || | ||||
|       (META_WINDOW_TILED_RIGHT (window) && mode == META_TILE_RIGHT)) | ||||
|     { | ||||
|       window->tile_monitor_number = window->saved_maximize ? window->monitor->number | ||||
|         : -1; | ||||
|       window->tile_mode = window->saved_maximize ? META_TILE_MAXIMIZED | ||||
|         : META_TILE_NONE; | ||||
|  | ||||
|       if (window->saved_maximize) | ||||
|         meta_window_maximize (window, META_MAXIMIZE_BOTH); | ||||
|       else | ||||
|         meta_window_unmaximize (window, META_MAXIMIZE_BOTH); | ||||
|     } | ||||
|   else if (meta_window_can_tile_side_by_side (window)) | ||||
|     { | ||||
|       window->tile_monitor_number = window->monitor->number; | ||||
|       window->tile_mode = mode; | ||||
|       /* Maximization constraints beat tiling constraints, so if the window | ||||
|        * is maximized, tiling won't have any effect unless we unmaximize it | ||||
|        * horizontally first; rather than calling meta_window_unmaximize(), | ||||
|        * we just set the flag and rely on meta_window_tile() syncing it to | ||||
|        * save an additional roundtrip. | ||||
|        */ | ||||
|       window->maximized_horizontally = FALSE; | ||||
|       meta_window_tile (window); | ||||
|     } | ||||
| static void | ||||
| handle_toggle_tiled_right (MetaDisplay     *display, | ||||
|                            MetaScreen      *screen, | ||||
|                            MetaWindow      *window, | ||||
|                            ClutterKeyEvent *event, | ||||
|                            MetaKeyBinding  *binding, | ||||
|                            gpointer         dummy) | ||||
| { | ||||
|   meta_window_toggle_tile (window, META_TILE_ZONE_E); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -3706,14 +3680,14 @@ init_builtin_key_bindings (MetaDisplay *display) | ||||
|                           mutter_keybindings, | ||||
|                           META_KEY_BINDING_PER_WINDOW, | ||||
|                           META_KEYBINDING_ACTION_TOGGLE_TILED_LEFT, | ||||
|                           handle_toggle_tiled, META_TILE_LEFT); | ||||
|                           handle_toggle_tiled_left, 0); | ||||
|  | ||||
|   add_builtin_keybinding (display, | ||||
|                           "toggle-tiled-right", | ||||
|                           mutter_keybindings, | ||||
|                           META_KEY_BINDING_PER_WINDOW, | ||||
|                           META_KEYBINDING_ACTION_TOGGLE_TILED_RIGHT, | ||||
|                           handle_toggle_tiled, META_TILE_RIGHT); | ||||
|                           handle_toggle_tiled_right, 0); | ||||
|  | ||||
|   add_builtin_keybinding (display, | ||||
|                           "toggle-above", | ||||
|   | ||||
| @@ -168,6 +168,7 @@ static gboolean  opt_disable_sm; | ||||
| static gboolean  opt_sync; | ||||
| #ifdef HAVE_WAYLAND | ||||
| static gboolean  opt_wayland; | ||||
| static gboolean  opt_nested; | ||||
| #endif | ||||
| #ifdef HAVE_NATIVE_BACKEND | ||||
| static gboolean  opt_display_server; | ||||
| @@ -216,6 +217,12 @@ static GOptionEntry meta_options[] = { | ||||
|     N_("Run as a wayland compositor"), | ||||
|     NULL | ||||
|   }, | ||||
|   { | ||||
|     "nested", 0, 0, G_OPTION_ARG_NONE, | ||||
|     &opt_nested, | ||||
|     N_("Run as a nested compositor"), | ||||
|     NULL | ||||
|   }, | ||||
| #endif | ||||
| #ifdef HAVE_NATIVE_BACKEND | ||||
|   { | ||||
| @@ -366,21 +373,30 @@ check_for_wayland_session_type (void) | ||||
| static void | ||||
| init_backend (void) | ||||
| { | ||||
|   gboolean session_type_is_wayland = FALSE; | ||||
| #ifdef HAVE_WAYLAND | ||||
|   gboolean run_as_wayland_compositor = opt_wayland; | ||||
|  | ||||
| #if defined(HAVE_WAYLAND) && defined(HAVE_NATIVE_BACKEND) | ||||
|   session_type_is_wayland = check_for_wayland_session_type (); | ||||
| #endif | ||||
| #ifdef HAVE_NATIVE_BACKEND | ||||
|   if (opt_nested && opt_display_server) | ||||
|     { | ||||
|       meta_warning ("Can't run both as nested and as a display server\n"); | ||||
|       meta_exit (META_EXIT_ERROR); | ||||
|     } | ||||
|  | ||||
| #if defined(CLUTTER_WINDOWING_EGL) && defined(HAVE_NATIVE_BACKEND) | ||||
|   if (opt_display_server || session_type_is_wayland) | ||||
|   if (!run_as_wayland_compositor) | ||||
|     run_as_wayland_compositor = check_for_wayland_session_type (); | ||||
|  | ||||
| #ifdef CLUTTER_WINDOWING_EGL | ||||
|   if (opt_display_server || (run_as_wayland_compositor && !opt_nested)) | ||||
|     clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL); | ||||
|   else | ||||
| #endif | ||||
| #endif | ||||
| #endif | ||||
|     clutter_set_windowing_backend (CLUTTER_WINDOWING_X11); | ||||
|  | ||||
| #ifdef HAVE_WAYLAND | ||||
|   meta_set_is_wayland_compositor (opt_wayland || session_type_is_wayland); | ||||
|   meta_set_is_wayland_compositor (run_as_wayland_compositor); | ||||
| #endif | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										154
									
								
								src/core/meta-border.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								src/core/meta-border.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,154 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2015 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jonas Ådahl <jadahl@gmail.com> | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "core/meta-border.h" | ||||
|  | ||||
| #include <math.h> | ||||
|  | ||||
| static inline float | ||||
| meta_vector2_cross_product (const MetaVector2 a, | ||||
|                             const MetaVector2 b) | ||||
| { | ||||
|   return a.x * b.y - a.y * b.x; | ||||
| } | ||||
|  | ||||
| static inline MetaVector2 | ||||
| meta_vector2_add (const MetaVector2 a, | ||||
|                   const MetaVector2 b) | ||||
| { | ||||
|   return (MetaVector2) { | ||||
|     .x = a.x + b.x, | ||||
|     .y = a.y + b.y, | ||||
|   }; | ||||
| } | ||||
|  | ||||
| static inline MetaVector2 | ||||
| meta_vector2_multiply_constant (const float       c, | ||||
|                                 const MetaVector2 a) | ||||
| { | ||||
|   return (MetaVector2) { | ||||
|     .x = c * a.x, | ||||
|     .y = c * a.y, | ||||
|   }; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_line2_intersects_with (const MetaLine2 *line1, | ||||
|                             const MetaLine2 *line2, | ||||
|                             MetaVector2     *intersection) | ||||
| { | ||||
|   MetaVector2 p = line1->a; | ||||
|   MetaVector2 r = meta_vector2_subtract (line1->b, line1->a); | ||||
|   MetaVector2 q = line2->a; | ||||
|   MetaVector2 s = meta_vector2_subtract (line2->b, line2->a); | ||||
|   float rxs; | ||||
|   float sxr; | ||||
|   float t; | ||||
|   float u; | ||||
|  | ||||
|   /* | ||||
|    * The line (p, r) and (q, s) intersects where | ||||
|    * | ||||
|    *   p + t r = q + u s | ||||
|    * | ||||
|    * Calculate t: | ||||
|    * | ||||
|    *   (p + t r) × s = (q + u s) × s | ||||
|    *   p × s + t (r × s) = q × s + u (s × s) | ||||
|    *   p × s + t (r × s) = q × s | ||||
|    *   t (r × s) = q × s - p × s | ||||
|    *   t (r × s) = (q - p) × s | ||||
|    *   t = ((q - p) × s) / (r × s) | ||||
|    * | ||||
|    * Using the same method, for u we get: | ||||
|    * | ||||
|    *   u = ((p - q) × r) / (s × r) | ||||
|    */ | ||||
|  | ||||
|   rxs = meta_vector2_cross_product (r, s); | ||||
|   sxr = meta_vector2_cross_product (s, r); | ||||
|  | ||||
|   /* If r × s = 0 then the lines are either parallel or collinear. */ | ||||
|   if (fabsf (rxs) < FLT_MIN) | ||||
|     return FALSE; | ||||
|  | ||||
|   t = meta_vector2_cross_product (meta_vector2_subtract (q, p), s) / rxs; | ||||
|   u = meta_vector2_cross_product (meta_vector2_subtract (p, q), r) / sxr; | ||||
|  | ||||
|   /* The lines only intersect if 0 ≤ t ≤ 1 and 0 ≤ u ≤ 1. */ | ||||
|   if (t < 0.0 || t > 1.0 || u < 0.0 || u > 1.0) | ||||
|     return FALSE; | ||||
|  | ||||
|   *intersection = meta_vector2_add (p, meta_vector2_multiply_constant (t, r)); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_border_is_horizontal (MetaBorder *border) | ||||
| { | ||||
|   return border->line.a.y == border->line.b.y; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_border_is_blocking_directions (MetaBorder               *border, | ||||
|                                     MetaBorderMotionDirection directions) | ||||
| { | ||||
|   if (meta_border_is_horizontal (border)) | ||||
|     { | ||||
|       if ((directions & (META_BORDER_MOTION_DIRECTION_POSITIVE_Y | | ||||
|                          META_BORDER_MOTION_DIRECTION_NEGATIVE_Y)) == 0) | ||||
|         return FALSE; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if ((directions & (META_BORDER_MOTION_DIRECTION_POSITIVE_X | | ||||
|                          META_BORDER_MOTION_DIRECTION_NEGATIVE_X)) == 0) | ||||
|         return FALSE; | ||||
|     } | ||||
|  | ||||
|   return (~border->blocking_directions & directions) != directions; | ||||
| } | ||||
|  | ||||
| unsigned int | ||||
| meta_border_get_allows_directions (MetaBorder *border) | ||||
| { | ||||
|   return ~border->blocking_directions & | ||||
|     (META_BORDER_MOTION_DIRECTION_POSITIVE_X | | ||||
|      META_BORDER_MOTION_DIRECTION_POSITIVE_Y | | ||||
|      META_BORDER_MOTION_DIRECTION_NEGATIVE_X | | ||||
|      META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_border_set_allows_directions (MetaBorder *border, unsigned int directions) | ||||
| { | ||||
|   border->blocking_directions = | ||||
|     ~directions & (META_BORDER_MOTION_DIRECTION_POSITIVE_X | | ||||
|                    META_BORDER_MOTION_DIRECTION_POSITIVE_Y | | ||||
|                    META_BORDER_MOTION_DIRECTION_NEGATIVE_X | | ||||
|                    META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); | ||||
| } | ||||
							
								
								
									
										84
									
								
								src/core/meta-border.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/core/meta-border.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2015 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jonas Ådahl <jadahl@gmail.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef META_BORDER_H | ||||
| #define META_BORDER_H | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   META_BORDER_MOTION_DIRECTION_POSITIVE_X = 1 << 0, | ||||
|   META_BORDER_MOTION_DIRECTION_POSITIVE_Y = 1 << 1, | ||||
|   META_BORDER_MOTION_DIRECTION_NEGATIVE_X = 1 << 2, | ||||
|   META_BORDER_MOTION_DIRECTION_NEGATIVE_Y = 1 << 3, | ||||
| } MetaBorderMotionDirection; | ||||
|  | ||||
| typedef struct _MetaVector2 | ||||
| { | ||||
|   float x; | ||||
|   float y; | ||||
| } MetaVector2; | ||||
|  | ||||
| typedef struct _MetaLine2 | ||||
| { | ||||
|   MetaVector2 a; | ||||
|   MetaVector2 b; | ||||
| } MetaLine2; | ||||
|  | ||||
| typedef struct _MetaBorder | ||||
| { | ||||
|   MetaLine2 line; | ||||
|   MetaBorderMotionDirection blocking_directions; | ||||
| } MetaBorder; | ||||
|  | ||||
| static inline MetaVector2 | ||||
| meta_vector2_subtract (const MetaVector2 a, | ||||
|                        const MetaVector2 b) | ||||
| { | ||||
|   return (MetaVector2) { | ||||
|     .x = a.x - b.x, | ||||
|     .y = a.y - b.y, | ||||
|   }; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_line2_intersects_with (const MetaLine2 *line1, | ||||
|                             const MetaLine2 *line2, | ||||
|                             MetaVector2     *intersection); | ||||
|  | ||||
| gboolean | ||||
| meta_border_is_horizontal (MetaBorder *border); | ||||
|  | ||||
| gboolean | ||||
| meta_border_is_blocking_directions (MetaBorder               *border, | ||||
|                                     MetaBorderMotionDirection directions); | ||||
|  | ||||
| unsigned int | ||||
| meta_border_get_allows_directions (MetaBorder *border); | ||||
|  | ||||
| void | ||||
| meta_border_set_allows_directions (MetaBorder *border, unsigned int directions); | ||||
|  | ||||
| #endif /* META_BORDER_H */ | ||||
| @@ -57,7 +57,13 @@ struct _MetaScreen | ||||
|   MetaRectangle rect;  /* Size of screen; rect.x & rect.y are always 0 */ | ||||
|   MetaUI *ui; | ||||
|  | ||||
|   guint tile_preview_timeout_id; | ||||
|   struct { | ||||
|     gboolean exists; | ||||
|     guint timeout_id; | ||||
|     MetaWindow *window; | ||||
|     MetaRectangle area; | ||||
|     int monitor; | ||||
|   } tile_preview; | ||||
|  | ||||
|   MetaWorkspace *active_workspace; | ||||
|  | ||||
| @@ -85,11 +91,7 @@ struct _MetaScreen | ||||
|   /* Cache the current monitor */ | ||||
|   int last_monitor_index; | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
|   SnMonitorContext *sn_context; | ||||
|   GSList *startup_sequences; | ||||
|   guint startup_sequence_timeout; | ||||
| #endif | ||||
|  | ||||
|   Window wm_cm_selection_window; | ||||
|   guint work_area_later; | ||||
| @@ -136,9 +138,12 @@ void          meta_screen_foreach_window      (MetaScreen                 *scree | ||||
|  | ||||
| void          meta_screen_update_cursor       (MetaScreen                 *screen); | ||||
|  | ||||
| void          meta_screen_update_tile_preview          (MetaScreen    *screen, | ||||
|                                                         gboolean       delay); | ||||
| void          meta_screen_hide_tile_preview            (MetaScreen    *screen); | ||||
| void          meta_screen_update_tile_preview (MetaScreen    *screen, | ||||
|                                                MetaWindow    *window, | ||||
|                                                MetaRectangle  area, | ||||
|                                                int            monitor, | ||||
|                                                gboolean       delay); | ||||
| void          meta_screen_hide_tile_preview   (MetaScreen *screen); | ||||
|  | ||||
| MetaWindow*   meta_screen_get_mouse_window     (MetaScreen                 *screen, | ||||
|                                                 MetaWindow                 *not_this_one); | ||||
|   | ||||
| @@ -71,11 +71,6 @@ static void prefs_changed_callback (MetaPreference pref, | ||||
| static void set_desktop_geometry_hint (MetaScreen *screen); | ||||
| static void set_desktop_viewport_hint (MetaScreen *screen); | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
| static void meta_screen_sn_event   (SnMonitorEvent *event, | ||||
|                                     void           *user_data); | ||||
| #endif | ||||
|  | ||||
| static void on_monitors_changed (MetaMonitorManager *manager, | ||||
|                                  MetaScreen         *screen); | ||||
|  | ||||
| @@ -723,24 +718,11 @@ meta_screen_new (MetaDisplay *display, | ||||
|   screen->ui = meta_ui_new (screen->display->xdisplay, | ||||
|                             screen->xscreen); | ||||
|  | ||||
|   screen->tile_preview_timeout_id = 0; | ||||
|  | ||||
|   screen->stack = meta_stack_new (screen); | ||||
|   screen->stack_tracker = meta_stack_tracker_new (screen); | ||||
|  | ||||
|   meta_prefs_add_listener (prefs_changed_callback, screen); | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
|   screen->sn_context = | ||||
|     sn_monitor_context_new (screen->display->sn_display, | ||||
|                             screen->number, | ||||
|                             meta_screen_sn_event, | ||||
|                             screen, | ||||
|                             NULL); | ||||
|   screen->startup_sequences = NULL; | ||||
|   screen->startup_sequence_timeout = 0; | ||||
| #endif | ||||
|  | ||||
|   meta_verbose ("Added screen %d ('%s') root 0x%lx\n", | ||||
|                 screen->number, screen->screen_name, screen->xroot); | ||||
|  | ||||
| @@ -800,24 +782,6 @@ meta_screen_free (MetaScreen *screen, | ||||
|  | ||||
|   meta_screen_ungrab_keys (screen); | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
|   g_slist_foreach (screen->startup_sequences, | ||||
|                    (GFunc) sn_startup_sequence_unref, NULL); | ||||
|   g_slist_free (screen->startup_sequences); | ||||
|   screen->startup_sequences = NULL; | ||||
|  | ||||
|   if (screen->startup_sequence_timeout != 0) | ||||
|     { | ||||
|       g_source_remove (screen->startup_sequence_timeout); | ||||
|       screen->startup_sequence_timeout = 0; | ||||
|     } | ||||
|   if (screen->sn_context) | ||||
|     { | ||||
|       sn_monitor_context_unref (screen->sn_context); | ||||
|       screen->sn_context = NULL; | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|   meta_ui_free (screen->ui); | ||||
|  | ||||
|   meta_stack_free (screen->stack); | ||||
| @@ -841,8 +805,8 @@ meta_screen_free (MetaScreen *screen, | ||||
|  | ||||
|   g_free (screen->monitor_infos); | ||||
|  | ||||
|   if (screen->tile_preview_timeout_id) | ||||
|     g_source_remove (screen->tile_preview_timeout_id); | ||||
|   if (screen->tile_preview.timeout_id) | ||||
|     g_source_remove (screen->tile_preview.timeout_id); | ||||
|  | ||||
|   g_free (screen->screen_name); | ||||
|  | ||||
| @@ -1267,7 +1231,8 @@ root_cursor_prepare_at (MetaCursorSprite *cursor_sprite, | ||||
|   monitor = meta_screen_get_monitor_for_point (screen, x, y); | ||||
|  | ||||
|   /* Reload the cursor texture if the scale has changed. */ | ||||
|   meta_cursor_sprite_set_theme_scale (cursor_sprite, monitor->scale); | ||||
|   if (monitor) | ||||
|     meta_cursor_sprite_set_theme_scale (cursor_sprite, monitor->scale); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -1321,44 +1286,20 @@ static gboolean | ||||
| meta_screen_update_tile_preview_timeout (gpointer data) | ||||
| { | ||||
|   MetaScreen *screen = data; | ||||
|   MetaWindow *window = screen->display->grab_window; | ||||
|   gboolean needs_preview = FALSE; | ||||
|  | ||||
|   screen->tile_preview_timeout_id = 0; | ||||
|   screen->tile_preview.timeout_id = 0; | ||||
|  | ||||
|   if (window) | ||||
|   if (screen->tile_preview.exists) | ||||
|     { | ||||
|       switch (window->tile_mode) | ||||
|         { | ||||
|           case META_TILE_LEFT: | ||||
|           case META_TILE_RIGHT: | ||||
|               if (!META_WINDOW_TILED_SIDE_BY_SIDE (window)) | ||||
|                 needs_preview = TRUE; | ||||
|               break; | ||||
|  | ||||
|           case META_TILE_MAXIMIZED: | ||||
|               if (!META_WINDOW_MAXIMIZED (window)) | ||||
|                 needs_preview = TRUE; | ||||
|               break; | ||||
|  | ||||
|           default: | ||||
|               needs_preview = FALSE; | ||||
|               break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   if (needs_preview) | ||||
|     { | ||||
|       MetaRectangle tile_rect; | ||||
|       int monitor; | ||||
|  | ||||
|       monitor = meta_window_get_current_tile_monitor_number (window); | ||||
|       meta_window_get_current_tile_area (window, &tile_rect); | ||||
|       meta_compositor_show_tile_preview (screen->display->compositor, | ||||
|                                          window, &tile_rect, monitor); | ||||
|                                          screen->tile_preview.window, | ||||
|                                          &screen->tile_preview.area, | ||||
|                                          screen->tile_preview.monitor); | ||||
|     } | ||||
|   else | ||||
|     meta_compositor_hide_tile_preview (screen->display->compositor); | ||||
|     { | ||||
|       meta_compositor_hide_tile_preview (screen->display->compositor); | ||||
|     } | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
| @@ -1366,37 +1307,47 @@ meta_screen_update_tile_preview_timeout (gpointer data) | ||||
| #define TILE_PREVIEW_TIMEOUT_MS 200 | ||||
|  | ||||
| void | ||||
| meta_screen_update_tile_preview (MetaScreen *screen, | ||||
|                                  gboolean    delay) | ||||
| meta_screen_update_tile_preview (MetaScreen    *screen, | ||||
|                                  MetaWindow    *window, | ||||
|                                  MetaRectangle  area, | ||||
|                                  int            monitor, | ||||
|                                  gboolean       delay) | ||||
| { | ||||
|   screen->tile_preview.exists = TRUE; | ||||
|   screen->tile_preview.window = window; | ||||
|   screen->tile_preview.area = area; | ||||
|   screen->tile_preview.monitor = monitor; | ||||
|  | ||||
|   if (delay) | ||||
|     { | ||||
|       if (screen->tile_preview_timeout_id > 0) | ||||
|       if (screen->tile_preview.timeout_id > 0) | ||||
|         return; | ||||
|  | ||||
|       screen->tile_preview_timeout_id = | ||||
|       screen->tile_preview.timeout_id = | ||||
|         g_timeout_add (TILE_PREVIEW_TIMEOUT_MS, | ||||
|                        meta_screen_update_tile_preview_timeout, | ||||
|                        screen); | ||||
|       g_source_set_name_by_id (screen->tile_preview_timeout_id, | ||||
|       g_source_set_name_by_id (screen->tile_preview.timeout_id, | ||||
|                                "[mutter] meta_screen_update_tile_preview_timeout"); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (screen->tile_preview_timeout_id > 0) | ||||
|         g_source_remove (screen->tile_preview_timeout_id); | ||||
|       if (screen->tile_preview.timeout_id > 0) | ||||
|         g_source_remove (screen->tile_preview.timeout_id); | ||||
|  | ||||
|       meta_screen_update_tile_preview_timeout ((gpointer)screen); | ||||
|       meta_screen_update_tile_preview_timeout ((gpointer) screen); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_screen_hide_tile_preview (MetaScreen *screen) | ||||
| { | ||||
|   if (screen->tile_preview_timeout_id > 0) | ||||
|     g_source_remove (screen->tile_preview_timeout_id); | ||||
|   screen->tile_preview.exists = FALSE; | ||||
|  | ||||
|   meta_compositor_hide_tile_preview (screen->display->compositor); | ||||
|   if (screen->tile_preview.timeout_id > 0) | ||||
|     g_source_remove (screen->tile_preview.timeout_id); | ||||
|  | ||||
|   meta_screen_update_tile_preview_timeout ((gpointer) screen); | ||||
| } | ||||
|  | ||||
| MetaWindow* | ||||
| @@ -2538,208 +2489,6 @@ meta_screen_unshow_desktop (MetaScreen *screen) | ||||
|   meta_screen_update_showing_desktop_hint (screen); | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
| static gboolean startup_sequence_timeout (void *data); | ||||
|  | ||||
| static void | ||||
| update_startup_feedback (MetaScreen *screen) | ||||
| { | ||||
|   if (screen->startup_sequences != NULL) | ||||
|     { | ||||
|       meta_topic (META_DEBUG_STARTUP, | ||||
|                   "Setting busy cursor\n"); | ||||
|       meta_screen_set_cursor (screen, META_CURSOR_BUSY); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       meta_topic (META_DEBUG_STARTUP, | ||||
|                   "Setting default cursor\n"); | ||||
|       meta_screen_set_cursor (screen, META_CURSOR_DEFAULT); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| add_sequence (MetaScreen        *screen, | ||||
|               SnStartupSequence *sequence) | ||||
| { | ||||
|   meta_topic (META_DEBUG_STARTUP, | ||||
|               "Adding sequence %s\n", | ||||
|               sn_startup_sequence_get_id (sequence)); | ||||
|   sn_startup_sequence_ref (sequence); | ||||
|   screen->startup_sequences = g_slist_prepend (screen->startup_sequences, | ||||
|                                                sequence); | ||||
|  | ||||
|   /* our timeout just polls every second, instead of bothering | ||||
|    * to compute exactly when we may next time out | ||||
|    */ | ||||
|   if (screen->startup_sequence_timeout == 0) | ||||
|     { | ||||
|       screen->startup_sequence_timeout = g_timeout_add_seconds (1, | ||||
|                                                                 startup_sequence_timeout, | ||||
|                                                                 screen); | ||||
|       g_source_set_name_by_id (screen->startup_sequence_timeout, | ||||
|                                "[mutter] startup_sequence_timeout"); | ||||
|     } | ||||
|  | ||||
|   update_startup_feedback (screen); | ||||
| } | ||||
|  | ||||
| static void | ||||
| remove_sequence (MetaScreen        *screen, | ||||
|                  SnStartupSequence *sequence) | ||||
| { | ||||
|   meta_topic (META_DEBUG_STARTUP, | ||||
|               "Removing sequence %s\n", | ||||
|               sn_startup_sequence_get_id (sequence)); | ||||
|  | ||||
|   screen->startup_sequences = g_slist_remove (screen->startup_sequences, | ||||
|                                               sequence); | ||||
|  | ||||
|   if (screen->startup_sequences == NULL && | ||||
|       screen->startup_sequence_timeout != 0) | ||||
|     { | ||||
|       g_source_remove (screen->startup_sequence_timeout); | ||||
|       screen->startup_sequence_timeout = 0; | ||||
|     } | ||||
|  | ||||
|   update_startup_feedback (screen); | ||||
|  | ||||
|   sn_startup_sequence_unref (sequence); | ||||
| } | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   GSList *list; | ||||
|   GTimeVal now; | ||||
| } CollectTimedOutData; | ||||
|  | ||||
| /* This should be fairly long, as it should never be required unless | ||||
|  * apps or .desktop files are buggy, and it's confusing if | ||||
|  * OpenOffice or whatever seems to stop launching - people | ||||
|  * might decide they need to launch it again. | ||||
|  */ | ||||
| #define STARTUP_TIMEOUT 15000 | ||||
|  | ||||
| static void | ||||
| collect_timed_out_foreach (void *element, | ||||
|                            void *data) | ||||
| { | ||||
|   CollectTimedOutData *ctod = data; | ||||
|   SnStartupSequence *sequence = element; | ||||
|   long tv_sec, tv_usec; | ||||
|   double elapsed; | ||||
|  | ||||
|   sn_startup_sequence_get_last_active_time (sequence, &tv_sec, &tv_usec); | ||||
|  | ||||
|   elapsed = | ||||
|     ((((double)ctod->now.tv_sec - tv_sec) * G_USEC_PER_SEC + | ||||
|       (ctod->now.tv_usec - tv_usec))) / 1000.0; | ||||
|  | ||||
|   meta_topic (META_DEBUG_STARTUP, | ||||
|               "Sequence used %g seconds vs. %g max: %s\n", | ||||
|               elapsed, (double) STARTUP_TIMEOUT, | ||||
|               sn_startup_sequence_get_id (sequence)); | ||||
|  | ||||
|   if (elapsed > STARTUP_TIMEOUT) | ||||
|     ctod->list = g_slist_prepend (ctod->list, sequence); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| startup_sequence_timeout (void *data) | ||||
| { | ||||
|   MetaScreen *screen = data; | ||||
|   CollectTimedOutData ctod; | ||||
|   GSList *l; | ||||
|  | ||||
|   ctod.list = NULL; | ||||
|   g_get_current_time (&ctod.now); | ||||
|   g_slist_foreach (screen->startup_sequences, | ||||
|                    collect_timed_out_foreach, | ||||
|                    &ctod); | ||||
|  | ||||
|   for (l = ctod.list; l != NULL; l = l->next) | ||||
|     { | ||||
|       SnStartupSequence *sequence = l->data; | ||||
|  | ||||
|       meta_topic (META_DEBUG_STARTUP, | ||||
|                   "Timed out sequence %s\n", | ||||
|                   sn_startup_sequence_get_id (sequence)); | ||||
|  | ||||
|       sn_startup_sequence_complete (sequence); | ||||
|     } | ||||
|  | ||||
|   g_slist_free (ctod.list); | ||||
|  | ||||
|   if (screen->startup_sequences != NULL) | ||||
|     { | ||||
|       return TRUE; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* remove */ | ||||
|       screen->startup_sequence_timeout = 0; | ||||
|       return FALSE; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_screen_sn_event (SnMonitorEvent *event, | ||||
|                       void           *user_data) | ||||
| { | ||||
|   MetaScreen *screen; | ||||
|   SnStartupSequence *sequence; | ||||
|  | ||||
|   screen = user_data; | ||||
|  | ||||
|   sequence = sn_monitor_event_get_startup_sequence (event); | ||||
|  | ||||
|   sn_startup_sequence_ref (sequence); | ||||
|  | ||||
|   switch (sn_monitor_event_get_type (event)) | ||||
|     { | ||||
|     case SN_MONITOR_EVENT_INITIATED: | ||||
|       { | ||||
|         const char *wmclass; | ||||
|  | ||||
|         wmclass = sn_startup_sequence_get_wmclass (sequence); | ||||
|  | ||||
|         meta_topic (META_DEBUG_STARTUP, | ||||
|                     "Received startup initiated for %s wmclass %s\n", | ||||
|                     sn_startup_sequence_get_id (sequence), | ||||
|                     wmclass ? wmclass : "(unset)"); | ||||
|         add_sequence (screen, sequence); | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case SN_MONITOR_EVENT_COMPLETED: | ||||
|       { | ||||
|         meta_topic (META_DEBUG_STARTUP, | ||||
|                     "Received startup completed for %s\n", | ||||
|                     sn_startup_sequence_get_id (sequence)); | ||||
|         remove_sequence (screen, | ||||
|                          sn_monitor_event_get_startup_sequence (event)); | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case SN_MONITOR_EVENT_CHANGED: | ||||
|       meta_topic (META_DEBUG_STARTUP, | ||||
|                   "Received startup changed for %s\n", | ||||
|                   sn_startup_sequence_get_id (sequence)); | ||||
|       break; | ||||
|  | ||||
|     case SN_MONITOR_EVENT_CANCELED: | ||||
|       meta_topic (META_DEBUG_STARTUP, | ||||
|                   "Received startup canceled for %s\n", | ||||
|                   sn_startup_sequence_get_id (sequence)); | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   g_signal_emit (G_OBJECT (screen), screen_signals[STARTUP_SEQUENCE_CHANGED], 0, sequence); | ||||
|  | ||||
|   sn_startup_sequence_unref (sequence); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_screen_get_startup_sequences: (skip) | ||||
|  * @screen: | ||||
| @@ -2751,7 +2500,6 @@ meta_screen_get_startup_sequences (MetaScreen *screen) | ||||
| { | ||||
|   return screen->startup_sequences; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /* Sets the initial_timestamp and initial_workspace properties | ||||
|  * of a window according to information given us by the | ||||
|   | ||||
| @@ -117,7 +117,6 @@ meta_stack_add (MetaStack  *stack, | ||||
|               window->desc, window->stack_position); | ||||
|  | ||||
|   stack_sync_to_xserver (stack); | ||||
|   meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -153,7 +152,6 @@ meta_stack_remove (MetaStack  *stack, | ||||
|                                      GUINT_TO_POINTER (window->frame->xwindow)); | ||||
|  | ||||
|   stack_sync_to_xserver (stack); | ||||
|   meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -163,7 +161,6 @@ meta_stack_update_layer (MetaStack  *stack, | ||||
|   stack->need_relayer = TRUE; | ||||
|  | ||||
|   stack_sync_to_xserver (stack); | ||||
|   meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -173,7 +170,6 @@ meta_stack_update_transient (MetaStack  *stack, | ||||
|   stack->need_constrain = TRUE; | ||||
|  | ||||
|   stack_sync_to_xserver (stack); | ||||
|   meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); | ||||
| } | ||||
|  | ||||
| /* raise/lower within a layer */ | ||||
| @@ -202,7 +198,6 @@ meta_stack_raise (MetaStack  *stack, | ||||
|   meta_window_set_stack_position_no_sync (window, max_stack_position); | ||||
|  | ||||
|   stack_sync_to_xserver (stack); | ||||
|   meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -230,7 +225,6 @@ meta_stack_lower (MetaStack  *stack, | ||||
|   meta_window_set_stack_position_no_sync (window, min_stack_position); | ||||
|  | ||||
|   stack_sync_to_xserver (stack); | ||||
|   meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -246,27 +240,6 @@ meta_stack_thaw (MetaStack *stack) | ||||
|  | ||||
|   stack->freeze_count -= 1; | ||||
|   stack_sync_to_xserver (stack); | ||||
|   meta_stack_update_window_tile_matches (stack, NULL); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_stack_update_window_tile_matches (MetaStack     *stack, | ||||
|                                        MetaWorkspace *workspace) | ||||
| { | ||||
|   GList *windows, *tmp; | ||||
|  | ||||
|   if (stack->freeze_count > 0) | ||||
|     return; | ||||
|  | ||||
|   windows = meta_stack_list_windows (stack, workspace); | ||||
|   tmp = windows; | ||||
|   while (tmp) | ||||
|     { | ||||
|       meta_window_compute_tile_match ((MetaWindow *) tmp->data); | ||||
|       tmp = tmp->next; | ||||
|     } | ||||
|  | ||||
|   g_list_free (windows); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| @@ -1448,7 +1421,6 @@ meta_stack_set_positions (MetaStack *stack, | ||||
|               "Reset the stack positions of (nearly) all windows\n"); | ||||
|  | ||||
|   stack_sync_to_xserver (stack); | ||||
|   meta_stack_update_window_tile_matches (stack, NULL); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -1511,6 +1483,4 @@ meta_window_set_stack_position (MetaWindow *window, | ||||
| { | ||||
|   meta_window_set_stack_position_no_sync (window, position); | ||||
|   stack_sync_to_xserver (window->screen->stack); | ||||
|   meta_stack_update_window_tile_matches (window->screen->stack, | ||||
|                                          window->screen->active_workspace); | ||||
| } | ||||
|   | ||||
| @@ -413,6 +413,4 @@ GList* meta_stack_get_positions (MetaStack *stack); | ||||
| void   meta_stack_set_positions (MetaStack *stack, | ||||
|                                  GList     *windows); | ||||
|  | ||||
| void meta_stack_update_window_tile_matches (MetaStack     *stack, | ||||
|                                             MetaWorkspace *workspace); | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										48
									
								
								src/core/startup-notification-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/core/startup-notification-private.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2001, 2002 Havoc Pennington | ||||
|  * Copyright (C) 2002, 2003 Red Hat Inc. | ||||
|  * Some ICCCM manager selection code derived from fvwm2, | ||||
|  * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team | ||||
|  * Copyright (C) 2003 Rob Adams | ||||
|  * Copyright (C) 2004-2006 Elijah Newren | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #ifndef META_STARTUP_NOTIFICATION_PRIVATE_H | ||||
| #define META_STARTUP_NOTIFICATION_PRIVATE_H | ||||
|  | ||||
| #include "display-private.h" | ||||
|  | ||||
| #define META_TYPE_STARTUP_NOTIFICATION (meta_startup_notification_get_type ()) | ||||
|  | ||||
| G_DECLARE_FINAL_TYPE (MetaStartupNotification, | ||||
|                       meta_startup_notification, | ||||
|                       META, STARTUP_NOTIFICATION, | ||||
|                       GObject) | ||||
|  | ||||
| MetaStartupNotification * | ||||
|          meta_startup_notification_get             (MetaDisplay             *display); | ||||
|  | ||||
| gboolean meta_startup_notification_handle_xevent   (MetaStartupNotification *sn, | ||||
|                                                     XEvent                  *xevent); | ||||
|  | ||||
| void     meta_startup_notification_remove_sequence (MetaStartupNotification *sn, | ||||
|                                                     const gchar             *id); | ||||
|  | ||||
| GSList * meta_startup_notification_get_sequences   (MetaStartupNotification *sn); | ||||
|  | ||||
| #endif /* META_STARTUP_NOTIFICATION_PRIVATE_H */ | ||||
							
								
								
									
										770
									
								
								src/core/startup-notification.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										770
									
								
								src/core/startup-notification.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,770 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2001, 2002 Havoc Pennington | ||||
|  * Copyright (C) 2002, 2003 Red Hat Inc. | ||||
|  * Some ICCCM manager selection code derived from fvwm2, | ||||
|  * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team | ||||
|  * Copyright (C) 2003 Rob Adams | ||||
|  * Copyright (C) 2004-2006 Elijah Newren | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #include <config.h> | ||||
|  | ||||
| #include <glib-object.h> | ||||
|  | ||||
| #include <meta/errors.h> | ||||
| #include "display-private.h" | ||||
| #include "screen-private.h" | ||||
| #include "startup-notification-private.h" | ||||
|  | ||||
| /* This should be fairly long, as it should never be required unless | ||||
|  * apps or .desktop files are buggy, and it's confusing if | ||||
|  * OpenOffice or whatever seems to stop launching - people | ||||
|  * might decide they need to launch it again. | ||||
|  */ | ||||
| #define STARTUP_TIMEOUT 15000000 | ||||
|  | ||||
| typedef struct _MetaStartupNotificationSequence MetaStartupNotificationSequence; | ||||
| typedef struct _MetaStartupNotificationSequenceClass MetaStartupNotificationSequenceClass; | ||||
|  | ||||
| enum { | ||||
|   PROP_SN_0, | ||||
|   PROP_SN_DISPLAY, | ||||
|   N_SN_PROPS | ||||
| }; | ||||
|  | ||||
| enum { | ||||
|   PROP_SEQ_0, | ||||
|   PROP_SEQ_ID, | ||||
|   PROP_SEQ_TIMESTAMP, | ||||
|   N_SEQ_PROPS | ||||
| }; | ||||
|  | ||||
| enum { | ||||
|   SN_CHANGED, | ||||
|   N_SN_SIGNALS | ||||
| }; | ||||
|  | ||||
| static guint sn_signals[N_SN_SIGNALS]; | ||||
| static GParamSpec *sn_props[N_SN_PROPS]; | ||||
| static GParamSpec *seq_props[N_SEQ_PROPS]; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   GSList *list; | ||||
|   gint64 now; | ||||
| } CollectTimedOutData; | ||||
|  | ||||
| struct _MetaStartupNotification | ||||
| { | ||||
|   GObject parent_instance; | ||||
|   MetaDisplay *display; | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
|   SnDisplay *sn_display; | ||||
|   SnMonitorContext *sn_context; | ||||
| #endif | ||||
|  | ||||
|   GSList *startup_sequences; | ||||
|   guint startup_sequence_timeout; | ||||
| }; | ||||
|  | ||||
| #define META_TYPE_STARTUP_NOTIFICATION_SEQUENCE \ | ||||
|   (meta_startup_notification_sequence_get_type ()) | ||||
|  | ||||
| G_DECLARE_DERIVABLE_TYPE (MetaStartupNotificationSequence, | ||||
|                           meta_startup_notification_sequence, | ||||
|                           META, STARTUP_NOTIFICATION_SEQUENCE, | ||||
|                           GObject) | ||||
|  | ||||
| typedef struct { | ||||
|   gchar *id; | ||||
|   gint64 timestamp; | ||||
| } MetaStartupNotificationSequencePrivate; | ||||
|  | ||||
| struct _MetaStartupNotificationSequenceClass { | ||||
|   GObjectClass parent_class; | ||||
|  | ||||
|   void (* complete) (MetaStartupNotificationSequence *sequence); | ||||
| }; | ||||
|  | ||||
| G_DEFINE_TYPE (MetaStartupNotification, | ||||
|                meta_startup_notification, | ||||
|                G_TYPE_OBJECT) | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (MetaStartupNotificationSequence, | ||||
|                             meta_startup_notification_sequence, | ||||
|                             G_TYPE_OBJECT) | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
|  | ||||
| enum { | ||||
|   PROP_SEQ_X11_0, | ||||
|   PROP_SEQ_X11_SEQ, | ||||
|   N_SEQ_X11_PROPS | ||||
| }; | ||||
|  | ||||
| struct _MetaStartupNotificationSequenceX11 { | ||||
|   MetaStartupNotificationSequence parent_instance; | ||||
|   SnStartupSequence *seq; | ||||
| }; | ||||
|  | ||||
| static GParamSpec *seq_x11_props[N_SEQ_X11_PROPS]; | ||||
|  | ||||
| #define META_TYPE_STARTUP_NOTIFICATION_SEQUENCE_X11 \ | ||||
|   (meta_startup_notification_sequence_x11_get_type ()) | ||||
|  | ||||
| G_DECLARE_FINAL_TYPE (MetaStartupNotificationSequenceX11, | ||||
|                       meta_startup_notification_sequence_x11, | ||||
|                       META, STARTUP_NOTIFICATION_SEQUENCE_X11, | ||||
|                       MetaStartupNotificationSequence) | ||||
|  | ||||
| G_DEFINE_TYPE (MetaStartupNotificationSequenceX11, | ||||
|                meta_startup_notification_sequence_x11, | ||||
|                META_TYPE_STARTUP_NOTIFICATION_SEQUENCE) | ||||
|  | ||||
| static void meta_startup_notification_ensure_timeout  (MetaStartupNotification *sn); | ||||
|  | ||||
| #endif | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_update_feedback (MetaStartupNotification *sn) | ||||
| { | ||||
|   MetaScreen *screen = sn->display->screen; | ||||
|  | ||||
|   if (sn->startup_sequences != NULL) | ||||
|     { | ||||
|       meta_topic (META_DEBUG_STARTUP, | ||||
|                   "Setting busy cursor\n"); | ||||
|       meta_screen_set_cursor (screen, META_CURSOR_BUSY); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       meta_topic (META_DEBUG_STARTUP, | ||||
|                   "Setting default cursor\n"); | ||||
|       meta_screen_set_cursor (screen, META_CURSOR_DEFAULT); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_sequence_init (MetaStartupNotificationSequence *seq) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_sequence_finalize (GObject *object) | ||||
| { | ||||
|   MetaStartupNotificationSequence *seq; | ||||
|   MetaStartupNotificationSequencePrivate *priv; | ||||
|  | ||||
|   seq = META_STARTUP_NOTIFICATION_SEQUENCE (object); | ||||
|   priv = meta_startup_notification_sequence_get_instance_private (seq); | ||||
|   g_free (priv->id); | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_startup_notification_sequence_parent_class)->finalize (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_sequence_set_property (GObject      *object, | ||||
|                                                  guint         prop_id, | ||||
|                                                  const GValue *value, | ||||
|                                                  GParamSpec   *pspec) | ||||
| { | ||||
|   MetaStartupNotificationSequence *seq; | ||||
|   MetaStartupNotificationSequencePrivate *priv; | ||||
|  | ||||
|   seq = META_STARTUP_NOTIFICATION_SEQUENCE (object); | ||||
|   priv = meta_startup_notification_sequence_get_instance_private (seq); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_SEQ_ID: | ||||
|       priv->id = g_value_dup_string (value); | ||||
|       break; | ||||
|     case PROP_SEQ_TIMESTAMP: | ||||
|       priv->timestamp = g_value_get_int64 (value); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_sequence_get_property (GObject    *object, | ||||
|                                                  guint       prop_id, | ||||
|                                                  GValue     *value, | ||||
|                                                  GParamSpec *pspec) | ||||
| { | ||||
|   MetaStartupNotificationSequence *seq; | ||||
|   MetaStartupNotificationSequencePrivate *priv; | ||||
|  | ||||
|   seq = META_STARTUP_NOTIFICATION_SEQUENCE (object); | ||||
|   priv = meta_startup_notification_sequence_get_instance_private (seq); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_SEQ_ID: | ||||
|       g_value_set_string (value, priv->id); | ||||
|       break; | ||||
|     case PROP_SEQ_TIMESTAMP: | ||||
|       g_value_set_int64 (value, priv->timestamp); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_sequence_class_init (MetaStartupNotificationSequenceClass *klass) | ||||
| { | ||||
|   GObjectClass *object_class; | ||||
|  | ||||
|   object_class = G_OBJECT_CLASS (klass); | ||||
|   object_class->finalize = meta_startup_notification_sequence_finalize; | ||||
|   object_class->set_property = meta_startup_notification_sequence_set_property; | ||||
|   object_class->get_property = meta_startup_notification_sequence_get_property; | ||||
|  | ||||
|   seq_props[PROP_SEQ_ID] = | ||||
|     g_param_spec_string ("id", | ||||
|                          "ID", | ||||
|                          "ID", | ||||
|                          NULL, | ||||
|                          G_PARAM_READWRITE | | ||||
|                          G_PARAM_CONSTRUCT_ONLY); | ||||
|   seq_props[PROP_SEQ_TIMESTAMP] = | ||||
|     g_param_spec_int64 ("timestamp", | ||||
|                         "Timestamp", | ||||
|                         "Timestamp", | ||||
|                         G_MININT64, G_MAXINT64, 0, | ||||
|                         G_PARAM_READWRITE | | ||||
|                         G_PARAM_CONSTRUCT_ONLY); | ||||
|  | ||||
|   g_object_class_install_properties (object_class, N_SEQ_PROPS, seq_props); | ||||
| } | ||||
|  | ||||
| static const gchar * | ||||
| meta_startup_notification_sequence_get_id (MetaStartupNotificationSequence *seq) | ||||
| { | ||||
|   MetaStartupNotificationSequencePrivate *priv; | ||||
|  | ||||
|   priv = meta_startup_notification_sequence_get_instance_private (seq); | ||||
|   return priv->id; | ||||
| } | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
| static gint64 | ||||
| meta_startup_notification_sequence_get_timestamp (MetaStartupNotificationSequence *seq) | ||||
| { | ||||
|   MetaStartupNotificationSequencePrivate *priv; | ||||
|  | ||||
|   priv = meta_startup_notification_sequence_get_instance_private (seq); | ||||
|   return priv->timestamp; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_sequence_complete (MetaStartupNotificationSequence *seq) | ||||
| { | ||||
|   MetaStartupNotificationSequenceClass *klass; | ||||
|  | ||||
|   klass = META_STARTUP_NOTIFICATION_SEQUENCE_GET_CLASS (seq); | ||||
|  | ||||
|   if (klass->complete) | ||||
|     klass->complete (seq); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
| static void | ||||
| meta_startup_notification_sequence_x11_complete (MetaStartupNotificationSequence *seq) | ||||
| { | ||||
|   MetaStartupNotificationSequenceX11 *seq_x11; | ||||
|  | ||||
|   seq_x11 = META_STARTUP_NOTIFICATION_SEQUENCE_X11 (seq); | ||||
|   sn_startup_sequence_complete (seq_x11->seq); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_sequence_x11_finalize (GObject *object) | ||||
| { | ||||
|   MetaStartupNotificationSequenceX11 *seq; | ||||
|  | ||||
|   seq = META_STARTUP_NOTIFICATION_SEQUENCE_X11 (object); | ||||
|   sn_startup_sequence_unref (seq->seq); | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_startup_notification_sequence_x11_parent_class)->finalize (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_sequence_x11_set_property (GObject      *object, | ||||
|                                                      guint         prop_id, | ||||
|                                                      const GValue *value, | ||||
|                                                      GParamSpec   *pspec) | ||||
| { | ||||
|   MetaStartupNotificationSequenceX11 *seq; | ||||
|  | ||||
|   seq = META_STARTUP_NOTIFICATION_SEQUENCE_X11 (object); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_SEQ_X11_SEQ: | ||||
|       seq->seq = g_value_get_pointer (value); | ||||
|       sn_startup_sequence_ref (seq->seq); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_sequence_x11_get_property (GObject    *object, | ||||
|                                                      guint       prop_id, | ||||
|                                                      GValue     *value, | ||||
|                                                      GParamSpec *pspec) | ||||
| { | ||||
|   MetaStartupNotificationSequenceX11 *seq; | ||||
|  | ||||
|   seq = META_STARTUP_NOTIFICATION_SEQUENCE_X11 (object); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_SEQ_X11_SEQ: | ||||
|       g_value_set_pointer (value, seq->seq); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_sequence_x11_init (MetaStartupNotificationSequenceX11 *seq) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_sequence_x11_class_init (MetaStartupNotificationSequenceX11Class *klass) | ||||
| { | ||||
|   MetaStartupNotificationSequenceClass *seq_class; | ||||
|   GObjectClass *object_class; | ||||
|  | ||||
|   seq_class = META_STARTUP_NOTIFICATION_SEQUENCE_CLASS (klass); | ||||
|   seq_class->complete = meta_startup_notification_sequence_x11_complete; | ||||
|  | ||||
|   object_class = G_OBJECT_CLASS (klass); | ||||
|   object_class->finalize = meta_startup_notification_sequence_x11_finalize; | ||||
|   object_class->set_property = meta_startup_notification_sequence_x11_set_property; | ||||
|   object_class->get_property = meta_startup_notification_sequence_x11_get_property; | ||||
|  | ||||
|   seq_x11_props[PROP_SEQ_X11_SEQ] = | ||||
|     g_param_spec_pointer ("seq", | ||||
|                           "Sequence", | ||||
|                           "Sequence", | ||||
|                           G_PARAM_READWRITE | | ||||
|                           G_PARAM_CONSTRUCT_ONLY); | ||||
|  | ||||
|   g_object_class_install_properties (object_class, N_SEQ_X11_PROPS, | ||||
|                                      seq_x11_props); | ||||
| } | ||||
|  | ||||
| static MetaStartupNotificationSequence * | ||||
| meta_startup_notification_sequence_x11_new (SnStartupSequence *seq) | ||||
| { | ||||
|   gint64 timestamp; | ||||
|  | ||||
|   timestamp = sn_startup_sequence_get_timestamp (seq) * 1000; | ||||
|   return g_object_new (META_TYPE_STARTUP_NOTIFICATION_SEQUENCE_X11, | ||||
|                        "id", sn_startup_sequence_get_id (seq), | ||||
|                        "timestamp", timestamp, | ||||
|                        "seq", seq, | ||||
|                        NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_add_sequence_internal (MetaStartupNotification         *sn, | ||||
|                                                  MetaStartupNotificationSequence *seq) | ||||
| { | ||||
|   sn->startup_sequences = g_slist_prepend (sn->startup_sequences, | ||||
|                                            g_object_ref (seq)); | ||||
|  | ||||
|   meta_startup_notification_ensure_timeout (sn); | ||||
|   meta_startup_notification_update_feedback (sn); | ||||
| } | ||||
|  | ||||
| static void | ||||
| collect_timed_out_foreach (void *element, | ||||
|                            void *data) | ||||
| { | ||||
|   MetaStartupNotificationSequence *sequence = element; | ||||
|   CollectTimedOutData *ctod = data; | ||||
|   gint64 elapsed, timestamp; | ||||
|  | ||||
|   timestamp = meta_startup_notification_sequence_get_timestamp (sequence); | ||||
|   elapsed = ctod->now - timestamp; | ||||
|  | ||||
|   meta_topic (META_DEBUG_STARTUP, | ||||
|               "Sequence used %ld ms vs. %d max: %s\n", | ||||
|               elapsed, STARTUP_TIMEOUT, | ||||
|               meta_startup_notification_sequence_get_id (sequence)); | ||||
|  | ||||
|   if (elapsed > STARTUP_TIMEOUT) | ||||
|     ctod->list = g_slist_prepend (ctod->list, sequence); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| startup_sequence_timeout (void *data) | ||||
| { | ||||
|   MetaStartupNotification *sn = data; | ||||
|   CollectTimedOutData ctod; | ||||
|   GSList *l; | ||||
|  | ||||
|   ctod.list = NULL; | ||||
|   ctod.now = g_get_monotonic_time (); | ||||
|   g_slist_foreach (sn->startup_sequences, | ||||
|                    collect_timed_out_foreach, | ||||
|                    &ctod); | ||||
|  | ||||
|   for (l = ctod.list; l != NULL; l = l->next) | ||||
|     { | ||||
|       MetaStartupNotificationSequence *sequence = l->data; | ||||
|  | ||||
|       meta_topic (META_DEBUG_STARTUP, | ||||
|                   "Timed out sequence %s\n", | ||||
|                   meta_startup_notification_sequence_get_id (sequence)); | ||||
|  | ||||
|       meta_startup_notification_sequence_complete (sequence); | ||||
|     } | ||||
|  | ||||
|   g_slist_free (ctod.list); | ||||
|  | ||||
|   if (sn->startup_sequences != NULL) | ||||
|     { | ||||
|       return TRUE; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* remove */ | ||||
|       sn->startup_sequence_timeout = 0; | ||||
|       return FALSE; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_ensure_timeout (MetaStartupNotification *sn) | ||||
| { | ||||
|   if (sn->startup_sequence_timeout != 0) | ||||
|     return; | ||||
|  | ||||
|   /* our timeout just polls every second, instead of bothering | ||||
|    * to compute exactly when we may next time out | ||||
|    */ | ||||
|   sn->startup_sequence_timeout = g_timeout_add_seconds (1, | ||||
|                                                         startup_sequence_timeout, | ||||
|                                                         sn); | ||||
|   g_source_set_name_by_id (sn->startup_sequence_timeout, | ||||
|                            "[mutter] startup_sequence_timeout"); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_remove_sequence_internal (MetaStartupNotification         *sn, | ||||
|                                                     MetaStartupNotificationSequence *seq) | ||||
| { | ||||
|   sn->startup_sequences = g_slist_remove (sn->startup_sequences, seq); | ||||
|   meta_startup_notification_update_feedback (sn); | ||||
|  | ||||
|   if (sn->startup_sequences == NULL && | ||||
|       sn->startup_sequence_timeout != 0) | ||||
|     { | ||||
|       g_source_remove (sn->startup_sequence_timeout); | ||||
|       sn->startup_sequence_timeout = 0; | ||||
|     } | ||||
|  | ||||
|   g_object_unref (seq); | ||||
| } | ||||
|  | ||||
| static MetaStartupNotificationSequence * | ||||
| meta_startup_notification_lookup_sequence (MetaStartupNotification *sn, | ||||
|                                            const gchar             *id) | ||||
| { | ||||
|   MetaStartupNotificationSequence *seq; | ||||
|   const gchar *seq_id; | ||||
|   GSList *l; | ||||
|  | ||||
|   for (l = sn->startup_sequences; l; l = l->next) | ||||
|     { | ||||
|       seq = l->data; | ||||
|       seq_id = meta_startup_notification_sequence_get_id (seq); | ||||
|  | ||||
|       if (g_str_equal (seq_id, id)) | ||||
|         return l->data; | ||||
|     } | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_init (MetaStartupNotification *sn) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_finalize (GObject *object) | ||||
| { | ||||
|   MetaStartupNotification *sn = META_STARTUP_NOTIFICATION (object); | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
|   sn_monitor_context_unref (sn->sn_context); | ||||
|   sn_display_unref (sn->sn_display); | ||||
| #endif | ||||
|  | ||||
|   if (sn->startup_sequence_timeout) | ||||
|     g_source_remove (sn->startup_sequence_timeout); | ||||
|  | ||||
|   g_slist_foreach (sn->startup_sequences, (GFunc) g_object_unref, NULL); | ||||
|   g_slist_free (sn->startup_sequences); | ||||
|   sn->startup_sequences = NULL; | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_startup_notification_parent_class)->finalize (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_set_property (GObject      *object, | ||||
|                                         guint         prop_id, | ||||
|                                         const GValue *value, | ||||
|                                         GParamSpec   *pspec) | ||||
| { | ||||
|   MetaStartupNotification *sn = META_STARTUP_NOTIFICATION (object); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_SN_DISPLAY: | ||||
|       sn->display = g_value_get_object (value); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_get_property (GObject    *object, | ||||
|                                         guint       prop_id, | ||||
|                                         GValue     *value, | ||||
|                                         GParamSpec *pspec) | ||||
| { | ||||
|   MetaStartupNotification *sn = META_STARTUP_NOTIFICATION (object); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_SN_DISPLAY: | ||||
|       g_value_set_object (value, sn->display); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
| static void | ||||
| sn_error_trap_push (SnDisplay *sn_display, | ||||
|                     Display   *xdisplay) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   display = meta_display_for_x_display (xdisplay); | ||||
|   if (display != NULL) | ||||
|     meta_error_trap_push (display); | ||||
| } | ||||
|  | ||||
| static void | ||||
| sn_error_trap_pop (SnDisplay *sn_display, | ||||
|                    Display   *xdisplay) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|   display = meta_display_for_x_display (xdisplay); | ||||
|   if (display != NULL) | ||||
|     meta_error_trap_pop (display); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_sn_event (SnMonitorEvent *event, | ||||
|                                     void           *user_data) | ||||
| { | ||||
|   MetaStartupNotification *sn = user_data; | ||||
|   MetaStartupNotificationSequence *seq; | ||||
|   SnStartupSequence *sequence; | ||||
|  | ||||
|   sequence = sn_monitor_event_get_startup_sequence (event); | ||||
|  | ||||
|   sn_startup_sequence_ref (sequence); | ||||
|  | ||||
|   switch (sn_monitor_event_get_type (event)) | ||||
|     { | ||||
|     case SN_MONITOR_EVENT_INITIATED: | ||||
|       { | ||||
|         const char *wmclass; | ||||
|  | ||||
|         wmclass = sn_startup_sequence_get_wmclass (sequence); | ||||
|  | ||||
|         meta_topic (META_DEBUG_STARTUP, | ||||
|                     "Received startup initiated for %s wmclass %s\n", | ||||
|                     sn_startup_sequence_get_id (sequence), | ||||
|                     wmclass ? wmclass : "(unset)"); | ||||
|  | ||||
|         seq = meta_startup_notification_sequence_x11_new (sequence); | ||||
|         meta_startup_notification_add_sequence_internal (sn, seq); | ||||
|         g_object_unref (seq); | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case SN_MONITOR_EVENT_COMPLETED: | ||||
|       { | ||||
|         meta_topic (META_DEBUG_STARTUP, | ||||
|                     "Received startup completed for %s\n", | ||||
|                     sn_startup_sequence_get_id (sequence)); | ||||
|  | ||||
|         meta_startup_notification_remove_sequence (sn, sn_startup_sequence_get_id (sequence)); | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case SN_MONITOR_EVENT_CHANGED: | ||||
|       meta_topic (META_DEBUG_STARTUP, | ||||
|                   "Received startup changed for %s\n", | ||||
|                   sn_startup_sequence_get_id (sequence)); | ||||
|       break; | ||||
|  | ||||
|     case SN_MONITOR_EVENT_CANCELED: | ||||
|       meta_topic (META_DEBUG_STARTUP, | ||||
|                   "Received startup canceled for %s\n", | ||||
|                   sn_startup_sequence_get_id (sequence)); | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   g_signal_emit (sn, sn_signals[SN_CHANGED], 0, sequence); | ||||
|  | ||||
|   sn_startup_sequence_unref (sequence); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_constructed (GObject *object) | ||||
| { | ||||
|   MetaStartupNotification *sn = META_STARTUP_NOTIFICATION (object); | ||||
|  | ||||
|   g_assert (sn->display != NULL); | ||||
|  | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
|   sn->sn_display = sn_display_new (sn->display->xdisplay, | ||||
|                                    sn_error_trap_push, | ||||
|                                    sn_error_trap_pop); | ||||
|   sn->sn_context = | ||||
|     sn_monitor_context_new (sn->sn_display, | ||||
|                             sn->display->screen->number, | ||||
|                             meta_startup_notification_sn_event, | ||||
|                             sn, | ||||
|                             NULL); | ||||
| #endif | ||||
|   sn->startup_sequences = NULL; | ||||
|   sn->startup_sequence_timeout = 0; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_startup_notification_class_init (MetaStartupNotificationClass *klass) | ||||
| { | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   object_class->constructed = meta_startup_notification_constructed; | ||||
|   object_class->finalize = meta_startup_notification_finalize; | ||||
|   object_class->set_property = meta_startup_notification_set_property; | ||||
|   object_class->get_property = meta_startup_notification_get_property; | ||||
|  | ||||
|   sn_props[PROP_SN_DISPLAY] = | ||||
|     g_param_spec_object ("display", | ||||
|                          "Display", | ||||
|                          "Display", | ||||
|                          META_TYPE_DISPLAY, | ||||
|                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | | ||||
|                          G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   sn_signals[SN_CHANGED] = | ||||
|     g_signal_new ("changed", | ||||
|                   META_TYPE_STARTUP_NOTIFICATION, | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   0, NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 1, G_TYPE_POINTER); | ||||
|  | ||||
|   g_object_class_install_properties (object_class, N_SN_PROPS, sn_props); | ||||
| } | ||||
|  | ||||
| MetaStartupNotification * | ||||
| meta_startup_notification_get (MetaDisplay *display) | ||||
| { | ||||
|   static MetaStartupNotification *notification = NULL; | ||||
|  | ||||
|   if (!notification) | ||||
|     notification = g_object_new (META_TYPE_STARTUP_NOTIFICATION, | ||||
|                                  "display", display, | ||||
|                                  NULL); | ||||
|  | ||||
|   return notification; | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_startup_notification_remove_sequence (MetaStartupNotification *sn, | ||||
|                                            const gchar             *id) | ||||
| { | ||||
|   MetaStartupNotificationSequence *seq; | ||||
|  | ||||
|   seq = meta_startup_notification_lookup_sequence (sn, id); | ||||
|   if (seq) | ||||
|     meta_startup_notification_remove_sequence_internal (sn, seq); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_startup_notification_handle_xevent (MetaStartupNotification *sn, | ||||
|                                          XEvent                  *xevent) | ||||
| { | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
|   return sn_display_process_event (sn->sn_display, xevent); | ||||
| #endif | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| GSList * | ||||
| meta_startup_notification_get_sequences (MetaStartupNotification *sn) | ||||
| { | ||||
|   GSList *sequences = NULL; | ||||
| #ifdef HAVE_STARTUP_NOTIFICATION | ||||
|   GSList *l; | ||||
|  | ||||
|   /* We return a list of SnStartupSequences here */ | ||||
|   for (l = sn->startup_sequences; l; l = l->next) | ||||
|     { | ||||
|       MetaStartupNotificationSequenceX11 *seq_x11; | ||||
|  | ||||
|       if (!META_IS_STARTUP_NOTIFICATION_SEQUENCE_X11 (l->data)) | ||||
|         continue; | ||||
|  | ||||
|       seq_x11 = META_STARTUP_NOTIFICATION_SEQUENCE_X11 (l->data); | ||||
|       sequences = g_slist_prepend (sequences, seq_x11->seq); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|   return sequences; | ||||
| } | ||||
							
								
								
									
										105
									
								
								src/core/util.c
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								src/core/util.c
									
									
									
									
									
								
							| @@ -49,6 +49,9 @@ meta_topic_real_valist (MetaDebugTopic topic, | ||||
|                         va_list        args) G_GNUC_PRINTF(2, 0); | ||||
| #endif | ||||
|  | ||||
| static gboolean | ||||
| meta_later_remove_from_list (guint later_id, GSList **laters_list); | ||||
|  | ||||
| static gint verbose_topics = 0; | ||||
| static gboolean is_debugging = FALSE; | ||||
| static gboolean replace_current = FALSE; | ||||
| @@ -739,7 +742,14 @@ typedef struct | ||||
|   gboolean run_once; | ||||
| } MetaLater; | ||||
|  | ||||
| static GSList *laters = NULL; | ||||
| static GSList *laters[] = { | ||||
|   NULL, /* META_LATER_RESIZE */ | ||||
|   NULL, /* META_LATER_CALC_SHOWING */ | ||||
|   NULL, /* META_LATER_CHECK_FULLSCREEN */ | ||||
|   NULL, /* META_LATER_SYNC_STACK */ | ||||
|   NULL, /* META_LATER_BEFORE_REDRAW */ | ||||
|   NULL, /* META_LATER_IDLE */ | ||||
| }; | ||||
| /* This is a dummy timeline used to get the Clutter master clock running */ | ||||
| static ClutterTimeline *later_timeline; | ||||
| static guint later_repaint_func = 0; | ||||
| @@ -772,25 +782,14 @@ destroy_later (MetaLater *later) | ||||
|   unref_later (later); | ||||
| } | ||||
|  | ||||
| /* Used to sort the list of laters with the highest priority | ||||
|  * functions first. | ||||
|  */ | ||||
| static int | ||||
| compare_laters (gconstpointer a, | ||||
|                 gconstpointer b) | ||||
| { | ||||
|   return ((const MetaLater *)a)->when - ((const MetaLater *)b)->when; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| run_repaint_laters (gpointer data) | ||||
| static void | ||||
| run_repaint_laters (GSList **laters_list) | ||||
| { | ||||
|   GSList *laters_copy; | ||||
|   GSList *l; | ||||
|   gboolean keep_timeline_running = FALSE; | ||||
|  | ||||
|   laters_copy = NULL; | ||||
|   for (l = laters; l; l = l->next) | ||||
|   for (l = *laters_list; l; l = l->next) | ||||
|     { | ||||
|       MetaLater *later = l->data; | ||||
|       if (later->source == 0 || | ||||
| @@ -806,22 +805,41 @@ run_repaint_laters (gpointer data) | ||||
|     { | ||||
|       MetaLater *later = l->data; | ||||
|  | ||||
|       if (later->func && later->func (later->data)) | ||||
|       if (!later->func || !later->func (later->data)) | ||||
|         meta_later_remove_from_list (later->id, laters_list); | ||||
|       unref_later (later); | ||||
|     } | ||||
|  | ||||
|   g_slist_free (laters_copy); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| run_all_repaint_laters (gpointer data) | ||||
| { | ||||
|   guint i; | ||||
|   GSList *l; | ||||
|   gboolean keep_timeline_running = FALSE; | ||||
|  | ||||
|   for (i = 0; i < G_N_ELEMENTS (laters); i++) | ||||
|     { | ||||
|       run_repaint_laters (&laters[i]); | ||||
|     } | ||||
|  | ||||
|   for (i = 0; i < G_N_ELEMENTS (laters); i++) | ||||
|     { | ||||
|       for (l = laters[i]; l; l = l->next) | ||||
|         { | ||||
|           MetaLater *later = l->data; | ||||
|  | ||||
|           if (later->source == 0) | ||||
|             keep_timeline_running = TRUE; | ||||
|         } | ||||
|       else | ||||
|         meta_later_remove (later->id); | ||||
|       unref_later (later); | ||||
|     } | ||||
|  | ||||
|   if (!keep_timeline_running) | ||||
|     clutter_timeline_stop (later_timeline); | ||||
|  | ||||
|   g_slist_free (laters_copy); | ||||
|  | ||||
|   /* Just keep the repaint func around - it's cheap if the list is empty */ | ||||
|   /* Just keep the repaint func around - it's cheap if the lists are empty */ | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| @@ -832,7 +850,7 @@ ensure_later_repaint_func (void) | ||||
|     later_timeline = clutter_timeline_new (G_MAXUINT); | ||||
|  | ||||
|   if (later_repaint_func == 0) | ||||
|     later_repaint_func = clutter_threads_add_repaint_func (run_repaint_laters, | ||||
|     later_repaint_func = clutter_threads_add_repaint_func (run_all_repaint_laters, | ||||
|                                                            NULL, NULL); | ||||
|  | ||||
|   /* Make sure the repaint function gets run */ | ||||
| @@ -888,7 +906,7 @@ meta_later_add (MetaLaterType  when, | ||||
|   later->data = data; | ||||
|   later->notify = notify; | ||||
|  | ||||
|   laters = g_slist_insert_sorted (laters, later, compare_laters); | ||||
|   laters[when] = g_slist_prepend (laters[when], later); | ||||
|  | ||||
|   switch (when) | ||||
|     { | ||||
| @@ -920,6 +938,29 @@ meta_later_add (MetaLaterType  when, | ||||
|   return later->id; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_later_remove_from_list (guint later_id, GSList **laters_list) | ||||
| { | ||||
|   GSList *l; | ||||
|  | ||||
|   for (l = *laters_list; l; l = l->next) | ||||
|     { | ||||
|       MetaLater *later = l->data; | ||||
|  | ||||
|       if (later->id == later_id) | ||||
|         { | ||||
|           *laters_list = g_slist_delete_link (*laters_list, l); | ||||
|           /* If this was a "repaint func" later, we just let the | ||||
|            * repaint func run and get removed | ||||
|            */ | ||||
|           destroy_later (later); | ||||
|           return TRUE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_later_remove: | ||||
|  * @later_id: the integer ID returned from meta_later_add() | ||||
| @@ -929,20 +970,12 @@ meta_later_add (MetaLaterType  when, | ||||
| void | ||||
| meta_later_remove (guint later_id) | ||||
| { | ||||
|   GSList *l; | ||||
|   guint i; | ||||
|  | ||||
|   for (l = laters; l; l = l->next) | ||||
|   for (i = 0; i < G_N_ELEMENTS (laters); i++) | ||||
|     { | ||||
|       MetaLater *later = l->data; | ||||
|       if (later->id == later_id) | ||||
|         { | ||||
|           laters = g_slist_delete_link (laters, l); | ||||
|           /* If this was a "repaint func" later, we just let the | ||||
|            * repaint func run and get removed | ||||
|            */ | ||||
|           destroy_later (later); | ||||
|           return; | ||||
|         } | ||||
|       if (meta_later_remove_from_list (later_id, &laters[i])) | ||||
|         return; | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -88,6 +88,20 @@ typedef enum | ||||
|   META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED = 1 << 2, | ||||
| } MetaMoveResizeResultFlags; | ||||
|  | ||||
| /* This contains all the "state" needed for a certain size configuration. | ||||
|  * We have three of these size configurations: normal, tiled, and | ||||
|  * maximized. The idea here is that if the user tiles a normal window, | ||||
|  * then maximizes it, we should, upon unmaximizing and untiling the window, | ||||
|  * return to a normal state. We need a way of storing this information | ||||
|  * while maximized, so we use this structure. */ | ||||
| struct _MetaWindowSizeState | ||||
| { | ||||
|   guint maximized_horizontally : 1; | ||||
|   guint maximized_vertically : 1; | ||||
|   MetaRectangle rect; | ||||
| }; | ||||
| typedef struct _MetaWindowSizeState MetaWindowSizeState; | ||||
|  | ||||
| struct _MetaWindow | ||||
| { | ||||
|   GObject parent_instance; | ||||
| @@ -157,14 +171,6 @@ struct _MetaWindow | ||||
|   guint maximize_vertically_after_placement : 1; | ||||
|   guint minimize_after_placement : 1; | ||||
|  | ||||
|   /* The current or requested tile mode. If maximized_vertically is true, | ||||
|    * this is the current mode. If not, it is the mode which will be | ||||
|    * requested after the window grab is released */ | ||||
|   guint tile_mode : 2; | ||||
|   /* The last "full" maximized/unmaximized state. We need to keep track of | ||||
|    * that to toggle between normal/tiled or maximized/tiled states. */ | ||||
|   guint saved_maximize : 1; | ||||
|   int tile_monitor_number; | ||||
|   int preferred_output_winsys_id; | ||||
|  | ||||
|   /* Whether we're shaded */ | ||||
| @@ -401,9 +407,6 @@ struct _MetaWindow | ||||
|   /* The current window geometry of the window. */ | ||||
|   MetaRectangle rect; | ||||
|  | ||||
|   /* The geometry to restore when we unmaximize. */ | ||||
|   MetaRectangle saved_rect; | ||||
|  | ||||
|   /* This is the geometry the window will have if no constraints have | ||||
|    * applied. We use this whenever we are moving implicitly (for example, | ||||
|    * if we move to avoid a panel, we can snap back to this position if | ||||
| @@ -441,11 +444,16 @@ struct _MetaWindow | ||||
|   /* Focused window that is (directly or indirectly) attached to this one */ | ||||
|   MetaWindow *attached_focus_window; | ||||
|  | ||||
|   /* The currently complementary tiled window, if any */ | ||||
|   MetaWindow *tile_match; | ||||
|  | ||||
|   /* Bypass compositor hints */ | ||||
|   guint bypass_compositor; | ||||
|  | ||||
|   /* This is where we store data while in another state. The information | ||||
|    * above in MetaWindow is always the current state of the window. */ | ||||
|   struct { | ||||
|     MetaWindowSizeState normal, tiled, maximized; | ||||
|   } size_states; | ||||
|  | ||||
|   MetaDirection constrained_edges; | ||||
| }; | ||||
|  | ||||
| struct _MetaWindowClass | ||||
| @@ -492,17 +500,8 @@ struct _MetaWindowClass | ||||
|                                         (w)->maximized_vertically) | ||||
| #define META_WINDOW_MAXIMIZED_VERTICALLY(w)    ((w)->maximized_vertically) | ||||
| #define META_WINDOW_MAXIMIZED_HORIZONTALLY(w)  ((w)->maximized_horizontally) | ||||
| #define META_WINDOW_TILED_SIDE_BY_SIDE(w)      ((w)->maximized_vertically && \ | ||||
|                                                 !(w)->maximized_horizontally && \ | ||||
|                                                  (w)->tile_mode != META_TILE_NONE) | ||||
| #define META_WINDOW_TILED_LEFT(w)     (META_WINDOW_TILED_SIDE_BY_SIDE(w) && \ | ||||
|                                        (w)->tile_mode == META_TILE_LEFT) | ||||
| #define META_WINDOW_TILED_RIGHT(w)    (META_WINDOW_TILED_SIDE_BY_SIDE(w) && \ | ||||
|                                        (w)->tile_mode == META_TILE_RIGHT) | ||||
| #define META_WINDOW_TILED_MAXIMIZED(w)(META_WINDOW_MAXIMIZED(w) && \ | ||||
|                                        (w)->tile_mode == META_TILE_MAXIMIZED) | ||||
| #define META_WINDOW_ALLOWS_MOVE(w)     ((w)->has_move_func && !(w)->fullscreen) | ||||
| #define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w)   ((w)->has_resize_func && !META_WINDOW_MAXIMIZED (w) && !META_WINDOW_TILED_SIDE_BY_SIDE(w) && !(w)->fullscreen && !(w)->shaded) | ||||
| #define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w)   ((w)->has_resize_func && !META_WINDOW_MAXIMIZED (w) && !(w)->fullscreen && !(w)->shaded) | ||||
| #define META_WINDOW_ALLOWS_RESIZE(w)   (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) &&                \ | ||||
|                                         (((w)->size_hints.min_width < (w)->size_hints.max_width) ||  \ | ||||
|                                          ((w)->size_hints.min_height < (w)->size_hints.max_height))) | ||||
| @@ -522,7 +521,6 @@ void        meta_window_unmanage           (MetaWindow  *window, | ||||
|                                             guint32      timestamp); | ||||
| void        meta_window_queue              (MetaWindow  *window, | ||||
|                                             guint queuebits); | ||||
| void        meta_window_tile               (MetaWindow        *window); | ||||
| void        meta_window_maximize_internal  (MetaWindow        *window, | ||||
|                                             MetaMaximizeFlags  directions, | ||||
|                                             MetaRectangle     *saved_rect); | ||||
| @@ -584,11 +582,6 @@ gboolean meta_window_handle_mouse_grab_op_event  (MetaWindow         *window, | ||||
|  | ||||
| GList* meta_window_get_workspaces (MetaWindow *window); | ||||
|  | ||||
| int meta_window_get_current_tile_monitor_number (MetaWindow *window); | ||||
| void meta_window_get_current_tile_area         (MetaWindow    *window, | ||||
|                                                 MetaRectangle *tile_area); | ||||
|  | ||||
|  | ||||
| gboolean meta_window_same_application (MetaWindow *window, | ||||
|                                        MetaWindow *other_window); | ||||
|  | ||||
| @@ -626,9 +619,6 @@ void meta_window_update_for_monitors_changed (MetaWindow *window); | ||||
| void meta_window_on_all_workspaces_changed (MetaWindow *window); | ||||
|  | ||||
| gboolean meta_window_should_attach_to_parent (MetaWindow *window); | ||||
| gboolean meta_window_can_tile_side_by_side   (MetaWindow *window); | ||||
|  | ||||
| void meta_window_compute_tile_match (MetaWindow *window); | ||||
|  | ||||
| gboolean meta_window_updates_are_frozen (MetaWindow *window); | ||||
|  | ||||
| @@ -695,4 +685,7 @@ gboolean meta_window_has_pointer (MetaWindow *window); | ||||
|  | ||||
| void meta_window_emit_size_changed (MetaWindow *window); | ||||
|  | ||||
| void meta_window_toggle_tile (MetaWindow   *window, | ||||
|                               MetaTileZone  tile_zone); | ||||
|  | ||||
| #endif | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -83,7 +83,11 @@ typedef enum | ||||
|   META_FRAME_IS_FLASHING              = 1 << 14, | ||||
|   META_FRAME_ABOVE                    = 1 << 15, | ||||
|   META_FRAME_TILED_LEFT               = 1 << 16, | ||||
|   META_FRAME_TILED_RIGHT              = 1 << 17 | ||||
|   META_FRAME_TILED_RIGHT              = 1 << 17, | ||||
|   META_FRAME_CONSTRAINED_LEFT_EDGE    = 1 << 18, | ||||
|   META_FRAME_CONSTRAINED_RIGHT_EDGE   = 1 << 19, | ||||
|   META_FRAME_CONSTRAINED_TOP_EDGE     = 1 << 20, | ||||
|   META_FRAME_CONSTRAINED_BOTTOM_EDGE  = 1 << 21, | ||||
| } MetaFrameFlags; | ||||
|  | ||||
| /** | ||||
| @@ -317,6 +321,26 @@ typedef enum | ||||
|   META_DIRECTION_VERTICAL   = META_DIRECTION_UP   | META_DIRECTION_DOWN, | ||||
| } MetaDirection; | ||||
|  | ||||
| /* Tile zones are specified in terms of their constrained edges. | ||||
|  * So, "top left corner" is top and left, which should be obvious, | ||||
|  * but "left side of the screen" is top, bottom, and left | ||||
|  */ | ||||
| typedef enum { | ||||
|   META_TILE_ZONE_MAXIMIZED_HORZ = META_DIRECTION_HORIZONTAL, | ||||
|   META_TILE_ZONE_MAXIMIZED_VERT = META_DIRECTION_VERTICAL, | ||||
|   META_TILE_ZONE_MAXIMIZED      = META_TILE_ZONE_MAXIMIZED_HORZ | META_TILE_ZONE_MAXIMIZED_VERT, | ||||
|  | ||||
|   META_TILE_ZONE_W = META_TILE_ZONE_MAXIMIZED_VERT | META_DIRECTION_LEFT, | ||||
|   META_TILE_ZONE_E = META_TILE_ZONE_MAXIMIZED_VERT | META_DIRECTION_RIGHT, | ||||
|   META_TILE_ZONE_N = META_TILE_ZONE_MAXIMIZED_HORZ | META_DIRECTION_TOP, | ||||
|   META_TILE_ZONE_S = META_TILE_ZONE_MAXIMIZED_HORZ | META_DIRECTION_BOTTOM, | ||||
|  | ||||
|   META_TILE_ZONE_NW = META_DIRECTION_TOP | META_DIRECTION_LEFT, | ||||
|   META_TILE_ZONE_NE = META_DIRECTION_TOP | META_DIRECTION_RIGHT, | ||||
|   META_TILE_ZONE_SW = META_DIRECTION_BOTTOM | META_DIRECTION_LEFT, | ||||
|   META_TILE_ZONE_SE = META_DIRECTION_BOTTOM | META_DIRECTION_RIGHT, | ||||
| } MetaTileZone; | ||||
|  | ||||
| /** | ||||
|  * MetaMotionDirection: | ||||
|  * @META_MOTION_UP: Upwards motion | ||||
| @@ -520,7 +544,6 @@ void meta_frame_borders_clear (MetaFrameBorders *self); | ||||
|  * @META_LAYER_TOP: Top layer | ||||
|  * @META_LAYER_DOCK: Dock layer | ||||
|  * @META_LAYER_FULLSCREEN: Fullscreen layer | ||||
|  * @META_LAYER_FOCUSED_WINDOW: Focused window layer | ||||
|  * @META_LAYER_OVERRIDE_REDIRECT: Override-redirect layer | ||||
|  * @META_LAYER_LAST: Marks the end of the #MetaStackLayer enumeration | ||||
|  * | ||||
| @@ -535,7 +558,6 @@ typedef enum | ||||
|   META_LAYER_TOP	       = 4, /* Same as DOCK; see EWMH and bug 330717 */ | ||||
|   META_LAYER_DOCK	       = 4, | ||||
|   META_LAYER_FULLSCREEN	       = 5, | ||||
|   META_LAYER_FOCUSED_WINDOW    = 6, | ||||
|   META_LAYER_OVERRIDE_REDIRECT = 7, | ||||
|   META_LAYER_LAST	       = 8 | ||||
| } MetaStackLayer; | ||||
|   | ||||
| @@ -214,8 +214,6 @@ MetaFrameType meta_window_get_frame_type (MetaWindow *window); | ||||
|  | ||||
| cairo_region_t *meta_window_get_frame_bounds (MetaWindow *window); | ||||
|  | ||||
| MetaWindow *meta_window_get_tile_match (MetaWindow *window); | ||||
|  | ||||
| void        meta_window_make_fullscreen    (MetaWindow  *window); | ||||
| void        meta_window_unmake_fullscreen  (MetaWindow  *window); | ||||
| void        meta_window_make_above         (MetaWindow  *window); | ||||
| @@ -260,4 +258,8 @@ gboolean meta_window_is_client_decorated (MetaWindow *window); | ||||
| gboolean meta_window_titlebar_is_onscreen    (MetaWindow *window); | ||||
| void     meta_window_shove_titlebar_onscreen (MetaWindow *window); | ||||
|  | ||||
| void     meta_window_tile (MetaWindow   *window, | ||||
|                            MetaTileZone  tile_zone); | ||||
| void     meta_window_untile (MetaWindow *window); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1136,10 +1136,10 @@ main (int argc, char **argv) | ||||
|  | ||||
|   /* Then initalize mutter with a different set of arguments */ | ||||
|  | ||||
|   char *fake_args[] = { NULL, (char *)"--wayland" }; | ||||
|   char *fake_args[] = { NULL, (char *)"--wayland", (char *)"--nested" }; | ||||
|   fake_args[0] = argv[0]; | ||||
|   char **fake_argv = fake_args; | ||||
|   int fake_argc = 2; | ||||
|   int fake_argc = G_N_ELEMENTS (fake_args); | ||||
|  | ||||
|   char *basename = g_path_get_basename (argv[0]); | ||||
|   char *dirname = g_path_get_dirname (argv[0]); | ||||
|   | ||||
							
								
								
									
										238
									
								
								src/tests/unit-tests.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								src/tests/unit-tests.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,238 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2015 Red Hat, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #include <glib.h> | ||||
| #include <stdlib.h> | ||||
|  | ||||
| #include <meta/main.h> | ||||
| #include <meta/util.h> | ||||
|  | ||||
| #include "compositor/meta-plugin-manager.h" | ||||
|  | ||||
| typedef struct _MetaTestLaterOrderCallbackData | ||||
| { | ||||
|   GMainLoop *loop; /* Loop to terminate when done. */ | ||||
|   int callback_num; /* Callback number integer. */ | ||||
|   int *expected_callback_num; /* Pointer to the expected callback number. */ | ||||
| } MetaTestLaterOrderCallbackData; | ||||
|  | ||||
| static gboolean | ||||
| test_later_order_callback (gpointer user_data) | ||||
| { | ||||
|   MetaTestLaterOrderCallbackData *data = user_data; | ||||
|  | ||||
|   g_assert_cmpint (data->callback_num, ==, *data->expected_callback_num); | ||||
|  | ||||
|   if (*data->expected_callback_num == 0) | ||||
|     g_main_loop_quit (data->loop); | ||||
|   else | ||||
|     (*data->expected_callback_num)--; | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_test_util_later_order (void) | ||||
| { | ||||
|   GMainLoop *loop; | ||||
|   int expected_callback_num; | ||||
|   int i; | ||||
|   const int num_callbacks = 3; | ||||
|   MetaTestLaterOrderCallbackData callback_data[num_callbacks]; | ||||
|  | ||||
|   loop = g_main_loop_new (NULL, FALSE); | ||||
|  | ||||
|   /* Schedule three BEFORE_DRAW callbacks each with its own number associated | ||||
|    * with it. | ||||
|    */ | ||||
|   for (i = 0; i < num_callbacks; i++) | ||||
|     { | ||||
|       callback_data[i] = (MetaTestLaterOrderCallbackData) { | ||||
|         .loop = loop, | ||||
|         .callback_num = i, | ||||
|         .expected_callback_num = &expected_callback_num, | ||||
|       }; | ||||
|       meta_later_add (META_LATER_BEFORE_REDRAW, | ||||
|                       test_later_order_callback, | ||||
|                       &callback_data[i], | ||||
|                       NULL); | ||||
|     } | ||||
|  | ||||
|   /* Check that the callbacks are invoked in the opposite order that they were | ||||
|    * scheduled. Each callback will decrease the number by 1 after it checks the | ||||
|    * validity. | ||||
|    */ | ||||
|   expected_callback_num = num_callbacks - 1; | ||||
|   g_main_loop_run (loop); | ||||
|   g_assert_cmpint (expected_callback_num, ==, 0); | ||||
|   g_main_loop_unref (loop); | ||||
| } | ||||
|  | ||||
| typedef enum _MetaTestLaterScheduleFromLaterState | ||||
| { | ||||
|   META_TEST_LATER_EXPECT_CALC_SHOWING, | ||||
|   META_TEST_LATER_EXPECT_SYNC_STACK, | ||||
|   META_TEST_LATER_EXPECT_BEFORE_REDRAW, | ||||
|   META_TEST_LATER_FINISHED, | ||||
| } MetaTestLaterScheduleFromLaterState; | ||||
|  | ||||
| typedef struct _MetaTestLaterScheduleFromLaterData | ||||
| { | ||||
|   GMainLoop *loop; | ||||
|   MetaTestLaterScheduleFromLaterState state; | ||||
| } MetaTestLaterScheduleFromLaterData; | ||||
|  | ||||
| static gboolean | ||||
| test_later_schedule_from_later_sync_stack_callback (gpointer user_data); | ||||
|  | ||||
| static gboolean | ||||
| test_later_schedule_from_later_calc_showing_callback (gpointer user_data) | ||||
| { | ||||
|   MetaTestLaterScheduleFromLaterData *data = user_data; | ||||
|  | ||||
|   g_assert_cmpint (data->state, ==, META_TEST_LATER_EXPECT_CALC_SHOWING); | ||||
|  | ||||
|   meta_later_add (META_LATER_SYNC_STACK, | ||||
|                   test_later_schedule_from_later_sync_stack_callback, | ||||
|                   data, | ||||
|                   NULL); | ||||
|  | ||||
|   data->state = META_TEST_LATER_EXPECT_SYNC_STACK; | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| test_later_schedule_from_later_sync_stack_callback (gpointer user_data) | ||||
| { | ||||
|   MetaTestLaterScheduleFromLaterData *data = user_data; | ||||
|  | ||||
|   g_assert_cmpint (data->state, ==, META_TEST_LATER_EXPECT_SYNC_STACK); | ||||
|  | ||||
|   data->state = META_TEST_LATER_EXPECT_BEFORE_REDRAW; | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| test_later_schedule_from_later_before_redraw_callback (gpointer user_data) | ||||
| { | ||||
|   MetaTestLaterScheduleFromLaterData *data = user_data; | ||||
|  | ||||
|   g_assert_cmpint (data->state, ==, META_TEST_LATER_EXPECT_BEFORE_REDRAW); | ||||
|   data->state = META_TEST_LATER_FINISHED; | ||||
|   g_main_loop_quit (data->loop); | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_test_util_later_schedule_from_later (void) | ||||
| { | ||||
|   MetaTestLaterScheduleFromLaterData data; | ||||
|  | ||||
|   data.loop = g_main_loop_new (NULL, FALSE); | ||||
|  | ||||
|   /* Test that scheduling a MetaLater with 'when' being later than the one being | ||||
|    * invoked causes it to be invoked before any callback with a later 'when' | ||||
|    * value being invoked. | ||||
|    * | ||||
|    * The first and last callback is queued here. The one to be invoked in | ||||
|    * between is invoked in test_later_schedule_from_later_calc_showing_callback. | ||||
|    */ | ||||
|   meta_later_add (META_LATER_CALC_SHOWING, | ||||
|                   test_later_schedule_from_later_calc_showing_callback, | ||||
|                   &data, | ||||
|                   NULL); | ||||
|   meta_later_add (META_LATER_BEFORE_REDRAW, | ||||
|                   test_later_schedule_from_later_before_redraw_callback, | ||||
|                   &data, | ||||
|                   NULL); | ||||
|  | ||||
|   data.state = META_TEST_LATER_EXPECT_CALC_SHOWING; | ||||
|  | ||||
|   g_main_loop_run (data.loop); | ||||
|   g_main_loop_unref (data.loop); | ||||
|  | ||||
|   g_assert_cmpint (data.state, ==, META_TEST_LATER_FINISHED); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| run_tests (gpointer data) | ||||
| { | ||||
|   gboolean ret; | ||||
|  | ||||
|   ret = g_test_run (); | ||||
|  | ||||
|   meta_quit (ret != 0); | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| init_tests (int argc, char **argv) | ||||
| { | ||||
|   g_test_init (&argc, &argv, NULL); | ||||
|   g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id="); | ||||
|  | ||||
|   g_test_add_func ("/util/meta-later/order", meta_test_util_later_order); | ||||
|   g_test_add_func ("/util/meta-later/schedule-from-later", | ||||
|                    meta_test_util_later_schedule_from_later); | ||||
| } | ||||
|  | ||||
| int | ||||
| main (int argc, char *argv[]) | ||||
| { | ||||
|   GOptionContext *ctx; | ||||
|   GError *error = NULL; | ||||
|  | ||||
|   ctx = g_option_context_new (NULL); | ||||
|  | ||||
|   if (!g_option_context_parse (ctx, | ||||
|                                &argc, &argv, &error)) | ||||
|     { | ||||
|       g_printerr ("%s", error->message); | ||||
|       return 1; | ||||
|     } | ||||
|  | ||||
|   g_option_context_free (ctx); | ||||
|  | ||||
|   const char *fake_args[] = { NULL, "--wayland", "--nested" }; | ||||
|   fake_args[0] = argv[0]; | ||||
|   char **fake_argv = (char**)fake_args; | ||||
|   int fake_argc = G_N_ELEMENTS (fake_args); | ||||
|  | ||||
|   ctx = meta_get_option_context (); | ||||
|   if (!g_option_context_parse (ctx, &fake_argc, &fake_argv, &error)) | ||||
|     { | ||||
|       g_printerr ("mutter: %s\n", error->message); | ||||
|       exit (1); | ||||
|     } | ||||
|   g_option_context_free (ctx); | ||||
|  | ||||
|   meta_plugin_manager_load ("default"); | ||||
|  | ||||
|   meta_init (); | ||||
|   meta_register_with_session (); | ||||
|  | ||||
|   init_tests (argc, argv); | ||||
|   g_idle_add (run_tests, NULL); | ||||
|  | ||||
|   return meta_run (); | ||||
| } | ||||
| @@ -447,7 +447,7 @@ meta_frames_new (int screen_number) | ||||
| } | ||||
|  | ||||
| static const char * | ||||
| get_theme_variant_override (MetaFrames *frames) | ||||
| get_global_theme_variant (MetaFrames *frames) | ||||
| { | ||||
|   GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (frames)); | ||||
|   GtkSettings *settings = gtk_settings_get_for_screen (screen); | ||||
| @@ -474,19 +474,15 @@ meta_ui_frame_attach_style (MetaUIFrame *frame) | ||||
| { | ||||
|   MetaFrames *frames = frame->frames; | ||||
|   const char *variant; | ||||
|   const char *variant_override; | ||||
|  | ||||
|   if (frame->style_info != NULL) | ||||
|     meta_style_info_unref (frame->style_info); | ||||
|  | ||||
|   variant_override = get_theme_variant_override (frame->frames); | ||||
|   variant = frame->meta_window->gtk_theme_variant; | ||||
|   if (variant == NULL) | ||||
|     variant = get_global_theme_variant (frame->frames);; | ||||
|  | ||||
|   if (variant_override) | ||||
|     variant = variant_override; | ||||
|   else | ||||
|     variant = frame->meta_window->gtk_theme_variant; | ||||
|  | ||||
|   if (variant == NULL || strcmp(variant, "normal") == 0) | ||||
|   if (variant == NULL || *variant == '\0') | ||||
|     frame->style_info = meta_style_info_ref (frames->normal_style); | ||||
|   else | ||||
|     frame->style_info = meta_style_info_ref (meta_frames_get_theme_variant (frames, | ||||
| @@ -1366,6 +1362,10 @@ meta_ui_frame_get_mask (MetaUIFrame *frame, | ||||
|                          borders.invisible.left / scale, | ||||
|                          borders.invisible.top / scale, | ||||
|                          frame_rect.width / scale, frame_rect.height / scale); | ||||
|   gtk_render_background (frame->style_info->styles[META_STYLE_ELEMENT_TITLEBAR], cr, | ||||
|                          borders.invisible.left / scale, | ||||
|                          borders.invisible.top / scale, | ||||
|                          frame_rect.width / scale, borders.total.top / scale); | ||||
| } | ||||
|  | ||||
| /* XXX -- this is disgusting. Find a better approach here. | ||||
|   | ||||
| @@ -53,6 +53,8 @@ typedef struct _MetaFrameGeometry MetaFrameGeometry; | ||||
|  **/ | ||||
| struct _MetaFrameLayout | ||||
| { | ||||
|   /** Invisible border required by the theme */ | ||||
|   GtkBorder invisible_border; | ||||
|   /** Border/padding of the entire frame */ | ||||
|   GtkBorder frame_border; | ||||
|   /** Border/padding of the titlebar region */ | ||||
| @@ -167,6 +169,7 @@ typedef enum | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   META_STYLE_ELEMENT_WINDOW, | ||||
|   META_STYLE_ELEMENT_FRAME, | ||||
|   META_STYLE_ELEMENT_TITLEBAR, | ||||
|   META_STYLE_ELEMENT_TITLE, | ||||
|   | ||||
| @@ -94,23 +94,31 @@ meta_frame_layout_get_borders (const MetaFrameLayout *layout, | ||||
|   borders->visible.right  = layout->frame_border.right; | ||||
|   borders->visible.bottom = layout->frame_border.bottom; | ||||
|  | ||||
|   borders->invisible = layout->invisible_border; | ||||
|  | ||||
|   draggable_borders = meta_prefs_get_draggable_border_width (); | ||||
|  | ||||
|   if (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE) | ||||
|     { | ||||
|       borders->invisible.left   = MAX (0, draggable_borders - borders->visible.left); | ||||
|       borders->invisible.right  = MAX (0, draggable_borders - borders->visible.right); | ||||
|       if (!(flags & META_FRAME_CONSTRAINED_LEFT_EDGE)) | ||||
|         borders->invisible.left   = MAX (borders->invisible.left, | ||||
|                                          draggable_borders - borders->visible.left); | ||||
|       if (!(flags & META_FRAME_CONSTRAINED_RIGHT_EDGE)) | ||||
|         borders->invisible.right  = MAX (borders->invisible.right, | ||||
|                                          draggable_borders - borders->visible.right); | ||||
|     } | ||||
|  | ||||
|   if (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE) | ||||
|     { | ||||
|       borders->invisible.bottom = MAX (0, draggable_borders - borders->visible.bottom); | ||||
|  | ||||
|       /* borders.visible.top is the height of the *title bar*. We can't do the same | ||||
|        * algorithm here, titlebars are expectedly much bigger. Just subtract a couple | ||||
|        * pixels to get a proper feel. */ | ||||
|       if (type != META_FRAME_TYPE_ATTACHED) | ||||
|         borders->invisible.top    = MAX (0, draggable_borders - 2); | ||||
|       if (!(flags & META_FRAME_CONSTRAINED_TOP_EDGE) && type != META_FRAME_TYPE_ATTACHED) | ||||
|         borders->invisible.top    = MAX (borders->invisible.top, draggable_borders - 2); | ||||
|  | ||||
|       if (!(flags & META_FRAME_CONSTRAINED_BOTTOM_EDGE)) | ||||
|         borders->invisible.bottom = MAX (borders->invisible.bottom, | ||||
|                                          draggable_borders - borders->visible.bottom); | ||||
|     } | ||||
|  | ||||
|   borders->total.left   = borders->invisible.left   + borders->visible.left; | ||||
| @@ -266,6 +274,7 @@ meta_frame_layout_sync_with_style (MetaFrameLayout *layout, | ||||
|   GtkStyleContext *style; | ||||
|   GtkBorder border; | ||||
|   GtkRequisition requisition; | ||||
|   GdkRectangle clip_rect; | ||||
|   int border_radius, max_radius; | ||||
|  | ||||
|   meta_style_info_set_flags (style_info, flags); | ||||
| @@ -274,6 +283,12 @@ meta_frame_layout_sync_with_style (MetaFrameLayout *layout, | ||||
|   get_padding_and_border (style, &layout->frame_border); | ||||
|   scale_border (&layout->frame_border, layout->title_scale); | ||||
|  | ||||
|   gtk_render_background_get_clip (style, 0, 0, 0, 0, &clip_rect); | ||||
|   layout->invisible_border.left = -clip_rect.x; | ||||
|   layout->invisible_border.right = clip_rect.width + clip_rect.x; | ||||
|   layout->invisible_border.top = -clip_rect.y; | ||||
|   layout->invisible_border.bottom = clip_rect.height + clip_rect.y; | ||||
|  | ||||
|   if (layout->hide_buttons) | ||||
|     layout->icon_size = 0; | ||||
|  | ||||
| @@ -1033,15 +1048,20 @@ meta_theme_create_style_info (GdkScreen   *screen, | ||||
|   style_info = g_new0 (MetaStyleInfo, 1); | ||||
|   style_info->refcount = 1; | ||||
|  | ||||
|   style_info->styles[META_STYLE_ELEMENT_FRAME] = | ||||
|   style_info->styles[META_STYLE_ELEMENT_WINDOW] = | ||||
|     create_style_context (META_TYPE_FRAMES, | ||||
|                           NULL, | ||||
|                           provider, | ||||
|                           "decoration", | ||||
|                           "window", | ||||
|                           GTK_STYLE_CLASS_BACKGROUND, | ||||
|                           "window-frame", | ||||
|                           "ssd", | ||||
|                           NULL); | ||||
|   style_info->styles[META_STYLE_ELEMENT_FRAME] = | ||||
|     create_style_context (META_TYPE_FRAMES, | ||||
|                           style_info->styles[META_STYLE_ELEMENT_WINDOW], | ||||
|                           provider, | ||||
|                           "decoration", | ||||
|                           NULL); | ||||
|   style_info->styles[META_STYLE_ELEMENT_TITLEBAR] = | ||||
|     create_style_context (GTK_TYPE_HEADER_BAR, | ||||
|                           style_info->styles[META_STYLE_ELEMENT_FRAME], | ||||
|   | ||||
							
								
								
									
										707
									
								
								src/wayland/meta-pointer-confinement-wayland.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										707
									
								
								src/wayland/meta-pointer-confinement-wayland.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,707 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2015 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jonas Ådahl <jadahl@gmail.com> | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "wayland/meta-pointer-confinement-wayland.h" | ||||
|  | ||||
| #include <glib-object.h> | ||||
| #include <cairo.h> | ||||
|  | ||||
| #include "backends/meta-backend-private.h" | ||||
| #include "core/meta-border.h" | ||||
| #include "wayland/meta-wayland-seat.h" | ||||
| #include "wayland/meta-wayland-pointer.h" | ||||
| #include "wayland/meta-wayland-pointer-constraints.h" | ||||
| #include "wayland/meta-wayland-surface.h" | ||||
| #include "backends/meta-pointer-constraint.h" | ||||
| #include "compositor/meta-surface-actor-wayland.h" | ||||
|  | ||||
| struct _MetaPointerConfinementWayland | ||||
| { | ||||
|   MetaPointerConstraint parent; | ||||
|  | ||||
|   MetaWaylandPointerConstraint *constraint; | ||||
| }; | ||||
|  | ||||
| typedef struct _MetaBox | ||||
| { | ||||
|   int x1; | ||||
|   int y1; | ||||
|   int x2; | ||||
|   int y2; | ||||
| } MetaBox; | ||||
|  | ||||
| G_DEFINE_TYPE (MetaPointerConfinementWayland, meta_pointer_confinement_wayland, | ||||
|                META_TYPE_POINTER_CONSTRAINT); | ||||
|  | ||||
| static MetaBorder * | ||||
| add_border (GArray *borders, | ||||
|             float x1, float y1, | ||||
|             float x2, float y2, | ||||
|             MetaBorderMotionDirection blocking_directions) | ||||
| { | ||||
|   MetaBorder border; | ||||
|  | ||||
|   border = (MetaBorder) { | ||||
|     .line = (MetaLine2) { | ||||
|       .a = (MetaVector2) { | ||||
|         .x = x1, | ||||
|         .y = y1, | ||||
|       }, | ||||
|       .b = (MetaVector2) { | ||||
|         .x = x2, | ||||
|         .y = y2, | ||||
|       }, | ||||
|     }, | ||||
|     .blocking_directions = blocking_directions, | ||||
|   }; | ||||
|  | ||||
|   g_array_append_val (borders, border); | ||||
|  | ||||
|   return &g_array_index (borders, MetaBorder, borders->len - 1); | ||||
| } | ||||
|  | ||||
| static gint | ||||
| compare_lines_x (gconstpointer a, gconstpointer b) | ||||
| { | ||||
|   const MetaBorder *border_a = a; | ||||
|   const MetaBorder *border_b = b; | ||||
|  | ||||
|   if (border_a->line.a.x == border_b->line.a.x) | ||||
|     return border_a->line.b.x < border_b->line.b.x; | ||||
|   else | ||||
|     return border_a->line.a.x > border_b->line.a.x; | ||||
| } | ||||
|  | ||||
| static void | ||||
| add_non_overlapping_edges (MetaBox     *boxes, | ||||
|                            unsigned int band_above_start, | ||||
|                            unsigned int band_below_start, | ||||
|                            unsigned int band_below_end, | ||||
|                            GArray      *borders) | ||||
| { | ||||
|   unsigned int i; | ||||
|   GArray *band_merge; | ||||
|   MetaBorder *border; | ||||
|   MetaBorder *prev_border; | ||||
|   MetaBorder *new_border; | ||||
|  | ||||
|   band_merge = g_array_new (FALSE, FALSE, sizeof *border); | ||||
|  | ||||
|   /* Add bottom band of previous row, and top band of current row, and | ||||
|    * sort them so lower left x coordinate comes first. If there are two | ||||
|    * borders with the same left x coordinate, the wider one comes first. | ||||
|    */ | ||||
|   for (i = band_above_start; i < band_below_start; i++) | ||||
|     { | ||||
|       MetaBox *box = &boxes[i]; | ||||
|       add_border (band_merge, box->x1, box->y2, box->x2, box->y2, | ||||
|                   META_BORDER_MOTION_DIRECTION_POSITIVE_Y); | ||||
|     } | ||||
|   for (i = band_below_start; i < band_below_end; i++) | ||||
|     { | ||||
|       MetaBox *box= &boxes[i]; | ||||
|       add_border (band_merge, box->x1, box->y1, box->x2, box->y1, | ||||
|                   META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); | ||||
|     } | ||||
|   g_array_sort (band_merge, compare_lines_x); | ||||
|  | ||||
|   /* Combine the two combined bands so that any overlapping border is | ||||
|    * eliminated. */ | ||||
|   prev_border = NULL; | ||||
|   for (i = 0; i < band_merge->len; i++) | ||||
|     { | ||||
|       border = &g_array_index (band_merge, MetaBorder, i); | ||||
|  | ||||
|       g_assert (border->line.a.y == border->line.b.y); | ||||
|       g_assert (!prev_border || | ||||
|                 prev_border->line.a.y == border->line.a.y); | ||||
|       g_assert (!prev_border || | ||||
|                 (prev_border->line.a.x != border->line.a.x || | ||||
|                  prev_border->line.b.x != border->line.b.x)); | ||||
|       g_assert (!prev_border || | ||||
|                 prev_border->line.a.x <= border->line.a.x); | ||||
|  | ||||
|       if (prev_border && | ||||
|           prev_border->line.a.x == border->line.a.x) | ||||
|         { | ||||
|           /* | ||||
|            * ------------ + | ||||
|            * -------      = | ||||
|            * [     ]----- | ||||
|            */ | ||||
|           prev_border->line.a.x = border->line.b.x; | ||||
|         } | ||||
|       else if (prev_border && | ||||
|                prev_border->line.b.x == border->line.b.x) | ||||
|         { | ||||
|           /* | ||||
|            * ------------ + | ||||
|            *       ------ = | ||||
|            * ------[    ] | ||||
|            */ | ||||
|           prev_border->line.b.x = border->line.a.x; | ||||
|         } | ||||
|       else if (prev_border && | ||||
|                prev_border->line.b.x == border->line.a.x) | ||||
|         { | ||||
|           /* | ||||
|            * --------        + | ||||
|            *         ------  = | ||||
|            * -------------- | ||||
|            */ | ||||
|           prev_border->line.b.x = border->line.b.x; | ||||
|         } | ||||
|       else if (prev_border && | ||||
|                prev_border->line.b.x >= border->line.a.x) | ||||
|         { | ||||
|           /* | ||||
|            * --------------- + | ||||
|            *      ------     = | ||||
|            * -----[    ]---- | ||||
|            */ | ||||
|           new_border = add_border (borders, | ||||
|                                    border->line.b.x, | ||||
|                                    border->line.b.y, | ||||
|                                    prev_border->line.b.x, | ||||
|                                    prev_border->line.b.y, | ||||
|                                    prev_border->blocking_directions); | ||||
|           prev_border->line.b.x = border->line.a.x; | ||||
|           prev_border = new_border; | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           g_assert (!prev_border || | ||||
|                     prev_border->line.b.x < border->line.a.x); | ||||
|           /* | ||||
|            * First border or non-overlapping. | ||||
|            * | ||||
|            * -----           + | ||||
|            *        -----    = | ||||
|            * -----  ----- | ||||
|            */ | ||||
|           g_array_append_val (borders, *border); | ||||
|           prev_border = &g_array_index (borders, MetaBorder, borders->len - 1); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   g_array_free (band_merge, FALSE); | ||||
| } | ||||
|  | ||||
| static void | ||||
| add_band_bottom_edges (MetaBox *boxes, | ||||
|                        int      band_start, | ||||
|                        int      band_end, | ||||
|                        GArray  *borders) | ||||
| { | ||||
|   int i; | ||||
|  | ||||
|   for (i = band_start; i < band_end; i++) | ||||
|     { | ||||
|       add_border (borders, | ||||
|                   boxes[i].x1, boxes[i].y2, | ||||
|                   boxes[i].x2, boxes[i].y2, | ||||
|                   META_BORDER_MOTION_DIRECTION_POSITIVE_Y); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| region_to_outline (cairo_region_t *region, | ||||
|                    GArray         *borders) | ||||
| { | ||||
|   MetaBox *boxes; | ||||
|   int num_boxes; | ||||
|   int i; | ||||
|   int top_most, bottom_most; | ||||
|   int current_roof; | ||||
|   int prev_top; | ||||
|   int band_start, prev_band_start; | ||||
|  | ||||
|   /* | ||||
|    * Remove any overlapping lines from the set of rectangles. Note that | ||||
|    * pixman regions are grouped as rows of rectangles, where rectangles | ||||
|    * in one row never touch or overlap and are all of the same height. | ||||
|    * | ||||
|    *             -------- ---                   -------- --- | ||||
|    *             |      | | |                   |      | | | | ||||
|    *   ----------====---- ---         -----------  ----- --- | ||||
|    *   |            |            =>   |            | | ||||
|    *   ----==========---------        -----        ---------- | ||||
|    *       |                 |            |                 | | ||||
|    *       -------------------            ------------------- | ||||
|    * | ||||
|    */ | ||||
|  | ||||
|   num_boxes  = cairo_region_num_rectangles (region); | ||||
|   boxes = g_new (MetaBox, num_boxes); | ||||
|   for (i = 0; i < num_boxes; i++) | ||||
|     { | ||||
|       cairo_rectangle_int_t rect; | ||||
|       cairo_region_get_rectangle (region, i, &rect); | ||||
|       boxes[i] = (MetaBox) { | ||||
|         .x1 = rect.x, | ||||
|         .y1 = rect.y, | ||||
|         .x2 = rect.x + rect.width, | ||||
|         .y2 = rect.y + rect.height, | ||||
|       }; | ||||
|     } | ||||
|   prev_top = 0; | ||||
|   top_most = boxes[0].y1; | ||||
|   current_roof = top_most; | ||||
|   bottom_most = boxes[num_boxes - 1].y2; | ||||
|   band_start = 0; | ||||
|   prev_band_start = 0; | ||||
|   for (i = 0; i < num_boxes; i++) | ||||
|     { | ||||
|       /* Detect if there is a vertical empty space, and add the lower | ||||
|        * level of the previous band if so was the case. */ | ||||
|       if (i > 0 && | ||||
|           boxes[i].y1 != prev_top && | ||||
|           boxes[i].y1 != boxes[i - 1].y2) | ||||
|         { | ||||
|           current_roof = boxes[i].y1; | ||||
|           add_band_bottom_edges (boxes, | ||||
|                                  band_start, | ||||
|                                  i, | ||||
|                                  borders); | ||||
|         } | ||||
|  | ||||
|       /* Special case adding the last band, since it won't be handled | ||||
|        * by the band change detection below. */ | ||||
|       if (boxes[i].y1 != current_roof && i == num_boxes - 1) | ||||
|         { | ||||
|           if (boxes[i].y1 != prev_top) | ||||
|             { | ||||
|               /* The last band is a single box, so we don't | ||||
|                * have a prev_band_start to tell us when the | ||||
|                * previous band started. */ | ||||
|               add_non_overlapping_edges (boxes, | ||||
|                                          band_start, | ||||
|                                          i, | ||||
|                                          i + 1, | ||||
|                                          borders); | ||||
|             } | ||||
|           else | ||||
|             { | ||||
|               add_non_overlapping_edges (boxes, | ||||
|                                          prev_band_start, | ||||
|                                          band_start, | ||||
|                                          i + 1, | ||||
|                                          borders); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|       /* Detect when passing a band and combine the top border of the | ||||
|        * just passed band with the bottom band of the previous band. | ||||
|        */ | ||||
|       if (boxes[i].y1 != top_most && boxes[i].y1 != prev_top) | ||||
|         { | ||||
|           /* Combine the two passed bands. */ | ||||
|           if (prev_top != current_roof) | ||||
|             { | ||||
|               add_non_overlapping_edges (boxes, | ||||
|                                          prev_band_start, | ||||
|                                          band_start, | ||||
|                                          i, | ||||
|                                          borders); | ||||
|             } | ||||
|  | ||||
|           prev_band_start = band_start; | ||||
|           band_start = i; | ||||
|         } | ||||
|  | ||||
|       /* Add the top border if the box is part of the current roof. */ | ||||
|       if (boxes[i].y1 == current_roof) | ||||
|         { | ||||
|           add_border (borders, | ||||
|                       boxes[i].x1, boxes[i].y1, | ||||
|                       boxes[i].x2, boxes[i].y1, | ||||
|                       META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); | ||||
|         } | ||||
|  | ||||
|       /* Add the bottom border of the last band. */ | ||||
|       if (boxes[i].y2 == bottom_most) | ||||
|         { | ||||
|           add_border (borders, | ||||
|                       boxes[i].x1, boxes[i].y2, | ||||
|                       boxes[i].x2, boxes[i].y2, | ||||
|                       META_BORDER_MOTION_DIRECTION_POSITIVE_Y); | ||||
|         } | ||||
|  | ||||
|       /* Always add the left border. */ | ||||
|       add_border (borders, | ||||
|                   boxes[i].x1, boxes[i].y1, | ||||
|                   boxes[i].x1, boxes[i].y2, | ||||
|                   META_BORDER_MOTION_DIRECTION_NEGATIVE_X); | ||||
|  | ||||
|       /* Always add the right border. */ | ||||
|       add_border (borders, | ||||
|                   boxes[i].x2, boxes[i].y1, | ||||
|                   boxes[i].x2, boxes[i].y2, | ||||
|                   META_BORDER_MOTION_DIRECTION_POSITIVE_X); | ||||
|  | ||||
|       prev_top = boxes[i].y1; | ||||
|     } | ||||
|  | ||||
|   g_free (boxes); | ||||
| } | ||||
|  | ||||
| static MetaBorder * | ||||
| get_closest_border (GArray    *borders, | ||||
|                     MetaLine2 *motion, | ||||
|                     uint32_t   directions) | ||||
| { | ||||
|   MetaBorder *border; | ||||
|   MetaVector2 intersection; | ||||
|   MetaVector2 delta; | ||||
|   float distance_2; | ||||
|   MetaBorder *closest_border = NULL; | ||||
|   float closest_distance_2 = DBL_MAX; | ||||
|   unsigned int i; | ||||
|  | ||||
|   for (i = 0; i < borders->len; i++) | ||||
|     { | ||||
|       border = &g_array_index (borders, MetaBorder, i); | ||||
|  | ||||
|       if (!meta_border_is_blocking_directions (border, directions)) | ||||
|         continue; | ||||
|  | ||||
|       if (!meta_line2_intersects_with (&border->line, motion, &intersection)) | ||||
|         continue; | ||||
|  | ||||
|       delta = meta_vector2_subtract (intersection, motion->a); | ||||
|       distance_2 = delta.x*delta.x + delta.y*delta.y; | ||||
|       if (distance_2 < closest_distance_2) | ||||
|         { | ||||
|           closest_border = border; | ||||
|           closest_distance_2 = distance_2; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   return closest_border; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clamp_to_border (MetaBorder *border, | ||||
|                  MetaLine2  *motion, | ||||
|                  uint32_t   *motion_dir) | ||||
| { | ||||
|   /* | ||||
|    * When clamping either rightward or downward motions, the motion needs to be | ||||
|    * clamped so that the destination coordinate does not end up on the border | ||||
|    * (see weston_pointer_clamp_event_to_region). Do this by clamping such | ||||
|    * motions to the border minus the smallest possible wl_fixed_t value. | ||||
|    * | ||||
|    * When clamping in either leftward or upward motion, the resulting coordinate | ||||
|    * needs to be clamped so that it is enough on the inside to avoid the | ||||
|    * inaccuracies of clutter's stage to actor transformation algorithm (the one | ||||
|    * used in clutter_actor_transform_stage_point) to make it end up outside the | ||||
|    * next motion. It also needs to be clamped so that to the wl_fixed_t | ||||
|    * coordinate may still be right on the border (i.e. at .0). Testing shows | ||||
|    * that the smallest wl_fixed_t value divided by 10 is small enough to make | ||||
|    * the wl_fixed_t coordinate .0 and large enough to avoid the inaccuracies of | ||||
|    * clutters transform algorithm. | ||||
|    */ | ||||
|   if (meta_border_is_horizontal (border)) | ||||
|     { | ||||
|       if (*motion_dir & META_BORDER_MOTION_DIRECTION_POSITIVE_Y) | ||||
|         motion->b.y = border->line.a.y - wl_fixed_to_double (1); | ||||
|       else | ||||
|         motion->b.y = border->line.a.y + wl_fixed_to_double (1) / 10; | ||||
|       *motion_dir &= ~(META_BORDER_MOTION_DIRECTION_POSITIVE_Y | | ||||
|                        META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (*motion_dir & META_BORDER_MOTION_DIRECTION_POSITIVE_X) | ||||
|         motion->b.x = border->line.a.x - wl_fixed_to_double (1); | ||||
|       else | ||||
|         motion->b.x = border->line.a.x + wl_fixed_to_double (1) / 10; | ||||
|       *motion_dir &= ~(META_BORDER_MOTION_DIRECTION_POSITIVE_X | | ||||
|                        META_BORDER_MOTION_DIRECTION_NEGATIVE_X); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static uint32_t | ||||
| get_motion_directions (MetaLine2 *motion) | ||||
| { | ||||
|   uint32_t directions = 0; | ||||
|  | ||||
|   if (motion->a.x < motion->b.x) | ||||
|     directions |= META_BORDER_MOTION_DIRECTION_POSITIVE_X; | ||||
|   else if (motion->a.x > motion->b.x) | ||||
|     directions |= META_BORDER_MOTION_DIRECTION_NEGATIVE_X; | ||||
|   if (motion->a.y < motion->b.y) | ||||
|     directions |= META_BORDER_MOTION_DIRECTION_POSITIVE_Y; | ||||
|   else if (motion->a.y > motion->b.y) | ||||
|     directions |= META_BORDER_MOTION_DIRECTION_NEGATIVE_Y; | ||||
|  | ||||
|   return directions; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_pointer_confinement_wayland_constrain (MetaPointerConstraint *constraint, | ||||
|                                             ClutterInputDevice    *device, | ||||
|                                             guint32                time, | ||||
|                                             float                  prev_x, | ||||
|                                             float                  prev_y, | ||||
|                                             float                  *x, | ||||
|                                             float                  *y) | ||||
| { | ||||
|   MetaPointerConfinementWayland *self = | ||||
|     META_POINTER_CONFINEMENT_WAYLAND (constraint); | ||||
|   MetaWaylandSurface *surface; | ||||
|   cairo_region_t *region; | ||||
|   float sx, sy; | ||||
|   float prev_sx, prev_sy; | ||||
|   GArray *borders; | ||||
|   MetaLine2 motion; | ||||
|   MetaBorder *closest_border; | ||||
|   uint32_t directions; | ||||
|  | ||||
|   surface = meta_wayland_pointer_constraint_get_surface (self->constraint); | ||||
|  | ||||
|   meta_wayland_surface_get_relative_coordinates (surface, *x, *y, &sx, &sy); | ||||
|   meta_wayland_surface_get_relative_coordinates (surface, prev_x, prev_y, | ||||
|                                                  &prev_sx, &prev_sy); | ||||
|  | ||||
|   /* For motions in a positive direction on any axis, append the smallest | ||||
|    * possible value representable in a Wayland absolute coordinate.  This is | ||||
|    * in order to avoid not clamping motion that as a floating point number | ||||
|    * won't be clamped, but will be rounded up to be outside of the range | ||||
|    * of wl_fixed_t. */ | ||||
|   if (sx > prev_sx) | ||||
|     sx += (float)wl_fixed_to_double(1); | ||||
|   if (sy > prev_sy) | ||||
|     sy += (float)wl_fixed_to_double(1); | ||||
|  | ||||
|   borders = g_array_new (FALSE, FALSE, sizeof (MetaBorder)); | ||||
|  | ||||
|   /* | ||||
|    * Generate borders given the confine region we are to use. The borders | ||||
|    * are defined to be the outer region of the allowed area. This means | ||||
|    * top/left borders are "within" the allowed area, while bottom/right | ||||
|    * borders are outside. This needs to be considered when clamping | ||||
|    * confined motion vectors. | ||||
|    */ | ||||
|   region = | ||||
|     meta_wayland_pointer_constraint_calculate_effective_region (self->constraint); | ||||
|   region_to_outline (region, borders); | ||||
|   cairo_region_destroy (region); | ||||
|  | ||||
|   motion = (MetaLine2) { | ||||
|     .a = (MetaVector2) { | ||||
|       .x = prev_sx, | ||||
|       .y = prev_sy, | ||||
|     }, | ||||
|     .b = (MetaVector2) { | ||||
|       .x = sx, | ||||
|       .y = sy, | ||||
|     }, | ||||
|   }; | ||||
|   directions = get_motion_directions (&motion); | ||||
|  | ||||
|   while (directions) | ||||
|     { | ||||
|       closest_border = get_closest_border (borders, | ||||
|                                            &motion, | ||||
|                                            directions); | ||||
|       if (closest_border) | ||||
|         clamp_to_border (closest_border, &motion, &directions); | ||||
|       else | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|   meta_wayland_surface_get_absolute_coordinates (surface, | ||||
|                                                  motion.b.x, motion.b.y, | ||||
|                                                  x, y); | ||||
|  | ||||
|   g_array_free (borders, FALSE); | ||||
| } | ||||
|  | ||||
| static float | ||||
| point_to_border_distance_2 (MetaBorder *border, | ||||
|                             float       x, | ||||
|                             float       y) | ||||
| { | ||||
|   float orig_x, orig_y; | ||||
|   float dx, dy; | ||||
|  | ||||
|   if (meta_border_is_horizontal (border)) | ||||
|     { | ||||
|       if (x < border->line.a.x) | ||||
|         orig_x = border->line.a.x; | ||||
|       else if (x > border->line.b.x) | ||||
|         orig_x = border->line.b.x; | ||||
|       else | ||||
|         orig_x = x; | ||||
|       orig_y = border->line.a.y; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (y < border->line.a.y) | ||||
|         orig_y = border->line.a.y; | ||||
|       else if (y > border->line.b.y) | ||||
|         orig_y = border->line.b.y; | ||||
|       else | ||||
|         orig_y = y; | ||||
|       orig_x = border->line.a.x; | ||||
|     } | ||||
|  | ||||
|   dx = fabsf (orig_x - x); | ||||
|   dy = fabsf (orig_y - y); | ||||
|   return dx*dx + dy*dy; | ||||
| } | ||||
|  | ||||
| static void | ||||
| warp_to_behind_border (MetaBorder *border, | ||||
|                        float      *sx, | ||||
|                        float      *sy) | ||||
| { | ||||
|   switch (border->blocking_directions) | ||||
|     { | ||||
|     case META_BORDER_MOTION_DIRECTION_POSITIVE_X: | ||||
|     case META_BORDER_MOTION_DIRECTION_NEGATIVE_X: | ||||
|       if (border->blocking_directions == META_BORDER_MOTION_DIRECTION_POSITIVE_X) | ||||
|         *sx = border->line.a.x - wl_fixed_to_double (1); | ||||
|       else | ||||
|         *sx = border->line.a.x + wl_fixed_to_double (1); | ||||
|       if (*sy < border->line.a.y) | ||||
|         *sy = border->line.a.y + wl_fixed_to_double (1); | ||||
|       else if (*sy > border->line.b.y) | ||||
|         *sy = border->line.b.y - wl_fixed_to_double (1); | ||||
|       break; | ||||
|     case META_BORDER_MOTION_DIRECTION_POSITIVE_Y: | ||||
|     case META_BORDER_MOTION_DIRECTION_NEGATIVE_Y: | ||||
|       if (border->blocking_directions == META_BORDER_MOTION_DIRECTION_POSITIVE_Y) | ||||
|         *sy = border->line.a.y - wl_fixed_to_double (1); | ||||
|       else | ||||
|         *sy = border->line.a.y + wl_fixed_to_double (1); | ||||
|       if (*sx < border->line.a.x) | ||||
|         *sx = border->line.a.x + wl_fixed_to_double (1); | ||||
|       else if (*sx > (border->line.b.x)) | ||||
|         *sx = border->line.b.x - wl_fixed_to_double (1); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_pointer_confinement_wayland_maybe_warp (MetaPointerConfinementWayland *self) | ||||
| { | ||||
|   MetaWaylandSeat *seat; | ||||
|   MetaWaylandSurface *surface; | ||||
|   ClutterPoint point; | ||||
|   float sx; | ||||
|   float sy; | ||||
|   cairo_region_t *region; | ||||
|  | ||||
|   seat = meta_wayland_pointer_constraint_get_seat (self->constraint); | ||||
|   surface = meta_wayland_pointer_constraint_get_surface (self->constraint); | ||||
|  | ||||
|   clutter_input_device_get_coords (seat->pointer.device, NULL, &point); | ||||
|   meta_wayland_surface_get_relative_coordinates (surface, | ||||
|                                                  point.x, point.y, | ||||
|                                                  &sx, &sy); | ||||
|  | ||||
|   region = | ||||
|     meta_wayland_pointer_constraint_calculate_effective_region (self->constraint); | ||||
|  | ||||
|   if (!cairo_region_contains_point (region, (int)sx, (int)sy)) | ||||
|     { | ||||
|       GArray *borders; | ||||
|       float closest_distance_2 = FLT_MAX; | ||||
|       MetaBorder *closest_border = NULL; | ||||
|       unsigned int i; | ||||
|       float x; | ||||
|       float y; | ||||
|  | ||||
|       borders = g_array_new (FALSE, FALSE, sizeof (MetaBorder)); | ||||
|  | ||||
|       region_to_outline (region, borders); | ||||
|  | ||||
|       for (i = 0; i < borders->len; i++) | ||||
|         { | ||||
|           MetaBorder *border = &g_array_index (borders, MetaBorder, i); | ||||
|           float distance_2; | ||||
|  | ||||
|           distance_2 = point_to_border_distance_2 (border, sx, sy); | ||||
|           if (distance_2 < closest_distance_2) | ||||
|             { | ||||
|               closest_border = border; | ||||
|               closest_distance_2 = distance_2; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|       warp_to_behind_border (closest_border, &sx, &sy); | ||||
|  | ||||
|       meta_wayland_surface_get_absolute_coordinates (surface, sx, sy, &x, &y); | ||||
|       meta_backend_warp_pointer (meta_get_backend (), (int)x, (int)y); | ||||
|     } | ||||
|  | ||||
|   cairo_region_destroy (region); | ||||
| } | ||||
|  | ||||
| static void | ||||
| surface_actor_painting (MetaSurfaceActorWayland       *surface_actor, | ||||
|                         MetaPointerConfinementWayland *self) | ||||
| { | ||||
|   meta_pointer_confinement_wayland_maybe_warp (self); | ||||
| } | ||||
|  | ||||
| MetaPointerConstraint * | ||||
| meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   GObject *object; | ||||
|   MetaPointerConfinementWayland *confinement; | ||||
|   MetaWaylandSurface *surface; | ||||
|  | ||||
|   object = g_object_new (META_TYPE_POINTER_CONFINEMENT_WAYLAND, NULL); | ||||
|   confinement = META_POINTER_CONFINEMENT_WAYLAND (object); | ||||
|  | ||||
|   confinement->constraint = constraint; | ||||
|  | ||||
|   surface = meta_wayland_pointer_constraint_get_surface (constraint); | ||||
|   g_signal_connect_object (surface->surface_actor, | ||||
|                            "painting", | ||||
|                            G_CALLBACK (surface_actor_painting), | ||||
|                            confinement, | ||||
|                            0); | ||||
|  | ||||
|   return META_POINTER_CONSTRAINT (confinement); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_pointer_confinement_wayland_init (MetaPointerConfinementWayland *confinement_wayland) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_pointer_confinement_wayland_class_init (MetaPointerConfinementWaylandClass *klass) | ||||
| { | ||||
|   MetaPointerConstraintClass *pointer_constraint_class = | ||||
|     META_POINTER_CONSTRAINT_CLASS (klass); | ||||
|  | ||||
|   pointer_constraint_class->constrain = meta_pointer_confinement_wayland_constrain; | ||||
| } | ||||
							
								
								
									
										45
									
								
								src/wayland/meta-pointer-confinement-wayland.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/wayland/meta-pointer-confinement-wayland.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2015 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jonas Ådahl <jadahl@gmail.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef META_POINTER_CONFINEMENT_WAYLAND_H | ||||
| #define META_POINTER_CONFINEMENT_WAYLAND_H | ||||
|  | ||||
| #include <glib-object.h> | ||||
|  | ||||
| #include "backends/meta-pointer-constraint.h" | ||||
| #include "wayland/meta-wayland-pointer-constraints.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define META_TYPE_POINTER_CONFINEMENT_WAYLAND (meta_pointer_confinement_wayland_get_type ()) | ||||
| G_DECLARE_FINAL_TYPE (MetaPointerConfinementWayland, | ||||
|                       meta_pointer_confinement_wayland, | ||||
|                       META, POINTER_CONFINEMENT_WAYLAND, | ||||
|                       MetaPointerConstraint); | ||||
|  | ||||
| MetaPointerConstraint *meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* META_CONFINEMENT_WAYLAND_H */ | ||||
							
								
								
									
										72
									
								
								src/wayland/meta-pointer-lock-wayland.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/wayland/meta-pointer-lock-wayland.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2015 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jonas Ådahl <jadahl@gmail.com> | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "wayland/meta-pointer-lock-wayland.h" | ||||
|  | ||||
| #include <glib-object.h> | ||||
|  | ||||
| #include "backends/meta-pointer-constraint.h" | ||||
|  | ||||
| struct _MetaPointerLockWayland | ||||
| { | ||||
|   MetaPointerConstraint parent; | ||||
| }; | ||||
|  | ||||
| G_DEFINE_TYPE (MetaPointerLockWayland, meta_pointer_lock_wayland, | ||||
|                META_TYPE_POINTER_CONSTRAINT); | ||||
|  | ||||
| static void | ||||
| meta_pointer_lock_wayland_constrain (MetaPointerConstraint *constraint, | ||||
|                                      ClutterInputDevice    *device, | ||||
|                                      guint32                time, | ||||
|                                      float                  prev_x, | ||||
|                                      float                  prev_y, | ||||
|                                      float                 *x, | ||||
|                                      float                 *y) | ||||
| { | ||||
|   *x = prev_x; | ||||
|   *y = prev_y; | ||||
| } | ||||
|  | ||||
| MetaPointerConstraint * | ||||
| meta_pointer_lock_wayland_new (void) | ||||
| { | ||||
|   return g_object_new (META_TYPE_POINTER_LOCK_WAYLAND, NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_pointer_lock_wayland_init (MetaPointerLockWayland *lock_wayland) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_pointer_lock_wayland_class_init (MetaPointerLockWaylandClass *klass) | ||||
| { | ||||
|   MetaPointerConstraintClass *pointer_constraint_class = | ||||
|     META_POINTER_CONSTRAINT_CLASS (klass); | ||||
|  | ||||
|   pointer_constraint_class->constrain = meta_pointer_lock_wayland_constrain; | ||||
| } | ||||
							
								
								
									
										42
									
								
								src/wayland/meta-pointer-lock-wayland.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/wayland/meta-pointer-lock-wayland.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2015 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jonas Ådahl <jadahl@gmail.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef META_POINTER_LOCK_WAYLAND_H | ||||
| #define META_POINTER_LOCK_WAYLAND_H | ||||
|  | ||||
| #include <glib-object.h> | ||||
|  | ||||
| #include "backends/meta-pointer-constraint.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define META_TYPE_POINTER_LOCK_WAYLAND (meta_pointer_lock_wayland_get_type ()) | ||||
| G_DECLARE_FINAL_TYPE (MetaPointerLockWayland, meta_pointer_lock_wayland, | ||||
|                       META, POINTER_LOCK_WAYLAND, MetaPointerConstraint); | ||||
|  | ||||
| MetaPointerConstraint *meta_pointer_lock_wayland_new (void); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* META_LOCK_WAYLAND_H */ | ||||
| @@ -30,6 +30,17 @@ | ||||
| #include <cogl/cogl-wayland-server.h> | ||||
| #include <meta/util.h> | ||||
|  | ||||
| enum | ||||
| { | ||||
|   RESOURCE_DESTROYED, | ||||
|  | ||||
|   LAST_SIGNAL | ||||
| }; | ||||
|  | ||||
| guint signals[LAST_SIGNAL]; | ||||
|  | ||||
| G_DEFINE_TYPE (MetaWaylandBuffer, meta_wayland_buffer, G_TYPE_OBJECT); | ||||
|  | ||||
| static void | ||||
| meta_wayland_buffer_destroy_handler (struct wl_listener *listener, | ||||
|                                      void *data) | ||||
| @@ -37,25 +48,9 @@ meta_wayland_buffer_destroy_handler (struct wl_listener *listener, | ||||
|   MetaWaylandBuffer *buffer = | ||||
|     wl_container_of (listener, buffer, destroy_listener); | ||||
|  | ||||
|   wl_signal_emit (&buffer->destroy_signal, buffer); | ||||
|   g_slice_free (MetaWaylandBuffer, buffer); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_buffer_ref (MetaWaylandBuffer *buffer) | ||||
| { | ||||
|   buffer->ref_count++; | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_buffer_unref (MetaWaylandBuffer *buffer) | ||||
| { | ||||
|   buffer->ref_count--; | ||||
|   if (buffer->ref_count == 0) | ||||
|     { | ||||
|       g_clear_pointer (&buffer->texture, cogl_object_unref); | ||||
|       wl_resource_queue_event (buffer->resource, WL_BUFFER_RELEASE); | ||||
|     } | ||||
|   buffer->resource = NULL; | ||||
|   g_signal_emit (buffer, signals[RESOURCE_DESTROYED], 0); | ||||
|   g_object_unref (buffer); | ||||
| } | ||||
|  | ||||
| MetaWaylandBuffer * | ||||
| @@ -74,10 +69,9 @@ meta_wayland_buffer_from_resource (struct wl_resource *resource) | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       buffer = g_slice_new0 (MetaWaylandBuffer); | ||||
|       buffer = g_object_new (META_TYPE_WAYLAND_BUFFER, NULL); | ||||
|  | ||||
|       buffer->resource = resource; | ||||
|       wl_signal_init (&buffer->destroy_signal); | ||||
|       buffer->destroy_listener.notify = meta_wayland_buffer_destroy_handler; | ||||
|       wl_resource_add_destroy_listener (resource, &buffer->destroy_listener); | ||||
|     } | ||||
| @@ -93,6 +87,8 @@ meta_wayland_buffer_ensure_texture (MetaWaylandBuffer *buffer) | ||||
|   CoglTexture *texture; | ||||
|   struct wl_shm_buffer *shm_buffer; | ||||
|  | ||||
|   g_return_val_if_fail (buffer->resource, NULL); | ||||
|  | ||||
|   if (buffer->texture) | ||||
|     goto out; | ||||
|  | ||||
| @@ -149,3 +145,33 @@ meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer, | ||||
|       wl_shm_buffer_end_access (shm_buffer); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_buffer_finalize (GObject *object) | ||||
| { | ||||
|   MetaWaylandBuffer *buffer = META_WAYLAND_BUFFER (object); | ||||
|  | ||||
|   g_clear_pointer (&buffer->texture, cogl_object_unref); | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_wayland_buffer_parent_class)->finalize (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_buffer_init (MetaWaylandBuffer *buffer) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_buffer_class_init (MetaWaylandBufferClass *klass) | ||||
| { | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   object_class->finalize = meta_wayland_buffer_finalize; | ||||
|  | ||||
|   signals[RESOURCE_DESTROYED] = g_signal_new ("resource-destroyed", | ||||
|                                               G_TYPE_FROM_CLASS (object_class), | ||||
|                                               G_SIGNAL_RUN_LAST, | ||||
|                                               0, | ||||
|                                               NULL, NULL, NULL, | ||||
|                                               G_TYPE_NONE, 0); | ||||
| } | ||||
|   | ||||
| @@ -33,17 +33,19 @@ | ||||
|  | ||||
| struct _MetaWaylandBuffer | ||||
| { | ||||
|   GObject parent; | ||||
|  | ||||
|   struct wl_resource *resource; | ||||
|   struct wl_signal destroy_signal; | ||||
|   struct wl_listener destroy_listener; | ||||
|  | ||||
|   CoglTexture *texture; | ||||
|   uint32_t ref_count; | ||||
| }; | ||||
|  | ||||
| #define META_TYPE_WAYLAND_BUFFER (meta_wayland_buffer_get_type ()) | ||||
| G_DECLARE_FINAL_TYPE (MetaWaylandBuffer, meta_wayland_buffer, | ||||
|                       META, WAYLAND_BUFFER, GObject); | ||||
|  | ||||
| MetaWaylandBuffer *     meta_wayland_buffer_from_resource       (struct wl_resource    *resource); | ||||
| void                    meta_wayland_buffer_ref                 (MetaWaylandBuffer     *buffer); | ||||
| void                    meta_wayland_buffer_unref               (MetaWaylandBuffer     *buffer); | ||||
| CoglTexture *           meta_wayland_buffer_ensure_texture      (MetaWaylandBuffer     *buffer); | ||||
| void                    meta_wayland_buffer_process_damage      (MetaWaylandBuffer     *buffer, | ||||
|                                                                  cairo_region_t        *region); | ||||
|   | ||||
| @@ -31,4 +31,10 @@ G_DECLARE_FINAL_TYPE (MetaWaylandDataSourceWayland, | ||||
|                       META, WAYLAND_DATA_SOURCE_WAYLAND, | ||||
|                       MetaWaylandDataSource); | ||||
|  | ||||
| #define META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY (meta_wayland_data_source_primary_get_type ()) | ||||
| G_DECLARE_FINAL_TYPE (MetaWaylandDataSourcePrimary, | ||||
|                       meta_wayland_data_source_primary, | ||||
|                       META, WAYLAND_DATA_SOURCE_PRIMARY, | ||||
|                       MetaWaylandDataSourceWayland); | ||||
|  | ||||
| #endif /* META_WAYLAND_DATA_DEVICE_PRIVATE_H */ | ||||
|   | ||||
| @@ -29,6 +29,7 @@ | ||||
| #include <unistd.h> | ||||
| #include <stdio.h> | ||||
| #include <glib.h> | ||||
| #include <glib-unix.h> | ||||
|  | ||||
| #include "meta-wayland-data-device.h" | ||||
| #include "meta-wayland-data-device-private.h" | ||||
| @@ -37,6 +38,10 @@ | ||||
| #include "meta-wayland-private.h" | ||||
| #include "meta-dnd-actor-private.h" | ||||
|  | ||||
| #include "gtk-primary-selection-server-protocol.h" | ||||
|  | ||||
| #define ROOTWINDOW_DROP_MIME "application/x-rootwindow-drop" | ||||
|  | ||||
| #define ALL_ACTIONS (WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | \ | ||||
|                      WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | \ | ||||
|                      WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) | ||||
| @@ -70,13 +75,24 @@ typedef struct _MetaWaylandDataSourceWayland | ||||
|   struct wl_resource *resource; | ||||
| } MetaWaylandDataSourceWayland; | ||||
|  | ||||
| typedef struct _MetaWaylandDataSourcePrimary | ||||
| { | ||||
|   MetaWaylandDataSourceWayland parent; | ||||
|  | ||||
|   struct wl_resource *resource; | ||||
| } MetaWaylandDataSourcePrimary; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandDataSource, meta_wayland_data_source, | ||||
|                             G_TYPE_OBJECT); | ||||
| G_DEFINE_TYPE (MetaWaylandDataSourceWayland, meta_wayland_data_source_wayland, | ||||
|                META_TYPE_WAYLAND_DATA_SOURCE); | ||||
| G_DEFINE_TYPE (MetaWaylandDataSourcePrimary, meta_wayland_data_source_primary, | ||||
|                META_TYPE_WAYLAND_DATA_SOURCE); | ||||
|  | ||||
| static MetaWaylandDataSource * | ||||
| meta_wayland_data_source_wayland_new (struct wl_resource *resource); | ||||
| static MetaWaylandDataSource * | ||||
| meta_wayland_data_source_primary_new (struct wl_resource *resource); | ||||
|  | ||||
| static void | ||||
| drag_grab_data_source_destroyed (gpointer data, GObject *where_the_object_was); | ||||
| @@ -160,7 +176,8 @@ static void | ||||
| meta_wayland_data_source_target (MetaWaylandDataSource *source, | ||||
|                                  const char *mime_type) | ||||
| { | ||||
|   META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->target (source, mime_type); | ||||
|   if (META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->target) | ||||
|     META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->target (source, mime_type); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -351,7 +368,8 @@ data_offer_receive (struct wl_client *client, struct wl_resource *resource, | ||||
| } | ||||
|  | ||||
| static void | ||||
| data_offer_destroy (struct wl_client *client, struct wl_resource *resource) | ||||
| default_destructor (struct wl_client   *client, | ||||
|                     struct wl_resource *resource) | ||||
| { | ||||
|   wl_resource_destroy (resource); | ||||
| } | ||||
| @@ -425,11 +443,42 @@ data_offer_set_actions (struct wl_client   *client, | ||||
| static const struct wl_data_offer_interface data_offer_interface = { | ||||
|   data_offer_accept, | ||||
|   data_offer_receive, | ||||
|   data_offer_destroy, | ||||
|   default_destructor, | ||||
|   data_offer_finish, | ||||
|   data_offer_set_actions, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| primary_offer_receive (struct wl_client *client, struct wl_resource *resource, | ||||
|                        const char *mime_type, int32_t fd) | ||||
| { | ||||
|   MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource); | ||||
|   MetaWaylandDataSource *source = offer->source; | ||||
|   MetaWaylandSeat *seat; | ||||
|  | ||||
|   if (!offer->source) | ||||
|     { | ||||
|       close (fd); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   seat = meta_wayland_data_source_get_seat (source); | ||||
|  | ||||
|   if (wl_resource_get_client (offer->resource) != | ||||
|       meta_wayland_keyboard_get_focus_client (&seat->keyboard)) | ||||
|     { | ||||
|       close (fd); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   meta_wayland_data_source_send (offer->source, mime_type, fd); | ||||
| } | ||||
|  | ||||
| static const struct gtk_primary_selection_offer_interface primary_offer_interface = { | ||||
|   primary_offer_receive, | ||||
|   default_destructor, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| meta_wayland_data_source_notify_drop_performed (MetaWaylandDataSource *source) | ||||
| { | ||||
| @@ -446,12 +495,16 @@ static void | ||||
| destroy_data_offer (struct wl_resource *resource) | ||||
| { | ||||
|   MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource); | ||||
|   MetaWaylandSeat *seat; | ||||
|  | ||||
|   if (offer->source) | ||||
|     { | ||||
|       seat = meta_wayland_data_source_get_seat (offer->source); | ||||
|  | ||||
|       if (offer == meta_wayland_data_source_get_current_offer (offer->source)) | ||||
|         { | ||||
|           if (wl_resource_get_version (offer->resource) < | ||||
|           if (seat && seat->data_device.dnd_data_source == offer->source && | ||||
|               wl_resource_get_version (offer->resource) < | ||||
|               WL_DATA_OFFER_ACTION_SINCE_VERSION) | ||||
|             meta_wayland_data_source_notify_finish (offer->source); | ||||
|           else | ||||
| @@ -470,6 +523,28 @@ destroy_data_offer (struct wl_resource *resource) | ||||
|   g_slice_free (MetaWaylandDataOffer, offer); | ||||
| } | ||||
|  | ||||
| static void | ||||
| destroy_primary_offer (struct wl_resource *resource) | ||||
| { | ||||
|   MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource); | ||||
|  | ||||
|   if (offer->source) | ||||
|     { | ||||
|       if (offer == meta_wayland_data_source_get_current_offer (offer->source)) | ||||
|         { | ||||
|           meta_wayland_data_source_cancel (offer->source); | ||||
|           meta_wayland_data_source_set_current_offer (offer->source, NULL); | ||||
|         } | ||||
|  | ||||
|       g_object_remove_weak_pointer (G_OBJECT (offer->source), | ||||
|                                     (gpointer *)&offer->source); | ||||
|       offer->source = NULL; | ||||
|     } | ||||
|  | ||||
|   meta_display_sync_wayland_input_focus (meta_get_display ()); | ||||
|   g_slice_free (MetaWaylandDataOffer, offer); | ||||
| } | ||||
|  | ||||
| static struct wl_resource * | ||||
| meta_wayland_data_source_send_offer (MetaWaylandDataSource *source, | ||||
|                                      struct wl_resource *target) | ||||
| @@ -500,6 +575,35 @@ meta_wayland_data_source_send_offer (MetaWaylandDataSource *source, | ||||
|   return offer->resource; | ||||
| } | ||||
|  | ||||
| static struct wl_resource * | ||||
| meta_wayland_data_source_send_primary_offer (MetaWaylandDataSource *source, | ||||
| 					     struct wl_resource    *target) | ||||
| { | ||||
|   MetaWaylandDataSourcePrivate *priv = | ||||
|     meta_wayland_data_source_get_instance_private (source); | ||||
|   MetaWaylandDataOffer *offer = g_slice_new0 (MetaWaylandDataOffer); | ||||
|   char **p; | ||||
|  | ||||
|   offer->source = source; | ||||
|   g_object_add_weak_pointer (G_OBJECT (source), (gpointer *)&offer->source); | ||||
|   offer->resource = wl_resource_create (wl_resource_get_client (target), | ||||
|                                         >k_primary_selection_offer_interface, | ||||
|                                         wl_resource_get_version (target), 0); | ||||
|   wl_resource_set_implementation (offer->resource, | ||||
|                                   &primary_offer_interface, | ||||
|                                   offer, | ||||
|                                   destroy_primary_offer); | ||||
|  | ||||
|   gtk_primary_selection_device_send_data_offer (target, offer->resource); | ||||
|  | ||||
|   wl_array_for_each (p, &priv->mime_types) | ||||
|     gtk_primary_selection_offer_send_offer (offer->resource, *p); | ||||
|  | ||||
|   meta_wayland_data_source_set_current_offer (source, offer); | ||||
|  | ||||
|   return offer->resource; | ||||
| } | ||||
|  | ||||
| static void | ||||
| data_source_offer (struct wl_client *client, | ||||
|                    struct wl_resource *resource, const char *type) | ||||
| @@ -510,12 +614,6 @@ data_source_offer (struct wl_client *client, | ||||
|     wl_resource_post_no_memory (resource); | ||||
| } | ||||
|  | ||||
| static void | ||||
| data_source_destroy (struct wl_client *client, struct wl_resource *resource) | ||||
| { | ||||
|   wl_resource_destroy (resource); | ||||
| } | ||||
|  | ||||
| static void | ||||
| data_source_set_actions (struct wl_client   *client, | ||||
|                          struct wl_resource *resource, | ||||
| @@ -557,10 +655,26 @@ data_source_set_actions (struct wl_client   *client, | ||||
|  | ||||
| static struct wl_data_source_interface data_source_interface = { | ||||
|   data_source_offer, | ||||
|   data_source_destroy, | ||||
|   default_destructor, | ||||
|   data_source_set_actions | ||||
| }; | ||||
|  | ||||
| static void | ||||
| primary_source_offer (struct wl_client   *client, | ||||
|                       struct wl_resource *resource, | ||||
|                       const char         *type) | ||||
| { | ||||
|   MetaWaylandDataSource *source = wl_resource_get_user_data (resource); | ||||
|  | ||||
|   if (!meta_wayland_data_source_add_mime_type (source, type)) | ||||
|     wl_resource_post_no_memory (resource); | ||||
| } | ||||
|  | ||||
| static struct gtk_primary_selection_source_interface primary_source_interface = { | ||||
|   primary_source_offer, | ||||
|   default_destructor, | ||||
| }; | ||||
|  | ||||
| struct _MetaWaylandDragGrab { | ||||
|   MetaWaylandPointerGrab  generic; | ||||
|  | ||||
| @@ -585,6 +699,8 @@ struct _MetaWaylandDragGrab { | ||||
|  | ||||
|   int                     drag_start_x, drag_start_y; | ||||
|   ClutterModifierType     buttons; | ||||
|  | ||||
|   guint                   need_initial_focus : 1; | ||||
| }; | ||||
|  | ||||
| static void | ||||
| @@ -613,30 +729,64 @@ meta_wayland_drag_grab_set_source (MetaWaylandDragGrab   *drag_grab, | ||||
|                        drag_grab); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_drag_source_fake_acceptance (MetaWaylandDataSource *source, | ||||
|                                           const gchar           *mimetype) | ||||
| { | ||||
|   uint32_t actions, user_action, action = 0; | ||||
|  | ||||
|   actions = meta_wayland_data_source_get_actions (source); | ||||
|   user_action = meta_wayland_data_source_get_user_action (source); | ||||
|  | ||||
|   /* Pick a suitable action */ | ||||
|   if ((user_action & actions) != 0) | ||||
|     action = user_action; | ||||
|   else if (actions != 0) | ||||
|     action = 1 << (ffs (actions) - 1); | ||||
|  | ||||
|   /* Bail out if there is none, source didn't cooperate */ | ||||
|   if (action == 0) | ||||
|     return; | ||||
|  | ||||
|   meta_wayland_data_source_target (source, mimetype); | ||||
|   meta_wayland_data_source_set_current_action (source, action); | ||||
|   meta_wayland_data_source_set_has_target (source, TRUE); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_drag_grab_set_focus (MetaWaylandDragGrab *drag_grab, | ||||
|                                   MetaWaylandSurface  *surface) | ||||
| { | ||||
|   MetaWaylandSeat *seat = drag_grab->seat; | ||||
|   MetaWaylandDataSource *source = drag_grab->drag_data_source; | ||||
|   struct wl_client *client; | ||||
|   struct wl_resource *data_device_resource, *offer = NULL; | ||||
|  | ||||
|   if (drag_grab->drag_focus == surface) | ||||
|   if (!drag_grab->need_initial_focus && | ||||
|       drag_grab->drag_focus == surface) | ||||
|     return; | ||||
|  | ||||
|   drag_grab->need_initial_focus = FALSE; | ||||
|  | ||||
|   if (drag_grab->drag_focus) | ||||
|     { | ||||
|       meta_wayland_surface_drag_dest_focus_out (drag_grab->drag_focus); | ||||
|       drag_grab->drag_focus = NULL; | ||||
|     } | ||||
|  | ||||
|   if (drag_grab->drag_data_source) | ||||
|     meta_wayland_data_source_set_current_offer (drag_grab->drag_data_source, NULL); | ||||
|   if (source) | ||||
|     meta_wayland_data_source_set_current_offer (source, NULL); | ||||
|  | ||||
|   if (!surface && source && | ||||
|       meta_wayland_data_source_has_mime_type (source, ROOTWINDOW_DROP_MIME)) | ||||
|     meta_wayland_drag_source_fake_acceptance (source, ROOTWINDOW_DROP_MIME); | ||||
|   else if (source) | ||||
|     meta_wayland_data_source_target (source, NULL); | ||||
|  | ||||
|   if (!surface) | ||||
|     return; | ||||
|  | ||||
|   if (!drag_grab->drag_data_source && | ||||
|   if (!source && | ||||
|       wl_resource_get_client (surface->resource) != drag_grab->drag_client) | ||||
|     return; | ||||
|  | ||||
| @@ -644,9 +794,8 @@ meta_wayland_drag_grab_set_focus (MetaWaylandDragGrab *drag_grab, | ||||
|  | ||||
|   data_device_resource = wl_resource_find_for_client (&seat->data_device.resource_list, client); | ||||
|  | ||||
|   if (drag_grab->drag_data_source && data_device_resource) | ||||
|     offer = meta_wayland_data_source_send_offer (drag_grab->drag_data_source, | ||||
|                                                  data_device_resource); | ||||
|   if (source && data_device_resource) | ||||
|     offer = meta_wayland_data_source_send_offer (source, data_device_resource); | ||||
|  | ||||
|   drag_grab->drag_focus = surface; | ||||
|   drag_grab->drag_focus_data_device = data_device_resource; | ||||
| @@ -739,6 +888,47 @@ data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab) | ||||
|   g_slice_free (MetaWaylandDragGrab, drag_grab); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| on_fake_read_hup (GIOChannel   *channel, | ||||
|                   GIOCondition  condition, | ||||
|                   gpointer      data) | ||||
| { | ||||
|   MetaWaylandDataSource *source = data; | ||||
|  | ||||
|   meta_wayland_data_source_notify_finish (source); | ||||
|   g_io_channel_shutdown (channel, FALSE, NULL); | ||||
|   g_io_channel_unref (channel); | ||||
|  | ||||
|   return G_SOURCE_REMOVE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_data_source_fake_read (MetaWaylandDataSource *source, | ||||
|                                     const gchar           *mimetype) | ||||
| { | ||||
|   GIOChannel *channel; | ||||
|   int p[2]; | ||||
|  | ||||
|   if (!g_unix_open_pipe (p, FD_CLOEXEC, NULL)) | ||||
|     { | ||||
|       meta_wayland_data_source_notify_finish (source); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   if (!g_unix_set_fd_nonblocking (p[0], TRUE, NULL) || | ||||
|       !g_unix_set_fd_nonblocking (p[1], TRUE, NULL)) | ||||
|     { | ||||
|       meta_wayland_data_source_notify_finish (source); | ||||
|       close (p[0]); | ||||
|       close (p[1]); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   meta_wayland_data_source_send (source, mimetype, p[1]); | ||||
|   channel = g_io_channel_unix_new (p[0]); | ||||
|   g_io_add_watch (channel, G_IO_HUP, on_fake_read_hup, source); | ||||
| } | ||||
|  | ||||
| static void | ||||
| drag_grab_button (MetaWaylandPointerGrab *grab, | ||||
| 		  const ClutterEvent     *event) | ||||
| @@ -767,6 +957,15 @@ drag_grab_button (MetaWaylandPointerGrab *grab, | ||||
|           meta_wayland_source_update_in_ask (source); | ||||
|           success = TRUE; | ||||
|         } | ||||
|       else if (!drag_grab->drag_focus && source && | ||||
|                meta_wayland_data_source_has_target (source) && | ||||
|                meta_wayland_data_source_get_current_action (source) && | ||||
|                meta_wayland_data_source_has_mime_type (source, ROOTWINDOW_DROP_MIME)) | ||||
|         { | ||||
|           /* Perform a fake read, that will lead to notify_finish() being called */ | ||||
|           meta_wayland_data_source_fake_read (source, ROOTWINDOW_DROP_MIME); | ||||
|           success = TRUE; | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           meta_wayland_data_source_cancel (source); | ||||
| @@ -868,7 +1067,7 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice                 *data | ||||
| { | ||||
|   MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device); | ||||
|   MetaWaylandDragGrab *drag_grab; | ||||
|   ClutterPoint pos, stage_pos; | ||||
|   ClutterPoint pos, surface_pos; | ||||
|   ClutterModifierType modifiers; | ||||
|  | ||||
|   data_device->current_grab = drag_grab = g_slice_new0 (MetaWaylandDragGrab); | ||||
| @@ -887,11 +1086,14 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice                 *data | ||||
|   wl_resource_add_destroy_listener (surface->resource, | ||||
|                                     &drag_grab->drag_origin_listener); | ||||
|  | ||||
|   clutter_input_device_get_coords (seat->pointer.device, NULL, &pos); | ||||
|   clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)), | ||||
|                                        pos.x, pos.y, &stage_pos.x, &stage_pos.y); | ||||
|   drag_grab->drag_start_x = stage_pos.x; | ||||
|   drag_grab->drag_start_y = stage_pos.y; | ||||
|                                        seat->pointer.grab_x, | ||||
|                                        seat->pointer.grab_y, | ||||
|                                        &surface_pos.x, &surface_pos.y); | ||||
|   drag_grab->drag_start_x = surface_pos.x; | ||||
|   drag_grab->drag_start_y = surface_pos.y; | ||||
|  | ||||
|   drag_grab->need_initial_focus = TRUE; | ||||
|  | ||||
|   modifiers = clutter_input_device_get_modifier_state (seat->pointer.device); | ||||
|   drag_grab->buttons = modifiers & | ||||
| @@ -919,6 +1121,7 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice                 *data | ||||
|       clutter_actor_add_child (drag_grab->feedback_actor, | ||||
|                                CLUTTER_ACTOR (drag_grab->drag_surface->surface_actor)); | ||||
|  | ||||
|       clutter_input_device_get_coords (seat->pointer.device, NULL, &pos); | ||||
|       meta_feedback_actor_set_position (META_FEEDBACK_ACTOR (drag_grab->feedback_actor), | ||||
|                                         pos.x, pos.y); | ||||
|     } | ||||
| @@ -1006,6 +1209,8 @@ selection_data_source_destroyed (gpointer data, GObject *object_was_here) | ||||
|       if (data_device_resource) | ||||
|         wl_data_device_send_selection (data_device_resource, NULL); | ||||
|     } | ||||
|  | ||||
|   wl_signal_emit (&data_device->selection_ownership_signal, NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -1108,6 +1313,43 @@ meta_wayland_data_source_wayland_class_init (MetaWaylandDataSourceWaylandClass * | ||||
|   data_source_class->drag_finished = meta_wayland_source_drag_finished; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_data_source_primary_send (MetaWaylandDataSource *source, | ||||
|                                        const gchar           *mime_type, | ||||
|                                        gint                   fd) | ||||
| { | ||||
|   MetaWaylandDataSourcePrimary *source_primary; | ||||
|  | ||||
|   source_primary = META_WAYLAND_DATA_SOURCE_PRIMARY (source); | ||||
|   gtk_primary_selection_source_send_send (source_primary->resource, | ||||
|                                           mime_type, fd); | ||||
|   close (fd); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_data_source_primary_cancel (MetaWaylandDataSource *source) | ||||
| { | ||||
|   MetaWaylandDataSourcePrimary *source_primary; | ||||
|  | ||||
|   source_primary = META_WAYLAND_DATA_SOURCE_PRIMARY (source); | ||||
|   gtk_primary_selection_source_send_cancelled (source_primary->resource); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_data_source_primary_init (MetaWaylandDataSourcePrimary *source_primary) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_data_source_primary_class_init (MetaWaylandDataSourcePrimaryClass *klass) | ||||
| { | ||||
|   MetaWaylandDataSourceClass *data_source_class = | ||||
|     META_WAYLAND_DATA_SOURCE_CLASS (klass); | ||||
|  | ||||
|   data_source_class->send = meta_wayland_data_source_primary_send; | ||||
|   data_source_class->cancel = meta_wayland_data_source_primary_cancel; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_data_source_finalize (GObject *object) | ||||
| { | ||||
| @@ -1299,6 +1541,7 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device, | ||||
|  | ||||
|   if (source) | ||||
|     { | ||||
|       meta_wayland_data_source_set_seat (source, seat); | ||||
|       g_object_weak_ref (G_OBJECT (source), | ||||
|                          selection_data_source_destroyed, | ||||
|                          data_device); | ||||
| @@ -1339,16 +1582,116 @@ data_device_set_selection (struct wl_client *client, | ||||
|   meta_wayland_data_device_set_selection (data_device, source, serial); | ||||
| } | ||||
|  | ||||
| static void | ||||
| data_device_release(struct wl_client *client, struct wl_resource *resource) | ||||
| { | ||||
|   wl_resource_destroy(resource); | ||||
| } | ||||
|  | ||||
| static const struct wl_data_device_interface data_device_interface = { | ||||
|   data_device_start_drag, | ||||
|   data_device_set_selection, | ||||
|   data_device_release, | ||||
|   default_destructor, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| primary_source_destroyed (gpointer  data, | ||||
|                           GObject  *object_was_here) | ||||
| { | ||||
|   MetaWaylandDataDevice *data_device = data; | ||||
|   MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device); | ||||
|   struct wl_client *focus_client = NULL; | ||||
|  | ||||
|   data_device->primary_data_source = NULL; | ||||
|  | ||||
|   focus_client = meta_wayland_keyboard_get_focus_client (&seat->keyboard); | ||||
|   if (focus_client) | ||||
|     { | ||||
|       struct wl_resource *data_device_resource; | ||||
|  | ||||
|       data_device_resource = wl_resource_find_for_client (&data_device->primary_resource_list, focus_client); | ||||
|       if (data_device_resource) | ||||
|         gtk_primary_selection_device_send_selection (data_device_resource, NULL); | ||||
|     } | ||||
|  | ||||
|   wl_signal_emit (&data_device->primary_ownership_signal, NULL); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device, | ||||
|                                       MetaWaylandDataSource *source, | ||||
|                                       guint32                serial) | ||||
| { | ||||
|   MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device); | ||||
|   struct wl_resource *data_device_resource, *offer; | ||||
|   struct wl_client *focus_client; | ||||
|  | ||||
|   if (META_IS_WAYLAND_DATA_SOURCE_PRIMARY (source)) | ||||
|     { | ||||
|       struct wl_resource *resource; | ||||
|  | ||||
|       resource = META_WAYLAND_DATA_SOURCE_PRIMARY (source)->resource; | ||||
|  | ||||
|       if (wl_resource_get_client (resource) != | ||||
|           meta_wayland_keyboard_get_focus_client (&seat->keyboard)) | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|   if (data_device->primary_data_source && | ||||
|       data_device->primary_serial - serial < UINT32_MAX / 2) | ||||
|     return; | ||||
|  | ||||
|   if (data_device->primary_data_source) | ||||
|     { | ||||
|       meta_wayland_data_source_cancel (data_device->primary_data_source); | ||||
|       g_object_weak_unref (G_OBJECT (data_device->primary_data_source), | ||||
|                            primary_source_destroyed, | ||||
|                            data_device); | ||||
|     } | ||||
|  | ||||
|   data_device->primary_data_source = source; | ||||
|   data_device->primary_serial = serial; | ||||
|  | ||||
|   focus_client = meta_wayland_keyboard_get_focus_client (&seat->keyboard); | ||||
|   if (focus_client) | ||||
|     { | ||||
|       data_device_resource = wl_resource_find_for_client (&data_device->primary_resource_list, focus_client); | ||||
|       if (data_device_resource) | ||||
|         { | ||||
|           if (data_device->primary_data_source) | ||||
|             { | ||||
|               offer = meta_wayland_data_source_send_primary_offer (data_device->primary_data_source, | ||||
|                                                                    data_device_resource); | ||||
|               gtk_primary_selection_device_send_selection (data_device_resource, offer); | ||||
|             } | ||||
|           else | ||||
|             { | ||||
|               gtk_primary_selection_device_send_selection (data_device_resource, NULL); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   if (source) | ||||
|     { | ||||
|       meta_wayland_data_source_set_seat (source, seat); | ||||
|       g_object_weak_ref (G_OBJECT (source), | ||||
|                          primary_source_destroyed, | ||||
|                          data_device); | ||||
|     } | ||||
|  | ||||
|   wl_signal_emit (&data_device->primary_ownership_signal, source); | ||||
| } | ||||
|  | ||||
| static void | ||||
| primary_device_set_selection (struct wl_client   *client, | ||||
|                               struct wl_resource *resource, | ||||
|                               struct wl_resource *source_resource, | ||||
|                               uint32_t            serial) | ||||
| { | ||||
|   MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource); | ||||
|   MetaWaylandDataSource *source; | ||||
|  | ||||
|   source = wl_resource_get_user_data (source_resource); | ||||
|   meta_wayland_data_device_set_primary (data_device, source, serial); | ||||
| } | ||||
|  | ||||
| static const struct gtk_primary_selection_device_interface primary_device_interface = { | ||||
|   primary_device_set_selection, | ||||
|   default_destructor, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| @@ -1389,6 +1732,51 @@ static const struct wl_data_device_manager_interface manager_interface = { | ||||
|   get_data_device | ||||
| }; | ||||
|  | ||||
| static void | ||||
| destroy_primary_source (struct wl_resource *resource) | ||||
| { | ||||
|   MetaWaylandDataSourcePrimary *source = wl_resource_get_user_data (resource); | ||||
|  | ||||
|   source->resource = NULL; | ||||
|   g_object_unref (source); | ||||
| } | ||||
|  | ||||
| static void | ||||
| primary_device_manager_create_source (struct wl_client   *client, | ||||
|                                       struct wl_resource *manager_resource, | ||||
|                                       guint32             id) | ||||
| { | ||||
|   struct wl_resource *source_resource; | ||||
|  | ||||
|   source_resource = | ||||
|     wl_resource_create (client, >k_primary_selection_source_interface, | ||||
|                         wl_resource_get_version (manager_resource), | ||||
|                         id); | ||||
|   meta_wayland_data_source_primary_new (source_resource); | ||||
| } | ||||
|  | ||||
| static void | ||||
| primary_device_manager_get_device (struct wl_client   *client, | ||||
|                                    struct wl_resource *manager_resource, | ||||
|                                    guint32             id, | ||||
|                                    struct wl_resource *seat_resource) | ||||
| { | ||||
|   MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); | ||||
|   struct wl_resource *cr; | ||||
|  | ||||
|   cr = wl_resource_create (client, >k_primary_selection_device_interface, | ||||
|                            wl_resource_get_version (manager_resource), id); | ||||
|   wl_resource_set_implementation (cr, &primary_device_interface, | ||||
|                                   &seat->data_device, unbind_resource); | ||||
|   wl_list_insert (&seat->data_device.primary_resource_list, wl_resource_get_link (cr)); | ||||
| } | ||||
|  | ||||
| static const struct gtk_primary_selection_device_manager_interface primary_manager_interface = { | ||||
|   primary_device_manager_create_source, | ||||
|   primary_device_manager_get_device, | ||||
|   default_destructor, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| bind_manager (struct wl_client *client, | ||||
|               void *data, guint32 version, guint32 id) | ||||
| @@ -1398,6 +1786,19 @@ bind_manager (struct wl_client *client, | ||||
|   wl_resource_set_implementation (resource, &manager_interface, NULL, NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| bind_primary_manager (struct wl_client *client, | ||||
|                       void             *data, | ||||
|                       uint32_t          version, | ||||
|                       uint32_t          id) | ||||
| { | ||||
|   struct wl_resource *resource; | ||||
|  | ||||
|   resource = wl_resource_create (client, >k_primary_selection_device_manager_interface, | ||||
|                                  version, id); | ||||
|   wl_resource_set_implementation (resource, &primary_manager_interface, NULL, NULL); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_data_device_manager_init (MetaWaylandCompositor *compositor) | ||||
| { | ||||
| @@ -1406,13 +1807,20 @@ meta_wayland_data_device_manager_init (MetaWaylandCompositor *compositor) | ||||
| 			META_WL_DATA_DEVICE_MANAGER_VERSION, | ||||
| 			NULL, bind_manager) == NULL) | ||||
|     g_error ("Could not create data_device"); | ||||
|  | ||||
|   if (wl_global_create (compositor->wayland_display, | ||||
| 			>k_primary_selection_device_manager_interface, | ||||
| 			1, NULL, bind_primary_manager) == NULL) | ||||
|     g_error ("Could not create data_device"); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_data_device_init (MetaWaylandDataDevice *data_device) | ||||
| { | ||||
|   wl_list_init (&data_device->resource_list); | ||||
|   wl_list_init (&data_device->primary_resource_list); | ||||
|   wl_signal_init (&data_device->selection_ownership_signal); | ||||
|   wl_signal_init (&data_device->primary_ownership_signal); | ||||
|   wl_signal_init (&data_device->dnd_ownership_signal); | ||||
| } | ||||
|  | ||||
| @@ -1435,17 +1843,34 @@ meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device) | ||||
|     return; | ||||
|  | ||||
|   data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client); | ||||
|   if (!data_device_resource) | ||||
|     return; | ||||
|  | ||||
|   source = data_device->selection_data_source; | ||||
|   if (source) | ||||
|   if (data_device_resource) | ||||
|     { | ||||
|       offer = meta_wayland_data_source_send_offer (source, data_device_resource); | ||||
|       wl_data_device_send_selection (data_device_resource, offer); | ||||
|       source = data_device->selection_data_source; | ||||
|       if (source) | ||||
|         { | ||||
|           offer = meta_wayland_data_source_send_offer (source, data_device_resource); | ||||
|           wl_data_device_send_selection (data_device_resource, offer); | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           wl_data_device_send_selection (data_device_resource, NULL); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   data_device_resource = wl_resource_find_for_client (&data_device->primary_resource_list, focus_client); | ||||
|   if (data_device_resource) | ||||
|     { | ||||
|       source = data_device->primary_data_source; | ||||
|       if (source) | ||||
|         { | ||||
|           offer = meta_wayland_data_source_send_primary_offer (source, data_device_resource); | ||||
|           gtk_primary_selection_device_send_selection (data_device_resource, offer); | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           gtk_primary_selection_device_send_selection (data_device_resource, NULL); | ||||
|         } | ||||
|     } | ||||
|   else | ||||
|     wl_data_device_send_selection (data_device_resource, NULL); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| @@ -1486,6 +1911,19 @@ meta_wayland_data_source_wayland_new (struct wl_resource *resource) | ||||
|   return META_WAYLAND_DATA_SOURCE (source_wayland); | ||||
| } | ||||
|  | ||||
| static MetaWaylandDataSource * | ||||
| meta_wayland_data_source_primary_new (struct wl_resource *resource) | ||||
| { | ||||
|   MetaWaylandDataSourcePrimary *source_primary = | ||||
|     g_object_new (META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY, NULL); | ||||
|  | ||||
|   source_primary->resource = resource; | ||||
|   wl_resource_set_implementation (resource, &primary_source_interface, | ||||
|                                   source_primary, destroy_primary_source); | ||||
|  | ||||
|   return META_WAYLAND_DATA_SOURCE (source_primary); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_wayland_data_source_add_mime_type (MetaWaylandDataSource *source, | ||||
|                                         const gchar           *mime_type) | ||||
|   | ||||
| @@ -55,15 +55,19 @@ struct _MetaWaylandDataSourceClass | ||||
| struct _MetaWaylandDataDevice | ||||
| { | ||||
|   uint32_t selection_serial; | ||||
|   uint32_t primary_serial; | ||||
|   MetaWaylandDataSource *selection_data_source; | ||||
|   MetaWaylandDataSource *dnd_data_source; | ||||
|   MetaWaylandDataSource *primary_data_source; | ||||
|   struct wl_listener selection_data_source_listener; | ||||
|   struct wl_list resource_list; | ||||
|   struct wl_list primary_resource_list; | ||||
|   MetaWaylandDragGrab *current_grab; | ||||
|   struct wl_client *focus_client; | ||||
|  | ||||
|   struct wl_signal selection_ownership_signal; | ||||
|   struct wl_signal dnd_ownership_signal; | ||||
|   struct wl_signal primary_ownership_signal; | ||||
| }; | ||||
|  | ||||
| void meta_wayland_data_device_manager_init (MetaWaylandCompositor *compositor); | ||||
| @@ -80,6 +84,9 @@ void meta_wayland_data_device_set_dnd_source     (MetaWaylandDataDevice *data_de | ||||
| void meta_wayland_data_device_set_selection      (MetaWaylandDataDevice *data_device, | ||||
|                                                   MetaWaylandDataSource *source, | ||||
|                                                   guint32 serial); | ||||
| void meta_wayland_data_device_set_primary        (MetaWaylandDataDevice *data_device, | ||||
|                                                   MetaWaylandDataSource *source, | ||||
|                                                   guint32                serial); | ||||
|  | ||||
| gboolean meta_wayland_data_source_add_mime_type  (MetaWaylandDataSource *source, | ||||
|                                                   const gchar           *mime_type); | ||||
|   | ||||
							
								
								
									
										990
									
								
								src/wayland/meta-wayland-pointer-constraints.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										990
									
								
								src/wayland/meta-wayland-pointer-constraints.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,990 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2015 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jonas Ådahl <jadahl@gmail.com> | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "meta-wayland-pointer-constraints.h" | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| #include "meta/meta-backend.h" | ||||
| #include "meta-wayland-private.h" | ||||
| #include "meta-wayland-seat.h" | ||||
| #include "meta-wayland-pointer.h" | ||||
| #include "meta-wayland-surface.h" | ||||
| #include "meta-wayland-region.h" | ||||
| #include "meta-pointer-lock-wayland.h" | ||||
| #include "meta-pointer-confinement-wayland.h" | ||||
| #include "window-private.h" | ||||
| #include "backends/meta-backend-private.h" | ||||
| #include "backends/native/meta-backend-native.h" | ||||
| #include "backends/meta-pointer-constraint.h" | ||||
|  | ||||
| #include "pointer-constraints-unstable-v1-server-protocol.h" | ||||
|  | ||||
| static GQuark quark_pending_constraint_state = 0; | ||||
| static GQuark quark_surface_pointer_constraints_data = 0; | ||||
|  | ||||
| struct _MetaWaylandPointerConstraint | ||||
| { | ||||
|   GObject parent; | ||||
|  | ||||
|   MetaWaylandSurface *surface; | ||||
|   gboolean is_enabled; | ||||
|   cairo_region_t *region; | ||||
|   struct wl_resource *resource; | ||||
|   MetaWaylandPointerGrab grab; | ||||
|   MetaWaylandSeat *seat; | ||||
|   enum zwp_pointer_constraints_v1_lifetime lifetime; | ||||
|  | ||||
|   gboolean hint_set; | ||||
|   wl_fixed_t x_hint; | ||||
|   wl_fixed_t y_hint; | ||||
|  | ||||
|   MetaPointerConstraint *constraint; | ||||
| }; | ||||
|  | ||||
| typedef struct _MetaWaylandSurfacePointerConstraintsData | ||||
| { | ||||
|   GList *pointer_constraints; | ||||
|   MetaWindow *window; | ||||
|   gulong appears_changed_handler_id; | ||||
|   gulong raised_handler_id; | ||||
| } MetaWaylandSurfacePointerConstraintsData; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   MetaWaylandPointerConstraint *constraint; | ||||
|   cairo_region_t *region; | ||||
|   gulong applied_handler_id; | ||||
| } MetaWaylandPendingConstraintState; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   GList *pending_constraint_states; | ||||
| } MetaWaylandPendingConstraintStateContainer; | ||||
|  | ||||
| G_DEFINE_TYPE (MetaWaylandPointerConstraint, meta_wayland_pointer_constraint, | ||||
|                G_TYPE_OBJECT); | ||||
|  | ||||
| static const struct zwp_locked_pointer_v1_interface locked_pointer_interface; | ||||
| static const struct zwp_confined_pointer_v1_interface confined_pointer_interface; | ||||
| static const MetaWaylandPointerGrabInterface locked_pointer_grab_interface; | ||||
| static const MetaWaylandPointerGrabInterface confined_pointer_grab_interface; | ||||
|  | ||||
| static void | ||||
| meta_wayland_pointer_constraint_destroy (MetaWaylandPointerConstraint *constraint); | ||||
|  | ||||
| static void | ||||
| meta_wayland_pointer_constraint_maybe_enable_for_window (MetaWindow *window); | ||||
|  | ||||
| static void | ||||
| meta_wayland_pointer_constraint_maybe_remove_for_seat (MetaWaylandSeat *seat, | ||||
|                                                        MetaWindow      *window); | ||||
|  | ||||
| static MetaWaylandSurfacePointerConstraintsData * | ||||
| get_surface_constraints_data (MetaWaylandSurface *surface) | ||||
| { | ||||
|   return g_object_get_qdata (G_OBJECT (surface), | ||||
|                              quark_surface_pointer_constraints_data); | ||||
| } | ||||
|  | ||||
| static void | ||||
| appears_focused_changed (MetaWindow *window, | ||||
|                          GParamSpec *pspec, | ||||
|                          gpointer    user_data) | ||||
| { | ||||
|   MetaWaylandCompositor *wayland_compositor; | ||||
|  | ||||
|   wayland_compositor = meta_wayland_compositor_get_default (); | ||||
|   meta_wayland_pointer_constraint_maybe_remove_for_seat (wayland_compositor->seat, | ||||
|                                                          window); | ||||
|  | ||||
|   if (window->unmanaging) | ||||
|     return; | ||||
|  | ||||
|   meta_wayland_pointer_constraint_maybe_enable_for_window (window); | ||||
| } | ||||
|  | ||||
| static void | ||||
| window_raised (MetaWindow *window) | ||||
| { | ||||
|   meta_wayland_pointer_constraint_maybe_enable_for_window (window); | ||||
| } | ||||
|  | ||||
| static MetaWaylandSurfacePointerConstraintsData * | ||||
| surface_constraint_data_new (MetaWaylandSurface *surface) | ||||
| { | ||||
|   MetaWaylandSurfacePointerConstraintsData *data; | ||||
|  | ||||
|   data = g_new0 (MetaWaylandSurfacePointerConstraintsData, 1); | ||||
|  | ||||
|   if (surface->window) | ||||
|     { | ||||
|       data->window = surface->window; | ||||
|       g_object_add_weak_pointer (G_OBJECT (data->window), | ||||
|                                  (gpointer *) &data->window); | ||||
|       data->appears_changed_handler_id = | ||||
|         g_signal_connect (data->window, "notify::appears-focused", | ||||
|                           G_CALLBACK (appears_focused_changed), NULL); | ||||
|       data->raised_handler_id = | ||||
|         g_signal_connect (data->window, "raised", | ||||
|                           G_CALLBACK (window_raised), NULL); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* TODO: Support constraints on non-toplevel windows, such as subsurfaces. | ||||
|        */ | ||||
|       g_warn_if_reached (); | ||||
|     } | ||||
|  | ||||
|   return data; | ||||
| } | ||||
| static void | ||||
| surface_constraint_data_free (MetaWaylandSurfacePointerConstraintsData *data) | ||||
| { | ||||
|   if (data->window) | ||||
|     { | ||||
|       g_signal_handler_disconnect (data->window, | ||||
|                                    data->appears_changed_handler_id); | ||||
|       g_signal_handler_disconnect (data->window, | ||||
|                                    data->raised_handler_id); | ||||
|       g_object_remove_weak_pointer (G_OBJECT (data->window), | ||||
|                                     (gpointer *) &data->window); | ||||
|     } | ||||
|  | ||||
|   g_list_free_full (data->pointer_constraints, | ||||
|                     (GDestroyNotify) meta_wayland_pointer_constraint_destroy); | ||||
|   g_free (data); | ||||
| } | ||||
|  | ||||
| static MetaWaylandSurfacePointerConstraintsData * | ||||
| ensure_surface_constraints_data (MetaWaylandSurface *surface) | ||||
| { | ||||
|   MetaWaylandSurfacePointerConstraintsData *data; | ||||
|  | ||||
|   data = get_surface_constraints_data (surface); | ||||
|   if (!data) | ||||
|     { | ||||
|       data = surface_constraint_data_new (surface); | ||||
|       g_object_set_qdata_full (G_OBJECT (surface), | ||||
|                                quark_surface_pointer_constraints_data, | ||||
|                                data, | ||||
|                                (GDestroyNotify) surface_constraint_data_free); | ||||
|     } | ||||
|  | ||||
|   return data; | ||||
| } | ||||
|  | ||||
| static void | ||||
| surface_add_pointer_constraint (MetaWaylandSurface           *surface, | ||||
|                                 MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   MetaWaylandSurfacePointerConstraintsData *data; | ||||
|  | ||||
|   data = ensure_surface_constraints_data (surface); | ||||
|   data->pointer_constraints = g_list_append (data->pointer_constraints, | ||||
|                                              constraint); | ||||
| } | ||||
|  | ||||
| static void | ||||
| surface_remove_pointer_constraints (MetaWaylandSurface           *surface, | ||||
|                                     MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   MetaWaylandSurfacePointerConstraintsData *data; | ||||
|  | ||||
|   data = get_surface_constraints_data (surface); | ||||
|   data->pointer_constraints = | ||||
|     g_list_remove (data->pointer_constraints, constraint); | ||||
|  | ||||
|   if (!data->pointer_constraints) | ||||
|     { | ||||
|       g_object_set_qdata (G_OBJECT (surface), | ||||
|                           quark_surface_pointer_constraints_data, | ||||
|                           NULL); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static MetaWaylandPointerConstraint * | ||||
| meta_wayland_pointer_constraint_new (MetaWaylandSurface                      *surface, | ||||
|                                      MetaWaylandSeat                         *seat, | ||||
|                                      MetaWaylandRegion                       *region, | ||||
|                                      enum zwp_pointer_constraints_v1_lifetime lifetime, | ||||
|                                      struct wl_resource                      *resource, | ||||
|                                      const MetaWaylandPointerGrabInterface   *grab_interface) | ||||
| { | ||||
|   MetaWaylandPointerConstraint *constraint; | ||||
|  | ||||
|   constraint = g_object_new (META_TYPE_WAYLAND_POINTER_CONSTRAINT, NULL); | ||||
|   if (!constraint) | ||||
|     return NULL; | ||||
|  | ||||
|   constraint->surface = surface; | ||||
|   constraint->seat = seat; | ||||
|   constraint->lifetime = lifetime; | ||||
|   constraint->resource = resource; | ||||
|   constraint->grab.interface = grab_interface; | ||||
|  | ||||
|   if (region) | ||||
|     { | ||||
|       constraint->region = | ||||
|         cairo_region_copy (meta_wayland_region_peek_cairo_region (region)); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       constraint->region = NULL; | ||||
|     } | ||||
|  | ||||
|   return constraint; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_wayland_pointer_constraint_is_enabled (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   return constraint->is_enabled; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_pointer_constraint_notify_activated (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   struct wl_resource *resource = constraint->resource; | ||||
|  | ||||
|   if (wl_resource_instance_of (resource, | ||||
|                                &zwp_locked_pointer_v1_interface, | ||||
|                                &locked_pointer_interface)) | ||||
|     { | ||||
|       zwp_locked_pointer_v1_send_locked (resource); | ||||
|     } | ||||
|   else if (wl_resource_instance_of (resource, | ||||
|                                     &zwp_confined_pointer_v1_interface, | ||||
|                                     &confined_pointer_interface)) | ||||
|     { | ||||
|       zwp_confined_pointer_v1_send_confined (resource); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_pointer_constraint_notify_deactivated (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   struct wl_resource *resource = constraint->resource; | ||||
|  | ||||
|   if (wl_resource_instance_of (resource, | ||||
|                                &zwp_locked_pointer_v1_interface, | ||||
|                                &locked_pointer_interface)) | ||||
|     zwp_locked_pointer_v1_send_unlocked (resource); | ||||
|   else if (wl_resource_instance_of (resource, | ||||
|                                     &zwp_confined_pointer_v1_interface, | ||||
|                                     &confined_pointer_interface)) | ||||
|     zwp_confined_pointer_v1_send_unconfined (resource); | ||||
| } | ||||
|  | ||||
| static MetaPointerConstraint * | ||||
| meta_wayland_pointer_constraint_create_pointer_constraint (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   struct wl_resource *resource = constraint->resource; | ||||
|  | ||||
|   if (wl_resource_instance_of (resource, | ||||
|                                &zwp_locked_pointer_v1_interface, | ||||
|                                &locked_pointer_interface)) | ||||
|     { | ||||
|       return meta_pointer_lock_wayland_new (); | ||||
|     } | ||||
|   else if (wl_resource_instance_of (resource, | ||||
|                                     &zwp_confined_pointer_v1_interface, | ||||
|                                     &confined_pointer_interface)) | ||||
|     { | ||||
|       return meta_pointer_confinement_wayland_new (constraint); | ||||
|     } | ||||
|   g_assert_not_reached (); | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_pointer_constraint_enable (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   MetaBackend *backend = meta_get_backend (); | ||||
|  | ||||
|   g_assert (!constraint->is_enabled); | ||||
|  | ||||
|   constraint->is_enabled = TRUE; | ||||
|   meta_wayland_pointer_constraint_notify_activated (constraint); | ||||
|   meta_wayland_pointer_start_grab (&constraint->seat->pointer, | ||||
|                                    &constraint->grab); | ||||
|  | ||||
|   constraint->constraint = | ||||
|     meta_wayland_pointer_constraint_create_pointer_constraint (constraint); | ||||
|   meta_backend_set_client_pointer_constraint (backend, constraint->constraint); | ||||
|   g_object_add_weak_pointer (G_OBJECT (constraint->constraint), | ||||
|                              (gpointer *) &constraint->constraint); | ||||
|   g_object_unref (constraint->constraint); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_pointer_constraint_disable (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   constraint->is_enabled = FALSE; | ||||
|   meta_wayland_pointer_constraint_notify_deactivated (constraint); | ||||
|   meta_wayland_pointer_end_grab (constraint->grab.pointer); | ||||
|   meta_backend_set_client_pointer_constraint (meta_get_backend (), NULL); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_pointer_constraint_destroy (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   if (meta_wayland_pointer_constraint_is_enabled (constraint)) | ||||
|     meta_wayland_pointer_constraint_disable (constraint); | ||||
|  | ||||
|   wl_resource_set_user_data (constraint->resource, NULL); | ||||
|   g_clear_pointer (&constraint->region, cairo_region_destroy); | ||||
|   g_object_unref (constraint); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| is_within_constraint_region (MetaWaylandPointerConstraint *constraint, | ||||
|                              wl_fixed_t                    sx, | ||||
|                              wl_fixed_t                    sy) | ||||
| { | ||||
|   cairo_region_t *region; | ||||
|   gboolean is_within; | ||||
|  | ||||
|   region = meta_wayland_pointer_constraint_calculate_effective_region (constraint); | ||||
|   is_within = cairo_region_contains_point (region, | ||||
|                                            wl_fixed_to_int (sx), | ||||
|                                            wl_fixed_to_int (sy)); | ||||
|   cairo_region_destroy (region); | ||||
|  | ||||
|   return is_within; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_pointer_constraint_maybe_enable (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   wl_fixed_t sx, sy; | ||||
|  | ||||
|   if (constraint->is_enabled) | ||||
|     return; | ||||
|  | ||||
|   if (!constraint->surface->window) | ||||
|     { | ||||
|       g_warn_if_reached (); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   if (!meta_window_appears_focused (constraint->surface->window)) | ||||
|     return; | ||||
|  | ||||
|   meta_wayland_pointer_get_relative_coordinates (&constraint->seat->pointer, | ||||
|                                                  constraint->surface, | ||||
|                                                  &sx, &sy); | ||||
|   if (!is_within_constraint_region (constraint, sx, sy)) | ||||
|     return; | ||||
|  | ||||
|   meta_wayland_pointer_constraint_enable (constraint); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_pointer_constraint_remove (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   MetaWaylandSurface *surface = constraint->surface; | ||||
|  | ||||
|   surface_remove_pointer_constraints (surface, constraint); | ||||
|   meta_wayland_pointer_constraint_destroy (constraint); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_pointer_constraint_maybe_remove_for_seat (MetaWaylandSeat *seat, | ||||
|                                                        MetaWindow      *window) | ||||
| { | ||||
|   MetaWaylandPointer *pointer = &seat->pointer; | ||||
|   MetaWaylandPointerConstraint *constraint; | ||||
|  | ||||
|   if ((pointer->grab->interface != &confined_pointer_grab_interface && | ||||
|        pointer->grab->interface != &locked_pointer_grab_interface)) | ||||
|     return; | ||||
|  | ||||
|   constraint = wl_container_of (pointer->grab, constraint, grab); | ||||
|  | ||||
|   if (constraint->surface != window->surface) | ||||
|     return; | ||||
|  | ||||
|   if (meta_window_appears_focused (window) && | ||||
|       pointer->focus_surface == window->surface) | ||||
|     return; | ||||
|  | ||||
|   switch (constraint->lifetime) | ||||
|     { | ||||
|     case ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT: | ||||
|       meta_wayland_pointer_constraint_remove (constraint); | ||||
|       break; | ||||
|  | ||||
|     case ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT: | ||||
|       meta_wayland_pointer_constraint_disable (constraint); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       g_assert_not_reached (); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_pointer_constraint_maybe_enable_for_window (MetaWindow *window) | ||||
| { | ||||
|   MetaWaylandSurface *surface = window->surface; | ||||
|   MetaWaylandSurfacePointerConstraintsData *surface_data; | ||||
|   GList *l; | ||||
|  | ||||
|   surface_data = get_surface_constraints_data (surface); | ||||
|   if (!surface_data) | ||||
|     return; | ||||
|  | ||||
|   for (l = surface_data->pointer_constraints; l; l = l->next) | ||||
|     { | ||||
|       MetaWaylandPointerConstraint *constraint = l->data; | ||||
|  | ||||
|       meta_wayland_pointer_constraint_maybe_enable (constraint); | ||||
|     } | ||||
| } | ||||
|  | ||||
| MetaWaylandSeat * | ||||
| meta_wayland_pointer_constraint_get_seat (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   return constraint->seat; | ||||
| } | ||||
|  | ||||
| cairo_region_t * | ||||
| meta_wayland_pointer_constraint_calculate_effective_region (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   cairo_region_t *region; | ||||
|  | ||||
|   region = meta_wayland_surface_calculate_input_region (constraint->surface); | ||||
|   if (constraint->region) | ||||
|     cairo_region_intersect (region, constraint->region); | ||||
|  | ||||
|   return region; | ||||
| } | ||||
|  | ||||
| MetaWaylandSurface * | ||||
| meta_wayland_pointer_constraint_get_surface (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   return constraint->surface; | ||||
| } | ||||
|  | ||||
| static void | ||||
| pointer_constraint_resource_destroyed (struct wl_resource *resource) | ||||
| { | ||||
|   MetaWaylandPointerConstraint *constraint = | ||||
|     wl_resource_get_user_data (resource); | ||||
|  | ||||
|   if (!constraint) | ||||
|     return; | ||||
|  | ||||
|   meta_wayland_pointer_constraint_remove (constraint); | ||||
| } | ||||
|  | ||||
| static void | ||||
| pending_constraint_state_free (MetaWaylandPendingConstraintState *constraint_pending) | ||||
| { | ||||
|   g_clear_pointer (&constraint_pending->region, cairo_region_destroy); | ||||
|   if (constraint_pending->constraint) | ||||
|     g_object_remove_weak_pointer (G_OBJECT (constraint_pending->constraint), | ||||
|                                   (gpointer *) &constraint_pending->constraint); | ||||
| } | ||||
|  | ||||
| static MetaWaylandPendingConstraintStateContainer * | ||||
| get_pending_constraint_state_container (MetaWaylandPendingState *pending) | ||||
| { | ||||
|   return g_object_get_qdata (G_OBJECT (pending), | ||||
|                              quark_pending_constraint_state); | ||||
| } | ||||
|  | ||||
| static MetaWaylandPendingConstraintState * | ||||
| get_pending_constraint_state (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   MetaWaylandPendingState *pending = constraint->surface->pending; | ||||
|   MetaWaylandPendingConstraintStateContainer *container; | ||||
|   GList *l; | ||||
|  | ||||
|   container = get_pending_constraint_state_container (pending); | ||||
|   for (l = container->pending_constraint_states; l; l = l->next) | ||||
|     { | ||||
|       MetaWaylandPendingConstraintState *constraint_pending = l->data; | ||||
|  | ||||
|       if (constraint_pending->constraint == constraint) | ||||
|         return constraint_pending; | ||||
|     } | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| static void | ||||
| pending_constraint_state_container_free (MetaWaylandPendingConstraintStateContainer *container) | ||||
| { | ||||
|   g_list_free_full (container->pending_constraint_states, | ||||
|                     (GDestroyNotify) pending_constraint_state_free); | ||||
|   g_free (container); | ||||
| } | ||||
|  | ||||
| static MetaWaylandPendingConstraintStateContainer * | ||||
| ensure_pending_constraint_state_container (MetaWaylandPendingState *pending) | ||||
| { | ||||
|   MetaWaylandPendingConstraintStateContainer *container; | ||||
|  | ||||
|   container = get_pending_constraint_state_container (pending); | ||||
|   if (!container) | ||||
|     { | ||||
|       container = g_new0 (MetaWaylandPendingConstraintStateContainer, 1); | ||||
|       g_object_set_qdata_full (G_OBJECT (pending), | ||||
|                                quark_pending_constraint_state, | ||||
|                                container, | ||||
|                                (GDestroyNotify) pending_constraint_state_container_free); | ||||
|  | ||||
|     } | ||||
|  | ||||
|   return container; | ||||
| } | ||||
|  | ||||
| static void | ||||
| remove_pending_constraint_state (MetaWaylandPointerConstraint *constraint, | ||||
|                                  MetaWaylandPendingState      *pending) | ||||
| { | ||||
|   MetaWaylandPendingConstraintStateContainer *container; | ||||
|   GList *l; | ||||
|  | ||||
|   container = get_pending_constraint_state_container (pending); | ||||
|   for (l = container->pending_constraint_states; l; l = l->next) | ||||
|     { | ||||
|       MetaWaylandPendingConstraintState *constraint_pending = l->data; | ||||
|       if (constraint_pending->constraint != constraint) | ||||
|         continue; | ||||
|  | ||||
|       pending_constraint_state_free (l->data); | ||||
|       container->pending_constraint_states = | ||||
|         g_list_remove_link (container->pending_constraint_states, l); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| pending_constraint_state_applied (MetaWaylandPendingState           *pending, | ||||
|                                   MetaWaylandPendingConstraintState *constraint_pending) | ||||
| { | ||||
|   MetaWaylandPointerConstraint *constraint = constraint_pending->constraint; | ||||
|  | ||||
|   if (!constraint) | ||||
|     return; | ||||
|  | ||||
|   g_clear_pointer (&constraint->region, cairo_region_destroy); | ||||
|   if (constraint_pending->region) | ||||
|     { | ||||
|       constraint->region = constraint_pending->region; | ||||
|       constraint_pending->region = NULL; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       constraint->region = NULL; | ||||
|     } | ||||
|  | ||||
|   g_signal_handler_disconnect (pending, | ||||
|                                constraint_pending->applied_handler_id); | ||||
|   remove_pending_constraint_state (constraint, pending); | ||||
|  | ||||
|   /* The pointer is potentially warped by the actor paint signal callback if | ||||
|    * the new region proved it necessary. | ||||
|    */ | ||||
| } | ||||
|  | ||||
| static MetaWaylandPendingConstraintState * | ||||
| ensure_pending_constraint_state (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
|   MetaWaylandPendingState *pending = constraint->surface->pending; | ||||
|   MetaWaylandPendingConstraintStateContainer *container; | ||||
|   MetaWaylandPendingConstraintState *constraint_pending; | ||||
|  | ||||
|   container = ensure_pending_constraint_state_container (pending); | ||||
|   constraint_pending = get_pending_constraint_state (constraint); | ||||
|   if (!constraint_pending) | ||||
|     { | ||||
|       constraint_pending = g_new0 (MetaWaylandPendingConstraintState, 1); | ||||
|       constraint_pending->constraint = constraint; | ||||
|       constraint_pending->applied_handler_id = | ||||
|         g_signal_connect (pending, "applied", | ||||
|                           G_CALLBACK (pending_constraint_state_applied), | ||||
|                           constraint_pending); | ||||
|       g_object_add_weak_pointer (G_OBJECT (constraint), | ||||
|                                  (gpointer *) &constraint_pending->constraint); | ||||
|  | ||||
|       container->pending_constraint_states = | ||||
|         g_list_append (container->pending_constraint_states, | ||||
|                        constraint_pending); | ||||
|     } | ||||
|  | ||||
|   return constraint_pending; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_pointer_constraint_set_pending_region (MetaWaylandPointerConstraint *constraint, | ||||
|                                                     MetaWaylandRegion            *region) | ||||
| { | ||||
|   MetaWaylandPendingConstraintState *constraint_pending; | ||||
|  | ||||
|   constraint_pending = ensure_pending_constraint_state (constraint); | ||||
|  | ||||
|   g_clear_pointer (&constraint_pending->region, cairo_region_destroy); | ||||
|   if (region) | ||||
|     { | ||||
|       constraint_pending->region = | ||||
|         cairo_region_copy (meta_wayland_region_peek_cairo_region (region)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static MetaWaylandPointerConstraint * | ||||
| get_pointer_constraint_for_seat (MetaWaylandSurface *surface, | ||||
|                                  MetaWaylandSeat    *seat) | ||||
| { | ||||
|   MetaWaylandSurfacePointerConstraintsData *surface_data; | ||||
|   GList *l; | ||||
|  | ||||
|   surface_data = get_surface_constraints_data (surface); | ||||
|   if (!surface_data) | ||||
|     return NULL; | ||||
|  | ||||
|   for (l = surface_data->pointer_constraints; l; l = l->next) | ||||
|     { | ||||
|       MetaWaylandPointerConstraint *constraint = l->data; | ||||
|  | ||||
|       if (seat == constraint->seat) | ||||
|         return constraint; | ||||
|     } | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| static void | ||||
| init_pointer_constraint (struct wl_resource                      *resource, | ||||
|                          uint32_t                                 id, | ||||
|                          MetaWaylandSurface                      *surface, | ||||
|                          MetaWaylandSeat                         *seat, | ||||
|                          MetaWaylandRegion                       *region, | ||||
|                          enum zwp_pointer_constraints_v1_lifetime lifetime, | ||||
|                          const struct wl_interface               *interface, | ||||
|                          const void                              *implementation, | ||||
|                          const MetaWaylandPointerGrabInterface   *grab_interface) | ||||
| { | ||||
|   struct wl_client *client = wl_resource_get_client (resource); | ||||
|   struct wl_resource *cr; | ||||
|   MetaWaylandPointerConstraint *constraint; | ||||
|  | ||||
|   if (get_pointer_constraint_for_seat (surface, seat)) | ||||
|     { | ||||
|       wl_resource_post_error (resource, | ||||
|                               WL_DISPLAY_ERROR_INVALID_OBJECT, | ||||
|                               "the pointer as already requested to be " | ||||
|                               "locked or confined on that surface"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   cr = wl_resource_create (client, interface, | ||||
|                            wl_resource_get_version (resource), | ||||
|                            id); | ||||
|   if (cr == NULL) | ||||
|     { | ||||
|       wl_client_post_no_memory (client); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   constraint = meta_wayland_pointer_constraint_new (surface, seat, | ||||
|                                                     region, | ||||
|                                                     lifetime, | ||||
|                                                     cr, grab_interface); | ||||
|   if (constraint == NULL) | ||||
|     { | ||||
|       wl_client_post_no_memory (client); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   surface_add_pointer_constraint (surface, constraint); | ||||
|  | ||||
|   wl_resource_set_implementation (cr, implementation, constraint, | ||||
|                                   pointer_constraint_resource_destroyed); | ||||
|  | ||||
|   meta_wayland_pointer_constraint_maybe_enable (constraint); | ||||
| } | ||||
|  | ||||
| static void | ||||
| locked_pointer_destroy (struct wl_client   *client, | ||||
|                         struct wl_resource *resource) | ||||
| { | ||||
|   MetaWaylandPointerConstraint *constraint = | ||||
|     wl_resource_get_user_data (resource); | ||||
|   gboolean warp_pointer = FALSE; | ||||
|   int warp_x, warp_y; | ||||
|  | ||||
|   if (constraint && constraint->is_enabled && constraint->hint_set && | ||||
|       is_within_constraint_region (constraint, | ||||
|                                    constraint->x_hint, | ||||
|                                    constraint->y_hint)) | ||||
|     { | ||||
|       float sx, sy; | ||||
|       float x, y; | ||||
|  | ||||
|       sx = (float)wl_fixed_to_double (constraint->x_hint); | ||||
|       sy = (float)wl_fixed_to_double (constraint->y_hint); | ||||
|       meta_wayland_surface_get_absolute_coordinates (constraint->surface, | ||||
|                                                      sx, sy, | ||||
|                                                      &x, &y); | ||||
|       warp_pointer = TRUE; | ||||
|       warp_x = (int) x; | ||||
|       warp_y = (int) y; | ||||
|     } | ||||
|   wl_resource_destroy (resource); | ||||
|  | ||||
|   if (warp_pointer) | ||||
|     meta_backend_warp_pointer (meta_get_backend (), warp_x, warp_y); | ||||
| } | ||||
|  | ||||
| static void | ||||
| locked_pointer_set_cursor_position_hint (struct wl_client   *client, | ||||
|                                          struct wl_resource *resource, | ||||
|                                          wl_fixed_t          surface_x, | ||||
|                                          wl_fixed_t          surface_y) | ||||
| { | ||||
|   MetaWaylandPointerConstraint *constraint = | ||||
|     wl_resource_get_user_data (resource); | ||||
|  | ||||
|   /* Ignore a set cursor hint that was already sent after the constraint | ||||
|    * was cancelled. */ | ||||
|   if (!constraint || !constraint->resource || constraint->resource != resource) | ||||
|     return; | ||||
|  | ||||
|   constraint->hint_set = TRUE; | ||||
|   constraint->x_hint = surface_x; | ||||
|   constraint->y_hint = surface_y; | ||||
| } | ||||
|  | ||||
| static void | ||||
| locked_pointer_set_region (struct wl_client   *client, | ||||
|                            struct wl_resource *resource, | ||||
|                            struct wl_resource *region_resource) | ||||
| { | ||||
|   MetaWaylandPointerConstraint *constraint = | ||||
|     wl_resource_get_user_data (resource); | ||||
|   MetaWaylandRegion *region = | ||||
|     region_resource ? wl_resource_get_user_data (region_resource) : NULL; | ||||
|  | ||||
|   if (!constraint) | ||||
|     return; | ||||
|  | ||||
|   meta_wayland_pointer_constraint_set_pending_region (constraint, region); | ||||
| } | ||||
|  | ||||
| static const struct zwp_locked_pointer_v1_interface locked_pointer_interface = { | ||||
|   locked_pointer_destroy, | ||||
|   locked_pointer_set_cursor_position_hint, | ||||
|   locked_pointer_set_region, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| locked_pointer_grab_pointer_focus (MetaWaylandPointerGrab *grab, | ||||
|                                    MetaWaylandSurface     *surface) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| locked_pointer_grab_pointer_motion (MetaWaylandPointerGrab *grab, | ||||
|                                     const ClutterEvent     *event) | ||||
| { | ||||
|   meta_wayland_pointer_send_relative_motion (grab->pointer, event); | ||||
| } | ||||
|  | ||||
| static void | ||||
| locked_pointer_grab_pointer_button (MetaWaylandPointerGrab *grab, | ||||
|                                     const ClutterEvent     *event) | ||||
| { | ||||
|   meta_wayland_pointer_send_button (grab->pointer, event); | ||||
| } | ||||
|  | ||||
| static const MetaWaylandPointerGrabInterface locked_pointer_grab_interface = { | ||||
|   locked_pointer_grab_pointer_focus, | ||||
|   locked_pointer_grab_pointer_motion, | ||||
|   locked_pointer_grab_pointer_button, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| pointer_constraints_destroy (struct wl_client   *client, | ||||
|                              struct wl_resource *resource) | ||||
| { | ||||
|   wl_resource_destroy (resource); | ||||
| } | ||||
|  | ||||
| static void | ||||
| pointer_constraints_lock_pointer (struct wl_client   *client, | ||||
|                                   struct wl_resource *resource, | ||||
|                                   uint32_t            id, | ||||
|                                   struct wl_resource *surface_resource, | ||||
|                                   struct wl_resource *pointer_resource, | ||||
|                                   struct wl_resource *region_resource, | ||||
|                                   uint32_t            lifetime) | ||||
| { | ||||
|   MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); | ||||
|   MetaWaylandPointer *pointer = wl_resource_get_user_data (pointer_resource); | ||||
|   MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer); | ||||
|   MetaWaylandRegion *region = | ||||
|     region_resource ? wl_resource_get_user_data (region_resource) : NULL; | ||||
|  | ||||
|   init_pointer_constraint (resource, id, surface, seat, region, lifetime, | ||||
|                            &zwp_locked_pointer_v1_interface, | ||||
|                            &locked_pointer_interface, | ||||
|                            &locked_pointer_grab_interface); | ||||
| } | ||||
|  | ||||
| static void | ||||
| confined_pointer_grab_pointer_focus (MetaWaylandPointerGrab *grab, | ||||
|                                      MetaWaylandSurface *surface) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| confined_pointer_grab_pointer_motion (MetaWaylandPointerGrab *grab, | ||||
|                                       const ClutterEvent     *event) | ||||
| { | ||||
|   MetaWaylandPointerConstraint *constraint = | ||||
|     wl_container_of (grab, constraint, grab); | ||||
|   MetaWaylandPointer *pointer = grab->pointer; | ||||
|  | ||||
|   g_assert (pointer->focus_surface); | ||||
|   g_assert (pointer->focus_surface == constraint->surface); | ||||
|  | ||||
|   meta_wayland_pointer_send_motion (pointer, event); | ||||
| } | ||||
|  | ||||
| static void | ||||
| confined_pointer_grab_pointer_button (MetaWaylandPointerGrab *grab, | ||||
|                                       const ClutterEvent     *event) | ||||
| { | ||||
|   meta_wayland_pointer_send_button (grab->pointer, event); | ||||
| } | ||||
|  | ||||
| static const MetaWaylandPointerGrabInterface confined_pointer_grab_interface = { | ||||
|   confined_pointer_grab_pointer_focus, | ||||
|   confined_pointer_grab_pointer_motion, | ||||
|   confined_pointer_grab_pointer_button, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| confined_pointer_destroy (struct wl_client   *client, | ||||
|                           struct wl_resource *resource) | ||||
| { | ||||
|   wl_resource_destroy (resource); | ||||
| } | ||||
|  | ||||
| static void | ||||
| confined_pointer_set_region (struct wl_client   *client, | ||||
|                              struct wl_resource *resource, | ||||
|                              struct wl_resource *region_resource) | ||||
| { | ||||
|   MetaWaylandPointerConstraint *constraint = | ||||
|     wl_resource_get_user_data (resource); | ||||
|   MetaWaylandRegion *region = | ||||
|     region_resource ? wl_resource_get_user_data (region_resource) : NULL; | ||||
|  | ||||
|   if (!constraint) | ||||
|     return; | ||||
|  | ||||
|   meta_wayland_pointer_constraint_set_pending_region (constraint, region); | ||||
| } | ||||
|  | ||||
| static const struct zwp_confined_pointer_v1_interface confined_pointer_interface = { | ||||
|   confined_pointer_destroy, | ||||
|   confined_pointer_set_region, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| pointer_constraints_confine_pointer (struct wl_client   *client, | ||||
|                                      struct wl_resource *resource, | ||||
|                                      uint32_t            id, | ||||
|                                      struct wl_resource *surface_resource, | ||||
|                                      struct wl_resource *pointer_resource, | ||||
|                                      struct wl_resource *region_resource, | ||||
|                                      uint32_t            lifetime) | ||||
| { | ||||
|   MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); | ||||
|   MetaWaylandPointer *pointer = wl_resource_get_user_data (pointer_resource); | ||||
|   MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer); | ||||
|   MetaWaylandRegion *region = | ||||
|     region_resource ? wl_resource_get_user_data (region_resource) : NULL; | ||||
|  | ||||
|   init_pointer_constraint (resource, id, surface, seat, region, lifetime, | ||||
|                            &zwp_confined_pointer_v1_interface, | ||||
|                            &confined_pointer_interface, | ||||
|                            &confined_pointer_grab_interface); | ||||
|  | ||||
| } | ||||
|  | ||||
| static const struct zwp_pointer_constraints_v1_interface pointer_constraints = { | ||||
|   pointer_constraints_destroy, | ||||
|   pointer_constraints_lock_pointer, | ||||
|   pointer_constraints_confine_pointer, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| bind_pointer_constraints (struct wl_client *client, | ||||
|                           void             *data, | ||||
|                           uint32_t          version, | ||||
|                           uint32_t          id) | ||||
| { | ||||
|   MetaWaylandCompositor *compositor = data; | ||||
|   struct wl_resource *resource; | ||||
|  | ||||
|   resource = wl_resource_create (client, | ||||
|                                  &zwp_pointer_constraints_v1_interface, | ||||
|                                  1, id); | ||||
|  | ||||
|   wl_resource_set_implementation (resource, | ||||
|                                   &pointer_constraints, | ||||
|                                   compositor, | ||||
|                                   NULL); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_pointer_constraints_init (MetaWaylandCompositor *compositor) | ||||
| { | ||||
|   if (!wl_global_create (compositor->wayland_display, | ||||
|                          &zwp_pointer_constraints_v1_interface, 1, | ||||
|                          compositor, bind_pointer_constraints)) | ||||
|     g_error ("Could not create wp_pointer_constraints global"); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_pointer_constraint_init (MetaWaylandPointerConstraint *constraint) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_pointer_constraint_class_init (MetaWaylandPointerConstraintClass *klass) | ||||
| { | ||||
|   quark_pending_constraint_state = | ||||
|     g_quark_from_static_string ("-meta-wayland-pointer-constraint-pending_state"); | ||||
|   quark_surface_pointer_constraints_data = | ||||
|     g_quark_from_static_string ("-meta-wayland-surface-constraints-data"); | ||||
| } | ||||
							
								
								
									
										47
									
								
								src/wayland/meta-wayland-pointer-constraints.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/wayland/meta-wayland-pointer-constraints.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2015 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jonas Ådahl <jadahl@gmail.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef META_WAYLAND_POINTER_CONSTRAINTS_H | ||||
| #define META_WAYLAND_POINTER_CONSTRAINTS_H | ||||
|  | ||||
| #include "meta-wayland-types.h" | ||||
| #include "meta/window.h" | ||||
|  | ||||
| #include <wayland-server.h> | ||||
|  | ||||
| #define META_TYPE_WAYLAND_POINTER_CONSTRAINT (meta_wayland_pointer_constraint_get_type ()) | ||||
| G_DECLARE_FINAL_TYPE (MetaWaylandPointerConstraint, | ||||
|                       meta_wayland_pointer_constraint, | ||||
|                       META, WAYLAND_POINTER_CONSTRAINT, | ||||
|                       GObject); | ||||
|  | ||||
| void meta_wayland_pointer_constraints_init (MetaWaylandCompositor *compositor); | ||||
|  | ||||
| MetaWaylandSeat * meta_wayland_pointer_constraint_get_seat (MetaWaylandPointerConstraint *constraint); | ||||
|  | ||||
| cairo_region_t * meta_wayland_pointer_constraint_calculate_effective_region (MetaWaylandPointerConstraint *constraint); | ||||
|  | ||||
| MetaWaylandSurface * meta_wayland_pointer_constraint_get_surface (MetaWaylandPointerConstraint *constraint); | ||||
|  | ||||
| #endif /* META_WAYLAND_POINTER_CONSTRAINTS_H */ | ||||
| @@ -63,6 +63,8 @@ | ||||
| #include "backends/meta-cursor-tracker-private.h" | ||||
| #include "backends/meta-cursor-renderer.h" | ||||
|  | ||||
| #include "relative-pointer-unstable-v1-server-protocol.h" | ||||
|  | ||||
| #ifdef HAVE_NATIVE_BACKEND | ||||
| #include "backends/native/meta-backend-native.h" | ||||
| #endif | ||||
| @@ -78,6 +80,8 @@ struct _MetaWaylandSurfaceRoleCursor | ||||
|   int hot_x; | ||||
|   int hot_y; | ||||
|   MetaCursorSprite *cursor_sprite; | ||||
|  | ||||
|   MetaWaylandBuffer *buffer; | ||||
| }; | ||||
|  | ||||
| G_DEFINE_TYPE (MetaWaylandSurfaceRoleCursor, | ||||
| @@ -96,6 +100,7 @@ meta_wayland_pointer_client_new (void) | ||||
|   wl_list_init (&pointer_client->pointer_resources); | ||||
|   wl_list_init (&pointer_client->swipe_gesture_resources); | ||||
|   wl_list_init (&pointer_client->pinch_gesture_resources); | ||||
|   wl_list_init (&pointer_client->relative_pointer_resources); | ||||
|  | ||||
|   return pointer_client; | ||||
| } | ||||
| @@ -124,6 +129,11 @@ meta_wayland_pointer_client_free (MetaWaylandPointerClient *pointer_client) | ||||
|       wl_list_remove (wl_resource_get_link (resource)); | ||||
|       wl_list_init (wl_resource_get_link (resource)); | ||||
|     } | ||||
|   wl_resource_for_each_safe (resource, next, &pointer_client->relative_pointer_resources) | ||||
|     { | ||||
|       wl_list_remove (wl_resource_get_link (resource)); | ||||
|       wl_list_init (wl_resource_get_link (resource)); | ||||
|     } | ||||
|  | ||||
|   g_slice_free (MetaWaylandPointerClient, pointer_client); | ||||
| } | ||||
| @@ -133,7 +143,8 @@ meta_wayland_pointer_client_is_empty (MetaWaylandPointerClient *pointer_client) | ||||
| { | ||||
|   return (wl_list_empty (&pointer_client->pointer_resources) && | ||||
|           wl_list_empty (&pointer_client->swipe_gesture_resources) && | ||||
|           wl_list_empty (&pointer_client->pinch_gesture_resources)); | ||||
|           wl_list_empty (&pointer_client->pinch_gesture_resources) && | ||||
|           wl_list_empty (&pointer_client->relative_pointer_resources)); | ||||
| } | ||||
|  | ||||
| MetaWaylandPointerClient * | ||||
| @@ -264,27 +275,79 @@ meta_wayland_pointer_broadcast_frame (MetaWaylandPointer *pointer) | ||||
|     } | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_pointer_send_relative_motion (MetaWaylandPointer *pointer, | ||||
|                                            const ClutterEvent *event) | ||||
| { | ||||
|   struct wl_resource *resource; | ||||
|   double dx, dy; | ||||
|   double dx_unaccel, dy_unaccel; | ||||
|   uint64_t time_us; | ||||
|   uint32_t time_us_hi; | ||||
|   uint32_t time_us_lo; | ||||
|   wl_fixed_t dxf, dyf; | ||||
|   wl_fixed_t dx_unaccelf, dy_unaccelf; | ||||
|  | ||||
|   if (!pointer->focus_client) | ||||
|     return; | ||||
|  | ||||
|   if (!meta_backend_get_relative_motion_deltas (meta_get_backend (), | ||||
|                                                 event, | ||||
|                                                 &dx, &dy, | ||||
|                                                 &dx_unaccel, &dy_unaccel)) | ||||
|     return; | ||||
|  | ||||
| #ifdef HAVE_NATIVE_BACKEND | ||||
|   time_us = clutter_evdev_event_get_time_usec (event); | ||||
|   if (time_us == 0) | ||||
| #endif | ||||
|     time_us = clutter_event_get_time (event) * 1000ULL; | ||||
|   time_us_hi = (uint32_t) (time_us >> 32); | ||||
|   time_us_lo = (uint32_t) time_us; | ||||
|   dxf = wl_fixed_from_double (dx); | ||||
|   dyf = wl_fixed_from_double (dy); | ||||
|   dx_unaccelf = wl_fixed_from_double (dx_unaccel); | ||||
|   dy_unaccelf = wl_fixed_from_double (dy_unaccel); | ||||
|  | ||||
|   wl_resource_for_each (resource, | ||||
|                         &pointer->focus_client->relative_pointer_resources) | ||||
|     { | ||||
|       zwp_relative_pointer_v1_send_relative_motion (resource, | ||||
|                                                     time_us_hi, | ||||
|                                                     time_us_lo, | ||||
|                                                     dxf, | ||||
|                                                     dyf, | ||||
|                                                     dx_unaccelf, | ||||
|                                                     dy_unaccelf); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer, | ||||
|                                   const ClutterEvent *event) | ||||
| { | ||||
|   struct wl_resource *resource; | ||||
|   uint32_t time; | ||||
|   wl_fixed_t sx, sy; | ||||
|   float sx, sy; | ||||
|  | ||||
|   if (!pointer->focus_client) | ||||
|     return; | ||||
|  | ||||
|   time = clutter_event_get_time (event); | ||||
|   meta_wayland_pointer_get_relative_coordinates (pointer, | ||||
|                                                  pointer->focus_surface, | ||||
|   meta_wayland_surface_get_relative_coordinates (pointer->focus_surface, | ||||
|                                                  event->motion.x, | ||||
|                                                  event->motion.y, | ||||
|                                                  &sx, &sy); | ||||
|  | ||||
|   wl_resource_for_each (resource, &pointer->focus_client->pointer_resources) | ||||
|     { | ||||
|       wl_pointer_send_motion (resource, time, sx, sy); | ||||
|       wl_pointer_send_motion (resource, time, | ||||
|                               wl_fixed_from_double (sx), | ||||
|                               wl_fixed_from_double (sy)); | ||||
|     } | ||||
|  | ||||
|   meta_wayland_pointer_send_relative_motion (pointer, event); | ||||
|  | ||||
|   meta_wayland_pointer_broadcast_frame (pointer); | ||||
| } | ||||
|  | ||||
| @@ -802,8 +865,7 @@ meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer, | ||||
|   interface = pointer->grab->interface; | ||||
|   grab->pointer = pointer; | ||||
|  | ||||
|   if (pointer->current) | ||||
|     interface->focus (pointer->grab, pointer->current); | ||||
|   interface->focus (pointer->grab, pointer->current); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -866,11 +928,10 @@ meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer, | ||||
|   ClutterPoint pos; | ||||
|  | ||||
|   clutter_input_device_get_coords (pointer->device, NULL, &pos); | ||||
|   clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)), | ||||
|                                        pos.x, pos.y, &xf, &yf); | ||||
|   meta_wayland_surface_get_relative_coordinates (surface, pos.x, pos.y, &xf, &yf); | ||||
|  | ||||
|   *sx = wl_fixed_from_double (xf) / surface->scale; | ||||
|   *sy = wl_fixed_from_double (yf) / surface->scale; | ||||
|   *sx = wl_fixed_from_double (xf); | ||||
|   *sy = wl_fixed_from_double (yf); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -907,28 +968,30 @@ update_cursor_sprite_texture (MetaWaylandSurface *surface) | ||||
|   MetaWaylandSurfaceRoleCursor *cursor_role = | ||||
|     META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role); | ||||
|   MetaCursorSprite *cursor_sprite = cursor_role->cursor_sprite; | ||||
|   ClutterBackend *clutter_backend = clutter_get_default_backend (); | ||||
|   CoglContext *cogl_context = | ||||
|     clutter_backend_get_cogl_context (clutter_backend); | ||||
|   CoglTexture *texture; | ||||
|   MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface); | ||||
|  | ||||
|   if (surface->buffer) | ||||
|   g_return_if_fail (!buffer || buffer->texture); | ||||
|  | ||||
|   if (buffer) | ||||
|     { | ||||
|       struct wl_resource *buffer; | ||||
|  | ||||
|       buffer = surface->buffer->resource; | ||||
|       texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, | ||||
|                                                          buffer, | ||||
|                                                          NULL); | ||||
|  | ||||
|       meta_cursor_sprite_set_texture (cursor_sprite, | ||||
|                                       texture, | ||||
|                                       buffer->texture, | ||||
|                                       cursor_role->hot_x * surface->scale, | ||||
|                                       cursor_role->hot_y * surface->scale); | ||||
|       meta_cursor_renderer_realize_cursor_from_wl_buffer (cursor_renderer, | ||||
|                                                           cursor_sprite, | ||||
|                                                           buffer); | ||||
|       cogl_object_unref (texture); | ||||
|  | ||||
|       if (cursor_role->buffer) | ||||
|         { | ||||
|           struct wl_resource *buffer_resource; | ||||
|  | ||||
|           g_assert (cursor_role->buffer == buffer); | ||||
|           buffer_resource = buffer->resource; | ||||
|           meta_cursor_renderer_realize_cursor_from_wl_buffer (cursor_renderer, | ||||
|                                                               cursor_sprite, | ||||
|                                                               buffer_resource); | ||||
|  | ||||
|           meta_wayland_surface_unref_buffer_use_count (surface); | ||||
|           g_clear_object (&cursor_role->buffer); | ||||
|         } | ||||
|     } | ||||
|   else | ||||
|     { | ||||
| @@ -954,8 +1017,9 @@ cursor_sprite_prepare_at (MetaCursorSprite *cursor_sprite, | ||||
|   if (!meta_xwayland_is_xwayland_surface (surface)) | ||||
|     { | ||||
|       monitor = meta_screen_get_monitor_for_point (screen, x, y); | ||||
|       meta_cursor_sprite_set_texture_scale (cursor_sprite, | ||||
|                                             (float)monitor->scale / surface->scale); | ||||
|       if (monitor) | ||||
|         meta_cursor_sprite_set_texture_scale (cursor_sprite, | ||||
|                                               (float)monitor->scale / surface->scale); | ||||
|     } | ||||
|   meta_wayland_surface_update_outputs (surface); | ||||
| } | ||||
| @@ -1097,21 +1161,158 @@ meta_wayland_pointer_get_top_popup (MetaWaylandPointer *pointer) | ||||
|   return meta_wayland_popup_grab_get_top_popup(grab); | ||||
| } | ||||
|  | ||||
| static void | ||||
| relative_pointer_destroy (struct wl_client *client, | ||||
|                           struct wl_resource *resource) | ||||
| { | ||||
|   wl_resource_destroy (resource); | ||||
| } | ||||
|  | ||||
| static const struct zwp_relative_pointer_v1_interface relative_pointer_interface = { | ||||
|   relative_pointer_destroy | ||||
| }; | ||||
|  | ||||
| static void | ||||
| relative_pointer_manager_destroy (struct wl_client *client, | ||||
|                                   struct wl_resource *resource) | ||||
| { | ||||
|   wl_resource_destroy (resource); | ||||
| } | ||||
|  | ||||
| static void | ||||
| relative_pointer_manager_get_relative_pointer (struct wl_client   *client, | ||||
|                                                struct wl_resource *resource, | ||||
|                                                uint32_t            id, | ||||
|                                                struct wl_resource *pointer_resource) | ||||
| { | ||||
|   MetaWaylandPointer *pointer = wl_resource_get_user_data (pointer_resource); | ||||
|   struct wl_resource *cr; | ||||
|   MetaWaylandPointerClient *pointer_client; | ||||
|  | ||||
|   cr = wl_resource_create (client, &zwp_relative_pointer_v1_interface, | ||||
|                            wl_resource_get_version (resource), id); | ||||
|   if (cr == NULL) | ||||
|     { | ||||
|       wl_client_post_no_memory (client); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   wl_resource_set_implementation (cr, &relative_pointer_interface, | ||||
|                                   pointer, | ||||
|                                   meta_wayland_pointer_unbind_pointer_client_resource); | ||||
|  | ||||
|   pointer_client = meta_wayland_pointer_ensure_pointer_client (pointer, client); | ||||
|  | ||||
|   wl_list_insert (&pointer_client->relative_pointer_resources, | ||||
|                   wl_resource_get_link (cr)); | ||||
| } | ||||
|  | ||||
| static const struct zwp_relative_pointer_manager_v1_interface relative_pointer_manager = { | ||||
|   relative_pointer_manager_destroy, | ||||
|   relative_pointer_manager_get_relative_pointer, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| bind_relative_pointer_manager (struct wl_client *client, | ||||
|                                void             *data, | ||||
|                                uint32_t          version, | ||||
|                                uint32_t          id) | ||||
| { | ||||
|   MetaWaylandCompositor *compositor = data; | ||||
|   struct wl_resource *resource; | ||||
|  | ||||
|   resource = wl_resource_create (client, | ||||
|                                  &zwp_relative_pointer_manager_v1_interface, | ||||
|                                  1, id); | ||||
|  | ||||
|   if (version != 1) | ||||
|     wl_resource_post_error (resource, | ||||
|                             WL_DISPLAY_ERROR_INVALID_OBJECT, | ||||
|                             "bound invalid version %u of " | ||||
|                             "wp_relative_pointer_manager", | ||||
|                             version); | ||||
|  | ||||
|   wl_resource_set_implementation (resource, &relative_pointer_manager, | ||||
|                                   compositor, | ||||
|                                   NULL); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_relative_pointer_init (MetaWaylandCompositor *compositor) | ||||
| { | ||||
|   /* Relative pointer events are currently only supported by the native backend | ||||
|    * so lets just advertise the extension when the native backend is used. | ||||
|    */ | ||||
| #ifdef HAVE_NATIVE_BACKEND | ||||
|   if (!META_IS_BACKEND_NATIVE (meta_get_backend ())) | ||||
|     return; | ||||
| #else | ||||
|   return; | ||||
| #endif | ||||
|  | ||||
|   if (!wl_global_create (compositor->wayland_display, | ||||
|                          &zwp_relative_pointer_manager_v1_interface, 1, | ||||
|                          compositor, bind_relative_pointer_manager)) | ||||
|     g_error ("Could not create relative pointer manager global"); | ||||
| } | ||||
|  | ||||
| MetaWaylandSeat * | ||||
| meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer) | ||||
| { | ||||
|   MetaWaylandSeat *seat = wl_container_of (pointer, seat, pointer); | ||||
|   return seat; | ||||
| } | ||||
|  | ||||
| static void | ||||
| cursor_surface_role_assigned (MetaWaylandSurfaceRole *surface_role) | ||||
| { | ||||
|   MetaWaylandSurfaceRoleCursor *cursor_role = | ||||
|     META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role); | ||||
|   MetaWaylandSurface *surface = | ||||
|     meta_wayland_surface_role_get_surface (surface_role); | ||||
|   MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface); | ||||
|  | ||||
|   if (buffer) | ||||
|     { | ||||
|       g_set_object (&cursor_role->buffer, buffer); | ||||
|       meta_wayland_surface_ref_buffer_use_count (surface); | ||||
|     } | ||||
|  | ||||
|   meta_wayland_surface_queue_pending_frame_callbacks (surface); | ||||
| } | ||||
|  | ||||
| static void | ||||
| cursor_surface_role_pre_commit (MetaWaylandSurfaceRole  *surface_role, | ||||
|                                 MetaWaylandPendingState *pending) | ||||
| { | ||||
|   MetaWaylandSurfaceRoleCursor *cursor_role = | ||||
|     META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role); | ||||
|   MetaWaylandSurface *surface = | ||||
|     meta_wayland_surface_role_get_surface (surface_role); | ||||
|  | ||||
|   meta_wayland_surface_queue_pending_frame_callbacks (surface); | ||||
|   if (pending->newly_attached && cursor_role->buffer) | ||||
|     { | ||||
|       meta_wayland_surface_unref_buffer_use_count (surface); | ||||
|       g_clear_object (&cursor_role->buffer); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| cursor_surface_role_commit (MetaWaylandSurfaceRole  *surface_role, | ||||
|                             MetaWaylandPendingState *pending) | ||||
| { | ||||
|   MetaWaylandSurfaceRoleCursor *cursor_role = | ||||
|     META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role); | ||||
|   MetaWaylandSurface *surface = | ||||
|     meta_wayland_surface_role_get_surface (surface_role); | ||||
|   MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface); | ||||
|  | ||||
|   if (pending->newly_attached) | ||||
|     { | ||||
|       g_set_object (&cursor_role->buffer, buffer); | ||||
|       if (cursor_role->buffer) | ||||
|         meta_wayland_surface_ref_buffer_use_count (surface); | ||||
|     } | ||||
|  | ||||
|   meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending); | ||||
|  | ||||
| @@ -1159,11 +1360,6 @@ cursor_surface_role_dispose (GObject *object) | ||||
|     meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (object)); | ||||
|   MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); | ||||
|   MetaWaylandPointer *pointer = &compositor->seat->pointer; | ||||
|   MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL); | ||||
|  | ||||
|   g_signal_handlers_disconnect_by_func (cursor_tracker, | ||||
|                                         (gpointer) cursor_sprite_prepare_at, | ||||
|                                         cursor_role); | ||||
|  | ||||
|   if (pointer->cursor_surface == surface) | ||||
|     pointer->cursor_surface = NULL; | ||||
| @@ -1171,6 +1367,12 @@ cursor_surface_role_dispose (GObject *object) | ||||
|  | ||||
|   g_clear_object (&cursor_role->cursor_sprite); | ||||
|  | ||||
|   if (cursor_role->buffer) | ||||
|     { | ||||
|       meta_wayland_surface_unref_buffer_use_count (surface); | ||||
|       g_clear_object (&cursor_role->buffer); | ||||
|     } | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_wayland_surface_role_cursor_parent_class)->dispose (object); | ||||
| } | ||||
|  | ||||
| @@ -1187,6 +1389,7 @@ meta_wayland_surface_role_cursor_class_init (MetaWaylandSurfaceRoleCursorClass * | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   surface_role_class->assigned = cursor_surface_role_assigned; | ||||
|   surface_role_class->pre_commit = cursor_surface_role_pre_commit; | ||||
|   surface_role_class->commit = cursor_surface_role_commit; | ||||
|   surface_role_class->is_on_output = cursor_surface_role_is_on_output; | ||||
|  | ||||
|   | ||||
| @@ -28,6 +28,7 @@ | ||||
| #include "meta-wayland-pointer-gesture-swipe.h" | ||||
| #include "meta-wayland-pointer-gesture-pinch.h" | ||||
| #include "meta-wayland-surface.h" | ||||
| #include "meta-wayland-pointer-constraints.h" | ||||
|  | ||||
| #include <meta/meta-cursor-tracker.h> | ||||
|  | ||||
| @@ -58,6 +59,7 @@ struct _MetaWaylandPointerClient | ||||
|   struct wl_list pointer_resources; | ||||
|   struct wl_list swipe_gesture_resources; | ||||
|   struct wl_list pinch_gesture_resources; | ||||
|   struct wl_list relative_pointer_resources; | ||||
| }; | ||||
|  | ||||
| struct _MetaWaylandPointer | ||||
| @@ -101,6 +103,9 @@ gboolean meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer, | ||||
| void meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer, | ||||
|                                        const ClutterEvent *event); | ||||
|  | ||||
| void meta_wayland_pointer_send_relative_motion (MetaWaylandPointer *pointer, | ||||
|                                                 const ClutterEvent *event); | ||||
|  | ||||
| void meta_wayland_pointer_send_button (MetaWaylandPointer *pointer, | ||||
|                                        const ClutterEvent *event); | ||||
|  | ||||
| @@ -142,4 +147,8 @@ MetaWaylandPointerClient * meta_wayland_pointer_get_pointer_client (MetaWaylandP | ||||
|                                                                     struct wl_client   *client); | ||||
| void meta_wayland_pointer_unbind_pointer_client_resource (struct wl_resource *resource); | ||||
|  | ||||
| void meta_wayland_relative_pointer_init (MetaWaylandCompositor *compositor); | ||||
|  | ||||
| MetaWaylandSeat *meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer); | ||||
|  | ||||
| #endif /* META_WAYLAND_POINTER_H */ | ||||
|   | ||||
| @@ -48,6 +48,7 @@ | ||||
| #include "display-private.h" | ||||
| #include "window-private.h" | ||||
| #include "meta-window-wayland.h" | ||||
| #include "bell.h" | ||||
|  | ||||
| #include "compositor/region-utils.h" | ||||
|  | ||||
| @@ -55,6 +56,14 @@ | ||||
| #include "meta-surface-actor-wayland.h" | ||||
| #include "meta-xwayland-private.h" | ||||
|  | ||||
| enum { | ||||
|   PENDING_STATE_SIGNAL_APPLIED, | ||||
|  | ||||
|   PENDING_STATE_SIGNAL_LAST_SIGNAL | ||||
| }; | ||||
|  | ||||
| static guint pending_state_signals[PENDING_STATE_SIGNAL_LAST_SIGNAL]; | ||||
|  | ||||
| typedef struct _MetaWaylandSurfaceRolePrivate | ||||
| { | ||||
|   MetaWaylandSurface *surface; | ||||
| @@ -79,6 +88,10 @@ G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandSurfaceRole, | ||||
|                             meta_wayland_surface_role, | ||||
|                             G_TYPE_OBJECT); | ||||
|  | ||||
| G_DEFINE_TYPE (MetaWaylandPendingState, | ||||
|                meta_wayland_pending_state, | ||||
|                G_TYPE_OBJECT); | ||||
|  | ||||
| struct _MetaWaylandSurfaceRoleSubsurface | ||||
| { | ||||
|   MetaWaylandSurfaceRole parent; | ||||
| @@ -127,6 +140,10 @@ G_DEFINE_TYPE (MetaWaylandSurfaceRoleDND, | ||||
| static void | ||||
| meta_wayland_surface_role_assigned (MetaWaylandSurfaceRole *surface_role); | ||||
|  | ||||
| static void | ||||
| meta_wayland_surface_role_pre_commit (MetaWaylandSurfaceRole  *surface_role, | ||||
|                                       MetaWaylandPendingState *pending); | ||||
|  | ||||
| static void | ||||
| meta_wayland_surface_role_commit (MetaWaylandSurfaceRole  *surface_role, | ||||
|                                   MetaWaylandPendingState *pending); | ||||
| @@ -150,6 +167,13 @@ meta_wayland_surface_assign_role (MetaWaylandSurface *surface, | ||||
|  | ||||
|       meta_wayland_surface_role_assigned (surface->role); | ||||
|  | ||||
|       /* Release the use count held on behalf of the just assigned role. */ | ||||
|       if (surface->unassigned.buffer) | ||||
|         { | ||||
|           meta_wayland_surface_unref_buffer_use_count (surface); | ||||
|           g_clear_object (&surface->unassigned.buffer); | ||||
|         } | ||||
|  | ||||
|       return TRUE; | ||||
|     } | ||||
|   else if (G_OBJECT_TYPE (surface->role) != role_type) | ||||
| @@ -162,54 +186,29 @@ meta_wayland_surface_assign_role (MetaWaylandSurface *surface, | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| surface_set_buffer (MetaWaylandSurface *surface, | ||||
|                     MetaWaylandBuffer  *buffer) | ||||
| { | ||||
|   if (surface->buffer == buffer) | ||||
|     return; | ||||
|  | ||||
|   if (surface->buffer) | ||||
|     { | ||||
|       wl_list_remove (&surface->buffer_destroy_listener.link); | ||||
|       meta_wayland_buffer_unref (surface->buffer); | ||||
|     } | ||||
|  | ||||
|   surface->buffer = buffer; | ||||
|  | ||||
|   if (surface->buffer) | ||||
|     { | ||||
|       meta_wayland_buffer_ref (surface->buffer); | ||||
|       wl_signal_add (&surface->buffer->destroy_signal, &surface->buffer_destroy_listener); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| surface_handle_buffer_destroy (struct wl_listener *listener, void *data) | ||||
| { | ||||
|   MetaWaylandSurface *surface = wl_container_of (listener, surface, buffer_destroy_listener); | ||||
|  | ||||
|   surface_set_buffer (surface, NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| surface_process_damage (MetaWaylandSurface *surface, | ||||
|                         cairo_region_t *region) | ||||
| { | ||||
|   MetaWaylandBuffer *buffer = surface->buffer_ref.buffer; | ||||
|   unsigned int buffer_width; | ||||
|   unsigned int buffer_height; | ||||
|   cairo_rectangle_int_t surface_rect; | ||||
|   cairo_region_t *scaled_region; | ||||
|   int i, n_rectangles; | ||||
|  | ||||
|   if (!surface->buffer) | ||||
|   /* If the client destroyed the buffer it attached before committing, but | ||||
|    * still posted damage, or posted damage without any buffer, don't try to | ||||
|    * process it on the non-existing buffer. | ||||
|    */ | ||||
|   if (!buffer) | ||||
|     return; | ||||
|  | ||||
|   /* Intersect the damage region with the surface region before scaling in | ||||
|    * order to avoid integer overflow when scaling a damage region is too large | ||||
|    * (for example INT32_MAX which mesa passes). */ | ||||
|   buffer_width = cogl_texture_get_width (surface->buffer->texture); | ||||
|   buffer_height = cogl_texture_get_height (surface->buffer->texture); | ||||
|   buffer_width = cogl_texture_get_width (buffer->texture); | ||||
|   buffer_height = cogl_texture_get_height (buffer->texture); | ||||
|   surface_rect = (cairo_rectangle_int_t) { | ||||
|     .width = buffer_width / surface->scale, | ||||
|     .height = buffer_height / surface->scale, | ||||
| @@ -221,7 +220,7 @@ surface_process_damage (MetaWaylandSurface *surface, | ||||
|   scaled_region = meta_region_scale (region, surface->scale); | ||||
|  | ||||
|   /* First update the buffer. */ | ||||
|   meta_wayland_buffer_process_damage (surface->buffer, scaled_region); | ||||
|   meta_wayland_buffer_process_damage (buffer, scaled_region); | ||||
|  | ||||
|   /* Now damage the actor. The actor expects damage in the unscaled texture | ||||
|    * coordinate space, i.e. same as the buffer. */ | ||||
| @@ -275,7 +274,7 @@ calculate_surface_window_geometry (MetaWaylandSurface *surface, | ||||
|   if (!CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR (surface_actor))) | ||||
|     return; | ||||
|  | ||||
|   if (!surface->buffer) | ||||
|   if (!surface->buffer_ref.buffer) | ||||
|     return; | ||||
|  | ||||
|   meta_surface_actor_wayland_get_subsurface_rect (surface_actor, | ||||
| @@ -311,6 +310,36 @@ destroy_window (MetaWaylandSurface *surface) | ||||
|   g_assert (surface->window == NULL); | ||||
| } | ||||
|  | ||||
| MetaWaylandBuffer * | ||||
| meta_wayland_surface_get_buffer (MetaWaylandSurface *surface) | ||||
| { | ||||
|   return surface->buffer_ref.buffer; | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_surface_ref_buffer_use_count (MetaWaylandSurface *surface) | ||||
| { | ||||
|   g_return_if_fail (surface->buffer_ref.buffer); | ||||
|   g_warn_if_fail (surface->buffer_ref.buffer->resource); | ||||
|  | ||||
|   surface->buffer_ref.use_count++; | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_surface_unref_buffer_use_count (MetaWaylandSurface *surface) | ||||
| { | ||||
|   MetaWaylandBuffer *buffer = surface->buffer_ref.buffer; | ||||
|  | ||||
|   g_return_if_fail (surface->buffer_ref.use_count != 0); | ||||
|  | ||||
|   surface->buffer_ref.use_count--; | ||||
|  | ||||
|   g_return_if_fail (buffer); | ||||
|  | ||||
|   if (surface->buffer_ref.use_count == 0 && buffer->resource) | ||||
|     wl_resource_queue_event (buffer->resource, WL_BUFFER_RELEASE); | ||||
| } | ||||
|  | ||||
| static void | ||||
| queue_surface_actor_frame_callbacks (MetaWaylandSurface      *surface, | ||||
|                                      MetaWaylandPendingState *pending) | ||||
| @@ -329,21 +358,28 @@ toplevel_surface_commit (MetaWaylandSurfaceRole  *surface_role, | ||||
| { | ||||
|   MetaWaylandSurface *surface = | ||||
|     meta_wayland_surface_role_get_surface (surface_role); | ||||
|   MetaWaylandBuffer *buffer = surface->buffer_ref.buffer; | ||||
|   MetaWindow *window = surface->window; | ||||
|  | ||||
|   queue_surface_actor_frame_callbacks (surface, pending); | ||||
|  | ||||
|   /* If there's no new buffer pending, then there's nothing else to | ||||
|    * do | ||||
|    */ | ||||
|   if (!pending->newly_attached) | ||||
|     return; | ||||
|  | ||||
|   if (META_IS_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE (surface->role)) | ||||
|     { | ||||
|       /* For wl_shell, it's equivalent to an unmap. Semantics | ||||
|        * are poorly defined, so we can choose some that are | ||||
|        * convenient for us. */ | ||||
|       if (surface->buffer && !window) | ||||
|       if (buffer && !window) | ||||
|         { | ||||
|           window = meta_window_wayland_new (meta_get_display (), surface); | ||||
|           meta_wayland_surface_set_window (surface, window); | ||||
|         } | ||||
|       else if (surface->buffer == NULL && window) | ||||
|       else if (buffer == NULL && window) | ||||
|         { | ||||
|           destroy_window (surface); | ||||
|           return; | ||||
| @@ -351,7 +387,7 @@ toplevel_surface_commit (MetaWaylandSurfaceRole  *surface_role, | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (surface->buffer == NULL) | ||||
|       if (buffer == NULL) | ||||
|         { | ||||
|           /* XDG surfaces can't commit NULL buffers */ | ||||
|           wl_resource_post_error (surface->resource, | ||||
| @@ -369,7 +405,7 @@ toplevel_surface_commit (MetaWaylandSurfaceRole  *surface_role, | ||||
|     { | ||||
|       MetaRectangle geom = { 0 }; | ||||
|  | ||||
|       CoglTexture *texture = surface->buffer->texture; | ||||
|       CoglTexture *texture = buffer->texture; | ||||
|       /* Update the buffer rect immediately. */ | ||||
|       window->buffer_rect.width = cogl_texture_get_width (texture); | ||||
|       window->buffer_rect.height = cogl_texture_get_height (texture); | ||||
| @@ -411,11 +447,11 @@ toplevel_surface_commit (MetaWaylandSurfaceRole  *surface_role, | ||||
| } | ||||
|  | ||||
| static void | ||||
| surface_handle_pending_buffer_destroy (struct wl_listener *listener, void *data) | ||||
| pending_buffer_resource_destroyed (MetaWaylandBuffer       *buffer, | ||||
|                                    MetaWaylandPendingState *pending) | ||||
| { | ||||
|   MetaWaylandPendingState *state = wl_container_of (listener, state, buffer_destroy_listener); | ||||
|  | ||||
|   state->buffer = NULL; | ||||
|   g_signal_handler_disconnect (buffer, pending->buffer_destroy_handler_id); | ||||
|   pending->buffer = NULL; | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -433,7 +469,6 @@ pending_state_init (MetaWaylandPendingState *state) | ||||
|   state->opaque_region_set = FALSE; | ||||
|  | ||||
|   state->damage = cairo_region_create (); | ||||
|   state->buffer_destroy_listener.notify = surface_handle_pending_buffer_destroy; | ||||
|   wl_list_init (&state->frame_callback_list); | ||||
|  | ||||
|   state->has_new_geometry = FALSE; | ||||
| @@ -449,7 +484,8 @@ pending_state_destroy (MetaWaylandPendingState *state) | ||||
|   g_clear_pointer (&state->opaque_region, cairo_region_destroy); | ||||
|  | ||||
|   if (state->buffer) | ||||
|     wl_list_remove (&state->buffer_destroy_listener.link); | ||||
|     g_signal_handler_disconnect (state->buffer, | ||||
|                                  state->buffer_destroy_handler_id); | ||||
|   wl_list_for_each_safe (cb, next, &state->frame_callback_list, link) | ||||
|     wl_resource_destroy (cb->resource); | ||||
| } | ||||
| @@ -466,19 +502,67 @@ move_pending_state (MetaWaylandPendingState *from, | ||||
|                     MetaWaylandPendingState *to) | ||||
| { | ||||
|   if (from->buffer) | ||||
|     wl_list_remove (&from->buffer_destroy_listener.link); | ||||
|     g_signal_handler_disconnect (from->buffer, from->buffer_destroy_handler_id); | ||||
|  | ||||
|   *to = *from; | ||||
|   to->newly_attached = from->newly_attached; | ||||
|   to->buffer = from->buffer; | ||||
|   to->dx = from->dx; | ||||
|   to->dy = from->dy; | ||||
|   to->scale = from->scale; | ||||
|   to->damage = from->damage; | ||||
|   to->input_region = from->input_region; | ||||
|   to->input_region_set = from->input_region_set; | ||||
|   to->opaque_region = from->opaque_region; | ||||
|   to->opaque_region_set = from->opaque_region_set; | ||||
|   to->new_geometry = from->new_geometry; | ||||
|   to->has_new_geometry = from->has_new_geometry; | ||||
|  | ||||
|   wl_list_init (&to->frame_callback_list); | ||||
|   wl_list_insert_list (&to->frame_callback_list, &from->frame_callback_list); | ||||
|  | ||||
|   if (to->buffer) | ||||
|     wl_signal_add (&to->buffer->destroy_signal, &to->buffer_destroy_listener); | ||||
|     { | ||||
|       to->buffer_destroy_handler_id = | ||||
|         g_signal_connect (to->buffer, "resource-destroyed", | ||||
|                           G_CALLBACK (pending_buffer_resource_destroyed), | ||||
|                           to); | ||||
|     } | ||||
|  | ||||
|   pending_state_init (from); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_pending_state_finalize (GObject *object) | ||||
| { | ||||
|   MetaWaylandPendingState *state = META_WAYLAND_PENDING_STATE (object); | ||||
|  | ||||
|   pending_state_destroy (state); | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_wayland_pending_state_parent_class)->finalize (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_pending_state_init (MetaWaylandPendingState *state) | ||||
| { | ||||
|   pending_state_init (state); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_pending_state_class_init (MetaWaylandPendingStateClass *klass) | ||||
| { | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   object_class->finalize = meta_wayland_pending_state_finalize; | ||||
|  | ||||
|   pending_state_signals[PENDING_STATE_SIGNAL_APPLIED] = | ||||
|     g_signal_new ("applied", | ||||
|                   G_TYPE_FROM_CLASS (object_class), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   0, | ||||
|                   NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 0); | ||||
| } | ||||
|  | ||||
| static void | ||||
| subsurface_surface_commit (MetaWaylandSurfaceRole  *surface_role, | ||||
|                            MetaWaylandPendingState *pending) | ||||
| @@ -490,7 +574,7 @@ subsurface_surface_commit (MetaWaylandSurfaceRole  *surface_role, | ||||
|  | ||||
|   queue_surface_actor_frame_callbacks (surface, pending); | ||||
|  | ||||
|   if (surface->buffer != NULL) | ||||
|   if (surface->buffer_ref.buffer != NULL) | ||||
|     clutter_actor_show (CLUTTER_ACTOR (surface_actor)); | ||||
|   else | ||||
|     clutter_actor_hide (CLUTTER_ACTOR (surface_actor)); | ||||
| @@ -577,7 +661,7 @@ parent_surface_state_applied (gpointer data, gpointer user_data) | ||||
|     } | ||||
|  | ||||
|   if (is_surface_effectively_synchronized (surface)) | ||||
|     apply_pending_state (surface, &surface->sub.pending); | ||||
|     apply_pending_state (surface, surface->sub.pending); | ||||
|  | ||||
|   meta_surface_actor_wayland_sync_subsurface_state ( | ||||
|     META_SURFACE_ACTOR_WAYLAND (surface->surface_actor)); | ||||
| @@ -587,18 +671,59 @@ static void | ||||
| apply_pending_state (MetaWaylandSurface      *surface, | ||||
|                      MetaWaylandPendingState *pending) | ||||
| { | ||||
|   MetaSurfaceActorWayland *surface_actor_wayland = | ||||
|     META_SURFACE_ACTOR_WAYLAND (surface->surface_actor); | ||||
|  | ||||
|   if (surface->role) | ||||
|     { | ||||
|       meta_wayland_surface_role_pre_commit (surface->role, pending); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (pending->newly_attached && surface->unassigned.buffer) | ||||
|         { | ||||
|           meta_wayland_surface_unref_buffer_use_count (surface); | ||||
|           g_clear_object (&surface->unassigned.buffer); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   if (pending->newly_attached) | ||||
|     { | ||||
|       if (!surface->buffer && surface->window) | ||||
|       gboolean switched_buffer; | ||||
|  | ||||
|       if (!surface->buffer_ref.buffer && surface->window) | ||||
|         meta_window_queue (surface->window, META_QUEUE_CALC_SHOWING); | ||||
|  | ||||
|       surface_set_buffer (surface, pending->buffer); | ||||
|       /* Always release any previously held buffer. If the buffer held is same | ||||
|        * as the newly attached buffer, we still need to release it here, because | ||||
|        * wl_surface.attach+commit and wl_buffer.release on the attached buffer | ||||
|        * is symmetric. | ||||
|        */ | ||||
|       if (surface->buffer_held) | ||||
|         meta_wayland_surface_unref_buffer_use_count (surface); | ||||
|  | ||||
|       switched_buffer = g_set_object (&surface->buffer_ref.buffer, | ||||
|                                       pending->buffer); | ||||
|  | ||||
|       if (pending->buffer) | ||||
|         meta_wayland_surface_ref_buffer_use_count (surface); | ||||
|  | ||||
|       if (switched_buffer && pending->buffer) | ||||
|         { | ||||
|           CoglTexture *texture = meta_wayland_buffer_ensure_texture (pending->buffer); | ||||
|           meta_surface_actor_wayland_set_texture (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor), texture); | ||||
|           CoglTexture *texture; | ||||
|  | ||||
|           texture = meta_wayland_buffer_ensure_texture (pending->buffer); | ||||
|           meta_surface_actor_wayland_set_texture (surface_actor_wayland, | ||||
|                                                   texture); | ||||
|         } | ||||
|  | ||||
|       /* If the newly attached buffer is going to be accessed directly without | ||||
|        * making a copy, such as an EGL buffer, mark it as in-use don't release | ||||
|        * it until is replaced by a subsequent wl_surface.commit or when the | ||||
|        * wl_surface is destroyed. | ||||
|        */ | ||||
|       surface->buffer_held = (pending->buffer && | ||||
|                               !wl_shm_buffer_get (pending->buffer->resource)); | ||||
|     } | ||||
|  | ||||
|   if (pending->scale > 0) | ||||
| @@ -644,10 +769,31 @@ apply_pending_state (MetaWaylandSurface      *surface, | ||||
|       wl_list_insert_list (&surface->pending_frame_callback_list, | ||||
|                            &pending->frame_callback_list); | ||||
|       wl_list_init (&pending->frame_callback_list); | ||||
|  | ||||
|       if (pending->newly_attached) | ||||
|         { | ||||
|           /* The need to keep the wl_buffer from being released depends on what | ||||
|            * role the surface is given. That means we need to also keep a use | ||||
|            * count for wl_buffer's that are used by unassigned wl_surface's. | ||||
|            */ | ||||
|           g_set_object (&surface->unassigned.buffer, surface->buffer_ref.buffer); | ||||
|           if (surface->unassigned.buffer) | ||||
|             meta_wayland_surface_ref_buffer_use_count (surface); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   meta_surface_actor_wayland_sync_state ( | ||||
|     META_SURFACE_ACTOR_WAYLAND (surface->surface_actor)); | ||||
|   /* If we have a buffer that we are not using, decrease the use count so it may | ||||
|    * be released if no-one else has a use-reference to it. | ||||
|    */ | ||||
|   if (pending->newly_attached && | ||||
|       !surface->buffer_held && surface->buffer_ref.buffer) | ||||
|     meta_wayland_surface_unref_buffer_use_count (surface); | ||||
|  | ||||
|   g_signal_emit (pending, | ||||
|                  pending_state_signals[PENDING_STATE_SIGNAL_APPLIED], | ||||
|                  0); | ||||
|  | ||||
|   meta_surface_actor_wayland_sync_state (surface_actor_wayland); | ||||
|  | ||||
|   pending_state_reset (pending); | ||||
|  | ||||
| @@ -666,9 +812,9 @@ meta_wayland_surface_commit (MetaWaylandSurface *surface) | ||||
|    *     surface is in effective desynchronized mode. | ||||
|    */ | ||||
|   if (is_surface_effectively_synchronized (surface)) | ||||
|     move_pending_state (&surface->pending, &surface->sub.pending); | ||||
|     move_pending_state (surface->pending, surface->sub.pending); | ||||
|   else | ||||
|     apply_pending_state (surface, &surface->pending); | ||||
|     apply_pending_state (surface, surface->pending); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -697,17 +843,24 @@ wl_surface_attach (struct wl_client *client, | ||||
|   else | ||||
|     buffer = NULL; | ||||
|  | ||||
|   if (surface->pending.buffer) | ||||
|     wl_list_remove (&surface->pending.buffer_destroy_listener.link); | ||||
|   if (surface->pending->buffer) | ||||
|     { | ||||
|       g_signal_handler_disconnect (surface->pending->buffer, | ||||
|                                    surface->pending->buffer_destroy_handler_id); | ||||
|     } | ||||
|  | ||||
|   surface->pending.newly_attached = TRUE; | ||||
|   surface->pending.buffer = buffer; | ||||
|   surface->pending.dx = dx; | ||||
|   surface->pending.dy = dy; | ||||
|   surface->pending->newly_attached = TRUE; | ||||
|   surface->pending->buffer = buffer; | ||||
|   surface->pending->dx = dx; | ||||
|   surface->pending->dy = dy; | ||||
|  | ||||
|   if (buffer) | ||||
|     wl_signal_add (&buffer->destroy_signal, | ||||
|                    &surface->pending.buffer_destroy_listener); | ||||
|     { | ||||
|       surface->pending->buffer_destroy_handler_id = | ||||
|         g_signal_connect (buffer, "resource-destroyed", | ||||
|                           G_CALLBACK (pending_buffer_resource_destroyed), | ||||
|                           surface->pending); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -725,7 +878,7 @@ wl_surface_damage (struct wl_client *client, | ||||
|   if (!surface) | ||||
|     return; | ||||
|  | ||||
|   cairo_region_union_rectangle (surface->pending.damage, &rectangle); | ||||
|   cairo_region_union_rectangle (surface->pending->damage, &rectangle); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -755,7 +908,7 @@ wl_surface_frame (struct wl_client *client, | ||||
|   callback->resource = wl_resource_create (client, &wl_callback_interface, META_WL_CALLBACK_VERSION, callback_id); | ||||
|   wl_resource_set_implementation (callback->resource, NULL, callback, destroy_frame_callback); | ||||
|  | ||||
|   wl_list_insert (surface->pending.frame_callback_list.prev, &callback->link); | ||||
|   wl_list_insert (surface->pending->frame_callback_list.prev, &callback->link); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -769,14 +922,14 @@ wl_surface_set_opaque_region (struct wl_client *client, | ||||
|   if (!surface) | ||||
|     return; | ||||
|  | ||||
|   g_clear_pointer (&surface->pending.opaque_region, cairo_region_destroy); | ||||
|   g_clear_pointer (&surface->pending->opaque_region, cairo_region_destroy); | ||||
|   if (region_resource) | ||||
|     { | ||||
|       MetaWaylandRegion *region = wl_resource_get_user_data (region_resource); | ||||
|       cairo_region_t *cr_region = meta_wayland_region_peek_cairo_region (region); | ||||
|       surface->pending.opaque_region = cairo_region_copy (cr_region); | ||||
|       surface->pending->opaque_region = cairo_region_copy (cr_region); | ||||
|     } | ||||
|   surface->pending.opaque_region_set = TRUE; | ||||
|   surface->pending->opaque_region_set = TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -790,14 +943,14 @@ wl_surface_set_input_region (struct wl_client *client, | ||||
|   if (!surface) | ||||
|     return; | ||||
|  | ||||
|   g_clear_pointer (&surface->pending.input_region, cairo_region_destroy); | ||||
|   g_clear_pointer (&surface->pending->input_region, cairo_region_destroy); | ||||
|   if (region_resource) | ||||
|     { | ||||
|       MetaWaylandRegion *region = wl_resource_get_user_data (region_resource); | ||||
|       cairo_region_t *cr_region = meta_wayland_region_peek_cairo_region (region); | ||||
|       surface->pending.input_region = cairo_region_copy (cr_region); | ||||
|       surface->pending->input_region = cairo_region_copy (cr_region); | ||||
|     } | ||||
|   surface->pending.input_region_set = TRUE; | ||||
|   surface->pending->input_region_set = TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -828,7 +981,7 @@ wl_surface_set_buffer_scale (struct wl_client *client, | ||||
| { | ||||
|   MetaWaylandSurface *surface = wl_resource_get_user_data (resource); | ||||
|   if (scale > 0) | ||||
|     surface->pending.scale = scale; | ||||
|     surface->pending->scale = scale; | ||||
|   else | ||||
|     g_warning ("Trying to set invalid buffer_scale of %d\n", scale); | ||||
| } | ||||
| @@ -1029,8 +1182,17 @@ wl_surface_destructor (struct wl_resource *resource) | ||||
|   if (surface->window) | ||||
|     destroy_window (surface); | ||||
|  | ||||
|   surface_set_buffer (surface, NULL); | ||||
|   pending_state_destroy (&surface->pending); | ||||
|   if (surface->unassigned.buffer) | ||||
|     { | ||||
|       meta_wayland_surface_unref_buffer_use_count (surface); | ||||
|       g_clear_object (&surface->unassigned.buffer); | ||||
|     } | ||||
|  | ||||
|   if (surface->buffer_held) | ||||
|     meta_wayland_surface_unref_buffer_use_count (surface); | ||||
|   g_clear_object (&surface->buffer_ref.buffer); | ||||
|  | ||||
|   g_clear_object (&surface->pending); | ||||
|  | ||||
|   if (surface->opaque_region) | ||||
|     cairo_region_destroy (surface->opaque_region); | ||||
| @@ -1069,6 +1231,13 @@ wl_surface_destructor (struct wl_resource *resource) | ||||
|   meta_wayland_compositor_repick (compositor); | ||||
| } | ||||
|  | ||||
| static void | ||||
| surface_actor_painting (MetaSurfaceActorWayland *surface_actor, | ||||
|                         MetaWaylandSurface      *surface) | ||||
| { | ||||
|   meta_wayland_surface_update_outputs (surface); | ||||
| } | ||||
|  | ||||
| MetaWaylandSurface * | ||||
| meta_wayland_surface_create (MetaWaylandCompositor *compositor, | ||||
|                              struct wl_client      *client, | ||||
| @@ -1083,16 +1252,20 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, | ||||
|   surface->resource = wl_resource_create (client, &wl_surface_interface, wl_resource_get_version (compositor_resource), id); | ||||
|   wl_resource_set_implementation (surface->resource, &meta_wayland_wl_surface_interface, surface, wl_surface_destructor); | ||||
|  | ||||
|   surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy; | ||||
|   surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface)); | ||||
|  | ||||
|   wl_list_init (&surface->pending_frame_callback_list); | ||||
|  | ||||
|   g_signal_connect_object (surface->surface_actor, | ||||
|                            "painting", | ||||
|                            G_CALLBACK (surface_actor_painting), | ||||
|                            surface, | ||||
|                            0); | ||||
|  | ||||
|   sync_drag_dest_funcs (surface); | ||||
|  | ||||
|   surface->outputs_to_destroy_notify_id = g_hash_table_new (NULL, NULL); | ||||
|  | ||||
|   pending_state_init (&surface->pending); | ||||
|   return surface; | ||||
| } | ||||
|  | ||||
| @@ -1295,11 +1468,11 @@ xdg_surface_set_window_geometry (struct wl_client *client, | ||||
| { | ||||
|   MetaWaylandSurface *surface = wl_resource_get_user_data (resource); | ||||
|  | ||||
|   surface->pending.has_new_geometry = TRUE; | ||||
|   surface->pending.new_geometry.x = x; | ||||
|   surface->pending.new_geometry.y = y; | ||||
|   surface->pending.new_geometry.width = width; | ||||
|   surface->pending.new_geometry.height = height; | ||||
|   surface->pending->has_new_geometry = TRUE; | ||||
|   surface->pending->new_geometry.x = x; | ||||
|   surface->pending->new_geometry.y = y; | ||||
|   surface->pending->new_geometry.width = width; | ||||
|   surface->pending->new_geometry.height = height; | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -1925,17 +2098,33 @@ gtk_surface_unset_modal (struct wl_client   *client, | ||||
|   meta_window_set_type (surface->window, META_WINDOW_NORMAL); | ||||
| } | ||||
|  | ||||
| static const struct gtk_surface_interface meta_wayland_gtk_surface_interface = { | ||||
| static void | ||||
| gtk_surface_present (struct wl_client   *client, | ||||
|                      struct wl_resource *resource, | ||||
|                      uint32_t            timestamp) | ||||
| { | ||||
|   MetaWaylandSurface *surface = wl_resource_get_user_data (resource); | ||||
|   MetaWindow *window = surface->window; | ||||
|  | ||||
|   if (!window) | ||||
|     return; | ||||
|  | ||||
|   meta_window_activate_full (window, timestamp, | ||||
|                              META_CLIENT_TYPE_APPLICATION, NULL); | ||||
| } | ||||
|  | ||||
| static const struct gtk_surface1_interface meta_wayland_gtk_surface_interface = { | ||||
|   gtk_surface_set_dbus_properties, | ||||
|   gtk_surface_set_modal, | ||||
|   gtk_surface_unset_modal, | ||||
|   gtk_surface_present, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| get_gtk_surface (struct wl_client *client, | ||||
|                  struct wl_resource *resource, | ||||
|                  guint32 id, | ||||
|                  struct wl_resource *surface_resource) | ||||
| gtk_shell_get_gtk_surface (struct wl_client   *client, | ||||
|                            struct wl_resource *resource, | ||||
|                            guint32             id, | ||||
|                            struct wl_resource *surface_resource) | ||||
| { | ||||
|   MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); | ||||
|  | ||||
| @@ -1947,12 +2136,52 @@ get_gtk_surface (struct wl_client *client, | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   surface->gtk_surface = wl_resource_create (client, >k_surface_interface, wl_resource_get_version (resource), id); | ||||
|   surface->gtk_surface = wl_resource_create (client, | ||||
|                                              >k_surface1_interface, | ||||
|                                              wl_resource_get_version (resource), | ||||
|                                              id); | ||||
|   wl_resource_set_implementation (surface->gtk_surface, &meta_wayland_gtk_surface_interface, surface, gtk_surface_destructor); | ||||
| } | ||||
|  | ||||
| static const struct gtk_shell_interface meta_wayland_gtk_shell_interface = { | ||||
|   get_gtk_surface | ||||
| static void | ||||
| gtk_shell_set_startup_id (struct wl_client   *client, | ||||
|                           struct wl_resource *resource, | ||||
|                           const char         *startup_id) | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   display = meta_get_display (); | ||||
|   meta_startup_notification_remove_sequence (display->startup_notification, | ||||
|                                              startup_id); | ||||
| } | ||||
|  | ||||
| static void | ||||
| gtk_shell_system_bell (struct wl_client   *client, | ||||
|                        struct wl_resource *resource, | ||||
|                        struct wl_resource *gtk_surface_resource) | ||||
| { | ||||
|   MetaDisplay *display = meta_get_display (); | ||||
|  | ||||
|   if (gtk_surface_resource) | ||||
|     { | ||||
|       MetaWaylandSurface *surface = | ||||
|         wl_resource_get_user_data (gtk_surface_resource); | ||||
|  | ||||
|       if (!surface->window) | ||||
|         return; | ||||
|  | ||||
|       meta_bell_notify (display, surface->window); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       meta_bell_notify (display, NULL); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static const struct gtk_shell1_interface meta_wayland_gtk_shell_interface = { | ||||
|   gtk_shell_get_gtk_surface, | ||||
|   gtk_shell_set_startup_id, | ||||
|   gtk_shell_system_bell, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| @@ -1964,24 +2193,13 @@ bind_gtk_shell (struct wl_client *client, | ||||
|   struct wl_resource *resource; | ||||
|   uint32_t capabilities = 0; | ||||
|  | ||||
|   resource = wl_resource_create (client, >k_shell_interface, version, id); | ||||
|  | ||||
|   if (version != META_GTK_SHELL_VERSION) | ||||
|     { | ||||
|       wl_resource_post_error (resource, | ||||
|                               WL_DISPLAY_ERROR_INVALID_OBJECT, | ||||
|                               "Incompatible gtk-shell version " | ||||
|                               "(supported version: %d)", | ||||
|                               META_GTK_SHELL_VERSION); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   resource = wl_resource_create (client, >k_shell1_interface, version, id); | ||||
|   wl_resource_set_implementation (resource, &meta_wayland_gtk_shell_interface, data, NULL); | ||||
|  | ||||
|   if (!meta_prefs_get_show_fallback_app_menu ()) | ||||
|     capabilities = GTK_SHELL_CAPABILITY_GLOBAL_APP_MENU; | ||||
|     capabilities = GTK_SHELL1_CAPABILITY_GLOBAL_APP_MENU; | ||||
|  | ||||
|   gtk_shell_send_capabilities (resource, capabilities); | ||||
|   gtk_shell1_send_capabilities (resource, capabilities); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -2008,7 +2226,7 @@ wl_subsurface_destructor (struct wl_resource *resource) | ||||
|       surface->sub.parent = NULL; | ||||
|     } | ||||
|  | ||||
|   pending_state_destroy (&surface->sub.pending); | ||||
|   g_clear_object (&surface->sub.pending); | ||||
|   surface->wl_subsurface = NULL; | ||||
| } | ||||
|  | ||||
| @@ -2134,7 +2352,7 @@ wl_subsurface_set_desync (struct wl_client *client, | ||||
|   surface->sub.synchronous = FALSE; | ||||
|   if (was_effectively_synchronized && | ||||
|       !is_surface_effectively_synchronized (surface)) | ||||
|     apply_pending_state (surface, &surface->sub.pending); | ||||
|     apply_pending_state (surface, surface->sub.pending); | ||||
| } | ||||
|  | ||||
| static const struct wl_subsurface_interface meta_wayland_wl_subsurface_interface = { | ||||
| @@ -2198,7 +2416,7 @@ wl_subcompositor_get_subsurface (struct wl_client *client, | ||||
|   surface->wl_subsurface = wl_resource_create (client, &wl_subsurface_interface, wl_resource_get_version (resource), id); | ||||
|   wl_resource_set_implementation (surface->wl_subsurface, &meta_wayland_wl_subsurface_interface, surface, wl_subsurface_destructor); | ||||
|  | ||||
|   pending_state_init (&surface->sub.pending); | ||||
|   surface->sub.pending = g_object_new (META_TYPE_WAYLAND_PENDING_STATE, NULL); | ||||
|   surface->sub.synchronous = TRUE; | ||||
|   surface->sub.parent = parent; | ||||
|   surface->sub.parent_destroy_listener.notify = surface_handle_parent_surface_destroyed; | ||||
| @@ -2244,8 +2462,8 @@ meta_wayland_shell_init (MetaWaylandCompositor *compositor) | ||||
|     g_error ("Failed to register a global wl-shell object"); | ||||
|  | ||||
|   if (wl_global_create (compositor->wayland_display, | ||||
|                         >k_shell_interface, | ||||
|                         META_GTK_SHELL_VERSION, | ||||
|                         >k_shell1_interface, | ||||
|                         META_GTK_SHELL1_VERSION, | ||||
|                         compositor, bind_gtk_shell) == NULL) | ||||
|     g_error ("Failed to register a global gtk-shell object"); | ||||
|  | ||||
| @@ -2413,9 +2631,46 @@ meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface) | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_surface_get_relative_coordinates (MetaWaylandSurface *surface, | ||||
|                                                float               abs_x, | ||||
|                                                float               abs_y, | ||||
|                                                float               *sx, | ||||
|                                                float               *sy) | ||||
| { | ||||
|   ClutterActor *actor = | ||||
|     CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)); | ||||
|  | ||||
|   clutter_actor_transform_stage_point (actor, abs_x, abs_y, sx, sy); | ||||
|   *sx /= surface->scale; | ||||
|   *sy /= surface->scale; | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_surface_get_absolute_coordinates (MetaWaylandSurface *surface, | ||||
|                                                float               sx, | ||||
|                                                float               sy, | ||||
|                                                float               *x, | ||||
|                                                float               *y) | ||||
| { | ||||
|   ClutterActor *actor = | ||||
|     CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)); | ||||
|   ClutterVertex sv = { | ||||
|     .x = sx * surface->scale, | ||||
|     .y = sy * surface->scale, | ||||
|   }; | ||||
|   ClutterVertex v = { 0 }; | ||||
|  | ||||
|   clutter_actor_apply_relative_transform_to_point (actor, NULL, &sv, &v); | ||||
|  | ||||
|   *x = v.x; | ||||
|   *y = v.y; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_surface_init (MetaWaylandSurface *surface) | ||||
| { | ||||
|   surface->pending = g_object_new (META_TYPE_WAYLAND_PENDING_STATE, NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -2439,6 +2694,17 @@ meta_wayland_surface_role_assigned (MetaWaylandSurfaceRole *surface_role) | ||||
|   META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role)->assigned (surface_role); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_surface_role_pre_commit (MetaWaylandSurfaceRole  *surface_role, | ||||
|                                       MetaWaylandPendingState *pending) | ||||
| { | ||||
|   MetaWaylandSurfaceRoleClass *klass; | ||||
|  | ||||
|   klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role); | ||||
|   if (klass->pre_commit) | ||||
|     klass->pre_commit (surface_role, pending); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_wayland_surface_role_commit (MetaWaylandSurfaceRole  *surface_role, | ||||
|                                   MetaWaylandPendingState *pending) | ||||
| @@ -2577,3 +2843,26 @@ meta_wayland_surface_role_subsurface_class_init (MetaWaylandSurfaceRoleSubsurfac | ||||
|   surface_role_class->commit = subsurface_surface_commit; | ||||
|   surface_role_class->is_on_output = actor_surface_is_on_output; | ||||
| } | ||||
|  | ||||
| cairo_region_t * | ||||
| meta_wayland_surface_calculate_input_region (MetaWaylandSurface *surface) | ||||
| { | ||||
|   cairo_region_t *region; | ||||
|   cairo_rectangle_int_t buffer_rect; | ||||
|   CoglTexture *texture; | ||||
|  | ||||
|   if (!surface->buffer_ref.buffer) | ||||
|     return NULL; | ||||
|  | ||||
|   texture = surface->buffer_ref.buffer->texture; | ||||
|   buffer_rect = (cairo_rectangle_int_t) { | ||||
|     .width = cogl_texture_get_width (texture) / surface->scale, | ||||
|     .height = cogl_texture_get_height (texture) / surface->scale, | ||||
|   }; | ||||
|   region = cairo_region_create_rectangle (&buffer_rect); | ||||
|  | ||||
|   if (surface->input_region) | ||||
|     cairo_region_intersect (region, surface->input_region); | ||||
|  | ||||
|   return region; | ||||
| } | ||||
|   | ||||
| @@ -31,6 +31,7 @@ | ||||
| #include "meta-wayland-types.h" | ||||
| #include "meta-surface-actor.h" | ||||
| #include "backends/meta-monitor-manager-private.h" | ||||
| #include "meta-wayland-pointer-constraints.h" | ||||
|  | ||||
| typedef struct _MetaWaylandPendingState MetaWaylandPendingState; | ||||
|  | ||||
| @@ -44,11 +45,19 @@ G_DECLARE_FINAL_TYPE (MetaWaylandSurface, | ||||
| G_DECLARE_DERIVABLE_TYPE (MetaWaylandSurfaceRole, meta_wayland_surface_role, | ||||
|                           META, WAYLAND_SURFACE_ROLE, GObject); | ||||
|  | ||||
| #define META_TYPE_WAYLAND_PENDING_STATE (meta_wayland_pending_state_get_type ()) | ||||
| G_DECLARE_FINAL_TYPE (MetaWaylandPendingState, | ||||
|                       meta_wayland_pending_state, | ||||
|                       META, WAYLAND_PENDING_STATE, | ||||
|                       GObject); | ||||
|  | ||||
| struct _MetaWaylandSurfaceRoleClass | ||||
| { | ||||
|   GObjectClass parent_class; | ||||
|  | ||||
|   void (*assigned) (MetaWaylandSurfaceRole *surface_role); | ||||
|   void (*pre_commit) (MetaWaylandSurfaceRole  *surface_role, | ||||
|                       MetaWaylandPendingState *pending); | ||||
|   void (*commit) (MetaWaylandSurfaceRole  *surface_role, | ||||
|                   MetaWaylandPendingState *pending); | ||||
|   gboolean (*is_on_output) (MetaWaylandSurfaceRole *surface_role, | ||||
| @@ -92,10 +101,12 @@ G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleDND, | ||||
|  | ||||
| struct _MetaWaylandPendingState | ||||
| { | ||||
|   GObject parent; | ||||
|  | ||||
|   /* wl_surface.attach */ | ||||
|   gboolean newly_attached; | ||||
|   MetaWaylandBuffer *buffer; | ||||
|   struct wl_listener buffer_destroy_listener; | ||||
|   gulong buffer_destroy_handler_id; | ||||
|   int32_t dx; | ||||
|   int32_t dy; | ||||
|  | ||||
| @@ -142,8 +153,6 @@ struct _MetaWaylandSurface | ||||
|   MetaSurfaceActor *surface_actor; | ||||
|   MetaWaylandSurfaceRole *role; | ||||
|   MetaWindow *window; | ||||
|   MetaWaylandBuffer *buffer; | ||||
|   struct wl_listener buffer_destroy_listener; | ||||
|   cairo_region_t *input_region; | ||||
|   cairo_region_t *opaque_region; | ||||
|   int scale; | ||||
| @@ -151,17 +160,31 @@ struct _MetaWaylandSurface | ||||
|   GList *subsurfaces; | ||||
|   GHashTable *outputs_to_destroy_notify_id; | ||||
|  | ||||
|   /* Buffer reference state. */ | ||||
|   struct { | ||||
|     MetaWaylandBuffer *buffer; | ||||
|     unsigned int use_count; | ||||
|   } buffer_ref; | ||||
|  | ||||
|   /* Buffer renderer state. */ | ||||
|   gboolean buffer_held; | ||||
|  | ||||
|   /* List of pending frame callbacks that needs to stay queued longer than one | ||||
|    * commit sequence, such as when it has not yet been assigned a role. | ||||
|    */ | ||||
|   struct wl_list pending_frame_callback_list; | ||||
|  | ||||
|   /* Intermediate state for when no role has been assigned. */ | ||||
|   struct { | ||||
|     MetaWaylandBuffer *buffer; | ||||
|   } unassigned; | ||||
|  | ||||
|   struct { | ||||
|     const MetaWaylandDragDestFuncs *funcs; | ||||
|   } dnd; | ||||
|  | ||||
|   /* All the pending state that wl_surface.commit will apply. */ | ||||
|   MetaWaylandPendingState pending; | ||||
|   MetaWaylandPendingState *pending; | ||||
|  | ||||
|   /* Extension resources. */ | ||||
|   struct wl_resource *xdg_surface; | ||||
| @@ -202,7 +225,7 @@ struct _MetaWaylandSurface | ||||
|      * state here. | ||||
|      */ | ||||
|     gboolean synchronous; | ||||
|     MetaWaylandPendingState pending; | ||||
|     MetaWaylandPendingState *pending; | ||||
|  | ||||
|     int32_t pending_x; | ||||
|     int32_t pending_y; | ||||
| @@ -221,6 +244,12 @@ MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *composit | ||||
| gboolean            meta_wayland_surface_assign_role (MetaWaylandSurface *surface, | ||||
|                                                       GType               role_type); | ||||
|  | ||||
| MetaWaylandBuffer  *meta_wayland_surface_get_buffer (MetaWaylandSurface *surface); | ||||
|  | ||||
| void                meta_wayland_surface_ref_buffer_use_count (MetaWaylandSurface *surface); | ||||
|  | ||||
| void                meta_wayland_surface_unref_buffer_use_count (MetaWaylandSurface *surface); | ||||
|  | ||||
| void                meta_wayland_surface_set_window (MetaWaylandSurface *surface, | ||||
|                                                      MetaWindow         *window); | ||||
|  | ||||
| @@ -253,6 +282,20 @@ void                meta_wayland_surface_queue_pending_frame_callbacks (MetaWayl | ||||
| void                meta_wayland_surface_queue_pending_state_frame_callbacks (MetaWaylandSurface      *surface, | ||||
|                                                                               MetaWaylandPendingState *pending); | ||||
|  | ||||
| void                meta_wayland_surface_get_relative_coordinates (MetaWaylandSurface *surface, | ||||
|                                                                    float               abs_x, | ||||
|                                                                    float               abs_y, | ||||
|                                                                    float              *sx, | ||||
|                                                                    float              *sy); | ||||
|  | ||||
| void                meta_wayland_surface_get_absolute_coordinates (MetaWaylandSurface *surface, | ||||
|                                                                    float               sx, | ||||
|                                                                    float               sy, | ||||
|                                                                    float              *x, | ||||
|                                                                    float              *y); | ||||
|  | ||||
| MetaWaylandSurface * meta_wayland_surface_role_get_surface (MetaWaylandSurfaceRole *role); | ||||
|  | ||||
| cairo_region_t *    meta_wayland_surface_calculate_input_region (MetaWaylandSurface *surface); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -42,7 +42,7 @@ | ||||
| #define META_WL_SEAT_VERSION                5 | ||||
| #define META_WL_OUTPUT_VERSION              2 | ||||
| #define META_XSERVER_VERSION                1 | ||||
| #define META_GTK_SHELL_VERSION              2 | ||||
| #define META_GTK_SHELL1_VERSION             1 | ||||
| #define META_WL_SUBCOMPOSITOR_VERSION       1 | ||||
| #define META_ZWP_POINTER_GESTURES_V1_VERSION    1 | ||||
|  | ||||
|   | ||||
| @@ -48,14 +48,6 @@ meta_wayland_compositor_get_default (void) | ||||
|   return &_meta_wayland_compositor; | ||||
| } | ||||
|  | ||||
| static guint32 | ||||
| get_time (void) | ||||
| { | ||||
|   struct timeval tv; | ||||
|   gettimeofday (&tv, NULL); | ||||
|   return tv.tv_sec * 1000 + tv.tv_usec / 1000; | ||||
| } | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   GSource source; | ||||
| @@ -186,7 +178,7 @@ meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor) | ||||
|       MetaWaylandFrameCallback *callback = | ||||
|         wl_container_of (compositor->frame_callbacks.next, callback, link); | ||||
|  | ||||
|       wl_callback_send_done (callback->resource, get_time ()); | ||||
|       wl_callback_send_done (callback->resource, g_get_monotonic_time () / 1000); | ||||
|       wl_resource_destroy (callback->resource); | ||||
|     } | ||||
| } | ||||
| @@ -336,6 +328,8 @@ meta_wayland_init (void) | ||||
|   meta_wayland_shell_init (compositor); | ||||
|   meta_wayland_pointer_gestures_init (compositor); | ||||
|   meta_wayland_seat_init (compositor); | ||||
|   meta_wayland_relative_pointer_init (compositor); | ||||
|   meta_wayland_pointer_constraints_init (compositor); | ||||
|  | ||||
|   if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display)) | ||||
|     g_error ("Failed to start X Wayland"); | ||||
|   | ||||
| @@ -30,6 +30,7 @@ | ||||
| #include "window-private.h" | ||||
| #include "boxes-private.h" | ||||
| #include "stack-tracker.h" | ||||
| #include "meta-wayland-private.h" | ||||
| #include "meta-wayland-surface.h" | ||||
| #include "compositor/meta-surface-actor-wayland.h" | ||||
|  | ||||
| @@ -362,7 +363,9 @@ meta_window_wayland_main_monitor_changed (MetaWindow *window, | ||||
|   /* Window size. */ | ||||
|   scale_rect_size (&window->rect, scale_factor); | ||||
|   scale_rect_size (&window->unconstrained_rect, scale_factor); | ||||
|   scale_rect_size (&window->saved_rect, scale_factor); | ||||
|   scale_rect_size (&window->size_states.normal.rect, scale_factor); | ||||
|   scale_rect_size (&window->size_states.tiled.rect, scale_factor); | ||||
|   scale_rect_size (&window->size_states.maximized.rect, scale_factor); | ||||
|  | ||||
|   /* Window geometry offset (XXX: Need a better place, see | ||||
|    * meta_window_wayland_move_resize). */ | ||||
|   | ||||
| @@ -91,6 +91,7 @@ struct _MetaWaylandDataSourceXWayland | ||||
|  | ||||
| struct _MetaXWaylandSelection { | ||||
|   MetaSelectionBridge clipboard; | ||||
|   MetaSelectionBridge primary; | ||||
|   MetaDndBridge dnd; | ||||
| }; | ||||
|  | ||||
| @@ -396,6 +397,8 @@ atom_to_selection_bridge (MetaWaylandCompositor *compositor, | ||||
|  | ||||
|   if (selection_atom == selection_data->clipboard.selection_atom) | ||||
|     return &selection_data->clipboard; | ||||
|   else if (selection_atom == selection_data->primary.selection_atom) | ||||
|     return &selection_data->primary; | ||||
|   else if (selection_atom == selection_data->dnd.selection.selection_atom) | ||||
|     return &selection_data->dnd.selection; | ||||
|   else | ||||
| @@ -530,6 +533,8 @@ data_device_get_active_source_for_atom (MetaWaylandDataDevice *data_device, | ||||
| { | ||||
|   if (selection_atom == gdk_x11_get_xatom_by_name ("CLIPBOARD")) | ||||
|     return data_device->selection_data_source; | ||||
|   else if (selection_atom == gdk_x11_get_xatom_by_name ("PRIMARY")) | ||||
|     return data_device->primary_data_source; | ||||
|   else if (selection_atom == xdnd_atoms[ATOM_DND_SELECTION]) | ||||
|     return data_device->dnd_data_source; | ||||
|   else | ||||
| @@ -667,11 +672,17 @@ wayland_data_read_cb (GObject      *object, | ||||
|                                            res, &error); | ||||
|   if (error) | ||||
|     { | ||||
|       if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) | ||||
|         { | ||||
|           g_error_free (error); | ||||
|           return; | ||||
|         } | ||||
|  | ||||
|       g_warning ("Error transfering wayland clipboard to X11: %s\n", | ||||
|                  error->message); | ||||
|       g_error_free (error); | ||||
|  | ||||
|       if (data) | ||||
|       if (data && data->stream == G_INPUT_STREAM (object)) | ||||
|         { | ||||
|           reply_selection_request (&data->request_event, FALSE); | ||||
|           g_clear_pointer (&selection->wayland_selection, | ||||
| @@ -1058,6 +1069,11 @@ meta_xwayland_selection_get_x11_targets (MetaWaylandCompositor *compositor, | ||||
|           meta_wayland_data_device_set_selection (&compositor->seat->data_device, data_source, | ||||
|                                                   wl_display_next_serial (compositor->wayland_display)); | ||||
|         } | ||||
|       else if (selection->selection_atom == gdk_x11_get_xatom_by_name ("PRIMARY")) | ||||
|         { | ||||
|           meta_wayland_data_device_set_primary (&compositor->seat->data_device, data_source, | ||||
|                                                 wl_display_next_serial (compositor->wayland_display)); | ||||
|         } | ||||
|     } | ||||
|   else | ||||
|     g_object_unref (data_source); | ||||
| @@ -1529,7 +1545,8 @@ meta_xwayland_selection_handle_xfixes_selection_notify (MetaWaylandCompositor *c | ||||
|   if (!selection) | ||||
|     return FALSE; | ||||
|  | ||||
|   if (selection->selection_atom == gdk_x11_get_xatom_by_name ("CLIPBOARD")) | ||||
|   if (selection->selection_atom == gdk_x11_get_xatom_by_name ("CLIPBOARD") || | ||||
|       selection->selection_atom == gdk_x11_get_xatom_by_name ("PRIMARY")) | ||||
|     { | ||||
|       if (event->owner == None) | ||||
|         { | ||||
| @@ -1712,6 +1729,9 @@ meta_xwayland_init_selection (void) | ||||
|   init_selection_bridge (&manager->selection_data->clipboard, | ||||
|                          gdk_x11_get_xatom_by_name ("CLIPBOARD"), | ||||
|                          &compositor->seat->data_device.selection_ownership_signal); | ||||
|   init_selection_bridge (&manager->selection_data->primary, | ||||
|                          gdk_x11_get_xatom_by_name ("PRIMARY"), | ||||
|                          &compositor->seat->data_device.primary_ownership_signal); | ||||
|   init_selection_bridge (&manager->selection_data->dnd.selection, | ||||
|                          xdnd_atoms[ATOM_DND_SELECTION], | ||||
|                          &compositor->seat->data_device.dnd_ownership_signal); | ||||
| @@ -1730,6 +1750,7 @@ meta_xwayland_shutdown_selection (void) | ||||
|  | ||||
|   meta_xwayland_shutdown_dnd (manager); | ||||
|   shutdown_selection_bridge (&selection->clipboard); | ||||
|   shutdown_selection_bridge (&selection->primary); | ||||
|   shutdown_selection_bridge (&selection->dnd.selection); | ||||
|  | ||||
|   g_slice_free (MetaXWaylandSelection, selection); | ||||
|   | ||||
							
								
								
									
										225
									
								
								src/wayland/protocol/gtk-primary-selection.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								src/wayland/protocol/gtk-primary-selection.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,225 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <protocol name="gtk_primary_selection"> | ||||
|   <copyright> | ||||
|     Copyright © 2015, 2016 Red Hat | ||||
|  | ||||
|     Permission is hereby granted, free of charge, to any person obtaining a | ||||
|     copy of this software and associated documentation files (the "Software"), | ||||
|     to deal in the Software without restriction, including without limitation | ||||
|     the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||||
|     and/or sell copies of the Software, and to permit persons to whom the | ||||
|     Software is furnished to do so, subject to the following conditions: | ||||
|  | ||||
|     The above copyright notice and this permission notice (including the next | ||||
|     paragraph) shall be included in all copies or substantial portions of the | ||||
|     Software. | ||||
|  | ||||
|     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL | ||||
|     THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
|     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||||
|     DEALINGS IN THE SOFTWARE. | ||||
|   </copyright> | ||||
|  | ||||
|   <description summary="Primary selection protocol"> | ||||
|     This protocol provides the ability to have a primary selection device to | ||||
|     match that of the X server. This primary selection is a shortcut to the | ||||
|     common clipboard selection, where text just needs to be selected in order | ||||
|     to allow copying it elsewhere. The de facto way to perform this action | ||||
|     is the middle mouse button, although it is not limited to this one. | ||||
|  | ||||
|     Clients wishing to honor primary selection should create a primary | ||||
|     selection source and set it as the selection through | ||||
|     wp_primary_selection_device.set_selection whenever the text selection | ||||
|     changes. In order to minimize calls in pointer-driven text selection, | ||||
|     it should happen only once after the operation finished. Similarly, | ||||
|     a NULL source should be set when text is unselected. | ||||
|  | ||||
|     wp_primary_selection_offer objects are first announced through the | ||||
|     wp_primary_selection_device.data_offer event. Immediately after this event, | ||||
|     the primary data offer will emit wp_primary_selection_offer.offer events | ||||
|     to let know of the mime types being offered. | ||||
|  | ||||
|     When the primary selection changes, the client with the keyboard focus | ||||
|     will receive wp_primary_selection_device.selection events. Only the client | ||||
|     with the keyboard focus will receive such events with a non-NULL | ||||
|     wp_primary_selection_offer. Across keyboard focus changes, previously | ||||
|     focused clients will receive wp_primary_selection_device.events with a | ||||
|     NULL wp_primary_selection_offer. | ||||
|  | ||||
|     In order to request the primary selection data, the client must pass | ||||
|     a recent serial pertaining to the press event that is triggering the | ||||
|     operation, if the compositor deems the serial valid and recent, the | ||||
|     wp_primary_selection_source.send event will happen in the other end | ||||
|     to let the transfer begin. The client owning the primary selection | ||||
|     should write the requested data, and close the file descriptor | ||||
|     immediately. | ||||
|  | ||||
|     If the primary selection owner client disappeared during the transfer, | ||||
|     the client reading the data will receive a | ||||
|     wp_primary_selection_device.selection event with a NULL | ||||
|     wp_primary_selection_offer, the client should take this as a hint | ||||
|     to finish the reads related to the no longer existing offer. | ||||
|  | ||||
|     The primary selection owner should be checking for errors during | ||||
|     writes, merely cancelling the ongoing transfer if any happened. | ||||
|   </description> | ||||
|  | ||||
|   <interface name="gtk_primary_selection_device_manager" version="1"> | ||||
|     <description summary="X primary selection emulation"> | ||||
|       The primary selection device manager is a singleton global object that | ||||
|       provides access to the primary selection. It allows to create | ||||
|       wp_primary_selection_source objects, as well as retrieving the per-seat | ||||
|       wp_primary_selection_device objects. | ||||
|     </description> | ||||
|  | ||||
|     <request name="create_source"> | ||||
|       <description summary="create a new primary selection source"> | ||||
| 	Create a new primary selection source. | ||||
|       </description> | ||||
|       <arg name="id" type="new_id" interface="gtk_primary_selection_source"/> | ||||
|     </request> | ||||
|  | ||||
|     <request name="get_device"> | ||||
|       <description summary="create a new primary selection device"> | ||||
|         Create a new data device for a given seat. | ||||
|       </description> | ||||
|       <arg name="id" type="new_id" interface="gtk_primary_selection_device"/> | ||||
|       <arg name="seat" type="object" interface="wl_seat"/> | ||||
|     </request> | ||||
|  | ||||
|     <request name="destroy" type="destructor"> | ||||
|       <description summary="destroy the primary selection device manager"> | ||||
| 	Destroy the primary selection device manager. | ||||
|       </description> | ||||
|     </request> | ||||
|   </interface> | ||||
|  | ||||
|   <interface name="gtk_primary_selection_device" version="1"> | ||||
|     <request name="set_selection"> | ||||
|       <description summary="set the primary selection"> | ||||
| 	Replaces the current selection. The previous owner of the primary selection | ||||
| 	will receive a wp_primary_selection_source.cancelled event. | ||||
|  | ||||
| 	To unset the selection, set the source to NULL. | ||||
|       </description> | ||||
|       <arg name="source" type="object" interface="gtk_primary_selection_source" allow-null="true"/> | ||||
|       <arg name="serial" type="uint" summary="serial of the event that triggered this request"/> | ||||
|     </request> | ||||
|  | ||||
|     <event name="data_offer"> | ||||
|       <description summary="introduce a new wp_primary_selection_offer"> | ||||
| 	Introduces a new wp_primary_selection_offer object that may be used | ||||
| 	to receive the current primary selection. Immediately following this | ||||
| 	event, the new wp_primary_selection_offer object will send | ||||
| 	wp_primary_selection_offer.offer events to describe the offered mime | ||||
| 	types. | ||||
|       </description> | ||||
|       <arg name="offer" type="new_id" interface="gtk_primary_selection_offer"/> | ||||
|     </event> | ||||
|  | ||||
|     <event name="selection"> | ||||
|       <description summary="advertise a new primary selection"> | ||||
| 	The wp_primary_selection_device.selection event is sent to notify the | ||||
| 	client of a new primary selection. This event is sent after the | ||||
| 	wp_primary_selection.data_offer event introducing this object, and after | ||||
| 	the offer has announced its mimetypes through | ||||
| 	wp_primary_selection_offer.offer. | ||||
|  | ||||
| 	The data_offer is valid until a new offer or NULL is received | ||||
| 	or until the client loses keyboard focus. The client must destroy the | ||||
| 	previous selection data_offer, if any, upon receiving this event. | ||||
|       </description> | ||||
|       <arg name="id" type="object" interface="gtk_primary_selection_offer" allow-null="true"/> | ||||
|     </event> | ||||
|  | ||||
|     <request name="destroy" type="destructor"> | ||||
|       <description summary="destroy the primary selection device"> | ||||
| 	Destroy the primary selection device. | ||||
|       </description> | ||||
|     </request> | ||||
|   </interface> | ||||
|  | ||||
|   <interface name="gtk_primary_selection_offer" version="1"> | ||||
|     <description summary="offer to transfer primary selection contents"> | ||||
|       A wp_primary_selection_offer represents an offer to transfer the contents | ||||
|       of the primary selection clipboard to the client. Similar to | ||||
|       wl_data_offer, the offer also describes the mime types that the source | ||||
|       will transferthat the | ||||
|       data can be converted to and provides the mechanisms for transferring the | ||||
|       data directly to the client. | ||||
|     </description> | ||||
|  | ||||
|     <request name="receive"> | ||||
|       <description summary="request that the data is transferred"> | ||||
| 	To transfer the contents of the primary selection clipboard, the client | ||||
| 	issues this request and indicates the mime type that it wants to | ||||
| 	receive. The transfer happens through the passed file descriptor | ||||
| 	(typically created with the pipe system call). The source client writes | ||||
| 	the data in the mime type representation requested and then closes the | ||||
| 	file descriptor. | ||||
|  | ||||
| 	The receiving client reads from the read end of the pipe until EOF and | ||||
| 	closes its end, at which point the transfer is complete. | ||||
|       </description> | ||||
|       <arg name="mime_type" type="string"/> | ||||
|       <arg name="fd" type="fd"/> | ||||
|     </request> | ||||
|  | ||||
|     <request name="destroy" type="destructor"> | ||||
|       <description summary="destroy the primary selection offer"> | ||||
| 	Destroy the primary selection offer. | ||||
|       </description> | ||||
|     </request> | ||||
|  | ||||
|     <event name="offer"> | ||||
|       <description summary="advertise offered mime type"> | ||||
| 	Sent immediately after creating announcing the wp_primary_selection_offer | ||||
| 	through wp_primary_selection_device.data_offer. One event is sent per | ||||
| 	offered mime type. | ||||
|       </description> | ||||
|       <arg name="mime_type" type="string"/> | ||||
|     </event> | ||||
|   </interface> | ||||
|  | ||||
|   <interface name="gtk_primary_selection_source" version="1"> | ||||
|     <description summary="offer to replace the contents of the primary selection"> | ||||
|       The source side of a wp_primary_selection_offer, it provides a way to | ||||
|       describe the offered data and respond to requests to transfer the | ||||
|       requested contents of the primary selection clipboard. | ||||
|     </description> | ||||
|  | ||||
|     <request name="offer"> | ||||
|       <description summary="add an offered mime type"> | ||||
| 	This request adds a mime type to the set of mime types advertised to | ||||
| 	targets. Can be called several times to offer multiple types. | ||||
|       </description> | ||||
|       <arg name="mime_type" type="string"/> | ||||
|     </request> | ||||
|  | ||||
|     <request name="destroy" type="destructor"> | ||||
|       <description summary="destroy the primary selection source"> | ||||
| 	Destroy the primary selection source. | ||||
|       </description> | ||||
|     </request> | ||||
|  | ||||
|     <event name="send"> | ||||
|       <description summary="send the primary selection contents"> | ||||
| 	Request for the current primary selection contents from the client. | ||||
| 	Send the specified mime type over the passed file descriptor, then | ||||
| 	close it. | ||||
|       </description> | ||||
|       <arg name="mime_type" type="string"/> | ||||
|       <arg name="fd" type="fd"/> | ||||
|     </event> | ||||
|  | ||||
|     <event name="cancelled"> | ||||
|       <description summary="request for primary selection contents was canceled"> | ||||
| 	This primary selection source is no longer valid. The client should | ||||
| 	clean up and destroy this primary selection source. | ||||
|       </description> | ||||
|     </event> | ||||
|   </interface> | ||||
| </protocol> | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user