Compare commits
	
		
			40 Commits
		
	
	
		
			wip/carlos
			...
			wip/xtogls
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 78522c9986 | ||
|   | e6f100b6d4 | ||
|   | a294989fce | ||
|   | 1ed41b7ed3 | ||
|   | 3d1d155561 | ||
|   | 7943cf50d4 | ||
|   | 489ad9e978 | ||
|   | a3f3c60a6c | ||
|   | b39ef6a961 | ||
|   | 14dbe8ac8a | ||
|   | d158e19133 | ||
|   | c2dadecab8 | ||
|   | 099059c930 | ||
|   | 24f5b37d6b | ||
|   | 2958b15a61 | ||
|   | fd263d8457 | ||
|   | 47758f0f5f | ||
|   | 477eb1afed | ||
|   | 3b8b05518c | ||
|   | 0bd30696b1 | ||
|   | fb4e9d2232 | ||
|   | e072295395 | ||
|   | 1066c19e67 | ||
|   | d654c93ed2 | ||
|   | 7d1611f666 | ||
|   | 2579e48f21 | ||
|   | 7278f9bd6b | ||
|   | da55e27c3b | ||
|   | f3196e356b | ||
|   | 491b17af19 | ||
|   | 01e0eaf1fc | ||
|   | f679ce7017 | ||
|   | 844f4e9348 | ||
|   | 5cfc1461a1 | ||
|   | 323e1aba59 | ||
|   | 992b97d565 | ||
|   | da5b9f3255 | ||
|   | 6c1eff0dc2 | ||
|   | 1ff986e227 | ||
|   | b86a289ee3 | 
							
								
								
									
										50
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								NEWS
									
									
									
									
									
								
							| @@ -1,3 +1,53 @@ | ||||
| 3.10.4 | ||||
| ====== | ||||
| * Fix CSD titlebars being placed off-screen [Jasper; #719772] | ||||
| * Expose MetaWindow:skip-taskbar property [Florian; #723307] | ||||
| * Fix legacy tray icons showing up blank [Adel; #721596] | ||||
| * Fix configuration of cloned monitors [Adel; #710610] | ||||
| * Use correct output property for backlight control [Robert; #723606] | ||||
| * Misc. bug fixes [Jasper, Adel, Giovanni, Ryan; #720630, #723468, #724258, | ||||
|   #724364] | ||||
|  | ||||
| Contributors: | ||||
|   Robert Ancell, Giovanni Campagna, Adel Gadllah, Ryan Lortie, Florian Müllner, | ||||
|   Jasper St. Pierre | ||||
|  | ||||
| Translations: | ||||
|   Shankar Prasad [kn], Khaled Hosny [ar] | ||||
|  | ||||
| 3.10.3 | ||||
| ====== | ||||
| * xrandr: Use "hotplug_mode_update" property [Marc-André; #711216] | ||||
| * Don't focus the no-focus-window for globally active windows [Jasper; #710296] | ||||
| * Fix window group paint volume [Owen; #719669] | ||||
| * Fix checks for KeyPress/ButtonPress [Jasper; #720545] | ||||
| * Fix problems with focus tracking [Owen; #720558] | ||||
| * Don't leave focus on windows that are being unmanaged [Owen; #711618] | ||||
| * Reduce server grabs [Daniel; #721345, #721709] | ||||
|  | ||||
| Contributors: | ||||
|   Daniel Drake, Marc-André Lureau, Jasper St. Pierre, Owen W. Taylor | ||||
|  | ||||
| Translations: | ||||
|   甘露(Gan  Lu) [zh_CN] | ||||
|  | ||||
| 3.10.2 | ||||
| ====== | ||||
| * Fix resize operations using mouse-button-modifier [Lionel; #710251] | ||||
|  | ||||
| Contributors: | ||||
|   Lionel Landwerlin | ||||
|  | ||||
| Translations: | ||||
|   Efstathios Iosifidis [el], Reinout van Schouwen [nl] | ||||
|  | ||||
| 3.10.1.1 | ||||
| ======== | ||||
| * Don't assert that at least one output is connected [Giovanni; #709009] | ||||
|  | ||||
| Contributors: | ||||
|   Giovanni Campagna | ||||
|  | ||||
| 3.10.1 | ||||
| ====== | ||||
| * Don't apply fullscreen workarounds to CSD windows [Giovanni; #708718] | ||||
|   | ||||
| @@ -2,7 +2,7 @@ AC_PREREQ(2.50) | ||||
|  | ||||
| m4_define([mutter_major_version], [3]) | ||||
| m4_define([mutter_minor_version], [10]) | ||||
| m4_define([mutter_micro_version], [1]) | ||||
| m4_define([mutter_micro_version], [4]) | ||||
|  | ||||
| m4_define([mutter_version], | ||||
|           [mutter_major_version.mutter_minor_version.mutter_micro_version]) | ||||
| @@ -363,6 +363,11 @@ fi | ||||
|  | ||||
| GTK_DOC_CHECK([1.15], [--flavour no-tmpl]) | ||||
|  | ||||
| AC_CHECK_DECL([GL_EXT_x11_sync_object], | ||||
|               [], | ||||
|               [AC_MSG_ERROR([GL_EXT_x11_sync_object definition not found, please update your GL headers])], | ||||
|               [#include <GL/glx.h>]) | ||||
|  | ||||
| #### Warnings (last since -Werror can disturb other tests) | ||||
|  | ||||
| # Stay command-line compatible with the gnome-common configure option. Here | ||||
|   | ||||
							
								
								
									
										16
									
								
								po/ar.po
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								po/ar.po
									
									
									
									
									
								
							| @@ -4,14 +4,14 @@ | ||||
| # Arafat Medini <lumina@silverpen.de>, 2003. | ||||
| # Abdulaziz Al-Arfaj <alarfaj0@yahoo.com>, 2004. | ||||
| # Djihed Afifi <djihed@gmail.com>, 2006. | ||||
| # Khaled Hosny <khaledhosny@eglug.org>, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013. | ||||
| # Khaled Hosny <khaledhosny@eglug.org>, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014. | ||||
| # Anas Afif Emad <anas.e87@gmail.com>, 2008. | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: metacity.HEAD\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2013-10-07 17:09+0200\n" | ||||
| "PO-Revision-Date: 2013-10-07 17:09+0200\n" | ||||
| "POT-Creation-Date: 2014-02-06 15:37+0200\n" | ||||
| "PO-Revision-Date: 2014-02-06 15:37+0200\n" | ||||
| "Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n" | ||||
| "Language-Team: Arabic <doc@arabeyes.org>\n" | ||||
| "Language: ar\n" | ||||
| @@ -314,16 +314,16 @@ msgstr "تعذّر إيجاد سِمة! تأكد من وجود %s و احتوا | ||||
|  | ||||
| #: ../src/core/monitor.c:696 | ||||
| msgid "Built-in display" | ||||
| msgstr "" | ||||
| msgstr "شاشة مدمجة" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor name (in case we don't know | ||||
| #. the vendor), it's Unknown followed by a size in inches, | ||||
| #. like 'Unknown 15"' | ||||
| #. | ||||
| #: ../src/core/monitor.c:724 | ||||
| #, fuzzy, c-format | ||||
| #, c-format | ||||
| msgid "Unknown %s" | ||||
| msgstr "عنصر مجهول %s" | ||||
| msgstr "غير معروفة %s" | ||||
|  | ||||
| #: ../src/core/mutter.c:40 | ||||
| #, c-format | ||||
| @@ -503,7 +503,7 @@ msgid "Window manager error: " | ||||
| msgstr "خطأ مدير النوافذ: " | ||||
|  | ||||
| #. first time through | ||||
| #: ../src/core/window.c:7515 | ||||
| #: ../src/core/window.c:7497 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " | ||||
| @@ -519,7 +519,7 @@ msgstr "" | ||||
| #. * MWM but not WM_NORMAL_HINTS are basically broken. We complain | ||||
| #. * about these apps but make them work. | ||||
| #. | ||||
| #: ../src/core/window.c:8345 | ||||
| #: ../src/core/window.c:8329 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Window %s sets an MWM hint indicating it isn't resizable, but sets min size " | ||||
|   | ||||
							
								
								
									
										234
									
								
								po/nl.po
									
									
									
									
									
								
							
							
						
						
									
										234
									
								
								po/nl.po
									
									
									
									
									
								
							| @@ -7,10 +7,9 @@ | ||||
| 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: 2013-08-18 20:03+0000\n" | ||||
| "PO-Revision-Date: 2013-10-12 00:32+0200\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2013-10-25 00:15+0200\n" | ||||
| "PO-Revision-Date: 2013-10-25 00:23+0200\n" | ||||
| "Last-Translator: Reinout van Schouwen <reinouts@gnome.org>\n" | ||||
| "Language-Team: Dutch <vertaling@vrijschrift.org>\n" | ||||
| "Language: nl\n" | ||||
| @@ -18,7 +17,6 @@ msgstr "" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "Plural-Forms: nplurals=2; plural=(n != 1);\n" | ||||
| "X-Generator: Virtaal 0.7.1\n" | ||||
| "X-Project-Style: gnome\n" | ||||
|  | ||||
| #: ../src/50-mutter-navigation.xml.in.h:1 | ||||
| @@ -211,16 +209,16 @@ msgstr "Weergave gesplitst op rechts" | ||||
|  | ||||
| #. 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:589 | ||||
| #: ../src/compositor/compositor.c:596 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Another compositing manager is already running on screen %i on display \"%s" | ||||
| "\"." | ||||
| msgstr "" | ||||
| "Er is al een andere ‘compositing manager’ actief op scherm %i van display ‘%" | ||||
| "s’." | ||||
| "Er is al een andere ‘compositing manager’ actief op scherm %i van display " | ||||
| "‘%s’." | ||||
|  | ||||
| #: ../src/compositor/meta-background.c:1076 | ||||
| #: ../src/compositor/meta-background.c:1075 | ||||
| msgid "background texture could not be created from file" | ||||
| msgstr "aanmaken achtergrondstructuur uit bestand mislukt" | ||||
|  | ||||
| @@ -235,7 +233,6 @@ msgstr "Onbekende aanvraag voor vensterinformatie: %d" | ||||
|  | ||||
| #: ../src/core/delete.c:111 | ||||
| #, c-format | ||||
| #| msgid "<tt>%s</tt> is not responding." | ||||
| msgid "“%s” is not responding." | ||||
| msgstr "‘%s’ reageert niet." | ||||
|  | ||||
| @@ -259,12 +256,12 @@ msgstr "_Wachten" | ||||
| msgid "_Force Quit" | ||||
| msgstr "Ge_forceerd afsluiten" | ||||
|  | ||||
| #: ../src/core/display.c:421 | ||||
| #: ../src/core/display.c:422 | ||||
| #, c-format | ||||
| msgid "Missing %s extension required for compositing" | ||||
| msgstr "Benodigde extensie ‘%s’ voor ‘compositing’ ontbreekt" | ||||
|  | ||||
| #: ../src/core/display.c:513 | ||||
| #: ../src/core/display.c:514 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Openen van X Window System display ‘%s’ mislukt\n" | ||||
| @@ -281,7 +278,6 @@ msgstr "" | ||||
|  | ||||
| #: ../src/core/keybindings.c:1333 | ||||
| #, c-format | ||||
| #| msgid "\"%s\" is not a valid value for focus attribute" | ||||
| msgid "\"%s\" is not a valid accelerator\n" | ||||
| msgstr "‘%s’ is geen geldige sneltoets\n" | ||||
|  | ||||
| @@ -322,7 +318,7 @@ msgstr "" | ||||
| "Kon geen thema vinden! Zorg ervoor dat %s bestaat en de gebruikelijke " | ||||
| "thema's bevat.\n" | ||||
|  | ||||
| #: ../src/core/monitor.c:711 | ||||
| #: ../src/core/monitor.c:696 | ||||
| msgid "Built-in display" | ||||
| msgstr "Ingebouwd beeldscherm" | ||||
|  | ||||
| @@ -330,9 +326,8 @@ msgstr "Ingebouwd beeldscherm" | ||||
| #. the vendor), it's Unknown followed by a size in inches, | ||||
| #. like 'Unknown 15"' | ||||
| #. | ||||
| #: ../src/core/monitor.c:739 | ||||
| #: ../src/core/monitor.c:724 | ||||
| #, c-format | ||||
| #| msgid "Unknown element %s" | ||||
| msgid "Unknown %s" | ||||
| msgstr "Onbekend %s" | ||||
|  | ||||
| @@ -394,12 +389,12 @@ msgstr "" | ||||
| msgid "Workspace %d" | ||||
| msgstr "Werkblad %d" | ||||
|  | ||||
| #: ../src/core/screen.c:534 | ||||
| #: ../src/core/screen.c:537 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Scherm %d op display '%s' is ongeldig\n" | ||||
|  | ||||
| #: ../src/core/screen.c:550 | ||||
| #: ../src/core/screen.c:553 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Screen %d on display \"%s\" already has a window manager; try using the --" | ||||
| @@ -408,19 +403,19 @@ msgstr "" | ||||
| "Scherm %d op display ‘%s’ heeft al een ‘window manager’; probeer de optie: --" | ||||
| "replace te gebruiken om de huidige ‘window manager’ te vervangen.\n" | ||||
|  | ||||
| #: ../src/core/screen.c:577 | ||||
| #: ../src/core/screen.c:580 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Could not acquire window manager selection on screen %d display \"%s\"\n" | ||||
| msgstr "" | ||||
| "Kon ‘window manager’-selectie niet verkrijgen op scherm %d display ‘%s’\n" | ||||
|  | ||||
| #: ../src/core/screen.c:655 | ||||
| #: ../src/core/screen.c:658 | ||||
| #, c-format | ||||
| msgid "Screen %d on display \"%s\" already has a window manager\n" | ||||
| msgstr "Scherm %d op display ‘%s’ heeft al een ‘window manager’\n" | ||||
|  | ||||
| #: ../src/core/screen.c:846 | ||||
| #: ../src/core/screen.c:850 | ||||
| #, c-format | ||||
| msgid "Could not release screen %d on display \"%s\"\n" | ||||
| msgstr "Kon scherm %d op display ‘%s’ niet vrijmaken\n" | ||||
| @@ -516,7 +511,7 @@ msgid "Window manager error: " | ||||
| msgstr "Fout van vensterbeheer:" | ||||
|  | ||||
| #. first time through | ||||
| #: ../src/core/window.c:7533 | ||||
| #: ../src/core/window.c:7515 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " | ||||
| @@ -532,7 +527,7 @@ msgstr "" | ||||
| #. * MWM but not WM_NORMAL_HINTS are basically broken. We complain | ||||
| #. * about these apps but make them work. | ||||
| #. | ||||
| #: ../src/core/window.c:8257 | ||||
| #: ../src/core/window.c:8345 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Window %s sets an MWM hint indicating it isn't resizable, but sets min size " | ||||
| @@ -650,6 +645,9 @@ msgid "" | ||||
| "static number of workspaces (determined by the num-workspaces key in org." | ||||
| "gnome.desktop.wm.preferences)." | ||||
| msgstr "" | ||||
| "Bepaalt of werkbladen dynamisch worden beheerd of dat er een statisch aantal " | ||||
| "werkbladen is (gegeven door de sleutel num-workspaces in org.gnome.desktop." | ||||
| "wm.preferences)." | ||||
|  | ||||
| #: ../src/org.gnome.mutter.gschema.xml.in.h:9 | ||||
| msgid "Workspaces only on primary" | ||||
| @@ -672,10 +670,12 @@ msgid "" | ||||
| "Determines whether the use of popup and highlight frame should be disabled " | ||||
| "for window cycling." | ||||
| msgstr "" | ||||
| "Bepaalt of het gebruik van pop-up en markering van het kader uitgeschakeld " | ||||
| "wordt voor het vensterbladeren." | ||||
|  | ||||
| #: ../src/org.gnome.mutter.gschema.xml.in.h:13 | ||||
| msgid "Delay focus changes until the pointer stops moving" | ||||
| msgstr "" | ||||
| msgstr "Aandacht vertragen totdat de muispijl stopt met bewegen" | ||||
|  | ||||
| #: ../src/org.gnome.mutter.gschema.xml.in.h:14 | ||||
| msgid "" | ||||
| @@ -683,16 +683,22 @@ msgid "" | ||||
| "the focus will not be changed immediately when entering a window, but only " | ||||
| "after the pointer stops moving." | ||||
| msgstr "" | ||||
| "Indien op ‘true’ ingesteld en de aandachtsmodus is ofwel ‘sloppy’ of ‘mouse’, " | ||||
| "dan zal de aandacht niet direct veranderd worden bij het binnengaan van een " | ||||
| "venster, maar slechts wanneer de muispijl stopt met bewegen." | ||||
|  | ||||
| #: ../src/org.gnome.mutter.gschema.xml.in.h:15 | ||||
| msgid "Draggable border width" | ||||
| msgstr "" | ||||
| msgstr "Sleepbare randbreedte" | ||||
|  | ||||
| #: ../src/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 "" | ||||
| "Het totaal aantal sleepbare randen. Als de zichtbare randen in het thema " | ||||
| "onvoldoende zijn, worden onzichtbare randen toegevoegd om deze waarde " | ||||
| "te bereiken." | ||||
|  | ||||
| #: ../src/org.gnome.mutter.gschema.xml.in.h:17 | ||||
| msgid "Auto maximize nearly monitor sized windows" | ||||
| @@ -957,13 +963,13 @@ msgid "Gradients should have at least two colors" | ||||
| msgstr "Kleurverloop moet tenminste twee kleuren hebben" | ||||
|  | ||||
| #: ../src/ui/theme.c:1203 | ||||
| #, fuzzy, c-format | ||||
| #, c-format | ||||
| msgid "" | ||||
| "GTK custom color specification must have color name and fallback in " | ||||
| "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" | ||||
| msgstr "" | ||||
| "GTK-kleurspecificatie moet een sluithaakje hebben na de status, dus: gtk: " | ||||
| "fg[NORMAL] waarbij NORMAL de stutus is; kon ‘%s’ niet verwerken" | ||||
| "Aangepaste GTK-kleurspecificatie moet een kleurnaam en terugvaloptie " | ||||
| "hebben tussen haakjes, dus: gtk:custom(foo,bar); kon ‘%s’ niet verwerken" | ||||
|  | ||||
| #: ../src/ui/theme.c:1219 | ||||
| #, c-format | ||||
| @@ -971,15 +977,17 @@ msgid "" | ||||
| "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" | ||||
| "_ are valid" | ||||
| msgstr "" | ||||
| "Ongeldig teken ‘%c’ in color_name-parameter van gtk:custom, alleen A-Za-z0-9-_ " | ||||
| "zijn geldig" | ||||
|  | ||||
| #: ../src/ui/theme.c:1233 | ||||
| #, fuzzy, c-format | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " | ||||
| "fit the format" | ||||
| msgstr "" | ||||
| "Schaduwformaat is ‘schaduw/basiskleur/factor’, ‘%s’ voldoet niet aan dit " | ||||
| "formaat" | ||||
| "Gtk:custom-formaat is ‘gtk:custom(color_name,fallback)’, ‘%s’ voldoet " | ||||
| "niet aan dit formaat" | ||||
|  | ||||
| #: ../src/ui/theme.c:1278 | ||||
| #, c-format | ||||
| @@ -987,8 +995,8 @@ msgid "" | ||||
| "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-kleurspecificatie moet de toestand in rechte haken hebben, bijv. gtk:fg" | ||||
| "[NORMAL] waarbij NORMAL de toestand is; kon ‘%s’ niet verwerken" | ||||
| "GTK-kleurspecificatie moet de toestand in rechte haken hebben, bijv. gtk:" | ||||
| "fg[NORMAL] waarbij NORMAL de toestand is; kon ‘%s’ niet verwerken" | ||||
|  | ||||
| #: ../src/ui/theme.c:1292 | ||||
| #, c-format | ||||
| @@ -996,8 +1004,8 @@ msgid "" | ||||
| "GTK color specification must have a close bracket after the state, e.g. gtk:" | ||||
| "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" | ||||
| msgstr "" | ||||
| "GTK-kleurspecificatie moet een sluithaakje hebben na de status, dus: gtk: fg" | ||||
| "[NORMAL] waarbij NORMAL de stutus is; kon ‘%s’ niet verwerken" | ||||
| "GTK-kleurspecificatie moet een sluithaakje hebben na de status, dus: gtk: " | ||||
| "fg[NORMAL] waarbij NORMAL de stutus is; kon ‘%s’ niet verwerken" | ||||
|  | ||||
| #: ../src/ui/theme.c:1303 | ||||
| #, c-format | ||||
| @@ -1222,59 +1230,59 @@ msgstr "Geen ‘%s’-attribuut op element <%s>" | ||||
| msgid "Line %d character %d: %s" | ||||
| msgstr "Regel %d teken %d: %s" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:479 | ||||
| #: ../src/ui/theme-parser.c:483 | ||||
| #, c-format | ||||
| msgid "Attribute \"%s\" repeated twice on the same <%s> element" | ||||
| msgstr "Attribuut ‘%s’ twee keer herhaald op hetzelfde <%s>-element" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 | ||||
| #: ../src/ui/theme-parser.c:507 ../src/ui/theme-parser.c:556 | ||||
| #, c-format | ||||
| msgid "Attribute \"%s\" is invalid on <%s> element in this context" | ||||
| msgstr "Attribuut ‘%s’ is ongeldig op een <%s>-element in deze context" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:594 | ||||
| #: ../src/ui/theme-parser.c:598 | ||||
| #, c-format | ||||
| msgid "Could not parse \"%s\" as an integer" | ||||
| msgstr "Kon ‘%s’ niet verwerken als geheel getal" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 | ||||
| #: ../src/ui/theme-parser.c:607 ../src/ui/theme-parser.c:662 | ||||
| #, c-format | ||||
| msgid "Did not understand trailing characters \"%s\" in string \"%s\"" | ||||
| msgstr "Niet begrepen: de laatste tekens ‘%s’ in ‘%s’" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:613 | ||||
| #: ../src/ui/theme-parser.c:617 | ||||
| #, c-format | ||||
| msgid "Integer %ld must be positive" | ||||
| msgstr "Geheel getal %ld moet positief zijn" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:621 | ||||
| #: ../src/ui/theme-parser.c:625 | ||||
| #, c-format | ||||
| msgid "Integer %ld is too large, current max is %d" | ||||
| msgstr "Geheel getal %ld is te groot, huidige maximum is %d" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 | ||||
| #: ../src/ui/theme-parser.c:653 ../src/ui/theme-parser.c:769 | ||||
| #, c-format | ||||
| msgid "Could not parse \"%s\" as a floating point number" | ||||
| msgstr "Kon ‘%s’ niet als 'floating-point'-getal verwerken" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 | ||||
| #: ../src/ui/theme-parser.c:684 ../src/ui/theme-parser.c:712 | ||||
| #, c-format | ||||
| msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" | ||||
| msgstr "Boolese waarde moet ‘true’ of ‘false’ zijn, niet ‘%s’" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:735 | ||||
| #: ../src/ui/theme-parser.c:739 | ||||
| #, c-format | ||||
| msgid "Angle must be between 0.0 and 360.0, was %g\n" | ||||
| msgstr "Hoek moet liggen tussen 0.0 en 360.0, maar was %g\n" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:798 | ||||
| #: ../src/ui/theme-parser.c:802 | ||||
| #, c-format | ||||
| msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" | ||||
| msgstr "" | ||||
| "Alpha moet liggen tussen 0.0 (onzichtbaar) en 1.0 (volledig ondoorzichtig), " | ||||
| "maar was %g\n" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:863 | ||||
| #: ../src/ui/theme-parser.c:867 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," | ||||
| @@ -1283,60 +1291,60 @@ msgstr "" | ||||
| "Ongeldige titel-schaal ‘%s’ (u kunt kiezen uit: xx-small, x-small, small, " | ||||
| "medium, large, x-large, xx-large)\n" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 | ||||
| #: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 | ||||
| #: ../src/ui/theme-parser.c:1023 ../src/ui/theme-parser.c:1086 | ||||
| #: ../src/ui/theme-parser.c:1120 ../src/ui/theme-parser.c:1223 | ||||
| #, c-format | ||||
| msgid "<%s> name \"%s\" used a second time" | ||||
| msgstr "<%s>-naam ‘%s’ een tweede keer gebruikt" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 | ||||
| #: ../src/ui/theme-parser.c:1231 | ||||
| #: ../src/ui/theme-parser.c:1035 ../src/ui/theme-parser.c:1132 | ||||
| #: ../src/ui/theme-parser.c:1235 | ||||
| #, c-format | ||||
| msgid "<%s> parent \"%s\" has not been defined" | ||||
| msgstr "<%s>-ouder ‘%s’ is niet gedefinieerd" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:1141 | ||||
| #: ../src/ui/theme-parser.c:1145 | ||||
| #, c-format | ||||
| msgid "<%s> geometry \"%s\" has not been defined" | ||||
| msgstr "<%s>-afmetingen ‘%s’ is niet gedefinieerd" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:1154 | ||||
| #: ../src/ui/theme-parser.c:1158 | ||||
| #, c-format | ||||
| msgid "<%s> must specify either a geometry or a parent that has a geometry" | ||||
| msgstr "<%s> moet ofwel afmetingen specificeren, of een ouder met afmetingen" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:1196 | ||||
| #: ../src/ui/theme-parser.c:1200 | ||||
| msgid "You must specify a background for an alpha value to be meaningful" | ||||
| msgstr "" | ||||
| "U dient een achtergrond te specificeren voordat een alpha-waarde betekenis " | ||||
| "heeft" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:1264 | ||||
| #: ../src/ui/theme-parser.c:1268 | ||||
| #, c-format | ||||
| msgid "Unknown type \"%s\" on <%s> element" | ||||
| msgstr "Onbekend type ‘%s’ op <%s>-element" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:1275 | ||||
| #: ../src/ui/theme-parser.c:1279 | ||||
| #, c-format | ||||
| msgid "Unknown style_set \"%s\" on <%s> element" | ||||
| msgstr "Onbekende style_set ‘%s’ op <%s>-element" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:1283 | ||||
| #: ../src/ui/theme-parser.c:1287 | ||||
| #, c-format | ||||
| msgid "Window type \"%s\" has already been assigned a style set" | ||||
| msgstr "Venstertype ‘%s’ heeft reeds een stijlset toegewezen gekregen" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 | ||||
| #: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 | ||||
| #: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 | ||||
| #: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 | ||||
| #: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 | ||||
| #: ../src/ui/theme-parser.c:1317 ../src/ui/theme-parser.c:1381 | ||||
| #: ../src/ui/theme-parser.c:1607 ../src/ui/theme-parser.c:2842 | ||||
| #: ../src/ui/theme-parser.c:2888 ../src/ui/theme-parser.c:3038 | ||||
| #: ../src/ui/theme-parser.c:3274 ../src/ui/theme-parser.c:3312 | ||||
| #: ../src/ui/theme-parser.c:3350 ../src/ui/theme-parser.c:3388 | ||||
| #, c-format | ||||
| msgid "Element <%s> is not allowed below <%s>" | ||||
| msgstr "Element <%s> is niet toegestaan onder <%s>" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 | ||||
| #: ../src/ui/theme-parser.c:1486 | ||||
| #: ../src/ui/theme-parser.c:1431 ../src/ui/theme-parser.c:1445 | ||||
| #: ../src/ui/theme-parser.c:1490 | ||||
| msgid "" | ||||
| "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " | ||||
| "for buttons" | ||||
| @@ -1344,123 +1352,123 @@ msgstr "" | ||||
| "Kan niet tegelijk ‘button_width’/‘button_height’ en ‘aspect_ratio’ voor " | ||||
| "knoppen opgeven." | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:1450 | ||||
| #: ../src/ui/theme-parser.c:1454 | ||||
| #, c-format | ||||
| msgid "Distance \"%s\" is unknown" | ||||
| msgstr "Afstand ‘%s’ is onbekend" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:1495 | ||||
| #: ../src/ui/theme-parser.c:1499 | ||||
| #, c-format | ||||
| msgid "Aspect ratio \"%s\" is unknown" | ||||
| msgstr "Verhouding ‘%s’ is onbekend" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:1557 | ||||
| #: ../src/ui/theme-parser.c:1561 | ||||
| #, c-format | ||||
| msgid "Border \"%s\" is unknown" | ||||
| msgstr "Rand ‘%s’ is onbekend" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:1868 | ||||
| #: ../src/ui/theme-parser.c:1872 | ||||
| #, c-format | ||||
| msgid "No \"start_angle\" or \"from\" attribute on element <%s>" | ||||
| msgstr "Geen ‘start_angle’- of ‘from’-attribuut op element <%s>" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:1875 | ||||
| #: ../src/ui/theme-parser.c:1879 | ||||
| #, c-format | ||||
| msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" | ||||
| msgstr "Geen ‘extent_angle’- of ‘to’-attribuut op element <%s>" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:2115 | ||||
| #: ../src/ui/theme-parser.c:2119 | ||||
| #, c-format | ||||
| msgid "Did not understand value \"%s\" for type of gradient" | ||||
| msgstr "Niet begrepen: de waarde ‘%s’ voor type kleurverloop" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 | ||||
| #: ../src/ui/theme-parser.c:2197 ../src/ui/theme-parser.c:2572 | ||||
| #, c-format | ||||
| msgid "Did not understand fill type \"%s\" for <%s> element" | ||||
| msgstr "Niet begrepen: vul-type ‘%s’ voor <%s>-element" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 | ||||
| #: ../src/ui/theme-parser.c:2506 | ||||
| #: ../src/ui/theme-parser.c:2364 ../src/ui/theme-parser.c:2447 | ||||
| #: ../src/ui/theme-parser.c:2510 | ||||
| #, c-format | ||||
| msgid "Did not understand state \"%s\" for <%s> element" | ||||
| msgstr "Niet begrepen: status ‘%s’ voor <%s>-element" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 | ||||
| #: ../src/ui/theme-parser.c:2374 ../src/ui/theme-parser.c:2457 | ||||
| #, c-format | ||||
| msgid "Did not understand shadow \"%s\" for <%s> element" | ||||
| msgstr "Niet begrepen: schaduw ‘%s’ voor <%s>-element" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:2380 | ||||
| #: ../src/ui/theme-parser.c:2384 | ||||
| #, c-format | ||||
| msgid "Did not understand arrow \"%s\" for <%s> element" | ||||
| msgstr "Niet begrepen: pijl ‘%s’ voor <%s>-element" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 | ||||
| #: ../src/ui/theme-parser.c:2698 ../src/ui/theme-parser.c:2794 | ||||
| #, c-format | ||||
| msgid "No <draw_ops> called \"%s\" has been defined" | ||||
| msgstr "Er zijn geen <draw_ops> genaamd ‘%s’ gedefinieerd" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 | ||||
| #: ../src/ui/theme-parser.c:2710 ../src/ui/theme-parser.c:2806 | ||||
| #, c-format | ||||
| msgid "Including draw_ops \"%s\" here would create a circular reference" | ||||
| msgstr "Hier ‘draw_ops’ ‘%s’ meenemen zou een circulaire verwijzing creëren" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:2917 | ||||
| #: ../src/ui/theme-parser.c:2921 | ||||
| #, c-format | ||||
| msgid "Unknown position \"%s\" for frame piece" | ||||
| msgstr "Onbekende positie ‘%s’ voor kader-onderdeel" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:2925 | ||||
| #: ../src/ui/theme-parser.c:2929 | ||||
| #, c-format | ||||
| msgid "Frame style already has a piece at position %s" | ||||
| msgstr "Kader-stijl heeft al een onderdeel op positie %s" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 | ||||
| #: ../src/ui/theme-parser.c:2946 ../src/ui/theme-parser.c:3023 | ||||
| #, c-format | ||||
| msgid "No <draw_ops> with the name \"%s\" has been defined" | ||||
| msgstr "Er zijn geen <draw_ops> met naam ‘%s’ gedefinieerd" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:2972 | ||||
| #: ../src/ui/theme-parser.c:2976 | ||||
| #, c-format | ||||
| msgid "Unknown function \"%s\" for button" | ||||
| msgstr "Onbekende functie ‘%s’ voor knop" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:2982 | ||||
| #: ../src/ui/theme-parser.c:2986 | ||||
| #, c-format | ||||
| msgid "Button function \"%s\" does not exist in this version (%d, need %d)" | ||||
| msgstr "Knopfunctie ‘%s’ bestaat niet in deze versie (%d, %d benodigd)" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:2994 | ||||
| #: ../src/ui/theme-parser.c:2998 | ||||
| #, c-format | ||||
| msgid "Unknown state \"%s\" for button" | ||||
| msgstr "Onbekende status ‘%s’ voor knop" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3002 | ||||
| #: ../src/ui/theme-parser.c:3006 | ||||
| #, c-format | ||||
| msgid "Frame style already has a button for function %s state %s" | ||||
| msgstr "Kader-stijl heeft reeds een knop voor functie %s status %s" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3073 | ||||
| #: ../src/ui/theme-parser.c:3077 | ||||
| #, c-format | ||||
| msgid "\"%s\" is not a valid value for focus attribute" | ||||
| msgstr "‘%s’ is geen geldige waarde voor ‘focus’-attribuut" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3082 | ||||
| #: ../src/ui/theme-parser.c:3086 | ||||
| #, c-format | ||||
| msgid "\"%s\" is not a valid value for state attribute" | ||||
| msgstr "‘%s’ is geen geldige waarde voor ‘state’-attribuut" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3092 | ||||
| #: ../src/ui/theme-parser.c:3096 | ||||
| #, c-format | ||||
| msgid "A style called \"%s\" has not been defined" | ||||
| msgstr "Een stijl genaamd ‘%s’ is niet gedefinieerd" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 | ||||
| #: ../src/ui/theme-parser.c:3117 ../src/ui/theme-parser.c:3140 | ||||
| #, c-format | ||||
| msgid "\"%s\" is not a valid value for resize attribute" | ||||
| msgstr "‘%s’ is geen geldige waarde voor ‘resize’-attribuut" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3147 | ||||
| #: ../src/ui/theme-parser.c:3151 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Should not have \"resize\" attribute on <%s> element for maximized/shaded " | ||||
| @@ -1469,7 +1477,7 @@ msgstr "" | ||||
| "Behoort geen ‘resize’-attribuut te hebben op <%s>-element voor " | ||||
| "gemaximaliseerde/opgerolde toestanden" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3161 | ||||
| #: ../src/ui/theme-parser.c:3165 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Should not have \"resize\" attribute on <%s> element for maximized states" | ||||
| @@ -1477,20 +1485,20 @@ msgstr "" | ||||
| "Behoort geen ‘resize’-attribuut te hebben op <%s>-element voor " | ||||
| "gemaximaliseerde toestand" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 | ||||
| #: ../src/ui/theme-parser.c:3179 ../src/ui/theme-parser.c:3223 | ||||
| #, c-format | ||||
| msgid "Style has already been specified for state %s resize %s focus %s" | ||||
| msgstr "" | ||||
| "Stijl is reeds gespecificeerd voor status %s grootte aanpassen %s aandacht %s" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 | ||||
| #: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 | ||||
| #: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 | ||||
| #: ../src/ui/theme-parser.c:3190 ../src/ui/theme-parser.c:3201 | ||||
| #: ../src/ui/theme-parser.c:3212 ../src/ui/theme-parser.c:3234 | ||||
| #: ../src/ui/theme-parser.c:3245 ../src/ui/theme-parser.c:3256 | ||||
| #, c-format | ||||
| msgid "Style has already been specified for state %s focus %s" | ||||
| msgstr "Stijl is reeds gespecificeerd voor status %s aandacht %s" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3294 | ||||
| #: ../src/ui/theme-parser.c:3295 | ||||
| msgid "" | ||||
| "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " | ||||
| "attribute and also a <draw_ops> element, or specified two elements)" | ||||
| @@ -1499,7 +1507,7 @@ msgstr "" | ||||
| "specificeerde een ‘draw_ops’-attribuut en tevens een <draw_ops>-element, of " | ||||
| "specificeerde twee elementen)" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3332 | ||||
| #: ../src/ui/theme-parser.c:3333 | ||||
| msgid "" | ||||
| "Can't have a two draw_ops for a <button> element (theme specified a draw_ops " | ||||
| "attribute and also a <draw_ops> element, or specified two elements)" | ||||
| @@ -1508,7 +1516,7 @@ msgstr "" | ||||
| "specificeerde een ‘draw_ops’-attribuut en tevens een <draw_ops>-element, of " | ||||
| "specificeerde twee elementen)" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3370 | ||||
| #: ../src/ui/theme-parser.c:3371 | ||||
| msgid "" | ||||
| "Can't have a two draw_ops for a <menu_icon> element (theme specified a " | ||||
| "draw_ops attribute and also a <draw_ops> element, or specified two elements)" | ||||
| @@ -1517,12 +1525,12 @@ msgstr "" | ||||
| "specificeerde een ‘draw_ops’-attribuut en tevens een <draw_ops>-element, of " | ||||
| "specificeerde twee elementen)" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3434 | ||||
| #: ../src/ui/theme-parser.c:3435 | ||||
| #, c-format | ||||
| msgid "Bad version specification '%s'" | ||||
| msgstr "Foutieve opgave van versie: ‘%s’" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3507 | ||||
| #: ../src/ui/theme-parser.c:3508 | ||||
| msgid "" | ||||
| "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" | ||||
| "theme-2.xml" | ||||
| @@ -1530,18 +1538,18 @@ msgstr "" | ||||
| "Het ‘version’-attribuut kan niet gebruikt worden in metacity-theme-1.xml of " | ||||
| "metacity-theme-2.xml." | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3530 | ||||
| #: ../src/ui/theme-parser.c:3531 | ||||
| #, c-format | ||||
| msgid "Theme requires version %s but latest supported theme version is %d.%d" | ||||
| msgstr "" | ||||
| "Het thema vereist versie %s, maar de recentste ondersteunde versie is %d.%d" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3562 | ||||
| #: ../src/ui/theme-parser.c:3563 | ||||
| #, c-format | ||||
| msgid "Outermost element in theme must be <metacity_theme> not <%s>" | ||||
| msgstr "Buitenste element in thema moet zijn: <metacity_theme>, niet <%s>" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3582 | ||||
| #: ../src/ui/theme-parser.c:3583 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Element <%s> is not allowed inside a name/author/date/description element" | ||||
| @@ -1549,12 +1557,12 @@ msgstr "" | ||||
| "Element <%s> is niet toegestaan binnen een naam/auteur/datum/beschrijving " | ||||
| "element" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3587 | ||||
| #: ../src/ui/theme-parser.c:3588 | ||||
| #, c-format | ||||
| msgid "Element <%s> is not allowed inside a <constant> element" | ||||
| msgstr "Element <%s> is niet toegestaan binnen een <constant>-element" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3599 | ||||
| #: ../src/ui/theme-parser.c:3600 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Element <%s> is not allowed inside a distance/border/aspect_ratio element" | ||||
| @@ -1562,38 +1570,38 @@ msgstr "" | ||||
| "Element <%s> is niet toegestaan binnen de elementen distance/border/" | ||||
| "aspect_ratio" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3621 | ||||
| #: ../src/ui/theme-parser.c:3622 | ||||
| #, c-format | ||||
| msgid "Element <%s> is not allowed inside a draw operation element" | ||||
| msgstr "Element <%s> is niet toegestaan binnen een ‘draw operation’-element" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 | ||||
| #: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 | ||||
| #: ../src/ui/theme-parser.c:3632 ../src/ui/theme-parser.c:3662 | ||||
| #: ../src/ui/theme-parser.c:3667 ../src/ui/theme-parser.c:3672 | ||||
| #, c-format | ||||
| msgid "Element <%s> is not allowed inside a <%s> element" | ||||
| msgstr "Element <%s> is niet toegestaan binnen een <%s>-element" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3899 | ||||
| #: ../src/ui/theme-parser.c:3900 | ||||
| msgid "No draw_ops provided for frame piece" | ||||
| msgstr "Geen ‘draw_ops’ gegeven voor kader-onderdeel" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3914 | ||||
| #: ../src/ui/theme-parser.c:3915 | ||||
| msgid "No draw_ops provided for button" | ||||
| msgstr "Geen ‘draw_ops’ gegeven voor knop" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:3968 | ||||
| #: ../src/ui/theme-parser.c:3969 | ||||
| #, c-format | ||||
| msgid "No text is allowed inside element <%s>" | ||||
| msgstr "Geen tekst toegestaan binnen element <%s>" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 | ||||
| #: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 | ||||
| #: ../src/ui/theme-parser.c:4074 | ||||
| #: ../src/ui/theme-parser.c:4027 ../src/ui/theme-parser.c:4039 | ||||
| #: ../src/ui/theme-parser.c:4051 ../src/ui/theme-parser.c:4063 | ||||
| #: ../src/ui/theme-parser.c:4075 | ||||
| #, c-format | ||||
| msgid "<%s> specified twice for this theme" | ||||
| msgstr "<%s> twee keer gegeven voor dit thema" | ||||
|  | ||||
| #: ../src/ui/theme-parser.c:4336 | ||||
| #: ../src/ui/theme-parser.c:4337 | ||||
| #, c-format | ||||
| msgid "Failed to find a valid file for theme %s\n" | ||||
| msgstr "Geen geldig bestand gevonden voor thema %s\n" | ||||
|   | ||||
							
								
								
									
										1197
									
								
								po/zh_CN.po
									
									
									
									
									
								
							
							
						
						
									
										1197
									
								
								po/zh_CN.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -64,6 +64,8 @@ libmutter_la_SOURCES =				\ | ||||
| 	compositor/meta-shadow-factory.c	\ | ||||
| 	compositor/meta-shadow-factory-private.h	\ | ||||
| 	compositor/meta-shaped-texture.c	\ | ||||
| 	compositor/meta-sync-ring.c		\ | ||||
| 	compositor/meta-sync-ring.h		\ | ||||
| 	compositor/meta-texture-rectangle.c	\ | ||||
| 	compositor/meta-texture-rectangle.h	\ | ||||
| 	compositor/meta-texture-tower.c		\ | ||||
|   | ||||
| @@ -19,7 +19,8 @@ struct _MetaCompositor | ||||
|  | ||||
|   Atom            atom_x_root_pixmap; | ||||
|   Atom            atom_net_wm_window_opacity; | ||||
|   guint           repaint_func_id; | ||||
|   guint           pre_paint_func_id; | ||||
|   guint           post_paint_func_id; | ||||
|  | ||||
|   ClutterActor   *shadow_src; | ||||
|  | ||||
| @@ -32,6 +33,9 @@ struct _MetaCompositor | ||||
|   guint           show_redraw : 1; | ||||
|   guint           debug       : 1; | ||||
|   guint           no_mipmaps  : 1; | ||||
|  | ||||
|   gboolean frame_has_updated_xsurfaces; | ||||
|   gboolean have_x11_sync_object; | ||||
| }; | ||||
|  | ||||
| struct _MetaCompScreen | ||||
|   | ||||
| @@ -86,6 +86,7 @@ | ||||
| #include "display-private.h" /* for meta_display_lookup_x_window() */ | ||||
| #include <X11/extensions/shape.h> | ||||
| #include <X11/extensions/Xcomposite.h> | ||||
| #include "meta-sync-ring.h" | ||||
|  | ||||
| /* #define DEBUG_TRACE g_print */ | ||||
| #define DEBUG_TRACE(X) | ||||
| @@ -142,7 +143,11 @@ meta_switch_workspace_completed (MetaScreen *screen) | ||||
| void | ||||
| meta_compositor_destroy (MetaCompositor *compositor) | ||||
| { | ||||
|   clutter_threads_remove_repaint_func (compositor->repaint_func_id); | ||||
|   clutter_threads_remove_repaint_func (compositor->pre_paint_func_id); | ||||
|   clutter_threads_remove_repaint_func (compositor->post_paint_func_id); | ||||
|  | ||||
|   if (compositor->have_x11_sync_object) | ||||
|     meta_sync_ring_destroy (); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -173,6 +178,8 @@ process_damage (MetaCompositor     *compositor, | ||||
|     return; | ||||
|  | ||||
|   meta_window_actor_process_damage (window_actor, event); | ||||
|  | ||||
|   compositor->frame_has_updated_xsurfaces = TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -719,6 +726,8 @@ meta_compositor_manage_screen (MetaCompositor *compositor, | ||||
|    */ | ||||
|   XMapWindow (xdisplay, info->output); | ||||
|  | ||||
|   compositor->have_x11_sync_object = meta_sync_ring_init (display); | ||||
|  | ||||
|   redirect_windows (compositor, screen); | ||||
| } | ||||
|  | ||||
| @@ -1019,6 +1028,10 @@ meta_compositor_process_event (MetaCompositor *compositor, | ||||
|   if (event->type == MapNotify) | ||||
|     clutter_x11_handle_event (event); | ||||
|  | ||||
|   if (compositor->have_x11_sync_object && | ||||
|       event->type == (compositor->display->xsync_event_base + XSyncAlarmNotify)) | ||||
|     meta_sync_ring_handle_event ((XSyncAlarmNotifyEvent *) event); | ||||
|  | ||||
|   /* The above handling is basically just "observing" the events, so we return | ||||
|    * FALSE to indicate that the event should not be filtered out; if we have | ||||
|    * GTK+ windows in the same process, GTK+ needs the ConfigureNotify event, for example. | ||||
| @@ -1468,7 +1481,7 @@ pre_paint_windows (MetaCompScreen *info) | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_repaint_func (gpointer data) | ||||
| meta_pre_paint_func (gpointer data) | ||||
| { | ||||
|   MetaCompositor *compositor = data; | ||||
|   GSList *screens = meta_display_get_screens (compositor->display); | ||||
| @@ -1484,6 +1497,52 @@ meta_repaint_func (gpointer data) | ||||
|       pre_paint_windows (info); | ||||
|     } | ||||
|  | ||||
|   if (compositor->frame_has_updated_xsurfaces) | ||||
|     { | ||||
|       /* We need to make sure that any X drawing that happens before | ||||
|        * the XDamageSubtract() for each window above is visible to | ||||
|        * subsequent GL rendering; the standardized way to do this is | ||||
|        * GL_EXT_X11_sync_object. Since this isn't implemented yet in | ||||
|        * mesa, we also have a path that relies on the implementation | ||||
|        * of the open source drivers. | ||||
|        * | ||||
|        * Anything else, we just hope for the best. | ||||
|        * | ||||
|        * Xorg and open source driver specifics: | ||||
|        * | ||||
|        * The X server makes sure to flush drawing to the kernel before | ||||
|        * sending out damage events, but since we use | ||||
|        * DamageReportBoundingBox there may be drawing between the last | ||||
|        * damage event and the XDamageSubtract() that needs to be | ||||
|        * flushed as well. | ||||
|        * | ||||
|        * Xorg always makes sure that drawing is flushed to the kernel | ||||
|        * before writing events or responses to the client, so any | ||||
|        * round trip request at this point is sufficient to flush the | ||||
|        * GLX buffers. | ||||
|        */ | ||||
|       if (compositor->have_x11_sync_object) | ||||
|         compositor->have_x11_sync_object = meta_sync_ring_insert_wait (); | ||||
|       else | ||||
|         XSync (compositor->display->xdisplay, False); | ||||
|     } | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_post_paint_func (gpointer data) | ||||
| { | ||||
|   MetaCompositor *compositor = data; | ||||
|  | ||||
|   if (compositor->frame_has_updated_xsurfaces) | ||||
|     { | ||||
|       if (compositor->have_x11_sync_object) | ||||
|         compositor->have_x11_sync_object = meta_sync_ring_after_frame (); | ||||
|  | ||||
|       compositor->frame_has_updated_xsurfaces = FALSE; | ||||
|     } | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| @@ -1545,10 +1604,16 @@ meta_compositor_new (MetaDisplay *display) | ||||
|   compositor->atom_x_root_pixmap = atoms[0]; | ||||
|   compositor->atom_net_wm_window_opacity = atoms[1]; | ||||
|  | ||||
|   compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func, | ||||
|                                                                   compositor, | ||||
|                                                                   NULL); | ||||
|  | ||||
|   compositor->pre_paint_func_id = | ||||
|     clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_PRE_PAINT, | ||||
|                                            meta_pre_paint_func, | ||||
|                                            compositor, | ||||
|                                            NULL); | ||||
|   compositor->post_paint_func_id = | ||||
|     clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT, | ||||
|                                            meta_post_paint_func, | ||||
|                                            compositor, | ||||
|                                            NULL); | ||||
|   return compositor; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										526
									
								
								src/compositor/meta-sync-ring.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										526
									
								
								src/compositor/meta-sync-ring.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,526 @@ | ||||
| /* | ||||
|  * This is based on an original C++ implementation for compiz that | ||||
|  * carries the following copyright notice: | ||||
|  * | ||||
|  * | ||||
|  * Copyright © 2011 NVIDIA Corporation | ||||
|  * | ||||
|  * Permission to use, copy, modify, distribute, and sell this software | ||||
|  * and its documentation for any purpose is hereby granted without | ||||
|  * fee, provided that the above copyright notice appear in all copies | ||||
|  * and that both that copyright notice and this permission notice | ||||
|  * appear in supporting documentation, and that the name of NVIDIA | ||||
|  * Corporation not be used in advertising or publicity pertaining to | ||||
|  * distribution of the software without specific, written prior | ||||
|  * permission.  NVIDIA Corporation makes no representations about the | ||||
|  * suitability of this software for any purpose. It is provided "as | ||||
|  * is" without express or implied warranty. | ||||
|  * | ||||
|  * NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS | ||||
|  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||||
|  * FITNESS, IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY | ||||
|  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | ||||
|  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING | ||||
|  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||||
|  * SOFTWARE. | ||||
|  * | ||||
|  * Authors: James Jones <jajones@nvidia.com> | ||||
|  */ | ||||
|  | ||||
| #include <string.h> | ||||
|  | ||||
| #include <GL/gl.h> | ||||
| #include <GL/glx.h> | ||||
|  | ||||
| #include <cogl/cogl.h> | ||||
|  | ||||
| #include <meta/display.h> | ||||
| #include <meta/util.h> | ||||
|  | ||||
| #include "meta-sync-ring.h" | ||||
|  | ||||
| /* Theory of operation: | ||||
|  * | ||||
|  * We use a ring of NUM_SYNCS fence objects. On each frame we advance | ||||
|  * to the next fence in the ring. For each fence we do: | ||||
|  * | ||||
|  * 1. fence is XSyncTriggerFence()'d and glWaitSync()'d | ||||
|  * 2. NUM_SYNCS / 2 frames later, fence should be triggered | ||||
|  * 3. fence is XSyncResetFence()'d | ||||
|  * 4. NUM_SYNCS / 2 frames later, fence should be reset | ||||
|  * 5. go back to 1 and re-use fence | ||||
|  * | ||||
|  * glClientWaitSync() and XAlarms are used in steps 2 and 4, | ||||
|  * respectively, to double-check the expectections. | ||||
|  */ | ||||
|  | ||||
| #define NUM_SYNCS 10 | ||||
| #define MAX_SYNC_WAIT_TIME (1 * 1000 * 1000 * 1000) /* one sec */ | ||||
| #define MAX_REBOOT_ATTEMPTS 2 | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   META_SYNC_STATE_READY, | ||||
|   META_SYNC_STATE_WAITING, | ||||
|   META_SYNC_STATE_DONE, | ||||
|   META_SYNC_STATE_RESET_PENDING, | ||||
| } MetaSyncState; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   Display *xdisplay; | ||||
|  | ||||
|   XSyncFence xfence; | ||||
|   GLsync glsync; | ||||
|  | ||||
|   XSyncCounter xcounter; | ||||
|   XSyncAlarm xalarm; | ||||
|   XSyncValue next_counter_value; | ||||
|  | ||||
|   MetaSyncState state; | ||||
| } MetaSync; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   MetaDisplay *display; | ||||
|  | ||||
|   GHashTable *alarm_to_sync; | ||||
|  | ||||
|   MetaSync *syncs_array[NUM_SYNCS]; | ||||
|   guint current_sync_idx; | ||||
|   MetaSync *current_sync; | ||||
|   guint warmup_syncs; | ||||
|  | ||||
|   guint reboots; | ||||
| } MetaSyncRing; | ||||
|  | ||||
| static MetaSyncRing meta_sync_ring = { 0 }; | ||||
|  | ||||
| static XSyncValue SYNC_VALUE_ZERO; | ||||
| static XSyncValue SYNC_VALUE_ONE; | ||||
|  | ||||
| static void             (*meta_gl_get_integerv) (GLenum  pname, | ||||
|                                                  GLint  *params); | ||||
| static const char*      (*meta_gl_get_stringi) (GLenum name, | ||||
|                                                 GLuint index); | ||||
| static void             (*meta_gl_delete_sync) (GLsync sync); | ||||
| static GLenum           (*meta_gl_client_wait_sync) (GLsync sync, | ||||
|                                                      GLbitfield flags, | ||||
|                                                      GLuint64 timeout); | ||||
| static void             (*meta_gl_wait_sync) (GLsync sync, | ||||
|                                               GLbitfield flags, | ||||
|                                               GLuint64 timeout); | ||||
| static GLsync           (*meta_gl_import_sync) (GLenum external_sync_type, | ||||
|                                                 GLintptr external_sync, | ||||
|                                                 GLbitfield flags); | ||||
|  | ||||
| static MetaSyncRing * | ||||
| meta_sync_ring_get (void) | ||||
| { | ||||
|   if (meta_sync_ring.reboots > MAX_REBOOT_ATTEMPTS) | ||||
|     return NULL; | ||||
|  | ||||
|   return &meta_sync_ring; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| load_gl_symbol (const char  *name, | ||||
|                 void       **func) | ||||
| { | ||||
|   *func = cogl_get_proc_address (name); | ||||
|   if (!*func) | ||||
|     { | ||||
|       meta_verbose ("MetaSyncRing: failed to resolve required GL symbol \"%s\"\n", name); | ||||
|       return FALSE; | ||||
|     } | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| check_gl_extensions (void) | ||||
| { | ||||
|   int num_extensions, i; | ||||
|   gboolean sync = FALSE; | ||||
|   gboolean x11_sync_object = FALSE; | ||||
|  | ||||
|   meta_gl_get_integerv (GL_NUM_EXTENSIONS, &num_extensions); | ||||
|  | ||||
|   for (i = 0; i < num_extensions; ++i) | ||||
|     { | ||||
|       const char *ext = meta_gl_get_stringi (GL_EXTENSIONS, i); | ||||
|  | ||||
|       if (g_strcmp0 ("GL_ARB_sync", ext) == 0) | ||||
|         sync = TRUE; | ||||
|       else if (g_strcmp0 ("GL_EXT_x11_sync_object", ext) == 0) | ||||
|         x11_sync_object = TRUE; | ||||
|     } | ||||
|  | ||||
|   return sync && x11_sync_object; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| load_required_symbols (void) | ||||
| { | ||||
|   static gboolean success = FALSE; | ||||
|  | ||||
|   if (success) | ||||
|     return TRUE; | ||||
|  | ||||
|   /* We don't link against libGL directly because cogl may want to | ||||
|    * use something else. This assumes that cogl has been initialized | ||||
|    * and dynamically loaded libGL at this point. | ||||
|    */ | ||||
|  | ||||
|   if (!load_gl_symbol ("glGetIntegerv", (void **) &meta_gl_get_integerv)) | ||||
|     goto out; | ||||
|   if (!load_gl_symbol ("glGetStringi", (void **) &meta_gl_get_stringi)) | ||||
|     goto out; | ||||
|  | ||||
|   if (!check_gl_extensions ()) | ||||
|     { | ||||
|       meta_verbose ("MetaSyncRing: couldn't find required GL extensions\n"); | ||||
|       goto out; | ||||
|     } | ||||
|  | ||||
|   if (!load_gl_symbol ("glDeleteSync", (void **) &meta_gl_delete_sync)) | ||||
|     goto out; | ||||
|   if (!load_gl_symbol ("glClientWaitSync", (void **) &meta_gl_client_wait_sync)) | ||||
|     goto out; | ||||
|   if (!load_gl_symbol ("glWaitSync", (void **) &meta_gl_wait_sync)) | ||||
|     goto out; | ||||
|   if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync)) | ||||
|     goto out; | ||||
|  | ||||
|   success = TRUE; | ||||
|  out: | ||||
|   return success; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_sync_insert (MetaSync *self) | ||||
| { | ||||
|   g_return_if_fail (self->state == META_SYNC_STATE_READY); | ||||
|  | ||||
|   XSyncTriggerFence (self->xdisplay, self->xfence); | ||||
|   XFlush (self->xdisplay); | ||||
|  | ||||
|   meta_gl_wait_sync (self->glsync, 0, GL_TIMEOUT_IGNORED); | ||||
|  | ||||
|   self->state = META_SYNC_STATE_WAITING; | ||||
| } | ||||
|  | ||||
| static GLenum | ||||
| meta_sync_check_update_finished (MetaSync *self, | ||||
|                                  GLuint64  timeout) | ||||
| { | ||||
|   GLenum status = GL_WAIT_FAILED; | ||||
|  | ||||
|   switch (self->state) | ||||
|     { | ||||
|     case META_SYNC_STATE_DONE: | ||||
|       status = GL_ALREADY_SIGNALED; | ||||
|       break; | ||||
|     case META_SYNC_STATE_WAITING: | ||||
|       status = meta_gl_client_wait_sync (self->glsync, 0, timeout); | ||||
|       if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED) | ||||
|         self->state = META_SYNC_STATE_DONE; | ||||
|       break; | ||||
|     default: | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   g_warn_if_fail (status != GL_WAIT_FAILED); | ||||
|  | ||||
|   return status; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_sync_reset (MetaSync *self) | ||||
| { | ||||
|   XSyncAlarmAttributes attrs; | ||||
|   int overflow; | ||||
|  | ||||
|   g_return_if_fail (self->state == META_SYNC_STATE_DONE); | ||||
|  | ||||
|   XSyncResetFence (self->xdisplay, self->xfence); | ||||
|  | ||||
|   attrs.trigger.wait_value = self->next_counter_value; | ||||
|  | ||||
|   XSyncChangeAlarm (self->xdisplay, self->xalarm, XSyncCAValue, &attrs); | ||||
|   XSyncSetCounter (self->xdisplay, self->xcounter, self->next_counter_value); | ||||
|  | ||||
|   XSyncValueAdd (&self->next_counter_value, | ||||
|                  self->next_counter_value, | ||||
|                  SYNC_VALUE_ONE, | ||||
|                  &overflow); | ||||
|  | ||||
|   self->state = META_SYNC_STATE_RESET_PENDING; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_sync_handle_event (MetaSync              *self, | ||||
|                         XSyncAlarmNotifyEvent *event) | ||||
| { | ||||
|   g_return_if_fail (event->alarm == self->xalarm); | ||||
|   g_return_if_fail (self->state == META_SYNC_STATE_RESET_PENDING); | ||||
|  | ||||
|   self->state = META_SYNC_STATE_READY; | ||||
| } | ||||
|  | ||||
| static MetaSync * | ||||
| meta_sync_new (Display *xdisplay) | ||||
| { | ||||
|   MetaSync *self; | ||||
|   XSyncAlarmAttributes attrs; | ||||
|  | ||||
|   self = g_malloc0 (sizeof (MetaSync)); | ||||
|  | ||||
|   self->xdisplay = xdisplay; | ||||
|  | ||||
|   self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), FALSE); | ||||
|   self->glsync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0); | ||||
|  | ||||
|   self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO); | ||||
|  | ||||
|   attrs.trigger.counter = self->xcounter; | ||||
|   attrs.trigger.value_type = XSyncAbsolute; | ||||
|   attrs.trigger.wait_value = SYNC_VALUE_ONE; | ||||
|   attrs.trigger.test_type = XSyncPositiveTransition; | ||||
|   attrs.events = TRUE; | ||||
|   self->xalarm = XSyncCreateAlarm (xdisplay, | ||||
|                                    XSyncCACounter | | ||||
|                                    XSyncCAValueType | | ||||
|                                    XSyncCAValue | | ||||
|                                    XSyncCATestType | | ||||
|                                    XSyncCAEvents, | ||||
|                                    &attrs); | ||||
|  | ||||
|   XSyncIntToValue (&self->next_counter_value, 1); | ||||
|  | ||||
|   self->state = META_SYNC_STATE_READY; | ||||
|  | ||||
|   return self; | ||||
| } | ||||
|  | ||||
| static Bool | ||||
| alarm_event_predicate (Display  *dpy, | ||||
|                        XEvent   *event, | ||||
|                        XPointer  data) | ||||
| { | ||||
|   int xsync_event_base; | ||||
|   MetaSyncRing *ring = meta_sync_ring_get (); | ||||
|  | ||||
|   if (!ring) | ||||
|     return False; | ||||
|  | ||||
|   xsync_event_base = meta_display_get_sync_event_base (ring->display); | ||||
|  | ||||
|   if (event->type == xsync_event_base + XSyncAlarmNotify) | ||||
|     { | ||||
|       if (((MetaSync *) data)->xalarm == ((XSyncAlarmNotifyEvent *) event)->alarm) | ||||
|         return True; | ||||
|     } | ||||
|   return False; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_sync_free (MetaSync *self) | ||||
| { | ||||
|   /* When our assumptions don't hold, something has gone wrong but we | ||||
|    * don't know what, so we reboot the ring. While doing that, we | ||||
|    * trigger fences before deleting them to try to get ourselves out | ||||
|    * of a potentially stuck GPU state. | ||||
|    */ | ||||
|   switch (self->state) | ||||
|     { | ||||
|     case META_SYNC_STATE_WAITING: | ||||
|     case META_SYNC_STATE_DONE: | ||||
|       /* nothing to do */ | ||||
|       break; | ||||
|     case META_SYNC_STATE_RESET_PENDING: | ||||
|       { | ||||
|         XEvent event; | ||||
|         XIfEvent (self->xdisplay, &event, alarm_event_predicate, (XPointer) self); | ||||
|         meta_sync_handle_event (self, (XSyncAlarmNotifyEvent *) &event); | ||||
|       } | ||||
|       /* fall through */ | ||||
|     case META_SYNC_STATE_READY: | ||||
|       XSyncTriggerFence (self->xdisplay, self->xfence); | ||||
|       XFlush (self->xdisplay); | ||||
|       break; | ||||
|     default: | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   meta_gl_delete_sync (self->glsync); | ||||
|   XSyncDestroyFence (self->xdisplay, self->xfence); | ||||
|   XSyncDestroyCounter (self->xdisplay, self->xcounter); | ||||
|   XSyncDestroyAlarm (self->xdisplay, self->xalarm); | ||||
|  | ||||
|   g_free (self); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_sync_ring_init (MetaDisplay *display) | ||||
| { | ||||
|   guint i; | ||||
|   MetaSyncRing *ring = meta_sync_ring_get (); | ||||
|  | ||||
|   if (!ring) | ||||
|     return FALSE; | ||||
|  | ||||
|   g_return_val_if_fail (display != NULL, FALSE); | ||||
|   g_return_val_if_fail (ring->display == NULL, FALSE); | ||||
|  | ||||
|   if (!load_required_symbols ()) | ||||
|     return FALSE; | ||||
|  | ||||
|   if (!meta_display_has_sync (display)) | ||||
|     return FALSE; | ||||
|  | ||||
|   XSyncIntToValue (&SYNC_VALUE_ZERO, 0); | ||||
|   XSyncIntToValue (&SYNC_VALUE_ONE, 1); | ||||
|  | ||||
|   ring->display = display; | ||||
|  | ||||
|   ring->alarm_to_sync = g_hash_table_new (NULL, NULL); | ||||
|  | ||||
|   for (i = 0; i < NUM_SYNCS; ++i) | ||||
|     { | ||||
|       MetaSync *sync = meta_sync_new (meta_display_get_xdisplay (display)); | ||||
|       ring->syncs_array[i] = sync; | ||||
|       g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, sync); | ||||
|     } | ||||
|  | ||||
|   ring->current_sync_idx = 0; | ||||
|   ring->current_sync = ring->syncs_array[0]; | ||||
|   ring->warmup_syncs = 0; | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_sync_ring_destroy (void) | ||||
| { | ||||
|   guint i; | ||||
|   MetaSyncRing *ring = meta_sync_ring_get (); | ||||
|  | ||||
|   if (!ring) | ||||
|     return; | ||||
|  | ||||
|   g_return_if_fail (ring->display != NULL); | ||||
|  | ||||
|   ring->current_sync_idx = 0; | ||||
|   ring->current_sync = NULL; | ||||
|   ring->warmup_syncs = 0; | ||||
|  | ||||
|   for (i = 0; i < NUM_SYNCS; ++i) | ||||
|     meta_sync_free (ring->syncs_array[i]); | ||||
|  | ||||
|   g_hash_table_destroy (ring->alarm_to_sync); | ||||
|  | ||||
|   ring->display = NULL; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_sync_ring_reboot (MetaDisplay *display) | ||||
| { | ||||
|   MetaSyncRing *ring = meta_sync_ring_get (); | ||||
|  | ||||
|   if (!ring) | ||||
|     return FALSE; | ||||
|  | ||||
|   meta_sync_ring_destroy (); | ||||
|  | ||||
|   ring->reboots += 1; | ||||
|  | ||||
|   if (!meta_sync_ring_get ()) | ||||
|     { | ||||
|       meta_warning ("MetaSyncRing: Too many reboots -- disabling\n"); | ||||
|       return FALSE; | ||||
|     } | ||||
|  | ||||
|   return meta_sync_ring_init (display); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_sync_ring_after_frame (void) | ||||
| { | ||||
|   MetaSyncRing *ring = meta_sync_ring_get (); | ||||
|  | ||||
|   if (!ring) | ||||
|     return FALSE; | ||||
|  | ||||
|   g_return_if_fail (ring->display != NULL); | ||||
|  | ||||
|   if (ring->warmup_syncs >= NUM_SYNCS / 2) | ||||
|     { | ||||
|       guint reset_sync_idx = (ring->current_sync_idx + NUM_SYNCS - (NUM_SYNCS / 2)) % NUM_SYNCS; | ||||
|       MetaSync *sync_to_reset = ring->syncs_array[reset_sync_idx]; | ||||
|  | ||||
|       GLenum status = meta_sync_check_update_finished (sync_to_reset, 0); | ||||
|       if (status == GL_TIMEOUT_EXPIRED) | ||||
|         { | ||||
|           meta_warning ("MetaSyncRing: We should never wait for a sync -- add more syncs?\n"); | ||||
|           status = meta_sync_check_update_finished (sync_to_reset, MAX_SYNC_WAIT_TIME); | ||||
|         } | ||||
|  | ||||
|       if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED) | ||||
|         { | ||||
|           meta_warning ("MetaSyncRing: Timed out waiting for sync object.\n"); | ||||
|           return meta_sync_ring_reboot (ring->display); | ||||
|         } | ||||
|  | ||||
|       meta_sync_reset (sync_to_reset); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       ring->warmup_syncs += 1; | ||||
|     } | ||||
|  | ||||
|   ring->current_sync_idx += 1; | ||||
|   ring->current_sync_idx %= NUM_SYNCS; | ||||
|  | ||||
|   ring->current_sync = ring->syncs_array[ring->current_sync_idx]; | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_sync_ring_insert_wait (void) | ||||
| { | ||||
|   MetaSyncRing *ring = meta_sync_ring_get (); | ||||
|  | ||||
|   if (!ring) | ||||
|     return FALSE; | ||||
|  | ||||
|   g_return_if_fail (ring->display != NULL); | ||||
|  | ||||
|   if (ring->current_sync->state != META_SYNC_STATE_READY) | ||||
|     { | ||||
|       meta_warning ("MetaSyncRing: Sync object is not ready -- were events handled properly?\n"); | ||||
|       if (!meta_sync_ring_reboot (ring->display)) | ||||
|         return FALSE; | ||||
|     } | ||||
|  | ||||
|   meta_sync_insert (ring->current_sync); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_sync_ring_handle_event (XSyncAlarmNotifyEvent *event) | ||||
| { | ||||
|   MetaSync *sync; | ||||
|   MetaSyncRing *ring = meta_sync_ring_get (); | ||||
|  | ||||
|   if (!ring) | ||||
|     return; | ||||
|  | ||||
|   g_return_if_fail (ring->display != NULL); | ||||
|  | ||||
|   sync = g_hash_table_lookup (ring->alarm_to_sync, (gpointer) event->alarm); | ||||
|   if (sync) | ||||
|     meta_sync_handle_event (sync, event); | ||||
| } | ||||
							
								
								
									
										17
									
								
								src/compositor/meta-sync-ring.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/compositor/meta-sync-ring.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| #ifndef _META_SYNC_RING_H_ | ||||
| #define _META_SYNC_RING_H_ | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| #include <X11/Xlib.h> | ||||
| #include <X11/extensions/sync.h> | ||||
|  | ||||
| #include <meta/display.h> | ||||
|  | ||||
| gboolean meta_sync_ring_init (MetaDisplay *dpy); | ||||
| void meta_sync_ring_destroy (void); | ||||
| gboolean meta_sync_ring_after_frame (void); | ||||
| gboolean meta_sync_ring_insert_wait (void); | ||||
| void meta_sync_ring_handle_event (XSyncAlarmNotifyEvent *event); | ||||
|  | ||||
| #endif  /* _META_SYNC_RING_H_ */ | ||||
| @@ -734,8 +734,12 @@ meta_window_actor_get_paint_volume (ClutterActor       *actor, | ||||
|       gdk_rectangle_union (&bounds, &shadow_bounds, &bounds); | ||||
|     } | ||||
|  | ||||
|   if (priv->unobscured_region) | ||||
|     cairo_region_intersect_rectangle (priv->unobscured_region, &bounds); | ||||
|   if (priv->unobscured_region && !clutter_actor_has_mapped_clones (actor)) | ||||
|     { | ||||
|       cairo_rectangle_int_t unobscured_bounds; | ||||
|       cairo_region_get_extents (priv->unobscured_region, &unobscured_bounds); | ||||
|       gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds); | ||||
|     } | ||||
|  | ||||
|   origin.x = bounds.x; | ||||
|   origin.y = bounds.y; | ||||
| @@ -1395,6 +1399,12 @@ meta_window_actor_destroy (MetaWindowActor *self) | ||||
|   window_type = meta_window_get_window_type (window); | ||||
|   meta_window_set_compositor_private (window, NULL); | ||||
|  | ||||
|   if (priv->send_frame_messages_timer != 0) | ||||
|     { | ||||
|       g_source_remove (priv->send_frame_messages_timer); | ||||
|       priv->send_frame_messages_timer = 0; | ||||
|     } | ||||
|  | ||||
|   /* | ||||
|    * We remove the window from internal lookup hashes and thus any other | ||||
|    * unmap events etc fail | ||||
| @@ -2219,7 +2229,8 @@ build_and_scan_frame_mask (MetaWindowActor       *self, | ||||
|  | ||||
|   meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor), | ||||
|                                         mask_texture); | ||||
|   cogl_object_unref (mask_texture); | ||||
|   if (mask_texture) | ||||
|     cogl_object_unref (mask_texture); | ||||
|  | ||||
|   g_free (mask_data); | ||||
| } | ||||
| @@ -2365,26 +2376,6 @@ meta_window_actor_handle_updates (MetaWindowActor *self) | ||||
|       XDamageSubtract (xdisplay, priv->damage, None, None); | ||||
|       meta_error_trap_pop (display); | ||||
|  | ||||
|       /* We need to make sure that any X drawing that happens before the | ||||
|        * XDamageSubtract() above is visible to subsequent GL rendering; | ||||
|        * the only standardized way to do this is EXT_x11_sync_object, | ||||
|        * which isn't yet widely available. For now, we count on details | ||||
|        * of Xorg and the open source drivers, and hope for the best | ||||
|        * otherwise. | ||||
|        * | ||||
|        * Xorg and open source driver specifics: | ||||
|        * | ||||
|        * The X server makes sure to flush drawing to the kernel before | ||||
|        * sending out damage events, but since we use DamageReportBoundingBox | ||||
|        * there may be drawing between the last damage event and the | ||||
|        * XDamageSubtract() that needs to be flushed as well. | ||||
|        * | ||||
|        * Xorg always makes sure that drawing is flushed to the kernel | ||||
|        * before writing events or responses to the client, so any round trip | ||||
|        * request at this point is sufficient to flush the GLX buffers. | ||||
|        */ | ||||
|       XSync (xdisplay, False); | ||||
|  | ||||
|       priv->received_damage = FALSE; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -277,11 +277,30 @@ meta_window_group_paint (ClutterActor *actor) | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* Adapted from clutter_actor_update_default_paint_volume() */ | ||||
| static gboolean | ||||
| meta_window_group_get_paint_volume (ClutterActor       *actor, | ||||
| meta_window_group_get_paint_volume (ClutterActor       *self, | ||||
|                                     ClutterPaintVolume *volume) | ||||
| { | ||||
|   return clutter_paint_volume_set_from_allocation (volume, actor); | ||||
|   ClutterActorIter iter; | ||||
|   ClutterActor *child; | ||||
|  | ||||
|   clutter_actor_iter_init (&iter, self); | ||||
|   while (clutter_actor_iter_next (&iter, &child)) | ||||
|     { | ||||
|       const ClutterPaintVolume *child_volume; | ||||
|  | ||||
|       if (!CLUTTER_ACTOR_IS_MAPPED (child)) | ||||
|         continue; | ||||
|  | ||||
|       child_volume = clutter_actor_get_transformed_paint_volume (child, self); | ||||
|       if (child_volume == NULL) | ||||
|         return FALSE; | ||||
|  | ||||
|       clutter_paint_volume_union (volume, child_volume); | ||||
|     } | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
|   | ||||
| @@ -1390,7 +1390,6 @@ constrain_titlebar_visible (MetaWindow         *window, | ||||
|       window->type == META_WINDOW_DOCK    || | ||||
|       window->fullscreen                  || | ||||
|       !window->require_titlebar_visible   || | ||||
|       !window->decorated                  || | ||||
|       unconstrained_user_action) | ||||
|     return TRUE; | ||||
|  | ||||
|   | ||||
| @@ -138,6 +138,14 @@ struct _MetaDisplay | ||||
|    */ | ||||
|   guint allow_terminal_deactivation : 1; | ||||
|  | ||||
|   /* If true, server->focus_serial refers to us changing the focus; in | ||||
|    * this case, we can ignore focus events that have exactly focus_serial, | ||||
|    * since we take care to make another request immediately afterwards. | ||||
|    * But if focus is being changed by another client, we have to accept | ||||
|    * multiple events with the same serial. | ||||
|    */ | ||||
|   guint focused_by_us : 1; | ||||
|  | ||||
|   guint static_gravity_works : 1; | ||||
|    | ||||
|   /*< private-ish >*/ | ||||
|   | ||||
| @@ -925,8 +925,6 @@ meta_display_open (void) | ||||
|  | ||||
|   enable_compositor (the_display); | ||||
|     | ||||
|   meta_display_grab (the_display); | ||||
|    | ||||
|   /* Now manage all existing windows */ | ||||
|   tmp = the_display->screens; | ||||
|   while (tmp != NULL) | ||||
| @@ -978,8 +976,6 @@ meta_display_open (void) | ||||
|  | ||||
|   meta_idle_monitor_init_dbus (); | ||||
|  | ||||
|   meta_display_ungrab (the_display); | ||||
|  | ||||
|   /* Done opening new display */ | ||||
|   the_display->display_opening = FALSE; | ||||
|  | ||||
| @@ -1224,7 +1220,18 @@ meta_display_screen_for_x_screen (MetaDisplay *display, | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| /* Grab/ungrab routines taken from fvwm */ | ||||
| /* Grab/ungrab routines taken from fvwm. | ||||
|  * Calling this function will cause X to ignore all other clients until | ||||
|  * you ungrab. This may not be quite as bad as it sounds, yet there is | ||||
|  * agreement that avoiding server grabs except when they are clearly needed | ||||
|  * is a good thing. | ||||
|  * | ||||
|  * If you do use such grabs, please clearly explain the necessity for their | ||||
|  * usage in a comment. Try to keep their scope extremely limited. In | ||||
|  * particular, try to avoid emitting any signals or notifications while | ||||
|  * a grab is active (if the signal receiver tries to block on an X request | ||||
|  * from another client at this point, you will have a deadlock). | ||||
|  */ | ||||
| void | ||||
| meta_display_grab (MetaDisplay *display) | ||||
| { | ||||
| @@ -1890,9 +1897,11 @@ static void | ||||
| update_focus_window (MetaDisplay *display, | ||||
|                      MetaWindow  *window, | ||||
|                      Window       xwindow, | ||||
|                      gulong       serial) | ||||
|                      gulong       serial, | ||||
|                      gboolean     focused_by_us) | ||||
| { | ||||
|   display->focus_serial = serial; | ||||
|   display->focused_by_us = focused_by_us; | ||||
|  | ||||
|   if (display->focus_xwindow == xwindow) | ||||
|     return; | ||||
| @@ -2003,7 +2012,8 @@ request_xserver_input_focus_change (MetaDisplay *display, | ||||
|   update_focus_window (display, | ||||
|                        meta_window, | ||||
|                        xwindow, | ||||
|                        serial); | ||||
|                        serial, | ||||
|                        TRUE); | ||||
|  | ||||
|   meta_error_trap_pop (display); | ||||
|  | ||||
| @@ -2117,12 +2127,20 @@ handle_window_focus_event (MetaDisplay  *display, | ||||
|   else | ||||
|     g_return_if_reached (); | ||||
|  | ||||
|   if (display->server_focus_serial > display->focus_serial) | ||||
|   /* If display->focused_by_us, then the focus_serial will be used only | ||||
|    * for a focus change we made and have already accounted for. | ||||
|    * (See request_xserver_input_focus_change().) Otherwise, we can get | ||||
|    * multiple focus events with the same serial. | ||||
|    */ | ||||
|   if (display->server_focus_serial > display->focus_serial || | ||||
|       (!display->focused_by_us && | ||||
|        display->server_focus_serial == display->focus_serial)) | ||||
|     { | ||||
|       update_focus_window (display, | ||||
|                            focus_window, | ||||
|                            focus_window ? focus_window->xwindow : None, | ||||
|                            display->server_focus_serial); | ||||
|                            display->server_focus_serial, | ||||
|                            FALSE); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -2179,7 +2197,8 @@ event_callback (XEvent   *event, | ||||
|   display->current_time = event_get_time (display, event); | ||||
|   display->monitor_cache_invalidated = TRUE; | ||||
|  | ||||
|   if (event->xany.serial > display->focus_serial && | ||||
|   if (display->focused_by_us && | ||||
|       event->xany.serial > display->focus_serial && | ||||
|       display->focus_window && | ||||
|       display->focus_window->xwindow != display->server_focus_window) | ||||
|     { | ||||
| @@ -2188,7 +2207,8 @@ event_callback (XEvent   *event, | ||||
|       update_focus_window (display, | ||||
|                            meta_display_lookup_x_window (display, display->server_focus_window), | ||||
|                            display->server_focus_window, | ||||
|                            display->server_focus_serial); | ||||
|                            display->server_focus_serial, | ||||
|                            FALSE); | ||||
|     } | ||||
|  | ||||
|   screen = meta_display_screen_for_root (display, event->xany.window); | ||||
| @@ -2304,7 +2324,7 @@ event_callback (XEvent   *event, | ||||
|       XIEnterEvent *enter_event = (XIEnterEvent *) input_event; | ||||
|  | ||||
|       if (window && !window->override_redirect && | ||||
|           ((input_event->type == XI_KeyPress) || (input_event->type == XI_ButtonPress))) | ||||
|           ((input_event->evtype == XI_KeyPress) || (input_event->evtype == XI_ButtonPress))) | ||||
|         { | ||||
|           if (CurrentTime == display->current_time) | ||||
|             { | ||||
| @@ -2774,14 +2794,14 @@ event_callback (XEvent   *event, | ||||
|               && meta_display_screen_for_root (display, event->xmap.event)) | ||||
|             { | ||||
|               window = meta_window_new (display, event->xmap.window, | ||||
|                                         FALSE); | ||||
|                                         FALSE, META_COMP_EFFECT_CREATE); | ||||
|             } | ||||
|           break; | ||||
|         case MapRequest: | ||||
|           if (window == NULL) | ||||
|             { | ||||
|               window = meta_window_new (display, event->xmaprequest.window, | ||||
|                                         FALSE); | ||||
|                                         FALSE, META_COMP_EFFECT_CREATE); | ||||
|             } | ||||
|           /* if frame was receiver it's some malicious send event or something */ | ||||
|           else if (!frame_was_receiver && window)         | ||||
| @@ -5808,25 +5828,6 @@ meta_display_request_take_focus (MetaDisplay *display, | ||||
|   meta_topic (META_DEBUG_FOCUS, "WM_TAKE_FOCUS(%s, %u)\n", | ||||
|               window->desc, timestamp); | ||||
|  | ||||
|   if (window != display->focus_window) | ||||
|     { | ||||
|       /* The "Globally Active Input" window case, where the window | ||||
|        * doesn't want us to call XSetInputFocus on it, but does | ||||
|        * want us to send a WM_TAKE_FOCUS. | ||||
|        * | ||||
|        * We can't just set display->focus_window to @window, since we | ||||
|        * we don't know when (or even if) the window will actually take | ||||
|        * focus, so we could end up being wrong for arbitrarily long. | ||||
|        * But we also can't leave it set to the current window, or else | ||||
|        * bug #597352 would come back. So we focus the no_focus_window | ||||
|        * now (and set display->focus_window to that), send the | ||||
|        * WM_TAKE_FOCUS, and then just forget about @window | ||||
|        * until/unless we get a FocusIn. | ||||
|        */ | ||||
|       meta_display_focus_the_no_focus_window (display, | ||||
|                                               window->screen, | ||||
|                                               timestamp); | ||||
|     } | ||||
|   meta_window_send_icccm_message (window, | ||||
|                                   display->atom_WM_TAKE_FOCUS, | ||||
|                                   timestamp); | ||||
| @@ -5969,6 +5970,12 @@ meta_display_has_shape (MetaDisplay *display) | ||||
|   return META_DISPLAY_HAS_SHAPE (display); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_display_has_sync (MetaDisplay *display) | ||||
| { | ||||
|   return META_DISPLAY_HAS_XSYNC (display); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_display_get_focus_window: | ||||
|  * @display: a #MetaDisplay | ||||
| @@ -6015,6 +6022,12 @@ meta_display_get_leader_window (MetaDisplay *display) | ||||
|   return display->leader_window; | ||||
| } | ||||
|  | ||||
| int | ||||
| meta_display_get_sync_event_base (MetaDisplay *display) | ||||
| { | ||||
|   return display->xsync_event_base; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_display_clear_mouse_mode: | ||||
|  * @display: a #MetaDisplay | ||||
|   | ||||
| @@ -51,9 +51,6 @@ meta_window_ensure_frame (MetaWindow *window) | ||||
|   if (window->frame) | ||||
|     return; | ||||
|    | ||||
|   /* See comment below for why this is required. */ | ||||
|   meta_display_grab (window->display); | ||||
|    | ||||
|   frame = g_new (MetaFrame, 1); | ||||
|  | ||||
|   frame->window = window; | ||||
| @@ -116,14 +113,6 @@ meta_window_ensure_frame (MetaWindow *window) | ||||
|    | ||||
|   meta_display_register_x_window (window->display, &frame->xwindow, window); | ||||
|  | ||||
|   /* Reparent the client window; it may be destroyed, | ||||
|    * thus the error trap. We'll get a destroy notify later | ||||
|    * and free everything. Comment in FVWM source code says | ||||
|    * we need a server grab or the child can get its MapNotify | ||||
|    * before we've finished reparenting and getting the decoration | ||||
|    * window onscreen, so ensure_frame must be called with | ||||
|    * a grab. | ||||
|    */ | ||||
|   meta_error_trap_push (window->display); | ||||
|   if (window->mapped) | ||||
|     { | ||||
| @@ -165,8 +154,6 @@ meta_window_ensure_frame (MetaWindow *window) | ||||
|  | ||||
|   /* Move keybindings to frame instead of window */ | ||||
|   meta_window_grab_keys (window); | ||||
|  | ||||
|   meta_display_ungrab (window->display); | ||||
| } | ||||
|  | ||||
| void | ||||
|   | ||||
| @@ -501,7 +501,7 @@ make_watch (MetaIdleMonitor           *monitor, | ||||
|       if (meta_idle_monitor_get_idletime (monitor) > (gint64)timeout_msec) | ||||
|         watch->idle_source_id = g_idle_add (fire_watch_idle, watch); | ||||
|     } | ||||
|   else | ||||
|   else if (monitor->user_active_alarm != None) | ||||
|     { | ||||
|       watch->xalarm = monitor->user_active_alarm; | ||||
|  | ||||
|   | ||||
| @@ -816,6 +816,22 @@ meta_monitor_config_match_current (MetaMonitorConfig  *self, | ||||
|   return ok; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager) | ||||
| { | ||||
|   MetaOutput *outputs; | ||||
|   unsigned n_outputs; | ||||
|   unsigned int i; | ||||
|  | ||||
|   outputs = meta_monitor_manager_get_outputs (manager, &n_outputs); | ||||
|  | ||||
|   for (i = 0; i < n_outputs; i++) | ||||
|     if (outputs[i].hotplug_mode_update) | ||||
|       return TRUE; | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static MetaConfiguration * | ||||
| meta_monitor_config_get_stored (MetaMonitorConfig *self, | ||||
| 				MetaOutput        *outputs, | ||||
| @@ -824,6 +840,9 @@ meta_monitor_config_get_stored (MetaMonitorConfig *self, | ||||
|   MetaConfiguration key; | ||||
|   MetaConfiguration *stored; | ||||
|  | ||||
|   if (n_outputs == 0) | ||||
|     return NULL; | ||||
|  | ||||
|   make_config_key (&key, outputs, n_outputs, -1); | ||||
|   stored = g_hash_table_lookup (self->configs, &key); | ||||
|  | ||||
| @@ -1231,6 +1250,12 @@ meta_monitor_config_make_default (MetaMonitorConfig  *self, | ||||
|   outputs = meta_monitor_manager_get_outputs (manager, &n_outputs); | ||||
|   meta_monitor_manager_get_screen_limits (manager, &max_width, &max_height); | ||||
|  | ||||
|   if (n_outputs == 0) | ||||
|     { | ||||
|       meta_verbose ("No output connected, not applying configuration\n"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   default_config = make_default_config (self, outputs, n_outputs, max_width, max_height); | ||||
|  | ||||
|   if (default_config != NULL) | ||||
|   | ||||
| @@ -116,6 +116,9 @@ struct _MetaOutput | ||||
|   */ | ||||
|   gboolean is_primary; | ||||
|   gboolean is_presentation; | ||||
|  | ||||
|   /* get a new preferred mode on hotplug events, to handle dynamic guest resizing */ | ||||
|   gboolean hotplug_mode_update; | ||||
| }; | ||||
|  | ||||
| struct _MetaCRTC | ||||
| @@ -383,6 +386,7 @@ void               meta_output_info_free (MetaOutputInfo *info); | ||||
|  | ||||
| void               meta_monitor_manager_free_output_array (MetaOutput *old_outputs, | ||||
|                                                            int         n_old_outputs); | ||||
| gboolean           meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager); | ||||
|  | ||||
| /* Returns true if transform causes width and height to be inverted | ||||
|    This is true for the odd transforms in the enum */ | ||||
|   | ||||
| @@ -187,7 +187,7 @@ output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr, | ||||
|  | ||||
|   XRRGetOutputProperty (manager_xrandr->xdisplay, | ||||
|                         (XID)output->output_id, | ||||
|                         display->atom_BACKLIGHT, | ||||
|                         display->atom_Backlight, | ||||
|                         0, G_MAXLONG, False, False, XA_INTEGER, | ||||
|                         &actual_type, &actual_format, | ||||
|                         &nitems, &bytes_after, &buffer); | ||||
| @@ -212,7 +212,7 @@ output_get_backlight_limits_xrandr (MetaMonitorManagerXrandr *manager_xrandr, | ||||
|   meta_error_trap_push (display); | ||||
|   info = XRRQueryOutputProperty (manager_xrandr->xdisplay, | ||||
|                                  (XID)output->output_id, | ||||
|                                  display->atom_BACKLIGHT); | ||||
|                                  display->atom_Backlight); | ||||
|   meta_error_trap_pop (display); | ||||
|  | ||||
|   if (info == NULL) | ||||
| @@ -311,6 +311,29 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr, | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr, | ||||
|                                 XID                       output_id) | ||||
| { | ||||
|   MetaDisplay *display = meta_get_display (); | ||||
|   XRRPropertyInfo *info; | ||||
|   gboolean result = FALSE; | ||||
|  | ||||
|   meta_error_trap_push (display); | ||||
|   info = XRRQueryOutputProperty (manager_xrandr->xdisplay, output_id, | ||||
|                                  display->atom_hotplug_mode_update); | ||||
|   meta_error_trap_pop (display); | ||||
|  | ||||
|   if (info) | ||||
|     { | ||||
|       result = TRUE; | ||||
|       XFree (info); | ||||
|     } | ||||
|  | ||||
|   return result; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void | ||||
| meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) | ||||
| { | ||||
| @@ -430,8 +453,10 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) | ||||
|       XRRFreeCrtcInfo (crtc); | ||||
|     } | ||||
|  | ||||
|   meta_error_trap_push (meta_get_display ()); | ||||
|   primary_output = XRRGetOutputPrimary (manager_xrandr->xdisplay, | ||||
| 					DefaultRootWindow (manager_xrandr->xdisplay)); | ||||
|   meta_error_trap_pop (meta_get_display ()); | ||||
|  | ||||
|   n_actual_outputs = 0; | ||||
|   for (i = 0; i < (unsigned)resources->noutput; i++) | ||||
| @@ -484,6 +509,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) | ||||
| 	  meta_output->width_mm = output->mm_width; | ||||
| 	  meta_output->height_mm = output->mm_height; | ||||
| 	  meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; | ||||
|           meta_output->hotplug_mode_update = | ||||
|               output_get_hotplug_mode_update (manager_xrandr, meta_output->output_id); | ||||
|  | ||||
| 	  meta_output->n_modes = output->nmode; | ||||
| 	  meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes); | ||||
| @@ -668,10 +695,11 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
| 						 unsigned int         n_outputs) | ||||
| { | ||||
|   MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager); | ||||
|   MetaDisplay *display = meta_get_display (); | ||||
|   unsigned i; | ||||
|   int width, height, width_mm, height_mm; | ||||
|  | ||||
|   meta_display_grab (meta_get_display ()); | ||||
|   meta_display_grab (display); | ||||
|  | ||||
|   /* First compute the new size of the screen (framebuffer) */ | ||||
|   width = 0; height = 0; | ||||
| @@ -765,10 +793,10 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
|    */ | ||||
|   width_mm = (width / DPI_FALLBACK) * 25.4 + 0.5; | ||||
|   height_mm = (height / DPI_FALLBACK) * 25.4 + 0.5; | ||||
|   meta_error_trap_push (meta_get_display ()); | ||||
|   meta_error_trap_push (display); | ||||
|   XRRSetScreenSize (manager_xrandr->xdisplay, DefaultRootWindow (manager_xrandr->xdisplay), | ||||
|                     width, height, width_mm, height_mm); | ||||
|   meta_error_trap_pop (meta_get_display ()); | ||||
|   meta_error_trap_pop (display); | ||||
|  | ||||
|   for (i = 0; i < n_crtcs; i++) | ||||
|     { | ||||
| @@ -825,7 +853,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
|               goto next; | ||||
|             } | ||||
|  | ||||
|           meta_error_trap_push (meta_get_display ()); | ||||
|           meta_error_trap_push (display); | ||||
|           ok = XRRSetCrtcConfig (manager_xrandr->xdisplay, | ||||
|                                  manager_xrandr->resources, | ||||
|                                  (XID)crtc->crtc_id, | ||||
| @@ -834,7 +862,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
|                                  (XID)mode->mode_id, | ||||
|                                  wl_transform_to_xrandr (crtc_info->transform), | ||||
|                                  outputs, n_outputs); | ||||
|           meta_error_trap_pop (meta_get_display ()); | ||||
|           meta_error_trap_pop (display); | ||||
|  | ||||
|           if (ok != Success) | ||||
|             { | ||||
| @@ -875,9 +903,11 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
|  | ||||
|       if (output_info->is_primary) | ||||
|         { | ||||
|           meta_error_trap_push (display); | ||||
|           XRRSetOutputPrimary (manager_xrandr->xdisplay, | ||||
|                                DefaultRootWindow (manager_xrandr->xdisplay), | ||||
|                                (XID)output_info->output->output_id); | ||||
|           meta_error_trap_pop (display); | ||||
|         } | ||||
|  | ||||
|       output_set_presentation_xrandr (manager_xrandr, | ||||
| @@ -903,7 +933,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
|       output->is_primary = FALSE; | ||||
|     } | ||||
|  | ||||
|   meta_display_ungrab (meta_get_display ()); | ||||
|   meta_display_ungrab (display); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -920,7 +950,7 @@ meta_monitor_manager_xrandr_change_backlight (MetaMonitorManager *manager, | ||||
|   meta_error_trap_push (display); | ||||
|   XRRChangeOutputProperty (manager_xrandr->xdisplay, | ||||
|                            (XID)output->output_id, | ||||
|                            display->atom_BACKLIGHT, | ||||
|                            display->atom_Backlight, | ||||
|                            XA_INTEGER, 32, PropModeReplace, | ||||
|                            (unsigned char *) &hw_value, 1); | ||||
|   meta_error_trap_pop (display); | ||||
| @@ -971,6 +1001,16 @@ meta_monitor_manager_xrandr_set_crtc_gamma (MetaMonitorManager *manager, | ||||
|   XRRFreeGamma (gamma); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_monitor_manager_xrandr_rebuild_derived (MetaMonitorManager *manager) | ||||
| { | ||||
|   /* This will be a no-op if the change was from our side, as | ||||
|      we already called it in the DBus method handler */ | ||||
|   meta_monitor_config_update_current (manager->config, manager); | ||||
|  | ||||
|   meta_monitor_manager_rebuild_derived (manager); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager, | ||||
| 					   XEvent             *event) | ||||
| @@ -980,6 +1020,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager, | ||||
|   MetaCRTC *old_crtcs; | ||||
|   MetaMonitorMode *old_modes; | ||||
|   int n_old_outputs; | ||||
|   gboolean new_config; | ||||
|  | ||||
|   if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify) | ||||
|     return FALSE; | ||||
| @@ -995,31 +1036,36 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager, | ||||
|   manager->serial++; | ||||
|   meta_monitor_manager_xrandr_read_current (manager); | ||||
|  | ||||
|   /* Check if the current intended configuration has the same outputs | ||||
|      as the new real one, or if the event is a result of an XRandR call. | ||||
|      If so, we can go straight to rebuild the logical config and tell | ||||
|      the outside world. | ||||
|      Otherwise, this event was caused by hotplug, so give a chance to | ||||
|      MetaMonitorConfig. | ||||
|   new_config = manager_xrandr->resources->timestamp >= | ||||
|     manager_xrandr->resources->configTimestamp; | ||||
|   if (meta_monitor_manager_has_hotplug_mode_update (manager)) | ||||
|  | ||||
|      Note that we need to check both the timestamps and the list of | ||||
|      outputs, because the X server might emit spurious events with | ||||
|      new configTimestamps (bug 702804), and the driver may have | ||||
|      changed the EDID for some other reason (old broken qxl and vbox | ||||
|      drivers...). | ||||
|   */ | ||||
|   if (manager_xrandr->resources->timestamp >= manager_xrandr->resources->configTimestamp || | ||||
|       meta_monitor_config_match_current (manager->config, manager)) | ||||
|     { | ||||
|       /* This will be a no-op if the change was from our side, as | ||||
|          we already called it in the DBus method handler */ | ||||
|       meta_monitor_config_update_current (manager->config, manager); | ||||
|  | ||||
|       meta_monitor_manager_rebuild_derived (manager); | ||||
|       /* Check if the current intended configuration is a result of an | ||||
|          XRandR call.  Otherwise, hotplug_mode_update tells us to get | ||||
|          a new preferred mode on hotplug events to handle dynamic | ||||
|          guest resizing. */ | ||||
|       if (new_config) | ||||
|         meta_monitor_manager_xrandr_rebuild_derived (manager); | ||||
|       else | ||||
|         meta_monitor_config_make_default (manager->config, manager); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (!meta_monitor_config_apply_stored (manager->config, manager)) | ||||
|       /* Check if the current intended configuration has the same outputs | ||||
|          as the new real one, or if the event is a result of an XRandR call. | ||||
|          If so, we can go straight to rebuild the logical config and tell | ||||
|          the outside world. | ||||
|          Otherwise, this event was caused by hotplug, so give a chance to | ||||
|          MetaMonitorConfig. | ||||
|  | ||||
|          Note that we need to check both the timestamps and the list of | ||||
|          outputs, because the X server might emit spurious events with new | ||||
|          configTimestamps (bug 702804), and the driver may have changed | ||||
|          the EDID for some other reason (old qxl and vbox drivers). */ | ||||
|       if (new_config || meta_monitor_config_match_current (manager->config, manager)) | ||||
|         meta_monitor_manager_xrandr_rebuild_derived (manager); | ||||
|       else if (!meta_monitor_config_apply_stored (manager->config, manager)) | ||||
|         meta_monitor_config_make_default (manager->config, manager); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -406,7 +406,7 @@ make_logical_config (MetaMonitorManager *manager) | ||||
|  | ||||
|       for (j = 0; j < monitor_infos->len; j++) | ||||
|         { | ||||
|           MetaMonitorInfo *info = &g_array_index (monitor_infos, MetaMonitorInfo, i); | ||||
|           MetaMonitorInfo *info = &g_array_index (monitor_infos, MetaMonitorInfo, j); | ||||
|           if (meta_rectangle_equal (&crtc->rect, | ||||
|                                     &info->rect)) | ||||
|             { | ||||
|   | ||||
| @@ -392,6 +392,8 @@ int | ||||
| meta_screen_monitor_index_to_xinerama_index (MetaScreen *screen, | ||||
|                                              int         index) | ||||
| { | ||||
|   g_return_val_if_fail (index >= 0 && index < screen->n_monitor_infos, -1); | ||||
|  | ||||
|   meta_screen_ensure_xinerama_indices (screen); | ||||
|  | ||||
|   return screen->monitor_infos[index].xinerama_index; | ||||
| @@ -877,83 +879,31 @@ meta_screen_free (MetaScreen *screen, | ||||
|   meta_display_ungrab (display); | ||||
| } | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   Window		xwindow; | ||||
|   XWindowAttributes	attrs; | ||||
| } WindowInfo; | ||||
|  | ||||
| static GList * | ||||
| list_windows (MetaScreen *screen) | ||||
| { | ||||
|   Window ignored1, ignored2; | ||||
|   Window *children; | ||||
|   guint n_children, i; | ||||
|   GList *result; | ||||
|  | ||||
|   XQueryTree (screen->display->xdisplay, | ||||
|               screen->xroot, | ||||
|               &ignored1, &ignored2, &children, &n_children); | ||||
|  | ||||
|   result = NULL; | ||||
|   for (i = 0; i < n_children; ++i) | ||||
|     { | ||||
|       WindowInfo *info = g_new0 (WindowInfo, 1); | ||||
|  | ||||
|       meta_error_trap_push_with_return (screen->display); | ||||
|        | ||||
|       XGetWindowAttributes (screen->display->xdisplay, | ||||
|                             children[i], &info->attrs); | ||||
|  | ||||
|       if (meta_error_trap_pop_with_return (screen->display)) | ||||
| 	{ | ||||
|           meta_verbose ("Failed to get attributes for window 0x%lx\n", | ||||
|                         children[i]); | ||||
| 	  g_free (info); | ||||
|         } | ||||
|       else | ||||
|         { | ||||
| 	  info->xwindow = children[i]; | ||||
| 	} | ||||
|  | ||||
|       result = g_list_prepend (result, info); | ||||
|     } | ||||
|  | ||||
|   if (children) | ||||
|     XFree (children); | ||||
|  | ||||
|   return g_list_reverse (result); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_screen_manage_all_windows (MetaScreen *screen) | ||||
| { | ||||
|   GList *windows; | ||||
|   GList *list; | ||||
|  | ||||
|   meta_display_grab (screen->display); | ||||
|   Window *_children; | ||||
|   Window *children; | ||||
|   int n_children, i; | ||||
|  | ||||
|   if (screen->guard_window == None) | ||||
|     screen->guard_window = create_guard_window (screen->display->xdisplay, | ||||
|                                                 screen); | ||||
|  | ||||
|   windows = list_windows (screen); | ||||
|  | ||||
|   meta_stack_freeze (screen->stack); | ||||
|   for (list = windows; list != NULL; list = list->next) | ||||
|   meta_stack_tracker_get_stack (screen->stack_tracker, &_children, &n_children); | ||||
|  | ||||
|   /* Copy the stack as it will be modified as part of the loop */ | ||||
|   children = g_memdup (_children, sizeof (Window) * n_children); | ||||
|  | ||||
|   for (i = 0; i < n_children; ++i) | ||||
|     { | ||||
|       WindowInfo *info = list->data; | ||||
|  | ||||
|       meta_window_new_with_attrs (screen->display, info->xwindow, TRUE, | ||||
|                                   META_COMP_EFFECT_NONE, | ||||
|                                   &info->attrs); | ||||
|       meta_window_new (screen->display, children[i], TRUE, | ||||
|                        META_COMP_EFFECT_NONE); | ||||
|     } | ||||
|  | ||||
|   g_free (children); | ||||
|   meta_stack_thaw (screen->stack); | ||||
|  | ||||
|   g_list_foreach (windows, (GFunc)g_free, NULL); | ||||
|   g_list_free (windows); | ||||
|  | ||||
|   meta_display_ungrab (screen->display); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -484,12 +484,8 @@ struct _MetaWindowClass | ||||
|  | ||||
| MetaWindow* meta_window_new                (MetaDisplay *display, | ||||
|                                             Window       xwindow, | ||||
|                                             gboolean     must_be_viewable); | ||||
| MetaWindow* meta_window_new_with_attrs     (MetaDisplay       *display, | ||||
|                                             Window             xwindow, | ||||
|                                             gboolean           must_be_viewable, | ||||
|                                             MetaCompEffect     effect, | ||||
|                                             XWindowAttributes *attrs); | ||||
|                                             gboolean     must_be_viewable, | ||||
|                                             MetaCompEffect     effect); | ||||
| void        meta_window_unmanage           (MetaWindow  *window, | ||||
|                                             guint32      timestamp); | ||||
| void        meta_window_calc_showing       (MetaWindow  *window); | ||||
|   | ||||
| @@ -175,6 +175,7 @@ enum { | ||||
|   PROP_USER_TIME, | ||||
|   PROP_DEMANDS_ATTENTION, | ||||
|   PROP_URGENT, | ||||
|   PROP_SKIP_TASKBAR, | ||||
|   PROP_MUTTER_HINTS, | ||||
|   PROP_APPEARS_FOCUSED, | ||||
|   PROP_RESIZEABLE, | ||||
| @@ -308,6 +309,9 @@ meta_window_get_property(GObject         *object, | ||||
|     case PROP_URGENT: | ||||
|       g_value_set_boolean (value, win->wm_hints_urgent); | ||||
|       break; | ||||
|     case PROP_SKIP_TASKBAR: | ||||
|       g_value_set_boolean (value, win->skip_taskbar); | ||||
|       break; | ||||
|     case PROP_MUTTER_HINTS: | ||||
|       g_value_set_string (value, win->mutter_hints); | ||||
|       break; | ||||
| @@ -468,6 +472,14 @@ meta_window_class_init (MetaWindowClass *klass) | ||||
|                                                          FALSE, | ||||
|                                                          G_PARAM_READABLE)); | ||||
|  | ||||
|   g_object_class_install_property (object_class, | ||||
|                                    PROP_SKIP_TASKBAR, | ||||
|                                    g_param_spec_boolean ("skip-taskbar", | ||||
|                                                          "Skip taskbar", | ||||
|                                                          "Whether the skip-taskbar flag of WM_HINTS is set", | ||||
|                                                          FALSE, | ||||
|                                                          G_PARAM_READABLE)); | ||||
|  | ||||
|   g_object_class_install_property (object_class, | ||||
|                                    PROP_MUTTER_HINTS, | ||||
|                                    g_param_spec_string ("mutter-hints", | ||||
| @@ -659,53 +671,6 @@ maybe_leave_show_desktop_mode (MetaWindow *window) | ||||
|     } | ||||
| } | ||||
|  | ||||
| MetaWindow* | ||||
| meta_window_new (MetaDisplay *display, | ||||
|                  Window       xwindow, | ||||
|                  gboolean     must_be_viewable) | ||||
| { | ||||
|   XWindowAttributes attrs; | ||||
|   MetaWindow *window; | ||||
|  | ||||
|   meta_display_grab (display); | ||||
|   meta_error_trap_push (display); /* Push a trap over all of window | ||||
|                                    * creation, to reduce XSync() calls | ||||
|                                    */ | ||||
|  | ||||
|   meta_error_trap_push_with_return (display); | ||||
|  | ||||
|   if (XGetWindowAttributes (display->xdisplay,xwindow, &attrs)) | ||||
|    { | ||||
|       if(meta_error_trap_pop_with_return (display) != Success) | ||||
|        { | ||||
|           meta_verbose ("Failed to get attributes for window 0x%lx\n", | ||||
|                         xwindow); | ||||
|           meta_error_trap_pop (display); | ||||
|           meta_display_ungrab (display); | ||||
|           return NULL; | ||||
|        } | ||||
|       window = meta_window_new_with_attrs (display, xwindow, | ||||
|                                            must_be_viewable, | ||||
|                                            META_COMP_EFFECT_CREATE, | ||||
|                                            &attrs); | ||||
|    } | ||||
|   else | ||||
|    { | ||||
|          meta_error_trap_pop_with_return (display); | ||||
|          meta_verbose ("Failed to get attributes for window 0x%lx\n", | ||||
|                         xwindow); | ||||
|          meta_error_trap_pop (display); | ||||
|          meta_display_ungrab (display); | ||||
|          return NULL; | ||||
|    } | ||||
|  | ||||
|  | ||||
|   meta_error_trap_pop (display); | ||||
|   meta_display_ungrab (display); | ||||
|  | ||||
|   return window; | ||||
| } | ||||
|  | ||||
| /* The MUTTER_WM_CLASS_FILTER environment variable is designed for | ||||
|  * performance and regression testing environments where we want to do | ||||
|  * tests with only a limited set of windows and ignore all other windows | ||||
| @@ -816,12 +781,12 @@ meta_window_should_attach_to_parent (MetaWindow *window) | ||||
| } | ||||
|  | ||||
| MetaWindow* | ||||
| meta_window_new_with_attrs (MetaDisplay       *display, | ||||
|                             Window             xwindow, | ||||
|                             gboolean           must_be_viewable, | ||||
|                             MetaCompEffect     effect, | ||||
|                             XWindowAttributes *attrs) | ||||
| meta_window_new (MetaDisplay   *display, | ||||
|                  Window         xwindow, | ||||
|                  gboolean       must_be_viewable, | ||||
|                  MetaCompEffect effect) | ||||
| { | ||||
|   XWindowAttributes	attrs; | ||||
|   MetaWindow *window; | ||||
|   GSList *tmp; | ||||
|   MetaWorkspace *space; | ||||
| @@ -830,8 +795,6 @@ meta_window_new_with_attrs (MetaDisplay       *display, | ||||
|   MetaMoveResizeFlags flags; | ||||
|   MetaScreen *screen; | ||||
|  | ||||
|   g_assert (attrs != NULL); | ||||
|  | ||||
|   meta_verbose ("Attempting to manage 0x%lx\n", xwindow); | ||||
|  | ||||
|   if (meta_display_xwindow_is_a_no_focus_window (display, xwindow)) | ||||
| @@ -841,12 +804,28 @@ meta_window_new_with_attrs (MetaDisplay       *display, | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
|   meta_error_trap_push (display); /* Push a trap over all of window | ||||
|                                    * creation, to reduce XSync() calls | ||||
|                                    */ | ||||
|   /* | ||||
|    * This function executes without any server grabs held. This means that | ||||
|    * the window could have already gone away, or could go away at any point, | ||||
|    * so we must be careful with X error handling. | ||||
|    */ | ||||
|  | ||||
|   if (!XGetWindowAttributes (display->xdisplay, xwindow, &attrs)) | ||||
|     { | ||||
|       meta_verbose ("Failed to get attributes for window 0x%lx\n", | ||||
|                     xwindow); | ||||
|       goto error; | ||||
|     } | ||||
|  | ||||
|   screen = NULL; | ||||
|   for (tmp = display->screens; tmp != NULL; tmp = tmp->next) | ||||
|     { | ||||
|       MetaScreen *scr = tmp->data; | ||||
|  | ||||
|       if (scr->xroot == attrs->root) | ||||
|       if (scr->xroot == attrs.root) | ||||
|         { | ||||
|           screen = tmp->data; | ||||
|           break; | ||||
| @@ -856,14 +835,14 @@ meta_window_new_with_attrs (MetaDisplay       *display, | ||||
|   g_assert (screen); | ||||
|  | ||||
|   /* A black list of override redirect windows that we don't need to manage: */ | ||||
|   if (attrs->override_redirect && | ||||
|   if (attrs.override_redirect && | ||||
|       (xwindow == screen->no_focus_window || | ||||
|        xwindow == screen->flash_window || | ||||
|        xwindow == screen->wm_sn_selection_window || | ||||
|        attrs->class == InputOnly || | ||||
|        attrs.class == InputOnly || | ||||
|        /* any windows created via meta_create_offscreen_window: */ | ||||
|        (attrs->x == -100 && attrs->y == -100 | ||||
| 	&& attrs->width == 1 && attrs->height == 1) || | ||||
|        (attrs.x == -100 && attrs.y == -100 | ||||
| 	&& attrs.width == 1 && attrs.height == 1) || | ||||
|        xwindow == screen->wm_cm_selection_window || | ||||
|        xwindow == screen->guard_window || | ||||
|        (display->compositor && | ||||
| @@ -873,34 +852,28 @@ meta_window_new_with_attrs (MetaDisplay       *display, | ||||
|       ) | ||||
|      ) { | ||||
|     meta_verbose ("Not managing our own windows\n"); | ||||
|     return NULL; | ||||
|     goto error; | ||||
|   } | ||||
|  | ||||
|   if (maybe_filter_window (display, xwindow, must_be_viewable, attrs)) | ||||
|   if (maybe_filter_window (display, xwindow, must_be_viewable, &attrs)) | ||||
|     { | ||||
|       meta_verbose ("Not managing filtered window\n"); | ||||
|       return NULL; | ||||
|       goto error; | ||||
|     } | ||||
|  | ||||
|   /* Grab server */ | ||||
|   meta_display_grab (display); | ||||
|   meta_error_trap_push (display); /* Push a trap over all of window | ||||
|                                    * creation, to reduce XSync() calls | ||||
|                                    */ | ||||
|  | ||||
|   meta_verbose ("must_be_viewable = %d attrs->map_state = %d (%s)\n", | ||||
|   meta_verbose ("must_be_viewable = %d attrs.map_state = %d (%s)\n", | ||||
|                 must_be_viewable, | ||||
|                 attrs->map_state, | ||||
|                 (attrs->map_state == IsUnmapped) ? | ||||
|                 attrs.map_state, | ||||
|                 (attrs.map_state == IsUnmapped) ? | ||||
|                 "IsUnmapped" : | ||||
|                 (attrs->map_state == IsViewable) ? | ||||
|                 (attrs.map_state == IsViewable) ? | ||||
|                 "IsViewable" : | ||||
|                 (attrs->map_state == IsUnviewable) ? | ||||
|                 (attrs.map_state == IsUnviewable) ? | ||||
|                 "IsUnviewable" : | ||||
|                 "(unknown)"); | ||||
|  | ||||
|   existing_wm_state = WithdrawnState; | ||||
|   if (must_be_viewable && attrs->map_state != IsViewable) | ||||
|   if (must_be_viewable && attrs.map_state != IsViewable) | ||||
|     { | ||||
|       /* Only manage if WM_STATE is IconicState or NormalState */ | ||||
|       gulong state; | ||||
| @@ -913,9 +886,7 @@ meta_window_new_with_attrs (MetaDisplay       *display, | ||||
|             (state == IconicState || state == NormalState))) | ||||
|         { | ||||
|           meta_verbose ("Deciding not to manage unmapped or unviewable window 0x%lx\n", xwindow); | ||||
|           meta_error_trap_pop (display); | ||||
|           meta_display_ungrab (display); | ||||
|           return NULL; | ||||
|           goto error; | ||||
|         } | ||||
|  | ||||
|       existing_wm_state = state; | ||||
| @@ -923,29 +894,26 @@ meta_window_new_with_attrs (MetaDisplay       *display, | ||||
|                     wm_state_to_string (existing_wm_state)); | ||||
|     } | ||||
|  | ||||
|   meta_error_trap_push_with_return (display); | ||||
|  | ||||
|   /* | ||||
|    * XAddToSaveSet can only be called on windows created by a different client. | ||||
|    * with Mutter we want to be able to create manageable windows from within | ||||
|    * the process (such as a dummy desktop window), so we do not want this | ||||
|    * call failing to prevent the window from being managed -- wrap it in its | ||||
|    * own error trap (we use the _with_return() version here to ensure that | ||||
|    * XSync() is done on the pop, otherwise the error will not get caught). | ||||
|    * the process (such as a dummy desktop window). As we do not want this | ||||
|    * call failing to prevent the window from being managed, we call this | ||||
|    * before creating the return-checked error trap. | ||||
|    */ | ||||
|   meta_error_trap_push_with_return (display); | ||||
|   XAddToSaveSet (display->xdisplay, xwindow); | ||||
|   meta_error_trap_pop_with_return (display); | ||||
|  | ||||
|   meta_error_trap_push_with_return (display); | ||||
|  | ||||
|   event_mask = PropertyChangeMask | ColormapChangeMask; | ||||
|   if (attrs->override_redirect) | ||||
|   if (attrs.override_redirect) | ||||
|     event_mask |= StructureNotifyMask; | ||||
|  | ||||
|   /* If the window is from this client (a menu, say) we need to augment | ||||
|    * the event mask, not replace it. For windows from other clients, | ||||
|    * attrs->your_event_mask will be empty at this point. | ||||
|    * attrs.your_event_mask will be empty at this point. | ||||
|    */ | ||||
|   XSelectInput (display->xdisplay, xwindow, attrs->your_event_mask | event_mask); | ||||
|   XSelectInput (display->xdisplay, xwindow, attrs.your_event_mask | event_mask); | ||||
|  | ||||
|   { | ||||
|     unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; | ||||
| @@ -967,11 +935,11 @@ meta_window_new_with_attrs (MetaDisplay       *display, | ||||
| #endif | ||||
|  | ||||
|   /* Get rid of any borders */ | ||||
|   if (attrs->border_width != 0) | ||||
|   if (attrs.border_width != 0) | ||||
|     XSetWindowBorderWidth (display->xdisplay, xwindow, 0); | ||||
|  | ||||
|   /* Get rid of weird gravities */ | ||||
|   if (attrs->win_gravity != NorthWestGravity) | ||||
|   if (attrs.win_gravity != NorthWestGravity) | ||||
|     { | ||||
|       XSetWindowAttributes set_attrs; | ||||
|  | ||||
| @@ -987,9 +955,7 @@ meta_window_new_with_attrs (MetaDisplay       *display, | ||||
|     { | ||||
|       meta_verbose ("Window 0x%lx disappeared just as we tried to manage it\n", | ||||
|                     xwindow); | ||||
|       meta_error_trap_pop (display); | ||||
|       meta_display_ungrab (display); | ||||
|       return NULL; | ||||
|       goto error; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @@ -1018,22 +984,22 @@ meta_window_new_with_attrs (MetaDisplay       *display, | ||||
|  | ||||
|   window->desc = g_strdup_printf ("0x%lx", window->xwindow); | ||||
|  | ||||
|   window->override_redirect = attrs->override_redirect; | ||||
|   window->override_redirect = attrs.override_redirect; | ||||
|  | ||||
|   /* avoid tons of stack updates */ | ||||
|   meta_stack_freeze (window->screen->stack); | ||||
|  | ||||
|   window->rect.x = attrs->x; | ||||
|   window->rect.y = attrs->y; | ||||
|   window->rect.width = attrs->width; | ||||
|   window->rect.height = attrs->height; | ||||
|   window->rect.x = attrs.x; | ||||
|   window->rect.y = attrs.y; | ||||
|   window->rect.width = attrs.width; | ||||
|   window->rect.height = attrs.height; | ||||
|  | ||||
|   /* And border width, size_hints are the "request" */ | ||||
|   window->border_width = attrs->border_width; | ||||
|   window->size_hints.x = attrs->x; | ||||
|   window->size_hints.y = attrs->y; | ||||
|   window->size_hints.width = attrs->width; | ||||
|   window->size_hints.height = attrs->height; | ||||
|   window->border_width = attrs.border_width; | ||||
|   window->size_hints.x = attrs.x; | ||||
|   window->size_hints.y = attrs.y; | ||||
|   window->size_hints.width = attrs.width; | ||||
|   window->size_hints.height = attrs.height; | ||||
|   /* initialize the remaining size_hints as if size_hints.flags were zero */ | ||||
|   meta_set_normal_hints (window, NULL); | ||||
|  | ||||
| @@ -1041,9 +1007,9 @@ meta_window_new_with_attrs (MetaDisplay       *display, | ||||
|   window->saved_rect = window->rect; | ||||
|   window->user_rect = window->rect; | ||||
|  | ||||
|   window->depth = attrs->depth; | ||||
|   window->xvisual = attrs->visual; | ||||
|   window->colormap = attrs->colormap; | ||||
|   window->depth = attrs.depth; | ||||
|   window->xvisual = attrs.visual; | ||||
|   window->colormap = attrs.colormap; | ||||
|  | ||||
|   window->title = NULL; | ||||
|   window->icon_name = NULL; | ||||
| @@ -1078,7 +1044,7 @@ meta_window_new_with_attrs (MetaDisplay       *display, | ||||
|   window->minimized = FALSE; | ||||
|   window->tab_unminimized = FALSE; | ||||
|   window->iconic = FALSE; | ||||
|   window->mapped = attrs->map_state != IsUnmapped; | ||||
|   window->mapped = attrs.map_state != IsUnmapped; | ||||
|   window->hidden = FALSE; | ||||
|   window->visible_to_compositor = FALSE; | ||||
|   window->pending_compositor_effect = effect; | ||||
| @@ -1483,7 +1449,6 @@ meta_window_new_with_attrs (MetaDisplay       *display, | ||||
|     unminimize_window_and_all_transient_parents (window); | ||||
|  | ||||
|   meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ | ||||
|   meta_display_ungrab (display); | ||||
|  | ||||
|   window->constructing = FALSE; | ||||
|  | ||||
| @@ -1496,6 +1461,10 @@ meta_window_new_with_attrs (MetaDisplay       *display, | ||||
|     g_signal_emit_by_name (window->display, "window-marked-urgent", window); | ||||
|  | ||||
|   return window; | ||||
|  | ||||
| error: | ||||
|   meta_error_trap_pop (display); | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| /* This function should only be called from the end of meta_window_new_with_attrs () */ | ||||
| @@ -2090,23 +2059,35 @@ set_net_wm_state (MetaWindow *window) | ||||
|  | ||||
|   if (window->fullscreen) | ||||
|     { | ||||
|       data[0] = meta_screen_monitor_index_to_xinerama_index (window->screen, | ||||
|                                                              window->fullscreen_monitors[0]); | ||||
|       data[1] = meta_screen_monitor_index_to_xinerama_index (window->screen, | ||||
|                                                              window->fullscreen_monitors[1]); | ||||
|       data[2] = meta_screen_monitor_index_to_xinerama_index (window->screen, | ||||
|                                                              window->fullscreen_monitors[2]); | ||||
|       data[3] = meta_screen_monitor_index_to_xinerama_index (window->screen, | ||||
|                                                              window->fullscreen_monitors[3]); | ||||
|       if (window->fullscreen_monitors[0] >= 0) | ||||
|         { | ||||
|           data[0] = meta_screen_monitor_index_to_xinerama_index (window->screen, | ||||
|                                                                  window->fullscreen_monitors[0]); | ||||
|           data[1] = meta_screen_monitor_index_to_xinerama_index (window->screen, | ||||
|                                                                  window->fullscreen_monitors[1]); | ||||
|           data[2] = meta_screen_monitor_index_to_xinerama_index (window->screen, | ||||
|                                                                  window->fullscreen_monitors[2]); | ||||
|           data[3] = meta_screen_monitor_index_to_xinerama_index (window->screen, | ||||
|                                                                  window->fullscreen_monitors[3]); | ||||
|  | ||||
|       meta_verbose ("Setting _NET_WM_FULLSCREEN_MONITORS\n"); | ||||
|       meta_error_trap_push (window->display); | ||||
|       XChangeProperty (window->display->xdisplay, | ||||
|                        window->xwindow, | ||||
|                        window->display->atom__NET_WM_FULLSCREEN_MONITORS, | ||||
|                        XA_CARDINAL, 32, PropModeReplace, | ||||
|                        (guchar*) data, 4); | ||||
|       meta_error_trap_pop (window->display); | ||||
|           meta_verbose ("Setting _NET_WM_FULLSCREEN_MONITORS\n"); | ||||
|           meta_error_trap_push (window->display); | ||||
|           XChangeProperty (window->display->xdisplay, | ||||
|                            window->xwindow, | ||||
|                            window->display->atom__NET_WM_FULLSCREEN_MONITORS, | ||||
|                            XA_CARDINAL, 32, PropModeReplace, | ||||
|                            (guchar*) data, 4); | ||||
|           meta_error_trap_pop (window->display); | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           meta_verbose ("Clearing _NET_WM_FULLSCREEN_MONITORS\n"); | ||||
|           meta_error_trap_push (window->display); | ||||
|           XDeleteProperty (window->display->xdisplay, | ||||
|                            window->xwindow, | ||||
|                            window->display->atom__NET_WM_FULLSCREEN_MONITORS); | ||||
|           meta_error_trap_pop (window->display); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -2292,7 +2273,6 @@ idle_calc_showing (gpointer data) | ||||
|   GSList *should_hide; | ||||
|   GSList *unplaced; | ||||
|   GSList *displays; | ||||
|   MetaWindow *first_window; | ||||
|   guint queue_index = GPOINTER_TO_INT (data); | ||||
|  | ||||
|   g_return_val_if_fail (queue_pending[queue_index] != NULL, FALSE); | ||||
| @@ -2345,10 +2325,6 @@ idle_calc_showing (gpointer data) | ||||
|   should_show = g_slist_sort (should_show, stackcmp); | ||||
|   should_show = g_slist_reverse (should_show); | ||||
|  | ||||
|   first_window = copy->data; | ||||
|  | ||||
|   meta_display_grab (first_window->display); | ||||
|  | ||||
|   tmp = unplaced; | ||||
|   while (tmp != NULL) | ||||
|     { | ||||
| @@ -2421,8 +2397,6 @@ idle_calc_showing (gpointer data) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   meta_display_ungrab (first_window->display); | ||||
|  | ||||
|   g_slist_free (copy); | ||||
|  | ||||
|   g_slist_free (unplaced); | ||||
| @@ -5890,7 +5864,8 @@ meta_window_focus (MetaWindow  *window, | ||||
|               window->desc, window->input, window->take_focus); | ||||
|  | ||||
|   if (window->display->grab_window && | ||||
|       window->display->grab_window->all_keys_grabbed) | ||||
|       window->display->grab_window->all_keys_grabbed && | ||||
|       !window->display->grab_window->unmanaging) | ||||
|     { | ||||
|       meta_topic (META_DEBUG_FOCUS, | ||||
|                   "Current focus window %s has global keygrab, not focusing window %s after all\n", | ||||
| @@ -5961,6 +5936,25 @@ meta_window_focus (MetaWindow  *window, | ||||
|                       "Sending WM_TAKE_FOCUS to %s since take_focus = true\n", | ||||
|                       window->desc); | ||||
|  | ||||
|           if (!window->input) | ||||
|             { | ||||
|               /* The "Globally Active Input" window case, where the window | ||||
|                * doesn't want us to call XSetInputFocus on it, but does | ||||
|                * want us to send a WM_TAKE_FOCUS. | ||||
|                * | ||||
|                * Normally, we want to just leave the focus undisturbed until | ||||
|                * the window respnds to WM_TAKE_FOCUS, but if we're unmanaging | ||||
|                * the current focus window we *need* to move the focus away, so | ||||
|                * we focus the no_focus_window now (and set | ||||
|                * display->focus_window to that) before sending WM_TAKE_FOCUS. | ||||
|                */ | ||||
|               if (window->display->focus_window != NULL && | ||||
|                   window->display->focus_window->unmanaging) | ||||
|                 meta_display_focus_the_no_focus_window (window->display, | ||||
|                                                         window->screen, | ||||
|                                                         timestamp); | ||||
|             } | ||||
|  | ||||
|           meta_display_request_take_focus (window->display, | ||||
|                                            window, | ||||
|                                            timestamp); | ||||
| @@ -8310,6 +8304,7 @@ recalc_window_features (MetaWindow *window) | ||||
|   gboolean old_has_resize_func; | ||||
|   gboolean old_has_shade_func; | ||||
|   gboolean old_always_sticky; | ||||
|   gboolean old_skip_taskbar; | ||||
|  | ||||
|   old_has_close_func = window->has_close_func; | ||||
|   old_has_minimize_func = window->has_minimize_func; | ||||
| @@ -8317,6 +8312,7 @@ recalc_window_features (MetaWindow *window) | ||||
|   old_has_resize_func = window->has_resize_func; | ||||
|   old_has_shade_func = window->has_shade_func; | ||||
|   old_always_sticky = window->always_sticky; | ||||
|   old_skip_taskbar = window->skip_taskbar; | ||||
|  | ||||
|   /* Use MWM hints initially */ | ||||
|   window->decorated = window->mwm_decorated; | ||||
| @@ -8509,6 +8505,9 @@ recalc_window_features (MetaWindow *window) | ||||
|               window->skip_taskbar, | ||||
|               window->skip_pager); | ||||
|  | ||||
|   if (old_skip_taskbar != window->skip_taskbar) | ||||
|     g_object_notify (G_OBJECT (window), "skip-taskbar"); | ||||
|  | ||||
|   /* FIXME: | ||||
|    * Lame workaround for recalc_window_features | ||||
|    * being used overzealously. The fix is to | ||||
| @@ -9711,7 +9710,8 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, | ||||
|   switch (xev->evtype) | ||||
|     { | ||||
|     case XI_ButtonRelease: | ||||
|       if (xev->detail == 1) | ||||
|       if (xev->detail == 1 || | ||||
|           xev->detail == meta_prefs_get_mouse_button_resize ()) | ||||
|         { | ||||
|           meta_display_check_threshold_reached (window->display, | ||||
|                                                 xev->root_x, | ||||
|   | ||||
| @@ -80,7 +80,8 @@ item(MULTIPLE) | ||||
| item(TIMESTAMP) | ||||
| item(VERSION) | ||||
| item(ATOM_PAIR) | ||||
| item(BACKLIGHT) | ||||
| item(Backlight) | ||||
| item(hotplug_mode_update) | ||||
|  | ||||
| /* Oddities: These are used, and we need atoms for them, | ||||
|  * but when we need all _NET_WM hints (i.e. when we're making | ||||
|   | ||||
| @@ -78,6 +78,7 @@ MetaCompositor *meta_display_get_compositor (MetaDisplay *display); | ||||
| GSList *meta_display_get_screens (MetaDisplay *display); | ||||
|  | ||||
| gboolean meta_display_has_shape (MetaDisplay *display); | ||||
| gboolean meta_display_has_sync (MetaDisplay *display); | ||||
|  | ||||
| MetaScreen *meta_display_screen_for_root (MetaDisplay *display, | ||||
|                                           Window       xroot); | ||||
| @@ -88,6 +89,7 @@ gboolean  meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display, | ||||
|  | ||||
| int meta_display_get_damage_event_base (MetaDisplay *display); | ||||
| int meta_display_get_shape_event_base (MetaDisplay *display); | ||||
| int meta_display_get_sync_event_base (MetaDisplay *display); | ||||
|  | ||||
| gboolean meta_display_xserver_time_is_before (MetaDisplay *display, | ||||
|                                               guint32      time1, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user