Compare commits
25 Commits
3.11.92
...
wip/quadbu
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0f214e24ee | ||
![]() |
cf67327f0e | ||
![]() |
8e5bb17750 | ||
![]() |
14d2f8fddc | ||
![]() |
c249c3f3e5 | ||
![]() |
db0383d19f | ||
![]() |
a175b3c947 | ||
![]() |
554be56639 | ||
![]() |
b4de2458ab | ||
![]() |
49952bdc69 | ||
![]() |
b2fd24a098 | ||
![]() |
fe9d2570d0 | ||
![]() |
b16ac1ba8c | ||
![]() |
330ce648d3 | ||
![]() |
0c0973bbd8 | ||
![]() |
a967d479c5 | ||
![]() |
9707c1061d | ||
![]() |
29cb77ce70 | ||
![]() |
f93fa1d705 | ||
![]() |
a742b17805 | ||
![]() |
c4b65e0e6e | ||
![]() |
9ec8232417 | ||
![]() |
768e830f11 | ||
![]() |
4a4a624b77 | ||
![]() |
b13b7ea72e |
18
NEWS
18
NEWS
@@ -1,3 +1,21 @@
|
||||
3.12.1
|
||||
======
|
||||
* Fix opacity values from _NET_WM_WINDOW_OPACITY [Nirbheek; #727874]
|
||||
* Misc. cleanups [Jasper; #720631]
|
||||
|
||||
Contributors:
|
||||
Nirbheek Chauhan, Jasper St. Pierre
|
||||
|
||||
Translations:
|
||||
Inaki Larranaga Murgoitio [eu], marablack3 [el]
|
||||
|
||||
3.12.0
|
||||
======
|
||||
|
||||
Translations:
|
||||
Ask H. Larsen [da], Мирослав Николић [sr, sr@latin], Andika Triwidada [id],
|
||||
Daniel Korostil [uk], Petr Kovar [cs]
|
||||
|
||||
3.11.92
|
||||
=======
|
||||
* Fix identification of CSD windows [Owen; #723029]
|
||||
|
@@ -2,8 +2,8 @@ AC_PREREQ(2.50)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [11])
|
||||
m4_define([mutter_micro_version], [92])
|
||||
m4_define([mutter_minor_version], [12])
|
||||
m4_define([mutter_micro_version], [1])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
@@ -70,12 +70,12 @@ CLUTTER_PACKAGE=clutter-1.0
|
||||
|
||||
MUTTER_PC_MODULES="
|
||||
gtk+-3.0 >= 3.9.11
|
||||
gio-2.0 >= 2.25.10
|
||||
gio-unix-2.0 >= 2.25.10
|
||||
pango >= 1.2.0
|
||||
cairo >= 1.10.0
|
||||
gsettings-desktop-schemas >= 3.7.3
|
||||
xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0
|
||||
$CLUTTER_PACKAGE >= 1.15.90
|
||||
$CLUTTER_PACKAGE >= 1.19.5
|
||||
cogl-1.0 >= 1.17.1
|
||||
upower-glib >= 0.99.0
|
||||
gnome-desktop-3.0
|
||||
|
147
po/cs.po
147
po/cs.po
@@ -5,24 +5,23 @@
|
||||
# Miloslav Trmac <mitr@volny.cz>, 2002, 2003, 2004, 2005, 2006.
|
||||
# Petr Tomeš <ptomes@gmail.com>, 2006.
|
||||
# Jakub Friedl <jfriedl@suse.cz>, 2006, 2007.
|
||||
# Petr Kovar <pknbe@volny.cz>, 2007, 2008, 2009, 2010, 2011, 2012, 2013.
|
||||
# Petr Kovar <pknbe@volny.cz>, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014.
|
||||
# Marek Černocký <marek@manet.cz>, 2012, 2013, 2014.
|
||||
#
|
||||
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: 2014-02-08 22:53+0000\n"
|
||||
"PO-Revision-Date: 2014-02-09 09:49+0100\n"
|
||||
"Last-Translator: Marek Černocký <marek@manet.cz>\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter"
|
||||
"&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2014-03-22 11:01+0000\n"
|
||||
"PO-Revision-Date: 2014-03-22 20:48+0200\n"
|
||||
"Last-Translator: Petr Kovar <pknbe@volny.cz>\n"
|
||||
"Language-Team: Czech <gnome-cs-list@gnome.org>\n"
|
||||
"Language: cs\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
"X-Generator: Gtranslator 2.91.6\n"
|
||||
"X-Generator: Virtaal 0.7.1\n"
|
||||
"X-Project-Style: gnome\n"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:1
|
||||
@@ -62,66 +61,86 @@ msgid "Move window one workspace down"
|
||||
msgstr "Přesunout okno o plochu dolů"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:10
|
||||
#| msgid "Move window one workspace to the left"
|
||||
msgid "Move window one monitor to the left"
|
||||
msgstr "Přesunout okno o monitor doleva"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:11
|
||||
#| msgid "Move window one workspace to the right"
|
||||
msgid "Move window one monitor to the right"
|
||||
msgstr "Přesunout okno o monitor doprava"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:12
|
||||
#| msgid "Move window one workspace up"
|
||||
msgid "Move window one monitor up"
|
||||
msgstr "Přesunout okno o monitor nahoru"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:13
|
||||
#| msgid "Move window one workspace down"
|
||||
msgid "Move window one monitor down"
|
||||
msgstr "Přesunout okno o monitor dolů"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:14
|
||||
msgid "Switch applications"
|
||||
msgstr "Přepnout mezi aplikacemi"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:11
|
||||
#: ../src/50-mutter-navigation.xml.in.h:15
|
||||
msgid "Switch windows"
|
||||
msgstr "Přepnout mezi okny"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:12
|
||||
#: ../src/50-mutter-navigation.xml.in.h:16
|
||||
msgid "Switch windows of an application"
|
||||
msgstr "Přepnout mezi okny aplikace"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:13
|
||||
#: ../src/50-mutter-navigation.xml.in.h:17
|
||||
msgid "Switch system controls"
|
||||
msgstr "Přepnout mezi systémovými ovládacími prvky"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:14
|
||||
#: ../src/50-mutter-navigation.xml.in.h:18
|
||||
msgid "Switch windows directly"
|
||||
msgstr "Přepnout přímo mezi okny"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:15
|
||||
#: ../src/50-mutter-navigation.xml.in.h:19
|
||||
msgid "Switch windows of an app directly"
|
||||
msgstr "Přepnout přímo mezi okny aplikace"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:16
|
||||
#: ../src/50-mutter-navigation.xml.in.h:20
|
||||
msgid "Switch system controls directly"
|
||||
msgstr "Přepnout přímo mezi systémovými ovládacími prvky"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:17
|
||||
#: ../src/50-mutter-navigation.xml.in.h:21
|
||||
msgid "Hide all normal windows"
|
||||
msgstr "Skrýt všechna běžná okna"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:18
|
||||
#: ../src/50-mutter-navigation.xml.in.h:22
|
||||
msgid "Switch to workspace 1"
|
||||
msgstr "Přepnout na plochu 1"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:19
|
||||
#: ../src/50-mutter-navigation.xml.in.h:23
|
||||
msgid "Switch to workspace 2"
|
||||
msgstr "Přepnout na plochu 2"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:20
|
||||
#: ../src/50-mutter-navigation.xml.in.h:24
|
||||
msgid "Switch to workspace 3"
|
||||
msgstr "Přepnout na plochu 3"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:21
|
||||
#: ../src/50-mutter-navigation.xml.in.h:25
|
||||
msgid "Switch to workspace 4"
|
||||
msgstr "Přepnout na plochu 4"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:22
|
||||
#: ../src/50-mutter-navigation.xml.in.h:26
|
||||
msgid "Move to workspace left"
|
||||
msgstr "Přesunout na plochu vlevo"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:23
|
||||
#: ../src/50-mutter-navigation.xml.in.h:27
|
||||
msgid "Move to workspace right"
|
||||
msgstr "Přesunout na plochu vpravo"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:24
|
||||
#: ../src/50-mutter-navigation.xml.in.h:28
|
||||
msgid "Move to workspace above"
|
||||
msgstr "Přesunout na plochu nad"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:25
|
||||
#: ../src/50-mutter-navigation.xml.in.h:29
|
||||
msgid "Move to workspace below"
|
||||
msgstr "Přesunout na plochu pod"
|
||||
|
||||
@@ -216,22 +235,22 @@ msgstr "Zobrazit rozdělení napravo"
|
||||
|
||||
#. 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:542
|
||||
#: ../src/compositor/compositor.c:534
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
"\"."
|
||||
msgstr "Jiný kompozitní správce již běží na obrazovce %i displeje „%s“."
|
||||
|
||||
#: ../src/compositor/meta-background.c:1073
|
||||
#: ../src/compositor/meta-background.c:1074
|
||||
msgid "background texture could not be created from file"
|
||||
msgstr "textura pozadí nemohla být ze souboru vytvořena"
|
||||
|
||||
#: ../src/core/bell.c:320
|
||||
#: ../src/core/bell.c:321
|
||||
msgid "Bell event"
|
||||
msgstr "Událost zvonku"
|
||||
|
||||
#: ../src/core/core.c:155
|
||||
#: ../src/core/core.c:156
|
||||
#, c-format
|
||||
msgid "Unknown window information request: %d"
|
||||
msgstr "Neznámý informační požadavek okna: %d"
|
||||
@@ -261,17 +280,17 @@ msgstr "_Počkat"
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Vynutit ukončení"
|
||||
|
||||
#: ../src/core/display.c:413
|
||||
#: ../src/core/display.c:405
|
||||
#, c-format
|
||||
msgid "Missing %s extension required for compositing"
|
||||
msgstr "Schází rozšíření %s vyžadované funkcemi kompozitoru"
|
||||
|
||||
#: ../src/core/display.c:505
|
||||
#: ../src/core/display.c:497
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Nelze otevřít displej X Window System „%s“\n"
|
||||
|
||||
#: ../src/core/keybindings.c:1135
|
||||
#: ../src/core/keybindings.c:1105
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Some other program is already using the key %s with modifiers %x as a "
|
||||
@@ -279,7 +298,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Klávesu %s s modifikátory %x již jako zkratku používá nějaký jiný program\n"
|
||||
|
||||
#: ../src/core/keybindings.c:1332
|
||||
#: ../src/core/keybindings.c:1308
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid accelerator\n"
|
||||
msgstr "„%s“ není platný akcelerátor\n"
|
||||
@@ -308,12 +327,12 @@ msgstr "Spustí sezení z uloženého souboru"
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "Provede volání X synchronně"
|
||||
|
||||
#: ../src/core/main.c:536
|
||||
#: ../src/core/main.c:544
|
||||
#, c-format
|
||||
msgid "Failed to scan themes directory: %s\n"
|
||||
msgstr "Nelze prohledat adresář motivů: %s\n"
|
||||
|
||||
#: ../src/core/main.c:552
|
||||
#: ../src/core/main.c:560
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
|
||||
@@ -341,7 +360,7 @@ msgstr "Neznámý displej"
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#: ../src/core/mutter.c:38
|
||||
#: ../src/core/mutter.c:39
|
||||
#, c-format
|
||||
msgid ""
|
||||
"mutter %s\n"
|
||||
@@ -357,15 +376,15 @@ msgstr ""
|
||||
"Tento software je BEZ JAKÉKOLIV ZÁRUKY; neposkytují se ani záruky "
|
||||
"PRODEJNOSTI anebo VHODNOSTI PRO URČITÝ ÚČEL.\n"
|
||||
|
||||
#: ../src/core/mutter.c:52
|
||||
#: ../src/core/mutter.c:53
|
||||
msgid "Print version"
|
||||
msgstr "Vypíše verzi"
|
||||
|
||||
#: ../src/core/mutter.c:58
|
||||
#: ../src/core/mutter.c:59
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Zásuvný modul Mutter, který se má použít"
|
||||
|
||||
#: ../src/core/prefs.c:1200
|
||||
#: ../src/core/prefs.c:1190
|
||||
msgid ""
|
||||
"Workarounds for broken applications disabled. Some applications may not "
|
||||
"behave properly.\n"
|
||||
@@ -373,12 +392,12 @@ msgstr ""
|
||||
"Bylo zakázáno obcházení chyb aplikací. Některé aplikace se možná nebudou "
|
||||
"chovat správně.\n"
|
||||
|
||||
#: ../src/core/prefs.c:1275
|
||||
#: ../src/core/prefs.c:1265
|
||||
#, c-format
|
||||
msgid "Could not parse font description \"%s\" from GSettings key %s\n"
|
||||
msgstr "Nelze zpracovat popis písma „%s“ v klíči GSettings %s\n"
|
||||
|
||||
#: ../src/core/prefs.c:1341
|
||||
#: ../src/core/prefs.c:1331
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\"%s\" found in configuration database is not a valid value for mouse button "
|
||||
@@ -387,7 +406,7 @@ msgstr ""
|
||||
"„%s“ nalezené v databázi nastavení není platnou hodnotou modifikátoru "
|
||||
"tlačítka myši\n"
|
||||
|
||||
#: ../src/core/prefs.c:1907
|
||||
#: ../src/core/prefs.c:1894
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\"%s\" found in configuration database is not a valid value for keybinding "
|
||||
@@ -396,17 +415,17 @@ msgstr ""
|
||||
"„%s“ nalezené v databázi nastavení není platnou hodnotou klávesové zkratky "
|
||||
"„%s“\n"
|
||||
|
||||
#: ../src/core/prefs.c:1997
|
||||
#: ../src/core/prefs.c:1984
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Plocha %d"
|
||||
|
||||
#: ../src/core/screen.c:537
|
||||
#: ../src/core/screen.c:539
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "Obrazovka %d na displeji „%s“ je neplatná\n"
|
||||
|
||||
#: ../src/core/screen.c:553
|
||||
#: ../src/core/screen.c:555
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
@@ -415,70 +434,70 @@ msgstr ""
|
||||
"Obrazovka %d na displeji „%s“ již správce oken má; zkuste prosím nahradit "
|
||||
"aktuálního správce oken pomocí přepínače --replace.\n"
|
||||
|
||||
#: ../src/core/screen.c:580
|
||||
#: ../src/core/screen.c:582
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not acquire window manager selection on screen %d display \"%s\"\n"
|
||||
msgstr "Nelze získat výběr správce oken na obrazovce %d displeje „%s“\n"
|
||||
|
||||
#: ../src/core/screen.c:658
|
||||
#: ../src/core/screen.c:660
|
||||
#, c-format
|
||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||
msgstr "Obrazovka %d na displeji „%s“ již má správce oken\n"
|
||||
|
||||
#: ../src/core/screen.c:850
|
||||
#: ../src/core/screen.c:848
|
||||
#, c-format
|
||||
msgid "Could not release screen %d on display \"%s\"\n"
|
||||
msgstr "Nelze uvolnit obrazovku %d na displeji „%s“\n"
|
||||
|
||||
#: ../src/core/session.c:841 ../src/core/session.c:848
|
||||
#: ../src/core/session.c:842 ../src/core/session.c:849
|
||||
#, c-format
|
||||
msgid "Could not create directory '%s': %s\n"
|
||||
msgstr "Nelze vytvořit adresář „%s“: %s\n"
|
||||
|
||||
#: ../src/core/session.c:858
|
||||
#: ../src/core/session.c:859
|
||||
#, c-format
|
||||
msgid "Could not open session file '%s' for writing: %s\n"
|
||||
msgstr "Nelze otevřít soubor sezení „%s“ k zápisu: %s\n"
|
||||
|
||||
#: ../src/core/session.c:999
|
||||
#: ../src/core/session.c:1000
|
||||
#, c-format
|
||||
msgid "Error writing session file '%s': %s\n"
|
||||
msgstr "Chyba při zápisu souboru sezení „%s“: %s\n"
|
||||
|
||||
#: ../src/core/session.c:1004
|
||||
#: ../src/core/session.c:1005
|
||||
#, c-format
|
||||
msgid "Error closing session file '%s': %s\n"
|
||||
msgstr "Chyba při zavírání souboru sezení „%s“: %s\n"
|
||||
|
||||
#: ../src/core/session.c:1134
|
||||
#: ../src/core/session.c:1135
|
||||
#, c-format
|
||||
msgid "Failed to parse saved session file: %s\n"
|
||||
msgstr "Chyba při analyzování uloženého souboru sezení: %s\n"
|
||||
|
||||
#: ../src/core/session.c:1183
|
||||
#: ../src/core/session.c:1184
|
||||
#, c-format
|
||||
msgid "<mutter_session> attribute seen but we already have the session ID"
|
||||
msgstr "nalezen atribut <mutter_session>, ale ID sezení už k dispozici je"
|
||||
|
||||
#: ../src/core/session.c:1196 ../src/core/session.c:1271
|
||||
#: ../src/core/session.c:1303 ../src/core/session.c:1375
|
||||
#: ../src/core/session.c:1435
|
||||
#: ../src/core/session.c:1197 ../src/core/session.c:1272
|
||||
#: ../src/core/session.c:1304 ../src/core/session.c:1376
|
||||
#: ../src/core/session.c:1436
|
||||
#, c-format
|
||||
msgid "Unknown attribute %s on <%s> element"
|
||||
msgstr "Neznámý atribut %s prvku <%s>"
|
||||
|
||||
#: ../src/core/session.c:1213
|
||||
#: ../src/core/session.c:1214
|
||||
#, c-format
|
||||
msgid "nested <window> tag"
|
||||
msgstr "vnořená značka <window>"
|
||||
|
||||
#: ../src/core/session.c:1455
|
||||
#: ../src/core/session.c:1456
|
||||
#, c-format
|
||||
msgid "Unknown element %s"
|
||||
msgstr "Neznámý prvek %s"
|
||||
|
||||
#: ../src/core/session.c:1807
|
||||
#: ../src/core/session.c:1808
|
||||
msgid ""
|
||||
"These windows do not support "save current setup" and will have to "
|
||||
"be restarted manually next time you log in."
|
||||
@@ -522,7 +541,7 @@ msgid "Window manager error: "
|
||||
msgstr "Chyba správce oken: "
|
||||
|
||||
#. first time through
|
||||
#: ../src/core/window.c:7589
|
||||
#: ../src/core/window.c:7562
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
|
||||
@@ -538,7 +557,7 @@ msgstr ""
|
||||
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
|
||||
#. * about these apps but make them work.
|
||||
#.
|
||||
#: ../src/core/window.c:8513
|
||||
#: ../src/core/window.c:8487
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
|
||||
@@ -548,22 +567,22 @@ msgstr ""
|
||||
"velikost, ale nastavuje min. velikost %d × %d a max. velikost %d × %d; to "
|
||||
"nedává smysl.\n"
|
||||
|
||||
#: ../src/core/window-props.c:348
|
||||
#: ../src/core/window-props.c:349
|
||||
#, c-format
|
||||
msgid "Application set a bogus _NET_WM_PID %lu\n"
|
||||
msgstr "Aplikace nastavila neplatný _NET_WM_PID %lu\n"
|
||||
|
||||
#: ../src/core/window-props.c:464
|
||||
#: ../src/core/window-props.c:465
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (na %s)"
|
||||
|
||||
#: ../src/core/window-props.c:1547
|
||||
#: ../src/core/window-props.c:1548
|
||||
#, c-format
|
||||
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
|
||||
msgstr "Neplatné okno WM_TRANSIENT_FOR 0x%lx specifikováno pro %s.\n"
|
||||
|
||||
#: ../src/core/window-props.c:1558
|
||||
#: ../src/core/window-props.c:1559
|
||||
#, c-format
|
||||
msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n"
|
||||
msgstr "Okno WM_TRANSIENT_FOR 0x%lx by vytvořilo smyčku pro %s.\n"
|
||||
|
553
po/sr@latin.po
553
po/sr@latin.po
File diff suppressed because it is too large
Load Diff
140
po/uk.po
140
po/uk.po
@@ -7,8 +7,8 @@ msgstr ""
|
||||
"Project-Id-Version: metacity\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter"
|
||||
"&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2014-02-13 02:27+0000\n"
|
||||
"PO-Revision-Date: 2014-02-13 11:14+0300\n"
|
||||
"POT-Creation-Date: 2014-03-16 22:53+0000\n"
|
||||
"PO-Revision-Date: 2014-03-17 12:39+0300\n"
|
||||
"Last-Translator: Daniel Korostil <ted.korostiled@gmail.com>\n"
|
||||
"Language-Team: linux.org.ua\n"
|
||||
"Language: uk\n"
|
||||
@@ -57,67 +57,86 @@ msgid "Move window one workspace down"
|
||||
msgstr "Перемістити вікно на робочий простір нижче"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:10
|
||||
#| msgid "Move window one workspace to the left"
|
||||
msgid "Move window one monitor to the left"
|
||||
msgstr "Перемістити вікно на монітор ліворуч"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:11
|
||||
#| msgid "Move window one workspace to the right"
|
||||
msgid "Move window one monitor to the right"
|
||||
msgstr "Перемістити вікно на монітор праворуч"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:12
|
||||
#| msgid "Move window one workspace up"
|
||||
msgid "Move window one monitor up"
|
||||
msgstr "Перемістити вікно на монітор вище"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:13
|
||||
#| msgid "Move window one workspace down"
|
||||
msgid "Move window one monitor down"
|
||||
msgstr "Перемістити вікно на монітор нижче"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:14
|
||||
msgid "Switch applications"
|
||||
msgstr "Перемкнути програми"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:11
|
||||
#| msgid "Switch windows directly"
|
||||
#: ../src/50-mutter-navigation.xml.in.h:15
|
||||
msgid "Switch windows"
|
||||
msgstr "Перемкнути вікна"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:12
|
||||
#: ../src/50-mutter-navigation.xml.in.h:16
|
||||
msgid "Switch windows of an application"
|
||||
msgstr "Перемкнути вікна програм"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:13
|
||||
#: ../src/50-mutter-navigation.xml.in.h:17
|
||||
msgid "Switch system controls"
|
||||
msgstr "Перемкнути системні керування"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:14
|
||||
#: ../src/50-mutter-navigation.xml.in.h:18
|
||||
msgid "Switch windows directly"
|
||||
msgstr "Перемкнути вікна напряму"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:15
|
||||
#: ../src/50-mutter-navigation.xml.in.h:19
|
||||
msgid "Switch windows of an app directly"
|
||||
msgstr "Перемкнути вікна програм напряму"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:16
|
||||
#: ../src/50-mutter-navigation.xml.in.h:20
|
||||
msgid "Switch system controls directly"
|
||||
msgstr "Перемкнути системні керування напряму"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:17
|
||||
#: ../src/50-mutter-navigation.xml.in.h:21
|
||||
msgid "Hide all normal windows"
|
||||
msgstr "Сховати всі звичайні вікна"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:18
|
||||
#: ../src/50-mutter-navigation.xml.in.h:22
|
||||
msgid "Switch to workspace 1"
|
||||
msgstr "Перейти до робочого простору 1"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:19
|
||||
#: ../src/50-mutter-navigation.xml.in.h:23
|
||||
msgid "Switch to workspace 2"
|
||||
msgstr "Перейти до робочого простору 2"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:20
|
||||
#: ../src/50-mutter-navigation.xml.in.h:24
|
||||
msgid "Switch to workspace 3"
|
||||
msgstr "Перейти до робочого простору 3"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:21
|
||||
#: ../src/50-mutter-navigation.xml.in.h:25
|
||||
msgid "Switch to workspace 4"
|
||||
msgstr "Перейти до робочого простору 4"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:22
|
||||
#: ../src/50-mutter-navigation.xml.in.h:26
|
||||
msgid "Move to workspace left"
|
||||
msgstr "Перейти до робочого простору ліворуч"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:23
|
||||
#: ../src/50-mutter-navigation.xml.in.h:27
|
||||
msgid "Move to workspace right"
|
||||
msgstr "Перейти до робочого простору праворуч"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:24
|
||||
#: ../src/50-mutter-navigation.xml.in.h:28
|
||||
msgid "Move to workspace above"
|
||||
msgstr "Перейти до робочого простору вище"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:25
|
||||
#: ../src/50-mutter-navigation.xml.in.h:29
|
||||
msgid "Move to workspace below"
|
||||
msgstr "Перейти до робочого простору знизу"
|
||||
|
||||
@@ -212,29 +231,28 @@ msgstr "Перегляд розділити праворуч"
|
||||
|
||||
#. 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:542
|
||||
#: ../src/compositor/compositor.c:534
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
"\"."
|
||||
msgstr "Уже запущено інший композитний менеджер на екрані %i через показ «%s»."
|
||||
|
||||
#: ../src/compositor/meta-background.c:1073
|
||||
#: ../src/compositor/meta-background.c:1074
|
||||
msgid "background texture could not be created from file"
|
||||
msgstr "будову тла неможливо створити з файла"
|
||||
|
||||
#: ../src/core/bell.c:320
|
||||
#: ../src/core/bell.c:321
|
||||
msgid "Bell event"
|
||||
msgstr "Подія гудка"
|
||||
|
||||
#: ../src/core/core.c:155
|
||||
#: ../src/core/core.c:156
|
||||
#, c-format
|
||||
msgid "Unknown window information request: %d"
|
||||
msgstr "Запит інформації невідомого вікна: %d"
|
||||
|
||||
#: ../src/core/delete.c:109
|
||||
#, c-format
|
||||
#| msgid "%s is not responding."
|
||||
msgid "“%s” is not responding."
|
||||
msgstr "«%s» не відповідає."
|
||||
|
||||
@@ -257,26 +275,25 @@ msgstr "_Зачекати"
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Завершити примусово"
|
||||
|
||||
#: ../src/core/display.c:413
|
||||
#: ../src/core/display.c:405
|
||||
#, c-format
|
||||
msgid "Missing %s extension required for compositing"
|
||||
msgstr "Нема розширення %s, яке потрібне для композитного режиму"
|
||||
|
||||
#: ../src/core/display.c:505
|
||||
#: ../src/core/display.c:497
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Не вдалось відкрити дисплей віконної системи X «%s»\n"
|
||||
|
||||
#: ../src/core/keybindings.c:1135
|
||||
#: ../src/core/keybindings.c:1105
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Some other program is already using the key %s with modifiers %x as a "
|
||||
"binding\n"
|
||||
msgstr "Клавішу «%s» з модифікаторами «%x» вже використовує інша програма\n"
|
||||
|
||||
#: ../src/core/keybindings.c:1332
|
||||
#: ../src/core/keybindings.c:1308
|
||||
#, c-format
|
||||
#| msgid "\"%s\" is not a valid value for focus attribute"
|
||||
msgid "\"%s\" is not a valid accelerator\n"
|
||||
msgstr "«%s» — недійсний акселератор\n"
|
||||
|
||||
@@ -337,7 +354,7 @@ msgstr "Невідомий екран"
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#: ../src/core/mutter.c:38
|
||||
#: ../src/core/mutter.c:39
|
||||
#, c-format
|
||||
msgid ""
|
||||
"mutter %s\n"
|
||||
@@ -352,15 +369,15 @@ msgstr ""
|
||||
"Не надається НІЯКИХ гарантій; навіть ПРИДАТНОСТІ ДЛЯ ПРОДАЖУ чи "
|
||||
"ВІДПОВІДНОСТІ ПЕВНІЙ МЕТІ.\n"
|
||||
|
||||
#: ../src/core/mutter.c:52
|
||||
#: ../src/core/mutter.c:53
|
||||
msgid "Print version"
|
||||
msgstr "Показати версію"
|
||||
|
||||
#: ../src/core/mutter.c:58
|
||||
#: ../src/core/mutter.c:59
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Додатки Clutter для використання"
|
||||
|
||||
#: ../src/core/prefs.c:1200
|
||||
#: ../src/core/prefs.c:1190
|
||||
msgid ""
|
||||
"Workarounds for broken applications disabled. Some applications may not "
|
||||
"behave properly.\n"
|
||||
@@ -368,12 +385,12 @@ msgstr ""
|
||||
"Обхід для роботи із зіпсованими програмами вимкнено. Деякі додатки можуть "
|
||||
"працювати некоректно.\n"
|
||||
|
||||
#: ../src/core/prefs.c:1275
|
||||
#: ../src/core/prefs.c:1265
|
||||
#, c-format
|
||||
msgid "Could not parse font description \"%s\" from GSettings key %s\n"
|
||||
msgstr "Неможливо проаналізувати опис шрифту «%s» у ключі GSettings %s\n"
|
||||
|
||||
#: ../src/core/prefs.c:1341
|
||||
#: ../src/core/prefs.c:1331
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\"%s\" found in configuration database is not a valid value for mouse button "
|
||||
@@ -382,7 +399,7 @@ msgstr ""
|
||||
"У базі даних налаштування знайдено «%s» — що не є правильним значенням "
|
||||
"модифікатора клавіші миші.\n"
|
||||
|
||||
#: ../src/core/prefs.c:1907
|
||||
#: ../src/core/prefs.c:1894
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\"%s\" found in configuration database is not a valid value for keybinding "
|
||||
@@ -391,17 +408,17 @@ msgstr ""
|
||||
"Знайдене у базі даних налаштування значення «%s» не є правильним записом "
|
||||
"прив'язки клавіш «%s»\n"
|
||||
|
||||
#: ../src/core/prefs.c:1997
|
||||
#: ../src/core/prefs.c:1984
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Робочий простір %d"
|
||||
|
||||
#: ../src/core/screen.c:537
|
||||
#: ../src/core/screen.c:539
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "Екран %d на дисплеї «%s» не правильний\n"
|
||||
|
||||
#: ../src/core/screen.c:553
|
||||
#: ../src/core/screen.c:555
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
@@ -410,7 +427,7 @@ msgstr ""
|
||||
"Екран %d на дисплеї «%s» вже має менеджера вікон; спробуйте вказати параметр "
|
||||
"--replace, щоб замінити поточний менеджер вікон.\n"
|
||||
|
||||
#: ../src/core/screen.c:580
|
||||
#: ../src/core/screen.c:582
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not acquire window manager selection on screen %d display \"%s\"\n"
|
||||
@@ -418,64 +435,64 @@ msgstr ""
|
||||
"Не вдалось одержати функцію виділення менеджеру вікон на екрані %d дисплею "
|
||||
"«%s»\n"
|
||||
|
||||
#: ../src/core/screen.c:658
|
||||
#: ../src/core/screen.c:660
|
||||
#, c-format
|
||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||
msgstr "Екран %d на дисплеї «%s» вже має менеджера вікон\n"
|
||||
|
||||
#: ../src/core/screen.c:850
|
||||
#: ../src/core/screen.c:848
|
||||
#, c-format
|
||||
msgid "Could not release screen %d on display \"%s\"\n"
|
||||
msgstr "Не вдалось відпустити екран %d на дисплеї «%s»\n"
|
||||
|
||||
#: ../src/core/session.c:841 ../src/core/session.c:848
|
||||
#: ../src/core/session.c:842 ../src/core/session.c:849
|
||||
#, c-format
|
||||
msgid "Could not create directory '%s': %s\n"
|
||||
msgstr "Не вдалось створити каталог «%s»: %s\n"
|
||||
|
||||
#: ../src/core/session.c:858
|
||||
#: ../src/core/session.c:859
|
||||
#, c-format
|
||||
msgid "Could not open session file '%s' for writing: %s\n"
|
||||
msgstr "Не вдалось відкрити для запису файл сеансу «%s»: %s\n"
|
||||
|
||||
#: ../src/core/session.c:999
|
||||
#: ../src/core/session.c:1000
|
||||
#, c-format
|
||||
msgid "Error writing session file '%s': %s\n"
|
||||
msgstr "Помилка запису файла сеансу \"%s\": %s\n"
|
||||
|
||||
#: ../src/core/session.c:1004
|
||||
#: ../src/core/session.c:1005
|
||||
#, c-format
|
||||
msgid "Error closing session file '%s': %s\n"
|
||||
msgstr "Помилка закриття файла сеансу «%s»: %s\n"
|
||||
|
||||
#: ../src/core/session.c:1134
|
||||
#: ../src/core/session.c:1135
|
||||
#, c-format
|
||||
msgid "Failed to parse saved session file: %s\n"
|
||||
msgstr "Збій аналізування збереженого файла сеансу: %s\n"
|
||||
|
||||
#: ../src/core/session.c:1183
|
||||
#: ../src/core/session.c:1184
|
||||
#, c-format
|
||||
msgid "<mutter_session> attribute seen but we already have the session ID"
|
||||
msgstr "Прочитано атрибут <mutter_session>, але вже є ідентифікатор сеансу"
|
||||
|
||||
#: ../src/core/session.c:1196 ../src/core/session.c:1271
|
||||
#: ../src/core/session.c:1303 ../src/core/session.c:1375
|
||||
#: ../src/core/session.c:1435
|
||||
#: ../src/core/session.c:1197 ../src/core/session.c:1272
|
||||
#: ../src/core/session.c:1304 ../src/core/session.c:1376
|
||||
#: ../src/core/session.c:1436
|
||||
#, c-format
|
||||
msgid "Unknown attribute %s on <%s> element"
|
||||
msgstr "Невідомий атрибут %s у елементі <%s>"
|
||||
|
||||
#: ../src/core/session.c:1213
|
||||
#: ../src/core/session.c:1214
|
||||
#, c-format
|
||||
msgid "nested <window> tag"
|
||||
msgstr "вкладена мітка <window>"
|
||||
|
||||
#: ../src/core/session.c:1455
|
||||
#: ../src/core/session.c:1456
|
||||
#, c-format
|
||||
msgid "Unknown element %s"
|
||||
msgstr "Невідомий елемент %s"
|
||||
|
||||
#: ../src/core/session.c:1807
|
||||
#: ../src/core/session.c:1808
|
||||
msgid ""
|
||||
"These windows do not support "save current setup" and will have to "
|
||||
"be restarted manually next time you log in."
|
||||
@@ -519,7 +536,7 @@ msgid "Window manager error: "
|
||||
msgstr "Помилка віконного менеджера:"
|
||||
|
||||
#. first time through
|
||||
#: ../src/core/window.c:7589
|
||||
#: ../src/core/window.c:7562
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
|
||||
@@ -535,7 +552,7 @@ msgstr ""
|
||||
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
|
||||
#. * about these apps but make them work.
|
||||
#.
|
||||
#: ../src/core/window.c:8513
|
||||
#: ../src/core/window.c:8487
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
|
||||
@@ -545,22 +562,22 @@ msgstr ""
|
||||
"змінюватись, але встановило мінімальний розмір %d x %d та максимальний %d x "
|
||||
"%d;, в чому не має сенсу.\n"
|
||||
|
||||
#: ../src/core/window-props.c:348
|
||||
#: ../src/core/window-props.c:349
|
||||
#, c-format
|
||||
msgid "Application set a bogus _NET_WM_PID %lu\n"
|
||||
msgstr "Програма встановила неправильне значення параметра _NET_WM_PID %lu\n"
|
||||
|
||||
#: ../src/core/window-props.c:464
|
||||
#: ../src/core/window-props.c:465
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (на %s)"
|
||||
|
||||
#: ../src/core/window-props.c:1547
|
||||
#: ../src/core/window-props.c:1548
|
||||
#, c-format
|
||||
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
|
||||
msgstr "Неправильний параметр WM_TRANSIENT_FOR вікна 0x%lx вказано для %s.\n"
|
||||
|
||||
#: ../src/core/window-props.c:1558
|
||||
#: ../src/core/window-props.c:1559
|
||||
#, c-format
|
||||
msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n"
|
||||
msgstr "Вікно WM_TRANSIENT_FOR 0x%lx для %s створило б петлю.\n"
|
||||
@@ -683,11 +700,6 @@ msgid "Delay focus changes until the pointer stops moving"
|
||||
msgstr "Затримувати зміни фокусу, поки вказівник не перестане рухатись"
|
||||
|
||||
#: ../src/org.gnome.mutter.gschema.xml.in.h:14
|
||||
#| msgid ""
|
||||
#| "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then "
|
||||
#| "the focused window will be automatically raised after a delay specified "
|
||||
#| "by the auto_raise_delay key. This is not related to clicking on a window "
|
||||
#| "to raise it, nor to entering a window during drag-and-drop."
|
||||
msgid ""
|
||||
"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then "
|
||||
"the focus will not be changed immediately when entering a window, but only "
|
||||
|
@@ -132,8 +132,11 @@ libmutter_la_SOURCES = \
|
||||
core/screen-private.h \
|
||||
meta/screen.h \
|
||||
meta/types.h \
|
||||
core/restart.c \
|
||||
core/session.c \
|
||||
core/session.h \
|
||||
core/stereo.c \
|
||||
core/stereo.h \
|
||||
core/stack.c \
|
||||
core/stack.h \
|
||||
core/stack-tracker.c \
|
||||
@@ -220,6 +223,10 @@ bin_PROGRAMS=mutter
|
||||
mutter_SOURCES = core/mutter.c
|
||||
mutter_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
|
||||
libexec_PROGRAMS = mutter-restart-helper
|
||||
mutter_restart_helper_SOURCES = core/restart-helper.c
|
||||
mutter_restart_helper_LDADD = $(MUTTER_LIBS)
|
||||
|
||||
if HAVE_INTROSPECTION
|
||||
include $(INTROSPECTION_MAKEFILE)
|
||||
|
||||
|
@@ -26,6 +26,8 @@ struct _MetaCompositor
|
||||
gint64 server_time_query_time;
|
||||
gint64 server_time_offset;
|
||||
|
||||
int glx_opcode;
|
||||
|
||||
guint server_time_is_monotonic_time : 1;
|
||||
guint show_redraw : 1;
|
||||
guint debug : 1;
|
||||
@@ -51,6 +53,9 @@ struct _MetaCompScreen
|
||||
|
||||
gint switch_workspace_in_progress;
|
||||
|
||||
guint stereo_tree_ext : 1;
|
||||
guint have_stereo_windows : 1;
|
||||
|
||||
MetaPluginManager *plugin_mgr;
|
||||
};
|
||||
|
||||
@@ -72,4 +77,9 @@ gint64 meta_compositor_monotonic_time_to_server_time (MetaDisplay *display,
|
||||
|
||||
void meta_check_end_modal (MetaScreen *screen);
|
||||
|
||||
gboolean meta_compositor_window_is_stereo (MetaScreen *screen,
|
||||
Window xwindow);
|
||||
void meta_compositor_select_stereo_notify (MetaScreen *screen,
|
||||
Window xwindow);
|
||||
|
||||
#endif /* META_COMPOSITOR_PRIVATE_H */
|
||||
|
@@ -74,7 +74,8 @@
|
||||
#include "meta-window-actor-private.h"
|
||||
#include "meta-window-group.h"
|
||||
#include "window-private.h" /* to check window->hidden */
|
||||
#include "display-private.h" /* for meta_display_lookup_x_window() */
|
||||
#include "display-private.h"
|
||||
#include "stereo.h"
|
||||
#include "util-private.h"
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
@@ -181,6 +182,10 @@ get_output_window (MetaScreen *screen)
|
||||
xroot = meta_screen_get_xroot (screen);
|
||||
output = XCompositeGetOverlayWindow (xdisplay, xroot);
|
||||
|
||||
/* Now that we've gotten taken a reference count on the COW, we
|
||||
* can close the helper that is holding on to it */
|
||||
meta_restart_finish ();
|
||||
|
||||
meta_core_add_old_event_mask (xdisplay, output, &mask);
|
||||
|
||||
XISetMask (mask.mask, XI_KeyPress);
|
||||
@@ -540,6 +545,101 @@ redirect_windows (MetaCompositor *compositor,
|
||||
}
|
||||
}
|
||||
|
||||
#define GLX_STEREO_TREE_EXT 0x20F5
|
||||
#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001
|
||||
#define GLX_STEREO_NOTIFY_EXT 0x00000000
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
unsigned long serial;
|
||||
Bool send_event;
|
||||
Display *display;
|
||||
int extension;
|
||||
int evtype;
|
||||
Drawable window;
|
||||
Bool stereo_tree;
|
||||
} StereoNotifyEvent;
|
||||
|
||||
static gboolean
|
||||
screen_has_stereo_tree_ext (MetaScreen *screen)
|
||||
{
|
||||
#if 0
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
const char *extensions_string;
|
||||
|
||||
static const char * (*query_extensions_string) (Display *display,
|
||||
int screen);
|
||||
|
||||
if (query_extensions_string == NULL)
|
||||
query_extensions_string =
|
||||
(const char * (*) (Display *, int))
|
||||
cogl_get_proc_address ("glXQueryExtensionsString");
|
||||
|
||||
extensions_string = query_extensions_string (xdisplay,
|
||||
meta_screen_get_screen_number (screen));
|
||||
|
||||
return strstr (extensions_string, "EXT_stereo_tree") != 0;
|
||||
#else
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
gboolean
|
||||
meta_compositor_window_is_stereo (MetaScreen *screen,
|
||||
Window xwindow)
|
||||
{
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
|
||||
static int (*query_drawable) (Display *dpy,
|
||||
Drawable draw,
|
||||
int attribute,
|
||||
unsigned int *value);
|
||||
|
||||
if (info->stereo_tree_ext)
|
||||
{
|
||||
unsigned int stereo_tree = 0;
|
||||
|
||||
if (query_drawable == NULL)
|
||||
query_drawable =
|
||||
(int (*) (Display *, Drawable, int, unsigned int *))
|
||||
cogl_get_proc_address ("glXQueryDrawable");
|
||||
|
||||
query_drawable (xdisplay, xwindow, GLX_STEREO_TREE_EXT, &stereo_tree);
|
||||
|
||||
return stereo_tree != 0;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_select_stereo_notify (MetaScreen *screen,
|
||||
Window xwindow)
|
||||
{
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
|
||||
static void (*select_event) (Display *dpy,
|
||||
Drawable draw,
|
||||
unsigned long event_mask);
|
||||
|
||||
if (info->stereo_tree_ext)
|
||||
{
|
||||
if (select_event == NULL)
|
||||
select_event =
|
||||
(void (*) (Display *, Drawable, unsigned long))
|
||||
cogl_get_proc_address ("glXSelectEvent");
|
||||
|
||||
select_event (xdisplay, xwindow, GLX_STEREO_NOTIFY_MASK_EXT);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||
MetaScreen *screen)
|
||||
@@ -562,14 +662,14 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||
info->output = None;
|
||||
info->windows = NULL;
|
||||
|
||||
info->stereo_tree_ext = screen_has_stereo_tree_ext (screen);
|
||||
|
||||
meta_screen_set_cm_selection (screen);
|
||||
|
||||
info->stage = clutter_stage_new ();
|
||||
|
||||
clutter_stage_set_paint_callback (CLUTTER_STAGE (info->stage),
|
||||
after_stage_paint,
|
||||
info,
|
||||
NULL);
|
||||
g_signal_connect (CLUTTER_STAGE (info->stage), "after-paint",
|
||||
G_CALLBACK (after_stage_paint), info);
|
||||
|
||||
clutter_stage_set_sync_delay (CLUTTER_STAGE (info->stage), META_SYNC_DELAY);
|
||||
|
||||
@@ -952,6 +1052,22 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
||||
}
|
||||
}
|
||||
|
||||
if (event->type == GenericEvent &&
|
||||
event->xcookie.extension == compositor->glx_opcode)
|
||||
{
|
||||
if (event->xcookie.evtype == GLX_STEREO_NOTIFY_EXT)
|
||||
{
|
||||
StereoNotifyEvent *stereo_event = (StereoNotifyEvent *)(event->xcookie.data);
|
||||
window = meta_display_lookup_x_window (compositor->display, stereo_event->window);
|
||||
|
||||
if (window != NULL)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
meta_window_actor_stereo_notify (window_actor, stereo_event->stereo_tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify)
|
||||
{
|
||||
/* Core code doesn't handle damage events, so we need to extract the MetaWindow
|
||||
@@ -1179,6 +1295,7 @@ meta_compositor_sync_stack (MetaCompositor *compositor,
|
||||
{
|
||||
GList *old_stack;
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
int stereo_window_count = 0;
|
||||
|
||||
DEBUG_TRACE ("meta_compositor_sync_stack\n");
|
||||
|
||||
@@ -1256,12 +1373,16 @@ meta_compositor_sync_stack (MetaCompositor *compositor,
|
||||
* near the front of the other.)
|
||||
*/
|
||||
info->windows = g_list_prepend (info->windows, actor);
|
||||
if (meta_window_actor_is_stereo (actor))
|
||||
stereo_window_count++;
|
||||
|
||||
stack = g_list_remove (stack, window);
|
||||
old_stack = g_list_remove (old_stack, actor);
|
||||
}
|
||||
|
||||
sync_actor_stacking (info);
|
||||
|
||||
meta_stereo_set_have_stereo_windows (stereo_window_count > 0);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1427,6 +1548,7 @@ MetaCompositor *
|
||||
meta_compositor_new (MetaDisplay *display)
|
||||
{
|
||||
MetaCompositor *compositor;
|
||||
int glx_major_opcode, glx_first_event, glx_first_error;
|
||||
|
||||
if (!composite_at_least_version (display, 0, 3))
|
||||
return NULL;
|
||||
@@ -1446,6 +1568,10 @@ meta_compositor_new (MetaDisplay *display)
|
||||
compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func,
|
||||
compositor,
|
||||
NULL);
|
||||
if (XQueryExtension (meta_display_get_xdisplay (display),
|
||||
"GLX",
|
||||
&glx_major_opcode, &glx_first_event, &glx_first_error))
|
||||
compositor->glx_opcode = glx_major_opcode;
|
||||
|
||||
return compositor;
|
||||
}
|
||||
|
@@ -31,7 +31,8 @@
|
||||
|
||||
ClutterActor *meta_shaped_texture_new (void);
|
||||
void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
|
||||
CoglTexture *texture);
|
||||
CoglTexture *texture,
|
||||
gboolean stereo);
|
||||
gboolean meta_shaped_texture_get_unobscured_bounds (MetaShapedTexture *stex,
|
||||
cairo_rectangle_int_t *unobscured_bounds);
|
||||
gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self);
|
||||
|
@@ -36,6 +36,7 @@
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <cogl/cogl-texture-pixmap-x11.h>
|
||||
#include <gdk/gdk.h> /* for gdk_rectangle_intersect() */
|
||||
#include "meta-cullable.h"
|
||||
|
||||
@@ -69,8 +70,10 @@ G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_AC
|
||||
struct _MetaShapedTexturePrivate
|
||||
{
|
||||
MetaTextureTower *paint_tower;
|
||||
MetaTextureTower *paint_tower_right;
|
||||
|
||||
CoglTexture *texture;
|
||||
CoglTexture *texture_right;
|
||||
CoglTexture *mask_texture;
|
||||
|
||||
cairo_region_t *input_shape_region;
|
||||
@@ -84,6 +87,7 @@ struct _MetaShapedTexturePrivate
|
||||
|
||||
guint tex_width, tex_height;
|
||||
|
||||
guint stereo : 1;
|
||||
guint create_mipmaps : 1;
|
||||
};
|
||||
|
||||
@@ -112,8 +116,10 @@ meta_shaped_texture_init (MetaShapedTexture *self)
|
||||
priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self);
|
||||
|
||||
priv->paint_tower = meta_texture_tower_new ();
|
||||
priv->paint_tower_right = NULL; /* demand create */
|
||||
|
||||
priv->texture = NULL;
|
||||
priv->texture_right = NULL;
|
||||
priv->mask_texture = NULL;
|
||||
priv->create_mipmaps = TRUE;
|
||||
}
|
||||
@@ -150,11 +156,10 @@ meta_shaped_texture_dispose (GObject *object)
|
||||
MetaShapedTexture *self = (MetaShapedTexture *) object;
|
||||
MetaShapedTexturePrivate *priv = self->priv;
|
||||
|
||||
if (priv->paint_tower)
|
||||
meta_texture_tower_free (priv->paint_tower);
|
||||
priv->paint_tower = NULL;
|
||||
|
||||
g_clear_pointer (&priv->paint_tower, meta_texture_tower_free);
|
||||
g_clear_pointer (&priv->paint_tower_right, meta_texture_tower_free);
|
||||
g_clear_pointer (&priv->texture, cogl_object_unref);
|
||||
g_clear_pointer (&priv->texture_right, cogl_object_unref);
|
||||
g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
|
||||
|
||||
meta_shaped_texture_set_mask_texture (self, NULL);
|
||||
@@ -233,49 +238,20 @@ paint_clipped_rectangle (CoglFramebuffer *fb,
|
||||
}
|
||||
|
||||
static void
|
||||
meta_shaped_texture_paint (ClutterActor *actor)
|
||||
paint_texture (MetaShapedTexture *stex,
|
||||
CoglTexture *paint_tex)
|
||||
{
|
||||
MetaShapedTexture *stex = (MetaShapedTexture *) actor;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (stex);
|
||||
MetaShapedTexturePrivate *priv = stex->priv;
|
||||
guint tex_width, tex_height;
|
||||
guchar opacity;
|
||||
CoglContext *ctx;
|
||||
CoglFramebuffer *fb;
|
||||
CoglPipeline *pipeline = NULL;
|
||||
CoglTexture *paint_tex;
|
||||
ClutterActorBox alloc;
|
||||
cairo_region_t *blended_region = NULL;
|
||||
CoglPipelineFilter filter;
|
||||
|
||||
if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
|
||||
return;
|
||||
|
||||
if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
|
||||
clutter_actor_realize (CLUTTER_ACTOR (stex));
|
||||
|
||||
/* The GL EXT_texture_from_pixmap extension does allow for it to be
|
||||
* used together with SGIS_generate_mipmap, however this is very
|
||||
* rarely supported. Also, even when it is supported there
|
||||
* are distinct performance implications from:
|
||||
*
|
||||
* - Updating mipmaps that we don't need
|
||||
* - Having to reallocate pixmaps on the server into larger buffers
|
||||
*
|
||||
* So, we just unconditionally use our mipmap emulation code. If we
|
||||
* wanted to use SGIS_generate_mipmap, we'd have to query COGL to
|
||||
* see if it was supported (no API currently), and then if and only
|
||||
* if that was the case, set the clutter texture quality to HIGH.
|
||||
* Setting the texture quality to high without SGIS_generate_mipmap
|
||||
* support for TFP textures will result in fallbacks to XGetImage.
|
||||
*/
|
||||
if (priv->create_mipmaps)
|
||||
paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower);
|
||||
else
|
||||
paint_tex = COGL_TEXTURE (priv->texture);
|
||||
|
||||
if (paint_tex == NULL)
|
||||
return;
|
||||
|
||||
tex_width = priv->tex_width;
|
||||
tex_height = priv->tex_height;
|
||||
|
||||
@@ -291,8 +267,8 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
if (!clutter_actor_is_in_clone_paint (actor) && meta_actor_is_untransformed (actor, NULL, NULL))
|
||||
filter = COGL_PIPELINE_FILTER_NEAREST;
|
||||
|
||||
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
fb = cogl_get_draw_framebuffer ();
|
||||
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
|
||||
opacity = clutter_actor_get_paint_opacity (actor);
|
||||
clutter_actor_get_allocation_box (actor, &alloc);
|
||||
@@ -415,6 +391,74 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
cairo_region_destroy (blended_region);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_shaped_texture_paint (ClutterActor *actor)
|
||||
{
|
||||
MetaShapedTexture *stex = (MetaShapedTexture *) actor;
|
||||
MetaShapedTexturePrivate *priv = stex->priv;
|
||||
CoglFramebuffer *fb;
|
||||
gboolean stereo;
|
||||
CoglTexture *paint_tex;
|
||||
CoglTexture *paint_tex_right;
|
||||
|
||||
if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
|
||||
return;
|
||||
|
||||
if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
|
||||
clutter_actor_realize (CLUTTER_ACTOR (stex));
|
||||
|
||||
/* The GL EXT_texture_from_pixmap extension does allow for it to be
|
||||
* used together with SGIS_generate_mipmap, however this is very
|
||||
* rarely supported. Also, even when it is supported there
|
||||
* are distinct performance implications from:
|
||||
*
|
||||
* - Updating mipmaps that we don't need
|
||||
* - Having to reallocate pixmaps on the server into larger buffers
|
||||
*
|
||||
* So, we just unconditionally use our mipmap emulation code. If we
|
||||
* wanted to use SGIS_generate_mipmap, we'd have to query COGL to
|
||||
* see if it was supported (no API currently), and then if and only
|
||||
* if that was the case, set the clutter texture quality to HIGH.
|
||||
* Setting the texture quality to high without SGIS_generate_mipmap
|
||||
* support for TFP textures will result in fallbacks to XGetImage.
|
||||
*/
|
||||
if (priv->create_mipmaps)
|
||||
paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower);
|
||||
else
|
||||
paint_tex = COGL_TEXTURE (priv->texture);
|
||||
|
||||
fb = cogl_get_draw_framebuffer ();
|
||||
|
||||
stereo = priv->stereo && cogl_framebuffer_get_is_stereo (fb);
|
||||
|
||||
if (stereo)
|
||||
{
|
||||
if (priv->create_mipmaps)
|
||||
paint_tex_right = meta_texture_tower_get_paint_texture (priv->paint_tower_right);
|
||||
else
|
||||
paint_tex_right = COGL_TEXTURE (priv->texture_right);
|
||||
}
|
||||
else
|
||||
paint_tex_right = NULL;
|
||||
|
||||
if (paint_tex != NULL)
|
||||
{
|
||||
if (stereo)
|
||||
cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_LEFT);
|
||||
else
|
||||
cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_BOTH);
|
||||
|
||||
paint_texture (stex, paint_tex);
|
||||
}
|
||||
|
||||
if (paint_tex_right != NULL)
|
||||
{
|
||||
cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_RIGHT);
|
||||
paint_texture (stex, paint_tex_right);
|
||||
cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_BOTH);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_shaped_texture_pick (ClutterActor *actor,
|
||||
const ClutterColor *color)
|
||||
@@ -570,6 +614,12 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
|
||||
priv->create_mipmaps = create_mipmaps;
|
||||
base_texture = create_mipmaps ? priv->texture : NULL;
|
||||
meta_texture_tower_set_base_texture (priv->paint_tower, base_texture);
|
||||
|
||||
if (priv->stereo)
|
||||
{
|
||||
base_texture = create_mipmaps ? priv->texture_right : NULL;
|
||||
meta_texture_tower_set_base_texture (priv->paint_tower_right, base_texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -668,6 +718,8 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
||||
return FALSE;
|
||||
|
||||
meta_texture_tower_update_area (priv->paint_tower, x, y, width, height);
|
||||
if (priv->stereo)
|
||||
meta_texture_tower_update_area (priv->paint_tower_right, x, y, width, height);
|
||||
|
||||
unobscured_region = effective_unobscured_region (stex);
|
||||
if (unobscured_region)
|
||||
@@ -701,7 +753,8 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
||||
|
||||
static void
|
||||
set_cogl_texture (MetaShapedTexture *stex,
|
||||
CoglTexture *cogl_tex)
|
||||
CoglTexture *cogl_tex,
|
||||
gboolean stereo)
|
||||
{
|
||||
MetaShapedTexturePrivate *priv;
|
||||
guint width, height;
|
||||
@@ -712,8 +765,23 @@ set_cogl_texture (MetaShapedTexture *stex,
|
||||
|
||||
if (priv->texture != NULL)
|
||||
cogl_object_unref (priv->texture);
|
||||
if (priv->texture_right != NULL)
|
||||
cogl_object_unref (priv->texture_right);
|
||||
|
||||
priv->stereo = stereo;
|
||||
|
||||
priv->texture = cogl_tex;
|
||||
if (priv->stereo)
|
||||
{
|
||||
priv->texture_right = cogl_texture_pixmap_x11_new_right ((CoglTexturePixmapX11 *)cogl_tex);
|
||||
if (priv->paint_tower_right == NULL)
|
||||
priv->paint_tower_right = meta_texture_tower_new ();
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->texture_right = NULL;
|
||||
g_clear_pointer (&priv->paint_tower_right, meta_texture_tower_free);
|
||||
}
|
||||
|
||||
if (cogl_tex != NULL)
|
||||
{
|
||||
@@ -743,7 +811,11 @@ set_cogl_texture (MetaShapedTexture *stex,
|
||||
* damage. */
|
||||
|
||||
if (priv->create_mipmaps)
|
||||
meta_texture_tower_set_base_texture (priv->paint_tower, cogl_tex);
|
||||
{
|
||||
meta_texture_tower_set_base_texture (priv->paint_tower, cogl_tex);
|
||||
if (priv->stereo)
|
||||
meta_texture_tower_set_base_texture (priv->paint_tower_right, priv->texture_right);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -753,11 +825,12 @@ set_cogl_texture (MetaShapedTexture *stex,
|
||||
*/
|
||||
void
|
||||
meta_shaped_texture_set_texture (MetaShapedTexture *stex,
|
||||
CoglTexture *texture)
|
||||
CoglTexture *texture,
|
||||
gboolean stereo)
|
||||
{
|
||||
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
|
||||
|
||||
set_cogl_texture (stex, texture);
|
||||
set_cogl_texture (stex, texture, stereo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -58,4 +58,11 @@ void meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
|
||||
void meta_window_actor_effect_completed (MetaWindowActor *actor,
|
||||
gulong event);
|
||||
|
||||
void meta_window_actor_stereo_notify (MetaWindowActor *actor,
|
||||
gboolean stereo_tree);
|
||||
|
||||
gboolean meta_window_actor_is_stereo (MetaWindowActor *actor);
|
||||
|
||||
void meta_window_actor_detach (MetaWindowActor *self);
|
||||
|
||||
#endif /* META_WINDOW_ACTOR_PRIVATE_H */
|
||||
|
@@ -94,6 +94,7 @@ struct _MetaWindowActorPrivate
|
||||
|
||||
guint visible : 1;
|
||||
guint argb32 : 1;
|
||||
guint stereo : 1;
|
||||
guint disposed : 1;
|
||||
guint redecorating : 1;
|
||||
|
||||
@@ -157,7 +158,6 @@ static gboolean meta_window_actor_get_paint_volume (ClutterActor *actor,
|
||||
ClutterPaintVolume *volume);
|
||||
|
||||
|
||||
static void meta_window_actor_detach (MetaWindowActor *self);
|
||||
static gboolean meta_window_actor_has_shadow (MetaWindowActor *self);
|
||||
|
||||
static void meta_window_actor_handle_updates (MetaWindowActor *self);
|
||||
@@ -318,6 +318,9 @@ meta_window_actor_constructed (GObject *object)
|
||||
if (format && format->type == PictTypeDirect && format->direct.alphaMask)
|
||||
priv->argb32 = TRUE;
|
||||
|
||||
priv->stereo = meta_compositor_window_is_stereo (screen, xwindow);
|
||||
meta_compositor_select_stereo_notify (screen, xwindow);
|
||||
|
||||
if (!priv->actor)
|
||||
{
|
||||
priv->actor = meta_shaped_texture_new ();
|
||||
@@ -968,27 +971,6 @@ is_frozen (MetaWindowActor *self)
|
||||
return self->priv->freeze_count ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_queue_create_pixmap (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
priv->needs_pixmap = TRUE;
|
||||
|
||||
if (is_frozen (self))
|
||||
return;
|
||||
|
||||
/* This will cause the compositor paint function to be run
|
||||
* if the actor is visible or a clone of the actor is visible.
|
||||
* if the actor isn't visible in any way, then we don't
|
||||
* need to repair the window anyways, and can wait until
|
||||
* the stage is redrawn for some other reason
|
||||
*
|
||||
* The compositor paint function repairs all windows.
|
||||
*/
|
||||
clutter_actor_queue_redraw (priv->actor);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_freeze_thaw_effect (gulong event)
|
||||
{
|
||||
@@ -1151,7 +1133,7 @@ meta_window_actor_effect_completed (MetaWindowActor *self,
|
||||
* when the window is unmapped or when we want to update to a new
|
||||
* pixmap for a new size.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
meta_window_actor_detach (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
@@ -1166,13 +1148,13 @@ meta_window_actor_detach (MetaWindowActor *self)
|
||||
* you are supposed to be able to free a GLXPixmap after freeing the underlying
|
||||
* pixmap, but it certainly doesn't work with current DRI/Mesa
|
||||
*/
|
||||
meta_shaped_texture_set_texture (META_SHAPED_TEXTURE (priv->actor), NULL);
|
||||
meta_shaped_texture_set_texture (META_SHAPED_TEXTURE (priv->actor), NULL, FALSE);
|
||||
cogl_flush();
|
||||
|
||||
XFreePixmap (xdisplay, priv->back_pixmap);
|
||||
priv->back_pixmap = None;
|
||||
|
||||
meta_window_actor_queue_create_pixmap (self);
|
||||
priv->needs_pixmap = TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -1311,7 +1293,7 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
|
||||
|
||||
if (priv->size_changed)
|
||||
{
|
||||
meta_window_actor_queue_create_pixmap (self);
|
||||
priv->needs_pixmap = TRUE;
|
||||
meta_window_actor_update_shape (self);
|
||||
}
|
||||
|
||||
@@ -1484,7 +1466,7 @@ meta_window_actor_new (MetaWindow *window)
|
||||
priv->last_width = -1;
|
||||
priv->last_height = -1;
|
||||
|
||||
meta_window_actor_queue_create_pixmap (self);
|
||||
priv->needs_pixmap = TRUE;
|
||||
|
||||
meta_window_actor_set_updates_frozen (self,
|
||||
meta_window_updates_are_frozen (priv->window));
|
||||
@@ -1690,11 +1672,15 @@ check_needs_pixmap (MetaWindowActor *self)
|
||||
meta_shaped_texture_set_create_mipmaps (META_SHAPED_TEXTURE (priv->actor),
|
||||
FALSE);
|
||||
|
||||
texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->back_pixmap, FALSE, NULL));
|
||||
if (priv->stereo)
|
||||
texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new_left (ctx, priv->back_pixmap, FALSE, NULL));
|
||||
else
|
||||
texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->back_pixmap, FALSE, NULL));
|
||||
|
||||
if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture))))
|
||||
g_warning ("NOTE: Not using GLX TFP!\n");
|
||||
|
||||
meta_shaped_texture_set_texture (META_SHAPED_TEXTURE (priv->actor), texture);
|
||||
meta_shaped_texture_set_texture (META_SHAPED_TEXTURE (priv->actor), texture, priv->stereo);
|
||||
}
|
||||
|
||||
priv->needs_pixmap = FALSE;
|
||||
@@ -2371,3 +2357,20 @@ meta_window_actor_set_updates_frozen (MetaWindowActor *self,
|
||||
meta_window_actor_thaw (self);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_stereo_notify (MetaWindowActor *self,
|
||||
gboolean stereo_tree)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaWindow *window = priv->window;
|
||||
|
||||
priv->stereo = stereo_tree;
|
||||
meta_window_actor_detach (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_window_actor_is_stereo (MetaWindowActor *self)
|
||||
{
|
||||
return self->priv->stereo;
|
||||
}
|
||||
|
@@ -33,7 +33,9 @@ typedef enum
|
||||
META_DO_GRAVITY_ADJUST = 1 << 1,
|
||||
META_IS_USER_ACTION = 1 << 2,
|
||||
META_IS_MOVE_ACTION = 1 << 3,
|
||||
META_IS_RESIZE_ACTION = 1 << 4
|
||||
META_IS_RESIZE_ACTION = 1 << 4,
|
||||
META_FORCE_STATIC_GRAVITY = 1 << 5,
|
||||
META_IS_INITIAL_RESIZE = 1 << 6
|
||||
} MetaMoveResizeFlags;
|
||||
|
||||
void meta_window_constrain (MetaWindow *window,
|
||||
|
@@ -483,4 +483,11 @@ void meta_display_set_input_focus_xwindow (MetaDisplay *display,
|
||||
Window window,
|
||||
guint32 timestamp);
|
||||
|
||||
gboolean meta_display_show_restart_message (MetaDisplay *display,
|
||||
const char *message);
|
||||
gboolean meta_display_request_restart (MetaDisplay *display);
|
||||
|
||||
void meta_restart_init (void);
|
||||
void meta_restart_finish (void);
|
||||
|
||||
#endif
|
||||
|
@@ -130,6 +130,8 @@ enum
|
||||
WINDOW_MARKED_URGENT,
|
||||
GRAB_OP_BEGIN,
|
||||
GRAB_OP_END,
|
||||
SHOW_RESTART_MESSAGE,
|
||||
RESTART,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@@ -306,6 +308,59 @@ meta_display_class_init (MetaDisplayClass *klass)
|
||||
META_TYPE_WINDOW,
|
||||
META_TYPE_GRAB_OP);
|
||||
|
||||
/**
|
||||
* MetaDisplay::show-restart-message:
|
||||
* @display: the #MetaDisplay instance
|
||||
* @message: (allow-none): The message to display, or %NULL
|
||||
* to clear a previous restart message.
|
||||
*
|
||||
* The ::show-restart-message signal will be emitted to indicate
|
||||
* that the compositor should show a message during restart. This is
|
||||
* emitted when meta_restart() is called, either by Mutter
|
||||
* internally or by the embedding compositor. The message should be
|
||||
* immediately added to the Clutter stage in its final form -
|
||||
* ::restart will be emitted to exit the application and leave the
|
||||
* stage contents frozen as soon as the the stage is painted again.
|
||||
*
|
||||
* On case of failure to restart, this signal will be emitted again
|
||||
* with %NULL for @message.
|
||||
*
|
||||
* Returns: %TRUE means the message was added to the stage; %FALSE
|
||||
* indicates that the compositor did not show the message.
|
||||
*/
|
||||
display_signals[SHOW_RESTART_MESSAGE] =
|
||||
g_signal_new ("show-restart-message",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
g_signal_accumulator_true_handled,
|
||||
NULL, NULL,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
G_TYPE_STRING);
|
||||
|
||||
/**
|
||||
* MetaDisplay::restart:
|
||||
* @display: the #MetaDisplay instance
|
||||
*
|
||||
* The ::restart signal is emitted to indicate that compositor
|
||||
* should reexec the process. This is
|
||||
* emitted when meta_restart() is called, either by Mutter
|
||||
* internally or by the embedding compositor. See also
|
||||
* ::show-restart-message.
|
||||
*
|
||||
* Returns: %FALSE to indicate that the compositor could not
|
||||
* be restarted. When the compositor is restarted, the signal
|
||||
* should not return.
|
||||
*/
|
||||
display_signals[RESTART] =
|
||||
g_signal_new ("restart",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
g_signal_accumulator_true_handled,
|
||||
NULL, NULL,
|
||||
G_TYPE_BOOLEAN, 0);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_FOCUS_WINDOW,
|
||||
g_param_spec_object ("focus-window",
|
||||
@@ -2781,14 +2836,14 @@ event_callback (XEvent *event,
|
||||
&& meta_display_screen_for_root (display, event->xmap.event))
|
||||
{
|
||||
window = meta_window_new (display, event->xmap.window,
|
||||
FALSE, META_COMP_EFFECT_CREATE);
|
||||
FALSE, FALSE);
|
||||
}
|
||||
break;
|
||||
case MapRequest:
|
||||
if (window == NULL)
|
||||
{
|
||||
window = meta_window_new (display, event->xmaprequest.window,
|
||||
FALSE, META_COMP_EFFECT_CREATE);
|
||||
FALSE, FALSE);
|
||||
}
|
||||
/* if frame was receiver it's some malicious send event or something */
|
||||
else if (!frame_was_receiver && window)
|
||||
@@ -5939,3 +5994,28 @@ meta_display_clear_mouse_mode (MetaDisplay *display)
|
||||
{
|
||||
display->mouse_mode = FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_display_show_restart_message (MetaDisplay *display,
|
||||
const char *message)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
|
||||
g_signal_emit (display,
|
||||
display_signals[SHOW_RESTART_MESSAGE], 0,
|
||||
message, &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_display_request_restart (MetaDisplay *display)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
|
||||
g_signal_emit (display,
|
||||
display_signals[RESTART], 0,
|
||||
&result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@@ -2522,7 +2522,19 @@ handle_switch_to_workspace (MetaDisplay *display,
|
||||
gint which = binding->handler->data;
|
||||
MetaWorkspace *workspace;
|
||||
|
||||
workspace = meta_screen_get_workspace_by_index (screen, which);
|
||||
if (which < 0)
|
||||
{
|
||||
/* Negative workspace numbers are directions with respect to the
|
||||
* current workspace.
|
||||
*/
|
||||
|
||||
workspace = meta_workspace_get_neighbor (screen->active_workspace,
|
||||
which);
|
||||
}
|
||||
else
|
||||
{
|
||||
workspace = meta_screen_get_workspace_by_index (screen, which);
|
||||
}
|
||||
|
||||
if (workspace)
|
||||
{
|
||||
@@ -3359,28 +3371,28 @@ init_builtin_key_bindings (MetaDisplay *display)
|
||||
common_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_LEFT,
|
||||
NULL, 0);
|
||||
handle_switch_to_workspace, META_MOTION_LEFT);
|
||||
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-workspace-right",
|
||||
common_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_RIGHT,
|
||||
NULL, 0);
|
||||
handle_switch_to_workspace, META_MOTION_RIGHT);
|
||||
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-workspace-up",
|
||||
common_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_UP,
|
||||
NULL, 0);
|
||||
handle_switch_to_workspace, META_MOTION_UP);
|
||||
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-workspace-down",
|
||||
common_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_DOWN,
|
||||
NULL, 0);
|
||||
handle_switch_to_workspace, META_MOTION_DOWN);
|
||||
|
||||
|
||||
/* The ones which have inverses. These can't be bound to any keystroke
|
||||
|
@@ -51,6 +51,7 @@
|
||||
#include <meta/errors.h>
|
||||
#include "ui.h"
|
||||
#include "session.h"
|
||||
#include "stereo.h"
|
||||
#include <meta/prefs.h>
|
||||
#include <meta/compositor.h>
|
||||
|
||||
@@ -444,6 +445,10 @@ meta_init (void)
|
||||
|
||||
meta_ui_init ();
|
||||
|
||||
meta_restart_init ();
|
||||
|
||||
meta_stereo_init ();
|
||||
|
||||
/*
|
||||
* Clutter can only be initialized after the UI.
|
||||
*/
|
||||
|
@@ -778,6 +778,9 @@ create_monitor_skeleton (GDBusObjectManagerServer *manager,
|
||||
meta_dbus_object_skeleton_set_idle_monitor (object, skeleton);
|
||||
|
||||
g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
|
||||
|
||||
g_object_unref (skeleton);
|
||||
g_object_unref (object);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -77,6 +77,7 @@ struct _MetaMonitorConfig {
|
||||
GHashTable *configs;
|
||||
MetaConfiguration *current;
|
||||
gboolean current_is_stored;
|
||||
gboolean current_is_for_laptop_lid;
|
||||
MetaConfiguration *previous;
|
||||
|
||||
GFile *file;
|
||||
@@ -876,7 +877,8 @@ apply_configuration (MetaMonitorConfig *self,
|
||||
|
||||
/* Stored (persistent) configurations override the previous one always.
|
||||
Also, we clear the previous configuration if the current one (which is
|
||||
about to become previous) is stored.
|
||||
about to become previous) is stored, or if the current one has
|
||||
different outputs.
|
||||
*/
|
||||
if (stored ||
|
||||
(self->current && self->current_is_stored))
|
||||
@@ -887,11 +889,27 @@ apply_configuration (MetaMonitorConfig *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
self->previous = self->current;
|
||||
/* Despite the name, config_equal() only checks the set of outputs,
|
||||
not their modes
|
||||
*/
|
||||
if (self->current && config_equal (self->current, config))
|
||||
{
|
||||
self->previous = self->current;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self->current)
|
||||
config_free (self->current);
|
||||
self->previous = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
self->current = config;
|
||||
self->current_is_stored = stored;
|
||||
/* If true, we'll be overridden at the end of this call
|
||||
inside turn_off_laptop_display()
|
||||
*/
|
||||
self->current_is_for_laptop_lid = FALSE;
|
||||
|
||||
if (self->current == self->previous)
|
||||
self->previous = NULL;
|
||||
@@ -1008,8 +1026,16 @@ meta_monitor_config_apply_stored (MetaMonitorConfig *self,
|
||||
if (self->lid_is_closed &&
|
||||
stored->n_outputs > 1 &&
|
||||
laptop_display_is_on (stored))
|
||||
return apply_configuration (self, make_laptop_lid_config (stored),
|
||||
manager, FALSE);
|
||||
{
|
||||
if (apply_configuration (self, make_laptop_lid_config (stored),
|
||||
manager, FALSE))
|
||||
{
|
||||
self->current_is_for_laptop_lid = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return apply_configuration (self, stored, manager, TRUE);
|
||||
}
|
||||
@@ -1356,6 +1382,7 @@ turn_off_laptop_display (MetaMonitorConfig *self,
|
||||
|
||||
new = make_laptop_lid_config (self->current);
|
||||
apply_configuration (self, new, manager, FALSE);
|
||||
self->current_is_for_laptop_lid = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1375,7 +1402,7 @@ power_client_changed_cb (UpClient *client,
|
||||
|
||||
if (is_closed)
|
||||
turn_off_laptop_display (self, manager);
|
||||
else
|
||||
else if (self->current_is_for_laptop_lid)
|
||||
meta_monitor_config_restore_previous (self, manager);
|
||||
}
|
||||
}
|
||||
|
@@ -75,6 +75,7 @@ main (int argc, char **argv)
|
||||
g_printerr ("mutter: %s\n", error->message);
|
||||
exit (1);
|
||||
}
|
||||
g_option_context_free (ctx);
|
||||
|
||||
if (plugin)
|
||||
meta_plugin_manager_load (plugin);
|
||||
|
82
src/core/restart-helper.c
Normal file
82
src/core/restart-helper.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* SECTION:restart-helper
|
||||
* @short_description: helper program during a restart
|
||||
*
|
||||
* To smoothly restart Mutter, we want to keep the composite
|
||||
* overlay window enabled during the restart. This is done by
|
||||
* spawning this program, which keeps a reference to the the composite
|
||||
* overlay window until Mutter picks it back up.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
{
|
||||
Display *display = XOpenDisplay (NULL);
|
||||
Window selection_window;
|
||||
XSetWindowAttributes xwa;
|
||||
unsigned long mask = 0;
|
||||
|
||||
xwa.override_redirect = True;
|
||||
mask |= CWOverrideRedirect;
|
||||
|
||||
|
||||
XCompositeGetOverlayWindow (display, DefaultRootWindow (display));
|
||||
|
||||
selection_window = XCreateWindow (display,
|
||||
DefaultRootWindow (display),
|
||||
-100, -100, 1, 1, 0,
|
||||
0,
|
||||
InputOnly,
|
||||
DefaultVisual (display, DefaultScreen (display)),
|
||||
mask, &xwa);
|
||||
|
||||
XSetSelectionOwner (display,
|
||||
XInternAtom (display, "_MUTTER_RESTART_HELPER", False),
|
||||
selection_window,
|
||||
CurrentTime);
|
||||
|
||||
/* Mutter looks for an (arbitrary) line printed to stdout to know that
|
||||
* we have started and have a reference to the COW. XSync() so that
|
||||
* everything is set on the X server before Mutter starts restarting.
|
||||
*/
|
||||
XSync (display, False);
|
||||
|
||||
printf ("STARTED\n");
|
||||
fflush (stdout);
|
||||
|
||||
while (True)
|
||||
{
|
||||
XEvent xev;
|
||||
|
||||
XNextEvent (display, &xev);
|
||||
/* Mutter restarted and unset the selection to indicate that
|
||||
* it has a reference on the COW again */
|
||||
if (xev.xany.type == SelectionClear)
|
||||
return 0;
|
||||
}
|
||||
}
|
208
src/core/restart.c
Normal file
208
src/core/restart.c
Normal file
@@ -0,0 +1,208 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* SECTION:restart
|
||||
* @short_description: Smoothly restart the compositor
|
||||
*
|
||||
* There are some cases where we need to restart Mutter in order
|
||||
* to deal with changes in state - the particular case inspiring
|
||||
* this is enabling or disabling stereo output. To make this
|
||||
* fairly smooth for the user, we need to do two things:
|
||||
*
|
||||
* - Display a message to the user and make sure that it is
|
||||
* actually painted before we exit.
|
||||
* - Use a helper program so that the Composite Overlay Window
|
||||
* isn't unmapped and mapped.
|
||||
*
|
||||
* This handles both of these.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <gio/gunixinputstream.h>
|
||||
|
||||
#include <meta/main.h>
|
||||
#include "ui.h"
|
||||
#include "util-private.h"
|
||||
#include "display-private.h"
|
||||
|
||||
static gboolean restart_helper_started = FALSE;
|
||||
static gboolean restart_message_shown = FALSE;
|
||||
static gboolean is_restart = FALSE;
|
||||
|
||||
void
|
||||
meta_restart_init (void)
|
||||
{
|
||||
Display *xdisplay = meta_ui_get_display ();
|
||||
Atom atom_restart_helper = XInternAtom (xdisplay, "_MUTTER_RESTART_HELPER", False);
|
||||
Window restart_helper_window = NULL;
|
||||
|
||||
restart_helper_window = XGetSelectionOwner (xdisplay, atom_restart_helper);
|
||||
if (restart_helper_window)
|
||||
is_restart = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
restart_check_ready (void)
|
||||
{
|
||||
if (restart_helper_started && restart_message_shown)
|
||||
meta_display_request_restart (meta_get_display ());
|
||||
}
|
||||
|
||||
static void
|
||||
restart_helper_read_line_callback (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gsize length;
|
||||
char *line = g_data_input_stream_read_line_finish_utf8 (G_DATA_INPUT_STREAM (source_object),
|
||||
res,
|
||||
&length, &error);
|
||||
if (line == NULL)
|
||||
{
|
||||
meta_warning ("Failed to read output from restart helper%s%s\n",
|
||||
error ? ": " : NULL,
|
||||
error ? error->message : NULL);
|
||||
}
|
||||
else
|
||||
g_free (line); /* We don't actually care what the restart helper outputs */
|
||||
|
||||
g_object_unref (source_object);
|
||||
|
||||
restart_helper_started = TRUE;
|
||||
restart_check_ready ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
restart_message_painted (gpointer data)
|
||||
{
|
||||
restart_message_shown = TRUE;
|
||||
restart_check_ready ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_restart:
|
||||
* @message: message to display to the user.
|
||||
*
|
||||
* Starts the process of restarting the compositor. Note that Mutter's
|
||||
* involvement here is to make the restart visually smooth for the
|
||||
* user - it cannot itself safely reexec a program that embeds libmuttter.
|
||||
* So in order for this to work, the compositor must handle two
|
||||
* signals - MetaDisplay::show-restart-message, to display the
|
||||
* message passed here on the Clutter stage, and ::restart to actually
|
||||
* reexec the compositor.
|
||||
*/
|
||||
void
|
||||
meta_restart (const char *message)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display();
|
||||
GError *error = NULL;
|
||||
int helper_out_fd;
|
||||
|
||||
static const char * const helper_argv[] = {
|
||||
MUTTER_LIBEXECDIR "/mutter-restart-helper", NULL
|
||||
};
|
||||
|
||||
if (meta_display_show_restart_message (display, message))
|
||||
{
|
||||
/* Wait until the stage was painted */
|
||||
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
|
||||
restart_message_painted,
|
||||
NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Can't show the message, show the message as soon as the
|
||||
* restart helper starts
|
||||
*/
|
||||
restart_message_painted (NULL);
|
||||
}
|
||||
|
||||
/* We also need to wait for the restart helper to get its
|
||||
* reference to the Composite Overlay Window.
|
||||
*/
|
||||
if (!g_spawn_async_with_pipes (NULL, /* working directory */
|
||||
(char **)helper_argv,
|
||||
NULL, /* envp */
|
||||
G_SPAWN_DEFAULT,
|
||||
NULL, NULL, /* child_setup */
|
||||
NULL, /* child_pid */
|
||||
NULL, /* standard_input */
|
||||
&helper_out_fd,
|
||||
NULL, /* standard_error */
|
||||
&error))
|
||||
{
|
||||
meta_warning ("Failed to start restart helper: %s\n", error->message);
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
GInputStream *unix_stream = g_unix_input_stream_new (helper_out_fd, TRUE);
|
||||
GDataInputStream *data_stream = g_data_input_stream_new (unix_stream);
|
||||
g_object_unref (unix_stream);
|
||||
|
||||
g_data_input_stream_read_line_async (data_stream, G_PRIORITY_DEFAULT,
|
||||
NULL, restart_helper_read_line_callback,
|
||||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
meta_warning ("Failed to read from restart helper: %s\n", error->message);
|
||||
g_object_unref (data_stream);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
restart_helper_started = TRUE;
|
||||
restart_check_ready ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
meta_restart_finish (void)
|
||||
{
|
||||
if (is_restart)
|
||||
{
|
||||
Display *xdisplay = meta_ui_get_display ();
|
||||
Atom atom_restart_helper = XInternAtom (xdisplay, "_MUTTER_RESTART_HELPER", False);
|
||||
XSetSelectionOwner (xdisplay, atom_restart_helper, None, CurrentTime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_is_restart:
|
||||
*
|
||||
* Returns %TRUE if this instance of Mutter comes from Mutter
|
||||
* restarting itself (for example to enable/disable stereo.)
|
||||
* See meta_restart(). If this is the case, any startup visuals
|
||||
* or animations should be suppressed.
|
||||
*/
|
||||
gboolean
|
||||
meta_is_restart (void)
|
||||
{
|
||||
return is_restart;
|
||||
}
|
@@ -891,8 +891,7 @@ meta_screen_manage_all_windows (MetaScreen *screen)
|
||||
|
||||
for (i = 0; i < n_children; ++i)
|
||||
{
|
||||
meta_window_new (screen->display, children[i], TRUE,
|
||||
META_COMP_EFFECT_NONE);
|
||||
meta_window_new (screen->display, children[i], TRUE, TRUE);
|
||||
}
|
||||
|
||||
g_free (children);
|
||||
|
144
src/core/stereo.c
Normal file
144
src/core/stereo.c
Normal file
@@ -0,0 +1,144 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* SECTION:stereo
|
||||
* @short_description: Keep track of whether we are a stereo compositor
|
||||
*
|
||||
* With GLX, we need to use a different GL context for stereo and
|
||||
* non-stereo support. Support for multiple GL contexts is unfinished
|
||||
* in Cogl and entirely lacking in Clutter, so it's by far easier
|
||||
* to just restart Mutter when we detect a stereo window.
|
||||
*
|
||||
* A property _MUTTER_ENABLE_STEREO is maintained on the root window
|
||||
* to know whether we should initialize clutter for stereo or not.
|
||||
* When the presence or absence of stereo windows mismatches the
|
||||
* stereo-enabled state for a sufficiently long period of time,
|
||||
* we restart Mutter.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
#include <gio/gunixinputstream.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#include <meta/main.h>
|
||||
#include "ui.h"
|
||||
#include "util-private.h"
|
||||
#include "display-private.h"
|
||||
#include "stereo.h"
|
||||
|
||||
static guint stereo_switch_id = 0;
|
||||
static gboolean stereo_enabled = FALSE;
|
||||
/* -1 so the first time meta_stereo_set_have_stereo_windows() is called
|
||||
* we avoid the short-circuit and set up a timeout to restart
|
||||
* if necessary */
|
||||
static gboolean stereo_have_windows = (gboolean)-1;
|
||||
static gboolean stereo_restart = FALSE;
|
||||
|
||||
#define STEREO_ENABLE_WAIT 1000
|
||||
#define STEREO_DISABLE_WAIT 5000
|
||||
|
||||
void
|
||||
meta_stereo_init (void)
|
||||
{
|
||||
Display *xdisplay = meta_ui_get_display ();
|
||||
Window root = DefaultRootWindow (xdisplay);
|
||||
Atom atom_enable_stereo = XInternAtom (xdisplay, "_MUTTER_ENABLE_STEREO", False);
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long n_items, bytes_after;
|
||||
guchar *data;
|
||||
|
||||
XGetWindowProperty (xdisplay, root, atom_enable_stereo,
|
||||
0, 1, False, XA_INTEGER,
|
||||
&type, &format, &n_items, &bytes_after, &data);
|
||||
if (type == XA_INTEGER)
|
||||
{
|
||||
if (format == 32 && n_items == 1 && bytes_after == 0)
|
||||
{
|
||||
stereo_enabled = *(long *)data;
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_warning ("Bad value for _MUTTER_ENABLE_STEREO property\n");
|
||||
}
|
||||
|
||||
XFree (data);
|
||||
}
|
||||
else if (type != None)
|
||||
{
|
||||
meta_warning ("Bad type for _MUTTER_ENABLE_STEREO property\n");
|
||||
}
|
||||
|
||||
meta_verbose ("On startup, _MUTTER_ENABLE_STEREO=%s",
|
||||
stereo_enabled ? "yes" : "no");
|
||||
clutter_x11_set_use_stereo_stage (stereo_enabled);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_stereo_switch (gpointer data)
|
||||
{
|
||||
stereo_switch_id = 0;
|
||||
stereo_restart = TRUE;
|
||||
|
||||
meta_restart (stereo_have_windows ?
|
||||
_("Enabling stereo...") :
|
||||
_("Disabling stereo..."));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_stereo_set_have_stereo_windows (gboolean have_windows)
|
||||
{
|
||||
have_windows = have_windows != FALSE;
|
||||
|
||||
if (!stereo_restart && have_windows != stereo_have_windows)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
Window root = DefaultRootWindow (xdisplay);
|
||||
Atom atom_enable_stereo = XInternAtom (xdisplay, "_MUTTER_ENABLE_STEREO", False);
|
||||
long value;
|
||||
|
||||
stereo_have_windows = have_windows;
|
||||
|
||||
if (stereo_have_windows)
|
||||
meta_verbose ("Detected stereo windows\n");
|
||||
else
|
||||
meta_verbose ("No stereo windows detected\n");
|
||||
|
||||
value = stereo_have_windows;
|
||||
XChangeProperty (xdisplay, root,
|
||||
atom_enable_stereo, XA_INTEGER, 32,
|
||||
PropModeReplace, (guchar *)&value, 1);
|
||||
|
||||
if (stereo_switch_id != 0)
|
||||
{
|
||||
g_source_remove (stereo_switch_id);
|
||||
stereo_switch_id = 0;
|
||||
}
|
||||
|
||||
if (stereo_have_windows != stereo_enabled)
|
||||
stereo_switch_id = g_timeout_add (stereo_have_windows ? STEREO_ENABLE_WAIT : STEREO_DISABLE_WAIT,
|
||||
meta_stereo_switch, NULL);
|
||||
}
|
||||
}
|
28
src/core/stereo.h
Normal file
28
src/core/stereo.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_STEREO_H
|
||||
#define META_STEREO_H
|
||||
|
||||
void meta_stereo_init (void);
|
||||
void meta_stereo_set_have_stereo_windows (gboolean have_windows);
|
||||
gboolean meta_stereo_is_restart (void);
|
||||
void meta_stereo_finish_restart (void);
|
||||
|
||||
#endif
|
@@ -488,8 +488,8 @@ struct _MetaWindowClass
|
||||
|
||||
MetaWindow* meta_window_new (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
gboolean must_be_viewable,
|
||||
MetaCompEffect effect);
|
||||
gboolean managing_screen,
|
||||
gboolean must_be_viewable);
|
||||
void meta_window_unmanage (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
void meta_window_calc_showing (MetaWindow *window);
|
||||
|
@@ -1714,12 +1714,12 @@ reload_window_opacity (MetaWindow *window,
|
||||
gboolean initial)
|
||||
|
||||
{
|
||||
int requested_value = 0xFF;
|
||||
guint8 opacity = 0xFF;
|
||||
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
requested_value = (int) value->v.cardinal;
|
||||
opacity = (guint8)((gfloat)value->v.cardinal * 255.0 / ((gfloat)0xffffffff));
|
||||
|
||||
meta_window_set_opacity (window, requested_value);
|
||||
meta_window_set_opacity (window, opacity);
|
||||
}
|
||||
|
||||
#define RELOAD_STRING(var_name, propname) \
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include "keybindings-private.h"
|
||||
#include "ui.h"
|
||||
#include "place.h"
|
||||
#include <meta/main.h>
|
||||
#include "session.h"
|
||||
#include <meta/prefs.h>
|
||||
#include "resizepopup.h"
|
||||
@@ -844,8 +845,8 @@ sync_client_window_mapped (MetaWindow *window)
|
||||
MetaWindow*
|
||||
meta_window_new (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
gboolean must_be_viewable,
|
||||
MetaCompEffect effect)
|
||||
gboolean managing_screen,
|
||||
gboolean must_be_viewable)
|
||||
{
|
||||
XWindowAttributes attrs;
|
||||
MetaWindow *window;
|
||||
@@ -855,6 +856,8 @@ meta_window_new (MetaDisplay *display,
|
||||
gulong event_mask;
|
||||
MetaMoveResizeFlags flags;
|
||||
MetaScreen *screen;
|
||||
MetaCompEffect effect =
|
||||
managing_screen ? META_COMP_EFFECT_NONE : META_COMP_EFFECT_CREATE;
|
||||
|
||||
meta_verbose ("Attempting to manage 0x%lx\n", xwindow);
|
||||
|
||||
@@ -1434,12 +1437,27 @@ meta_window_new (MetaDisplay *display,
|
||||
else
|
||||
window->layer = META_LAYER_OVERRIDE_REDIRECT; /* otherwise set by MetaStack */
|
||||
|
||||
/* Put our state back where it should be,
|
||||
* passing TRUE for is_configure_request, ICCCM says
|
||||
* initial map is handled same as configure request
|
||||
*/
|
||||
flags =
|
||||
META_IS_CONFIGURE_REQUEST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
||||
META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION | META_IS_INITIAL_RESIZE;
|
||||
|
||||
/* ICCCM says initial map is handled same as configure request. When
|
||||
* we are initially managing the screen, we distinguish two cases:
|
||||
*
|
||||
* Restart: in this case, we put the windows back to the unframed
|
||||
* position before exiting, so we need to give them gravity
|
||||
* adjustments.
|
||||
* Something else: (perhaps a crash) if we didn't exit cleanly, then
|
||||
* windows will be reparented by the X server so that the client
|
||||
* origin stays the same, and no frame adjustment is needed.
|
||||
*
|
||||
* We don't have any way to distinguish replacing a different window
|
||||
* manager from respawning on crash, so when we replace a different
|
||||
* window manager, windows will shift onscreen, but this is expected
|
||||
* to only happen in development.
|
||||
*/
|
||||
if (!managing_screen || meta_is_restart())
|
||||
flags |= META_IS_CONFIGURE_REQUEST;
|
||||
|
||||
if (!window->override_redirect)
|
||||
meta_window_move_resize_internal (window,
|
||||
flags,
|
||||
@@ -5180,7 +5198,8 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
if (need_configure_notify)
|
||||
send_configure_notify (window);
|
||||
|
||||
if (!window->placed && window->force_save_user_rect && !window->fullscreen)
|
||||
if ((flags & META_IS_INITIAL_RESIZE) != 0 &&
|
||||
window->force_save_user_rect && !window->fullscreen)
|
||||
force_save_user_window_placement (window);
|
||||
else if (is_user_action)
|
||||
save_user_window_placement (window);
|
||||
@@ -5397,6 +5416,9 @@ meta_window_move_to_monitor (MetaWindow *window,
|
||||
window->tile_monitor_number = monitor;
|
||||
|
||||
meta_window_move_between_rects (window, &old_area, &new_area);
|
||||
|
||||
if (window->fullscreen || window->override_redirect)
|
||||
meta_screen_queue_check_fullscreen (window->screen);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -33,6 +33,9 @@ gboolean meta_get_replace_current_wm (void); /* Actually defined in util
|
||||
void meta_set_wm_name (const char *wm_name);
|
||||
void meta_set_gnome_wm_keybindings (const char *wm_keybindings);
|
||||
|
||||
void meta_restart (const char *message);
|
||||
gboolean meta_is_restart (void);
|
||||
|
||||
/**
|
||||
* MetaExitCode:
|
||||
* @META_EXIT_SUCCESS: Success
|
||||
|
Reference in New Issue
Block a user