Compare commits
40 Commits
wip/remove
...
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 |
@@ -8,5 +8,3 @@ EXTRA_DIST = HACKING MAINTAINERS rationales.txt
|
|||||||
DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache
|
DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache
|
||||||
|
|
||||||
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
|
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
|
||||||
|
62
NEWS
62
NEWS
@@ -1,26 +1,52 @@
|
|||||||
3.11.2
|
3.10.4
|
||||||
======
|
======
|
||||||
* Fix resize operations using mouse-button-modifier [Lionel; #710251]
|
* Fix CSD titlebars being placed off-screen [Jasper; #719772]
|
||||||
* Misc. fixes and cleanups [Jasper, Rico, Florian; #711731]
|
* 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:
|
Contributors:
|
||||||
Lionel Landwerlin, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz
|
Robert Ancell, Giovanni Campagna, Adel Gadllah, Ryan Lortie, Florian Müllner,
|
||||||
|
Jasper St. Pierre
|
||||||
3.11.1
|
|
||||||
======
|
|
||||||
* Don't require at least one output device to be connected [Giovanni; #709009]
|
|
||||||
* Name the guard window [Andrew; #710346]
|
|
||||||
* Use new UPower API [Bastien]
|
|
||||||
* Expose min-backlight-step [Asad; #710380]
|
|
||||||
* Don't focus the no-focus-window for globally active windows [Jasper; #710296]
|
|
||||||
* Misc. fixes and cleanups [Jasper, Rico, Olav, Magdalen; #709776]
|
|
||||||
|
|
||||||
Contributors:
|
|
||||||
Magdalen Berns, Giovanni Campagna, Asad Mehmood, Bastien Nocera,
|
|
||||||
Jasper St. Pierre, Rico Tzschichholz, Olav Vitters, Andrew Walton
|
|
||||||
|
|
||||||
Translations:
|
Translations:
|
||||||
Reinout van Schouwen [nl]
|
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
|
3.10.1
|
||||||
======
|
======
|
||||||
|
12
configure.ac
12
configure.ac
@@ -1,9 +1,8 @@
|
|||||||
AC_PREREQ(2.50)
|
AC_PREREQ(2.50)
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
|
||||||
|
|
||||||
m4_define([mutter_major_version], [3])
|
m4_define([mutter_major_version], [3])
|
||||||
m4_define([mutter_minor_version], [11])
|
m4_define([mutter_minor_version], [10])
|
||||||
m4_define([mutter_micro_version], [2])
|
m4_define([mutter_micro_version], [4])
|
||||||
|
|
||||||
m4_define([mutter_version],
|
m4_define([mutter_version],
|
||||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||||
@@ -77,7 +76,7 @@ MUTTER_PC_MODULES="
|
|||||||
xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0
|
xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0
|
||||||
$CLUTTER_PACKAGE >= 1.15.90
|
$CLUTTER_PACKAGE >= 1.15.90
|
||||||
cogl-1.0 >= 1.15.6
|
cogl-1.0 >= 1.15.6
|
||||||
upower-glib >= 0.99.0
|
upower-glib > 0.9.11
|
||||||
gnome-desktop-3.0
|
gnome-desktop-3.0
|
||||||
"
|
"
|
||||||
|
|
||||||
@@ -364,6 +363,11 @@ fi
|
|||||||
|
|
||||||
GTK_DOC_CHECK([1.15], [--flavour no-tmpl])
|
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)
|
#### Warnings (last since -Werror can disturb other tests)
|
||||||
|
|
||||||
# Stay command-line compatible with the gnome-common configure option. Here
|
# Stay command-line compatible with the gnome-common configure option. Here
|
||||||
|
@@ -49,8 +49,8 @@ FIXXREF_OPTIONS=
|
|||||||
# Used for dependencies. The docs will be rebuilt if any of these change.
|
# Used for dependencies. The docs will be rebuilt if any of these change.
|
||||||
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
|
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
|
||||||
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
|
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
|
||||||
HFILE_GLOB=$(top_srcdir)/src/*/*.h
|
HFILE_GLOB=$(top_srcdir)/src/*.h
|
||||||
CFILE_GLOB=$(top_srcdir)/src/*/*.c
|
CFILE_GLOB=$(top_srcdir)/src/*.c
|
||||||
|
|
||||||
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
|
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
|
||||||
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
|
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
|
||||||
|
@@ -96,6 +96,8 @@ meta_compositor_hide_window
|
|||||||
meta_compositor_switch_workspace
|
meta_compositor_switch_workspace
|
||||||
meta_compositor_maximize_window
|
meta_compositor_maximize_window
|
||||||
meta_compositor_unmaximize_window
|
meta_compositor_unmaximize_window
|
||||||
|
meta_compositor_window_mapped
|
||||||
|
meta_compositor_window_unmapped
|
||||||
meta_compositor_sync_window_geometry
|
meta_compositor_sync_window_geometry
|
||||||
meta_compositor_set_updates_frozen
|
meta_compositor_set_updates_frozen
|
||||||
meta_compositor_queue_frame_drawn
|
meta_compositor_queue_frame_drawn
|
||||||
@@ -205,6 +207,7 @@ meta_key_binding_get_modifiers
|
|||||||
meta_key_binding_get_mask
|
meta_key_binding_get_mask
|
||||||
meta_key_binding_is_builtin
|
meta_key_binding_is_builtin
|
||||||
meta_keybindings_set_custom_handler
|
meta_keybindings_set_custom_handler
|
||||||
|
meta_keybindings_switch_window
|
||||||
meta_screen_ungrab_all_keys
|
meta_screen_ungrab_all_keys
|
||||||
meta_screen_grab_all_keys
|
meta_screen_grab_all_keys
|
||||||
</SECTION>
|
</SECTION>
|
||||||
@@ -386,23 +389,6 @@ MetaWindowActorPrivate
|
|||||||
meta_window_actor_get_type
|
meta_window_actor_get_type
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
|
||||||
<FILE>meta-cullable</FILE>
|
|
||||||
<TITLE>MetaCullable</TITLE>
|
|
||||||
MetaCullable
|
|
||||||
MetaCullableInterface
|
|
||||||
meta_cullable_cull_out
|
|
||||||
meta_cullable_reset_culling
|
|
||||||
meta_cullable_cull_out_children
|
|
||||||
meta_cullable_reset_culling_children
|
|
||||||
<SUBSECTION Standard>
|
|
||||||
META_TYPE_CULLABLE
|
|
||||||
META_CULLABLE
|
|
||||||
META_IS_CULLABLE
|
|
||||||
META_CULLABLE_GET_IFACE
|
|
||||||
meta_cullable_get_type
|
|
||||||
</SECTION>
|
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>prefs</FILE>
|
<FILE>prefs</FILE>
|
||||||
MetaPreference
|
MetaPreference
|
||||||
@@ -556,10 +542,7 @@ meta_window_is_override_redirect
|
|||||||
meta_window_is_skip_taskbar
|
meta_window_is_skip_taskbar
|
||||||
meta_window_get_rect
|
meta_window_get_rect
|
||||||
meta_window_get_input_rect
|
meta_window_get_input_rect
|
||||||
meta_window_get_frame_rect
|
|
||||||
meta_window_get_outer_rect
|
meta_window_get_outer_rect
|
||||||
meta_window_client_rect_to_frame_rect
|
|
||||||
meta_window_frame_rect_to_client_rect
|
|
||||||
meta_window_get_screen
|
meta_window_get_screen
|
||||||
meta_window_get_display
|
meta_window_get_display
|
||||||
meta_window_get_xwindow
|
meta_window_get_xwindow
|
||||||
|
@@ -21,7 +21,6 @@ environment.</description>
|
|||||||
-->
|
-->
|
||||||
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gnome-shell-list" />
|
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gnome-shell-list" />
|
||||||
<download-page rdf:resource="http://download.gnome.org/sources/mutter/" />
|
<download-page rdf:resource="http://download.gnome.org/sources/mutter/" />
|
||||||
<download-page rdf:resource="http://download.gnome.org/sources/mutter-wayland/" />
|
|
||||||
<bug-database rdf:resource="http://bugzilla.gnome.org/browse.cgi?product=mutter" />
|
<bug-database rdf:resource="http://bugzilla.gnome.org/browse.cgi?product=mutter" />
|
||||||
|
|
||||||
<category rdf:resource="http://api.gnome.org/doap-extensions#desktop" />
|
<category rdf:resource="http://api.gnome.org/doap-extensions#desktop" />
|
||||||
|
16
po/ar.po
16
po/ar.po
@@ -4,14 +4,14 @@
|
|||||||
# Arafat Medini <lumina@silverpen.de>, 2003.
|
# Arafat Medini <lumina@silverpen.de>, 2003.
|
||||||
# Abdulaziz Al-Arfaj <alarfaj0@yahoo.com>, 2004.
|
# Abdulaziz Al-Arfaj <alarfaj0@yahoo.com>, 2004.
|
||||||
# Djihed Afifi <djihed@gmail.com>, 2006.
|
# 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.
|
# Anas Afif Emad <anas.e87@gmail.com>, 2008.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: metacity.HEAD\n"
|
"Project-Id-Version: metacity.HEAD\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2013-10-07 17:09+0200\n"
|
"POT-Creation-Date: 2014-02-06 15:37+0200\n"
|
||||||
"PO-Revision-Date: 2013-10-07 17:09+0200\n"
|
"PO-Revision-Date: 2014-02-06 15:37+0200\n"
|
||||||
"Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n"
|
"Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n"
|
||||||
"Language-Team: Arabic <doc@arabeyes.org>\n"
|
"Language-Team: Arabic <doc@arabeyes.org>\n"
|
||||||
"Language: ar\n"
|
"Language: ar\n"
|
||||||
@@ -314,16 +314,16 @@ msgstr "تعذّر إيجاد سِمة! تأكد من وجود %s و احتوا
|
|||||||
|
|
||||||
#: ../src/core/monitor.c:696
|
#: ../src/core/monitor.c:696
|
||||||
msgid "Built-in display"
|
msgid "Built-in display"
|
||||||
msgstr ""
|
msgstr "شاشة مدمجة"
|
||||||
|
|
||||||
#. TRANSLATORS: this is a monitor name (in case we don't know
|
#. TRANSLATORS: this is a monitor name (in case we don't know
|
||||||
#. the vendor), it's Unknown followed by a size in inches,
|
#. the vendor), it's Unknown followed by a size in inches,
|
||||||
#. like 'Unknown 15"'
|
#. like 'Unknown 15"'
|
||||||
#.
|
#.
|
||||||
#: ../src/core/monitor.c:724
|
#: ../src/core/monitor.c:724
|
||||||
#, fuzzy, c-format
|
#, c-format
|
||||||
msgid "Unknown %s"
|
msgid "Unknown %s"
|
||||||
msgstr "عنصر مجهول %s"
|
msgstr "غير معروفة %s"
|
||||||
|
|
||||||
#: ../src/core/mutter.c:40
|
#: ../src/core/mutter.c:40
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -503,7 +503,7 @@ msgid "Window manager error: "
|
|||||||
msgstr "خطأ مدير النوافذ: "
|
msgstr "خطأ مدير النوافذ: "
|
||||||
|
|
||||||
#. first time through
|
#. first time through
|
||||||
#: ../src/core/window.c:7515
|
#: ../src/core/window.c:7497
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
|
"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
|
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
|
||||||
#. * about these apps but make them work.
|
#. * about these apps but make them work.
|
||||||
#.
|
#.
|
||||||
#: ../src/core/window.c:8345
|
#: ../src/core/window.c:8329
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
|
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
|
||||||
|
42
po/nl.po
42
po/nl.po
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: mutter\n"
|
"Project-Id-Version: mutter\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2013-10-25 00:25+0200\n"
|
"POT-Creation-Date: 2013-10-25 00:15+0200\n"
|
||||||
"PO-Revision-Date: 2013-10-25 00:23+0200\n"
|
"PO-Revision-Date: 2013-10-25 00:23+0200\n"
|
||||||
"Last-Translator: Reinout van Schouwen <reinouts@gnome.org>\n"
|
"Last-Translator: Reinout van Schouwen <reinouts@gnome.org>\n"
|
||||||
"Language-Team: Dutch <vertaling@vrijschrift.org>\n"
|
"Language-Team: Dutch <vertaling@vrijschrift.org>\n"
|
||||||
@@ -256,12 +256,12 @@ msgstr "_Wachten"
|
|||||||
msgid "_Force Quit"
|
msgid "_Force Quit"
|
||||||
msgstr "Ge_forceerd afsluiten"
|
msgstr "Ge_forceerd afsluiten"
|
||||||
|
|
||||||
#: ../src/core/display.c:421
|
#: ../src/core/display.c:422
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Missing %s extension required for compositing"
|
msgid "Missing %s extension required for compositing"
|
||||||
msgstr "Benodigde extensie ‘%s’ voor ‘compositing’ ontbreekt"
|
msgstr "Benodigde extensie ‘%s’ voor ‘compositing’ ontbreekt"
|
||||||
|
|
||||||
#: ../src/core/display.c:513
|
#: ../src/core/display.c:514
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Failed to open X Window System display '%s'\n"
|
msgid "Failed to open X Window System display '%s'\n"
|
||||||
msgstr "Openen van X Window System display ‘%s’ mislukt\n"
|
msgstr "Openen van X Window System display ‘%s’ mislukt\n"
|
||||||
@@ -389,12 +389,12 @@ msgstr ""
|
|||||||
msgid "Workspace %d"
|
msgid "Workspace %d"
|
||||||
msgstr "Werkblad %d"
|
msgstr "Werkblad %d"
|
||||||
|
|
||||||
#: ../src/core/screen.c:540
|
#: ../src/core/screen.c:537
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Screen %d on display '%s' is invalid\n"
|
msgid "Screen %d on display '%s' is invalid\n"
|
||||||
msgstr "Scherm %d op display '%s' is ongeldig\n"
|
msgstr "Scherm %d op display '%s' is ongeldig\n"
|
||||||
|
|
||||||
#: ../src/core/screen.c:556
|
#: ../src/core/screen.c:553
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||||
@@ -403,19 +403,19 @@ msgstr ""
|
|||||||
"Scherm %d op display ‘%s’ heeft al een ‘window manager’; probeer de optie: --"
|
"Scherm %d op display ‘%s’ heeft al een ‘window manager’; probeer de optie: --"
|
||||||
"replace te gebruiken om de huidige ‘window manager’ te vervangen.\n"
|
"replace te gebruiken om de huidige ‘window manager’ te vervangen.\n"
|
||||||
|
|
||||||
#: ../src/core/screen.c:583
|
#: ../src/core/screen.c:580
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Could not acquire window manager selection on screen %d display \"%s\"\n"
|
"Could not acquire window manager selection on screen %d display \"%s\"\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Kon ‘window manager’-selectie niet verkrijgen op scherm %d display ‘%s’\n"
|
"Kon ‘window manager’-selectie niet verkrijgen op scherm %d display ‘%s’\n"
|
||||||
|
|
||||||
#: ../src/core/screen.c:661
|
#: ../src/core/screen.c:658
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||||
msgstr "Scherm %d op display ‘%s’ heeft al een ‘window manager’\n"
|
msgstr "Scherm %d op display ‘%s’ heeft al een ‘window manager’\n"
|
||||||
|
|
||||||
#: ../src/core/screen.c:853
|
#: ../src/core/screen.c:850
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Could not release screen %d on display \"%s\"\n"
|
msgid "Could not release screen %d on display \"%s\"\n"
|
||||||
msgstr "Kon scherm %d op display ‘%s’ niet vrijmaken\n"
|
msgstr "Kon scherm %d op display ‘%s’ niet vrijmaken\n"
|
||||||
@@ -511,7 +511,7 @@ msgid "Window manager error: "
|
|||||||
msgstr "Fout van vensterbeheer:"
|
msgstr "Fout van vensterbeheer:"
|
||||||
|
|
||||||
#. first time through
|
#. first time through
|
||||||
#: ../src/core/window.c:7510
|
#: ../src/core/window.c:7515
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
|
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
|
||||||
@@ -527,7 +527,7 @@ msgstr ""
|
|||||||
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
|
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
|
||||||
#. * about these apps but make them work.
|
#. * about these apps but make them work.
|
||||||
#.
|
#.
|
||||||
#: ../src/core/window.c:8340
|
#: ../src/core/window.c:8345
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
|
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
|
||||||
@@ -683,9 +683,9 @@ msgid ""
|
|||||||
"the focus will not be changed immediately when entering a window, but only "
|
"the focus will not be changed immediately when entering a window, but only "
|
||||||
"after the pointer stops moving."
|
"after the pointer stops moving."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Indien op ‘true’ ingesteld en de aandachtsmodus is ofwel ‘sloppy’ of "
|
"Indien op ‘true’ ingesteld en de aandachtsmodus is ofwel ‘sloppy’ of ‘mouse’, "
|
||||||
"‘mouse’, dan zal de aandacht niet direct veranderd worden bij het binnengaan "
|
"dan zal de aandacht niet direct veranderd worden bij het binnengaan van een "
|
||||||
"van een venster, maar slechts wanneer de muispijl stopt met bewegen."
|
"venster, maar slechts wanneer de muispijl stopt met bewegen."
|
||||||
|
|
||||||
#: ../src/org.gnome.mutter.gschema.xml.in.h:15
|
#: ../src/org.gnome.mutter.gschema.xml.in.h:15
|
||||||
msgid "Draggable border width"
|
msgid "Draggable border width"
|
||||||
@@ -697,8 +697,8 @@ msgid ""
|
|||||||
"not enough, invisible borders will be added to meet this value."
|
"not enough, invisible borders will be added to meet this value."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Het totaal aantal sleepbare randen. Als de zichtbare randen in het thema "
|
"Het totaal aantal sleepbare randen. Als de zichtbare randen in het thema "
|
||||||
"onvoldoende zijn, worden onzichtbare randen toegevoegd om deze waarde te "
|
"onvoldoende zijn, worden onzichtbare randen toegevoegd om deze waarde "
|
||||||
"bereiken."
|
"te bereiken."
|
||||||
|
|
||||||
#: ../src/org.gnome.mutter.gschema.xml.in.h:17
|
#: ../src/org.gnome.mutter.gschema.xml.in.h:17
|
||||||
msgid "Auto maximize nearly monitor sized windows"
|
msgid "Auto maximize nearly monitor sized windows"
|
||||||
@@ -968,8 +968,8 @@ msgid ""
|
|||||||
"GTK custom color specification must have color name and fallback in "
|
"GTK custom color specification must have color name and fallback in "
|
||||||
"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\""
|
"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Aangepaste GTK-kleurspecificatie moet een kleurnaam en terugvaloptie hebben "
|
"Aangepaste GTK-kleurspecificatie moet een kleurnaam en terugvaloptie "
|
||||||
"tussen haakjes, dus: gtk:custom(foo,bar); kon ‘%s’ niet verwerken"
|
"hebben tussen haakjes, dus: gtk:custom(foo,bar); kon ‘%s’ niet verwerken"
|
||||||
|
|
||||||
#: ../src/ui/theme.c:1219
|
#: ../src/ui/theme.c:1219
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -977,8 +977,8 @@ msgid ""
|
|||||||
"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-"
|
"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-"
|
||||||
"_ are valid"
|
"_ are valid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Ongeldig teken ‘%c’ in color_name-parameter van gtk:custom, alleen A-Za-z0-9-"
|
"Ongeldig teken ‘%c’ in color_name-parameter van gtk:custom, alleen A-Za-z0-9-_ "
|
||||||
"_ zijn geldig"
|
"zijn geldig"
|
||||||
|
|
||||||
#: ../src/ui/theme.c:1233
|
#: ../src/ui/theme.c:1233
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -986,8 +986,8 @@ msgid ""
|
|||||||
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
|
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
|
||||||
"fit the format"
|
"fit the format"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Gtk:custom-formaat is ‘gtk:custom(color_name,fallback)’, ‘%s’ voldoet niet "
|
"Gtk:custom-formaat is ‘gtk:custom(color_name,fallback)’, ‘%s’ voldoet "
|
||||||
"aan dit formaat"
|
"niet aan dit formaat"
|
||||||
|
|
||||||
#: ../src/ui/theme.c:1278
|
#: ../src/ui/theme.c:1278
|
||||||
#, c-format
|
#, c-format
|
||||||
|
28
po/zh_CN.po
28
po/zh_CN.po
@@ -16,7 +16,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: mutter master\n"
|
"Project-Id-Version: mutter master\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
|
||||||
"product=mutter&keywords=I18N+L10N&component=general\n"
|
"product=mutter&keywords=I18N+L10N&component=general\n"
|
||||||
"POT-Creation-Date: 2013-12-05 16:15+0000\n"
|
"POT-Creation-Date: 2013-12-04 16:17+0000\n"
|
||||||
"PO-Revision-Date: 2013-11-30 17:50+0800\n"
|
"PO-Revision-Date: 2013-11-30 17:50+0800\n"
|
||||||
"Last-Translator: 甘露(Gan Lu) <rhythm.gan@gmail.com>\n"
|
"Last-Translator: 甘露(Gan Lu) <rhythm.gan@gmail.com>\n"
|
||||||
"Language-Team: Chinese (simplified) <i18n-zh@googlegroups.com>\n"
|
"Language-Team: Chinese (simplified) <i18n-zh@googlegroups.com>\n"
|
||||||
@@ -260,12 +260,12 @@ msgstr "等待(_W)"
|
|||||||
msgid "_Force Quit"
|
msgid "_Force Quit"
|
||||||
msgstr "强制退出(_F)"
|
msgstr "强制退出(_F)"
|
||||||
|
|
||||||
#: ../src/core/display.c:415
|
#: ../src/core/display.c:422
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Missing %s extension required for compositing"
|
msgid "Missing %s extension required for compositing"
|
||||||
msgstr "缺少复合效果所需的 %s 扩展"
|
msgstr "缺少复合效果所需的 %s 扩展"
|
||||||
|
|
||||||
#: ../src/core/display.c:507
|
#: ../src/core/display.c:514
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Failed to open X Window System display '%s'\n"
|
msgid "Failed to open X Window System display '%s'\n"
|
||||||
msgstr "无法打开 X Window System 显示“%s”\n"
|
msgstr "无法打开 X Window System 显示“%s”\n"
|
||||||
@@ -382,12 +382,12 @@ msgstr "在配置数据库中找到的“%s”不是按键组合“%s”的有
|
|||||||
msgid "Workspace %d"
|
msgid "Workspace %d"
|
||||||
msgstr "工作区 %d"
|
msgstr "工作区 %d"
|
||||||
|
|
||||||
#: ../src/core/screen.c:540
|
#: ../src/core/screen.c:537
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Screen %d on display '%s' is invalid\n"
|
msgid "Screen %d on display '%s' is invalid\n"
|
||||||
msgstr "显示“%2$s”上的屏幕 %1$d 无效\n"
|
msgstr "显示“%2$s”上的屏幕 %1$d 无效\n"
|
||||||
|
|
||||||
#: ../src/core/screen.c:556
|
#: ../src/core/screen.c:553
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||||
@@ -396,18 +396,18 @@ msgstr ""
|
|||||||
"显示“%2$s”上的屏幕 %1$d 已经有一个窗口管理器;请尝试使用 --replace 选项替换当"
|
"显示“%2$s”上的屏幕 %1$d 已经有一个窗口管理器;请尝试使用 --replace 选项替换当"
|
||||||
"前的窗口管理器。\n"
|
"前的窗口管理器。\n"
|
||||||
|
|
||||||
#: ../src/core/screen.c:583
|
#: ../src/core/screen.c:580
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Could not acquire window manager selection on screen %d display \"%s\"\n"
|
"Could not acquire window manager selection on screen %d display \"%s\"\n"
|
||||||
msgstr "无法获得显示“%2$s”上的屏幕 %1$d 的窗口管理器选定项\n"
|
msgstr "无法获得显示“%2$s”上的屏幕 %1$d 的窗口管理器选定项\n"
|
||||||
|
|
||||||
#: ../src/core/screen.c:661
|
#: ../src/core/screen.c:658
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||||
msgstr "在显示“%2$s”上的 %1$d 屏幕已经有一个窗口管理器\n"
|
msgstr "在显示“%2$s”上的 %1$d 屏幕已经有一个窗口管理器\n"
|
||||||
|
|
||||||
#: ../src/core/screen.c:853
|
#: ../src/core/screen.c:850
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Could not release screen %d on display \"%s\"\n"
|
msgid "Could not release screen %d on display \"%s\"\n"
|
||||||
msgstr "无法释放显示“%2$s”上的屏幕 %1$d\n"
|
msgstr "无法释放显示“%2$s”上的屏幕 %1$d\n"
|
||||||
@@ -503,7 +503,7 @@ msgid "Window manager error: "
|
|||||||
msgstr "窗口管理器错误:"
|
msgstr "窗口管理器错误:"
|
||||||
|
|
||||||
#. first time through
|
#. first time through
|
||||||
#: ../src/core/window.c:7613
|
#: ../src/core/window.c:7515
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
|
"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
|
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
|
||||||
#. * about these apps but make them work.
|
#. * about these apps but make them work.
|
||||||
#.
|
#.
|
||||||
#: ../src/core/window.c:8535
|
#: ../src/core/window.c:8345
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
|
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
|
||||||
@@ -528,22 +528,22 @@ msgstr ""
|
|||||||
"窗口 %s 设置了一个 MWM 提示,表明它是不可改变大小的,但设置最小尺寸为 %d x "
|
"窗口 %s 设置了一个 MWM 提示,表明它是不可改变大小的,但设置最小尺寸为 %d x "
|
||||||
"%d,最大尺寸为 %d x %d;这没有任何意义。\n"
|
"%d,最大尺寸为 %d x %d;这没有任何意义。\n"
|
||||||
|
|
||||||
#: ../src/core/window-props.c:350
|
#: ../src/core/window-props.c:347
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Application set a bogus _NET_WM_PID %lu\n"
|
msgid "Application set a bogus _NET_WM_PID %lu\n"
|
||||||
msgstr "应用程序设置一个假的 _NET_WM_PID %lu\n"
|
msgstr "应用程序设置一个假的 _NET_WM_PID %lu\n"
|
||||||
|
|
||||||
#: ../src/core/window-props.c:466
|
#: ../src/core/window-props.c:463
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s (on %s)"
|
msgid "%s (on %s)"
|
||||||
msgstr "%s (于 %s)"
|
msgstr "%s (于 %s)"
|
||||||
|
|
||||||
#: ../src/core/window-props.c:1549
|
#: ../src/core/window-props.c:1546
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
|
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
|
||||||
msgstr "为 %2$s 指定了无效的 WM_TRANSIENT_FOR 窗口 0x%1$lx。\n"
|
msgstr "为 %2$s 指定了无效的 WM_TRANSIENT_FOR 窗口 0x%1$lx。\n"
|
||||||
|
|
||||||
#: ../src/core/window-props.c:1560
|
#: ../src/core/window-props.c:1557
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n"
|
msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n"
|
||||||
msgstr "为 %2$s 指定的 WM_TRANSIENT_FOR 窗口 0x%1$lx 将导致循环。\n"
|
msgstr "为 %2$s 指定的 WM_TRANSIENT_FOR 窗口 0x%1$lx 将导致循环。\n"
|
||||||
|
@@ -55,8 +55,7 @@ libmutter_la_SOURCES = \
|
|||||||
compositor/meta-background-actor.c \
|
compositor/meta-background-actor.c \
|
||||||
compositor/meta-background-actor-private.h \
|
compositor/meta-background-actor-private.h \
|
||||||
compositor/meta-background-group.c \
|
compositor/meta-background-group.c \
|
||||||
compositor/meta-cullable.c \
|
compositor/meta-background-group-private.h \
|
||||||
compositor/meta-cullable.h \
|
|
||||||
compositor/meta-module.c \
|
compositor/meta-module.c \
|
||||||
compositor/meta-module.h \
|
compositor/meta-module.h \
|
||||||
compositor/meta-plugin.c \
|
compositor/meta-plugin.c \
|
||||||
@@ -65,6 +64,8 @@ libmutter_la_SOURCES = \
|
|||||||
compositor/meta-shadow-factory.c \
|
compositor/meta-shadow-factory.c \
|
||||||
compositor/meta-shadow-factory-private.h \
|
compositor/meta-shadow-factory-private.h \
|
||||||
compositor/meta-shaped-texture.c \
|
compositor/meta-shaped-texture.c \
|
||||||
|
compositor/meta-sync-ring.c \
|
||||||
|
compositor/meta-sync-ring.h \
|
||||||
compositor/meta-texture-rectangle.c \
|
compositor/meta-texture-rectangle.c \
|
||||||
compositor/meta-texture-rectangle.h \
|
compositor/meta-texture-rectangle.h \
|
||||||
compositor/meta-texture-tower.c \
|
compositor/meta-texture-tower.c \
|
||||||
@@ -169,9 +170,7 @@ libmutter_la_SOURCES = \
|
|||||||
ui/theme.c \
|
ui/theme.c \
|
||||||
meta/theme.h \
|
meta/theme.h \
|
||||||
ui/theme-private.h \
|
ui/theme-private.h \
|
||||||
ui/ui.c
|
ui/ui.c \
|
||||||
|
|
||||||
nodist_libmutter_la_SOURCES = \
|
|
||||||
$(mutter_built_sources)
|
$(mutter_built_sources)
|
||||||
|
|
||||||
libmutter_la_LDFLAGS = -no-undefined
|
libmutter_la_LDFLAGS = -no-undefined
|
||||||
@@ -252,7 +251,7 @@ Meta-$(api_version).gir: libmutter.la
|
|||||||
@META_GIR@_FILES = \
|
@META_GIR@_FILES = \
|
||||||
mutter-enum-types.h \
|
mutter-enum-types.h \
|
||||||
$(libmutterinclude_base_headers) \
|
$(libmutterinclude_base_headers) \
|
||||||
$(filter %.c,$(libmutter_la_SOURCES) $(nodist_libmutter_la_SOURCES))
|
$(filter %.c,$(libmutter_la_SOURCES))
|
||||||
@META_GIR@_SCANNERFLAGS = --warn-all --warn-error
|
@META_GIR@_SCANNERFLAGS = --warn-all --warn-error
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
@@ -17,7 +17,10 @@ struct _MetaCompositor
|
|||||||
{
|
{
|
||||||
MetaDisplay *display;
|
MetaDisplay *display;
|
||||||
|
|
||||||
guint repaint_func_id;
|
Atom atom_x_root_pixmap;
|
||||||
|
Atom atom_net_wm_window_opacity;
|
||||||
|
guint pre_paint_func_id;
|
||||||
|
guint post_paint_func_id;
|
||||||
|
|
||||||
ClutterActor *shadow_src;
|
ClutterActor *shadow_src;
|
||||||
|
|
||||||
@@ -30,6 +33,9 @@ struct _MetaCompositor
|
|||||||
guint show_redraw : 1;
|
guint show_redraw : 1;
|
||||||
guint debug : 1;
|
guint debug : 1;
|
||||||
guint no_mipmaps : 1;
|
guint no_mipmaps : 1;
|
||||||
|
|
||||||
|
gboolean frame_has_updated_xsurfaces;
|
||||||
|
gboolean have_x11_sync_object;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaCompScreen
|
struct _MetaCompScreen
|
||||||
|
@@ -42,6 +42,15 @@
|
|||||||
* the call, so it may be necessary to readjust the display based on the
|
* the call, so it may be necessary to readjust the display based on the
|
||||||
* old_rect to start the animation.
|
* old_rect to start the animation.
|
||||||
*
|
*
|
||||||
|
* meta_compositor_window_mapped() and meta_compositor_window_unmapped() are
|
||||||
|
* notifications when the toplevel window (frame or client window) is mapped or
|
||||||
|
* unmapped. That is, when the result of meta_window_toplevel_is_mapped()
|
||||||
|
* changes. The main use of this is to drop resources when a window is unmapped.
|
||||||
|
* A window will always be mapped before meta_compositor_show_window()
|
||||||
|
* is called and will not be unmapped until after meta_compositor_hide_window()
|
||||||
|
* is called. If the live_hidden_windows preference is set, windows will never
|
||||||
|
* be unmapped.
|
||||||
|
*
|
||||||
* # Containers #
|
* # Containers #
|
||||||
*
|
*
|
||||||
* There's two containers in the stage that are used to place window actors, here
|
* There's two containers in the stage that are used to place window actors, here
|
||||||
@@ -77,6 +86,7 @@
|
|||||||
#include "display-private.h" /* for meta_display_lookup_x_window() */
|
#include "display-private.h" /* for meta_display_lookup_x_window() */
|
||||||
#include <X11/extensions/shape.h>
|
#include <X11/extensions/shape.h>
|
||||||
#include <X11/extensions/Xcomposite.h>
|
#include <X11/extensions/Xcomposite.h>
|
||||||
|
#include "meta-sync-ring.h"
|
||||||
|
|
||||||
/* #define DEBUG_TRACE g_print */
|
/* #define DEBUG_TRACE g_print */
|
||||||
#define DEBUG_TRACE(X)
|
#define DEBUG_TRACE(X)
|
||||||
@@ -133,7 +143,11 @@ meta_switch_workspace_completed (MetaScreen *screen)
|
|||||||
void
|
void
|
||||||
meta_compositor_destroy (MetaCompositor *compositor)
|
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
|
static void
|
||||||
@@ -164,6 +178,33 @@ process_damage (MetaCompositor *compositor,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
meta_window_actor_process_damage (window_actor, event);
|
meta_window_actor_process_damage (window_actor, event);
|
||||||
|
|
||||||
|
compositor->frame_has_updated_xsurfaces = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
process_property_notify (MetaCompositor *compositor,
|
||||||
|
XPropertyEvent *event,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaWindowActor *window_actor;
|
||||||
|
|
||||||
|
if (window == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||||
|
if (window_actor == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Check for the opacity changing */
|
||||||
|
if (event->atom == compositor->atom_net_wm_window_opacity)
|
||||||
|
{
|
||||||
|
meta_window_actor_update_opacity (window_actor);
|
||||||
|
DEBUG_TRACE ("process_property_notify: net_wm_window_opacity\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_TRACE ("process_property_notify: unknown\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static Window
|
static Window
|
||||||
@@ -651,6 +692,15 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
|||||||
clutter_actor_add_child (info->stage, info->window_group);
|
clutter_actor_add_child (info->stage, info->window_group);
|
||||||
clutter_actor_add_child (info->stage, info->top_window_group);
|
clutter_actor_add_child (info->stage, info->top_window_group);
|
||||||
|
|
||||||
|
info->plugin_mgr = meta_plugin_manager_new (screen);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delay the creation of the overlay window as long as we can, to avoid
|
||||||
|
* blanking out the screen. This means that during the plugin loading, the
|
||||||
|
* overlay window is not accessible; if the plugin needs to access it
|
||||||
|
* directly, it should hook into the "show" signal on stage, and do
|
||||||
|
* its stuff there.
|
||||||
|
*/
|
||||||
info->output = get_output_window (screen);
|
info->output = get_output_window (screen);
|
||||||
XReparentWindow (xdisplay, xwin, info->output, 0, 0);
|
XReparentWindow (xdisplay, xwin, info->output, 0, 0);
|
||||||
|
|
||||||
@@ -671,13 +721,13 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
|||||||
info->pending_input_region = None;
|
info->pending_input_region = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->plugin_mgr = meta_plugin_manager_new (screen);
|
|
||||||
|
|
||||||
/* Map overlay window before redirecting windows offscreen so we catch their
|
/* Map overlay window before redirecting windows offscreen so we catch their
|
||||||
* contents until we show the stage.
|
* contents until we show the stage.
|
||||||
*/
|
*/
|
||||||
XMapWindow (xdisplay, info->output);
|
XMapWindow (xdisplay, info->output);
|
||||||
|
|
||||||
|
compositor->have_x11_sync_object = meta_sync_ring_init (display);
|
||||||
|
|
||||||
redirect_windows (compositor, screen);
|
redirect_windows (compositor, screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -715,7 +765,7 @@ meta_shape_cow_for_window (MetaScreen *screen,
|
|||||||
int width, height;
|
int width, height;
|
||||||
MetaRectangle rect;
|
MetaRectangle rect;
|
||||||
|
|
||||||
meta_window_get_frame_rect (metaWindow, &rect);
|
meta_window_get_outer_rect (metaWindow, &rect);
|
||||||
|
|
||||||
window_bounds.x = rect.x;
|
window_bounds.x = rect.x;
|
||||||
window_bounds.y = rect.y;
|
window_bounds.y = rect.y;
|
||||||
@@ -843,18 +893,6 @@ meta_compositor_window_shape_changed (MetaCompositor *compositor,
|
|||||||
meta_window_actor_update_shape (window_actor);
|
meta_window_actor_update_shape (window_actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
meta_compositor_window_opacity_changed (MetaCompositor *compositor,
|
|
||||||
MetaWindow *window)
|
|
||||||
{
|
|
||||||
MetaWindowActor *window_actor;
|
|
||||||
window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
|
||||||
if (!window_actor)
|
|
||||||
return;
|
|
||||||
|
|
||||||
meta_window_actor_update_opacity (window_actor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clutter makes the assumption that there is only one X window
|
/* Clutter makes the assumption that there is only one X window
|
||||||
* per stage, which is a valid assumption to make for a generic
|
* per stage, which is a valid assumption to make for a generic
|
||||||
* application toolkit. As such, it will ignore any events sent
|
* application toolkit. As such, it will ignore any events sent
|
||||||
@@ -961,19 +999,28 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
/* Core code doesn't handle damage events, so we need to extract the MetaWindow
|
case PropertyNotify:
|
||||||
* ourselves
|
process_property_notify (compositor, (XPropertyEvent *) event, window);
|
||||||
*/
|
break;
|
||||||
if (window == NULL)
|
|
||||||
{
|
|
||||||
Window xwin = ((XDamageNotifyEvent *) event)->drawable;
|
|
||||||
window = meta_display_lookup_x_window (compositor->display, xwin);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n");
|
default:
|
||||||
process_damage (compositor, (XDamageNotifyEvent *) event, window);
|
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
|
||||||
|
* ourselves
|
||||||
|
*/
|
||||||
|
if (window == NULL)
|
||||||
|
{
|
||||||
|
Window xwin = ((XDamageNotifyEvent *) event)->drawable;
|
||||||
|
window = meta_display_lookup_x_window (compositor->display, xwin);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n");
|
||||||
|
process_damage (compositor, (XDamageNotifyEvent *) event, window);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clutter needs to know about MapNotify events otherwise it will
|
/* Clutter needs to know about MapNotify events otherwise it will
|
||||||
@@ -981,6 +1028,10 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
|||||||
if (event->type == MapNotify)
|
if (event->type == MapNotify)
|
||||||
clutter_x11_handle_event (event);
|
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
|
/* 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
|
* 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.
|
* GTK+ windows in the same process, GTK+ needs the ConfigureNotify event, for example.
|
||||||
@@ -1273,6 +1324,30 @@ meta_compositor_sync_stack (MetaCompositor *compositor,
|
|||||||
sync_actor_stacking (info);
|
sync_actor_stacking (info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_compositor_window_mapped (MetaCompositor *compositor,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||||
|
DEBUG_TRACE ("meta_compositor_window_mapped\n");
|
||||||
|
if (!window_actor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_window_actor_mapped (window_actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_compositor_window_unmapped (MetaCompositor *compositor,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||||
|
DEBUG_TRACE ("meta_compositor_window_unmapped\n");
|
||||||
|
if (!window_actor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_window_actor_unmapped (window_actor);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_compositor_sync_window_geometry (MetaCompositor *compositor,
|
meta_compositor_sync_window_geometry (MetaCompositor *compositor,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
@@ -1406,7 +1481,7 @@ pre_paint_windows (MetaCompScreen *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_repaint_func (gpointer data)
|
meta_pre_paint_func (gpointer data)
|
||||||
{
|
{
|
||||||
MetaCompositor *compositor = data;
|
MetaCompositor *compositor = data;
|
||||||
GSList *screens = meta_display_get_screens (compositor->display);
|
GSList *screens = meta_display_get_screens (compositor->display);
|
||||||
@@ -1422,6 +1497,52 @@ meta_repaint_func (gpointer data)
|
|||||||
pre_paint_windows (info);
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1453,7 +1574,13 @@ on_shadow_factory_changed (MetaShadowFactory *factory,
|
|||||||
MetaCompositor *
|
MetaCompositor *
|
||||||
meta_compositor_new (MetaDisplay *display)
|
meta_compositor_new (MetaDisplay *display)
|
||||||
{
|
{
|
||||||
|
char *atom_names[] = {
|
||||||
|
"_XROOTPMAP_ID",
|
||||||
|
"_NET_WM_WINDOW_OPACITY",
|
||||||
|
};
|
||||||
|
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||||
MetaCompositor *compositor;
|
MetaCompositor *compositor;
|
||||||
|
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||||
|
|
||||||
if (!composite_at_least_version (display, 0, 3))
|
if (!composite_at_least_version (display, 0, 3))
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1465,15 +1592,28 @@ meta_compositor_new (MetaDisplay *display)
|
|||||||
if (g_getenv("META_DISABLE_MIPMAPS"))
|
if (g_getenv("META_DISABLE_MIPMAPS"))
|
||||||
compositor->no_mipmaps = TRUE;
|
compositor->no_mipmaps = TRUE;
|
||||||
|
|
||||||
|
meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names));
|
||||||
|
XInternAtoms (xdisplay, atom_names, G_N_ELEMENTS (atom_names),
|
||||||
|
False, atoms);
|
||||||
|
|
||||||
g_signal_connect (meta_shadow_factory_get_default (),
|
g_signal_connect (meta_shadow_factory_get_default (),
|
||||||
"changed",
|
"changed",
|
||||||
G_CALLBACK (on_shadow_factory_changed),
|
G_CALLBACK (on_shadow_factory_changed),
|
||||||
compositor);
|
compositor);
|
||||||
|
|
||||||
compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func,
|
compositor->atom_x_root_pixmap = atoms[0];
|
||||||
compositor,
|
compositor->atom_net_wm_window_opacity = atoms[1];
|
||||||
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;
|
return compositor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,6 +6,9 @@
|
|||||||
#include <meta/screen.h>
|
#include <meta/screen.h>
|
||||||
#include <meta/meta-background-actor.h>
|
#include <meta/meta-background-actor.h>
|
||||||
|
|
||||||
|
void meta_background_actor_set_clip_region (MetaBackgroundActor *self,
|
||||||
|
cairo_region_t *clip_region);
|
||||||
|
|
||||||
cairo_region_t *meta_background_actor_get_clip_region (MetaBackgroundActor *self);
|
cairo_region_t *meta_background_actor_get_clip_region (MetaBackgroundActor *self);
|
||||||
|
|
||||||
#endif /* META_BACKGROUND_ACTOR_PRIVATE_H */
|
#endif /* META_BACKGROUND_ACTOR_PRIVATE_H */
|
||||||
|
@@ -41,35 +41,20 @@
|
|||||||
#include <meta/errors.h>
|
#include <meta/errors.h>
|
||||||
#include <meta/meta-background.h>
|
#include <meta/meta-background.h>
|
||||||
#include "meta-background-actor-private.h"
|
#include "meta-background-actor-private.h"
|
||||||
#include "meta-cullable.h"
|
|
||||||
|
|
||||||
struct _MetaBackgroundActorPrivate
|
struct _MetaBackgroundActorPrivate
|
||||||
{
|
{
|
||||||
cairo_region_t *clip_region;
|
cairo_region_t *clip_region;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void cullable_iface_init (MetaCullableInterface *iface);
|
G_DEFINE_TYPE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR);
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR,
|
|
||||||
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
|
|
||||||
|
|
||||||
static void
|
|
||||||
set_clip_region (MetaBackgroundActor *self,
|
|
||||||
cairo_region_t *clip_region)
|
|
||||||
{
|
|
||||||
MetaBackgroundActorPrivate *priv = self->priv;
|
|
||||||
|
|
||||||
g_clear_pointer (&priv->clip_region, (GDestroyNotify) cairo_region_destroy);
|
|
||||||
if (clip_region)
|
|
||||||
priv->clip_region = cairo_region_copy (clip_region);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_background_actor_dispose (GObject *object)
|
meta_background_actor_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
|
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
|
||||||
|
|
||||||
set_clip_region (self, NULL);
|
meta_background_actor_set_clip_region (self, NULL);
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object);
|
G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
@@ -119,6 +104,26 @@ meta_background_actor_get_preferred_height (ClutterActor *actor,
|
|||||||
*natural_height_p = height;
|
*natural_height_p = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_background_actor_get_paint_volume (ClutterActor *actor,
|
||||||
|
ClutterPaintVolume *volume)
|
||||||
|
{
|
||||||
|
ClutterContent *content;
|
||||||
|
gfloat width, height;
|
||||||
|
|
||||||
|
content = clutter_actor_get_content (actor);
|
||||||
|
|
||||||
|
if (!content)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
clutter_content_get_preferred_size (content, &width, &height);
|
||||||
|
|
||||||
|
clutter_paint_volume_set_width (volume, width);
|
||||||
|
clutter_paint_volume_set_height (volume, height);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_background_actor_class_init (MetaBackgroundActorClass *klass)
|
meta_background_actor_class_init (MetaBackgroundActorClass *klass)
|
||||||
{
|
{
|
||||||
@@ -131,6 +136,7 @@ meta_background_actor_class_init (MetaBackgroundActorClass *klass)
|
|||||||
|
|
||||||
actor_class->get_preferred_width = meta_background_actor_get_preferred_width;
|
actor_class->get_preferred_width = meta_background_actor_get_preferred_width;
|
||||||
actor_class->get_preferred_height = meta_background_actor_get_preferred_height;
|
actor_class->get_preferred_height = meta_background_actor_get_preferred_height;
|
||||||
|
actor_class->get_paint_volume = meta_background_actor_get_paint_volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -160,27 +166,31 @@ meta_background_actor_new (void)
|
|||||||
return CLUTTER_ACTOR (self);
|
return CLUTTER_ACTOR (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/**
|
||||||
meta_background_actor_cull_out (MetaCullable *cullable,
|
* meta_background_actor_set_clip_region:
|
||||||
cairo_region_t *unobscured_region,
|
* @self: a #MetaBackgroundActor
|
||||||
cairo_region_t *clip_region)
|
* @clip_region: (allow-none): the area of the actor (in allocate-relative
|
||||||
|
* coordinates) that is visible.
|
||||||
|
*
|
||||||
|
* Sets the area of the background that is unobscured by overlapping windows.
|
||||||
|
* This is used to optimize and only paint the visible portions.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
meta_background_actor_set_clip_region (MetaBackgroundActor *self,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable);
|
MetaBackgroundActorPrivate *priv;
|
||||||
set_clip_region (self, clip_region);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
g_return_if_fail (META_IS_BACKGROUND_ACTOR (self));
|
||||||
meta_background_actor_reset_culling (MetaCullable *cullable)
|
|
||||||
{
|
|
||||||
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable);
|
|
||||||
set_clip_region (self, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
priv = self->priv;
|
||||||
cullable_iface_init (MetaCullableInterface *iface)
|
|
||||||
{
|
g_clear_pointer (&priv->clip_region,
|
||||||
iface->cull_out = meta_background_actor_cull_out;
|
(GDestroyNotify)
|
||||||
iface->reset_culling = meta_background_actor_reset_culling;
|
cairo_region_destroy);
|
||||||
|
|
||||||
|
if (clip_region)
|
||||||
|
priv->clip_region = cairo_region_copy (clip_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
11
src/compositor/meta-background-group-private.h
Normal file
11
src/compositor/meta-background-group-private.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
|
||||||
|
#ifndef META_BACKGROUND_GROUP_PRIVATE_H
|
||||||
|
#define META_BACKGROUND_GROUP_PRIVATE_H
|
||||||
|
|
||||||
|
#include <meta/screen.h>
|
||||||
|
#include <meta/meta-background-group.h>
|
||||||
|
|
||||||
|
void meta_background_group_set_clip_region (MetaBackgroundGroup *self,
|
||||||
|
cairo_region_t *visible_region);
|
||||||
|
#endif /* META_BACKGROUND_GROUP_PRIVATE_H */
|
@@ -16,43 +16,87 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <meta/meta-background-group.h>
|
#include "compositor-private.h"
|
||||||
#include "meta-cullable.h"
|
#include "clutter-utils.h"
|
||||||
|
#include "meta-background-actor-private.h"
|
||||||
|
#include "meta-background-group-private.h"
|
||||||
|
|
||||||
static void cullable_iface_init (MetaCullableInterface *iface);
|
G_DEFINE_TYPE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR);
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR,
|
struct _MetaBackgroundGroupPrivate
|
||||||
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
|
{
|
||||||
|
gpointer dummy;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_background_group_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
G_OBJECT_CLASS (meta_background_group_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_background_group_get_paint_volume (ClutterActor *actor,
|
||||||
|
ClutterPaintVolume *volume)
|
||||||
|
{
|
||||||
|
return clutter_paint_volume_set_from_allocation (volume, actor);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_background_group_class_init (MetaBackgroundGroupClass *klass)
|
meta_background_group_class_init (MetaBackgroundGroupClass *klass)
|
||||||
{
|
{
|
||||||
}
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
|
|
||||||
static void
|
actor_class->get_paint_volume = meta_background_group_get_paint_volume;
|
||||||
meta_background_group_cull_out (MetaCullable *cullable,
|
object_class->dispose = meta_background_group_dispose;
|
||||||
cairo_region_t *unobscured_region,
|
|
||||||
cairo_region_t *clip_region)
|
|
||||||
{
|
|
||||||
meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
g_type_class_add_private (klass, sizeof (MetaBackgroundGroupPrivate));
|
||||||
meta_background_group_reset_culling (MetaCullable *cullable)
|
|
||||||
{
|
|
||||||
meta_cullable_reset_culling_children (cullable);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cullable_iface_init (MetaCullableInterface *iface)
|
|
||||||
{
|
|
||||||
iface->cull_out = meta_background_group_cull_out;
|
|
||||||
iface->reset_culling = meta_background_group_reset_culling;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_background_group_init (MetaBackgroundGroup *self)
|
meta_background_group_init (MetaBackgroundGroup *self)
|
||||||
{
|
{
|
||||||
|
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
||||||
|
META_TYPE_BACKGROUND_GROUP,
|
||||||
|
MetaBackgroundGroupPrivate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_background_group_set_clip_region:
|
||||||
|
* @self: a #MetaBackgroundGroup
|
||||||
|
* @region: (allow-none): the parts of the background to paint
|
||||||
|
*
|
||||||
|
* Sets the area of the backgrounds that is unobscured by overlapping windows.
|
||||||
|
* This is used to optimize and only paint the visible portions.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
meta_background_group_set_clip_region (MetaBackgroundGroup *self,
|
||||||
|
cairo_region_t *region)
|
||||||
|
{
|
||||||
|
GList *children, *l;
|
||||||
|
|
||||||
|
children = clutter_actor_get_children (CLUTTER_ACTOR (self));
|
||||||
|
for (l = children; l; l = l->next)
|
||||||
|
{
|
||||||
|
ClutterActor *actor = l->data;
|
||||||
|
|
||||||
|
if (META_IS_BACKGROUND_ACTOR (actor))
|
||||||
|
{
|
||||||
|
meta_background_actor_set_clip_region (META_BACKGROUND_ACTOR (actor), region);
|
||||||
|
}
|
||||||
|
else if (META_IS_BACKGROUND_GROUP (actor))
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
if (!meta_actor_is_untransformed (actor, &x, &y))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cairo_region_translate (region, -x, -y);
|
||||||
|
meta_background_group_set_clip_region (META_BACKGROUND_GROUP (actor), region);
|
||||||
|
cairo_region_translate (region, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_list_free (children);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClutterActor *
|
ClutterActor *
|
||||||
|
@@ -1,191 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2013 Red Hat
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
* 02111-1307, USA.
|
|
||||||
*
|
|
||||||
* Written by:
|
|
||||||
* Owen Taylor <otaylor@redhat.com>
|
|
||||||
* Ray Strode <rstrode@redhat.com>
|
|
||||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "meta-cullable.h"
|
|
||||||
#include "clutter-utils.h"
|
|
||||||
|
|
||||||
G_DEFINE_INTERFACE (MetaCullable, meta_cullable, CLUTTER_TYPE_ACTOR);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:meta-cullable
|
|
||||||
* @title: MetaCullable
|
|
||||||
* @short_description: CPU culling operations for efficient drawing
|
|
||||||
*
|
|
||||||
* When we are painting a stack of 5-10 large actors, the standard
|
|
||||||
* bottom-to-top method of drawing every actor results in a tremendous
|
|
||||||
* amount of overdraw. If these actors are painting textures like
|
|
||||||
* windows, it can easily max out the available memory bandwidth on a
|
|
||||||
* low-end graphics chipset. It's even worse if window textures are
|
|
||||||
* being accessed over the AGP bus.
|
|
||||||
*
|
|
||||||
* #MetaCullable is our solution. The basic technique applied here is to
|
|
||||||
* do a pre-pass before painting where we walk each actor from top to bottom
|
|
||||||
* and ask each actor to "cull itself out". We pass in a region it can copy
|
|
||||||
* to clip its drawing to, and the actor can subtract its fully opaque pixels
|
|
||||||
* so that actors underneath know not to draw there as well.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* meta_cullable_cull_out_children:
|
|
||||||
* @cullable: The #MetaCullable
|
|
||||||
* @unobscured_region: The unobscured region, as passed into cull_out()
|
|
||||||
* @clip_region: The clip region, as passed into cull_out()
|
|
||||||
*
|
|
||||||
* This is a helper method for actors that want to recurse over their
|
|
||||||
* child actors, and cull them out.
|
|
||||||
*
|
|
||||||
* See #MetaCullable and meta_cullable_cull_out() for more details.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
meta_cullable_cull_out_children (MetaCullable *cullable,
|
|
||||||
cairo_region_t *unobscured_region,
|
|
||||||
cairo_region_t *clip_region)
|
|
||||||
{
|
|
||||||
ClutterActor *actor = CLUTTER_ACTOR (cullable);
|
|
||||||
ClutterActor *child;
|
|
||||||
ClutterActorIter iter;
|
|
||||||
|
|
||||||
clutter_actor_iter_init (&iter, actor);
|
|
||||||
while (clutter_actor_iter_prev (&iter, &child))
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
if (!CLUTTER_ACTOR_IS_VISIBLE (child))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* If an actor has effects applied, then that can change the area
|
|
||||||
* it paints and the opacity, so we no longer can figure out what
|
|
||||||
* portion of the actor is obscured and what portion of the screen
|
|
||||||
* it obscures, so we skip the actor.
|
|
||||||
*
|
|
||||||
* This has a secondary beneficial effect: if a ClutterOffscreenEffect
|
|
||||||
* is applied to an actor, then our clipped redraws interfere with the
|
|
||||||
* caching of the FBO - even if we only need to draw a small portion
|
|
||||||
* of the window right now, ClutterOffscreenEffect may use other portions
|
|
||||||
* of the FBO later. So, skipping actors with effects applied also
|
|
||||||
* prevents these bugs.
|
|
||||||
*
|
|
||||||
* Theoretically, we should check clutter_actor_get_offscreen_redirect()
|
|
||||||
* as well for the same reason, but omitted for simplicity in the
|
|
||||||
* hopes that no-one will do that.
|
|
||||||
*/
|
|
||||||
if (clutter_actor_has_effects (child))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!META_IS_CULLABLE (child))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!meta_actor_is_untransformed (child, &x, &y))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Temporarily move to the coordinate system of the actor */
|
|
||||||
cairo_region_translate (unobscured_region, - x, - y);
|
|
||||||
cairo_region_translate (clip_region, - x, - y);
|
|
||||||
|
|
||||||
meta_cullable_cull_out (META_CULLABLE (child), unobscured_region, clip_region);
|
|
||||||
|
|
||||||
cairo_region_translate (unobscured_region, x, y);
|
|
||||||
cairo_region_translate (clip_region, x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* meta_cullable_reset_culling_children:
|
|
||||||
* @cullable: The #MetaCullable
|
|
||||||
*
|
|
||||||
* This is a helper method for actors that want to recurse over their
|
|
||||||
* child actors, and cull them out.
|
|
||||||
*
|
|
||||||
* See #MetaCullable and meta_cullable_reset_culling() for more details.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
meta_cullable_reset_culling_children (MetaCullable *cullable)
|
|
||||||
{
|
|
||||||
ClutterActor *actor = CLUTTER_ACTOR (cullable);
|
|
||||||
ClutterActor *child;
|
|
||||||
ClutterActorIter iter;
|
|
||||||
|
|
||||||
clutter_actor_iter_init (&iter, actor);
|
|
||||||
while (clutter_actor_iter_next (&iter, &child))
|
|
||||||
{
|
|
||||||
if (!META_IS_CULLABLE (child))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
meta_cullable_reset_culling (META_CULLABLE (child));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_cullable_default_init (MetaCullableInterface *iface)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* meta_cullable_cull_out:
|
|
||||||
* @cullable: The #MetaCullable
|
|
||||||
* @unobscured_region: The unobscured region, in @cullable's space.
|
|
||||||
* @clip_region: The clip region, in @cullable's space.
|
|
||||||
*
|
|
||||||
* When #MetaWindowGroup is painted, we walk over its direct cullable
|
|
||||||
* children from top to bottom and ask themselves to "cull out". Cullables
|
|
||||||
* can use @unobscured_region and @clip_region to clip their drawing. Actors
|
|
||||||
* interested in eliminating overdraw should copy the @clip_region and only
|
|
||||||
* paint those parts, as everything else has been obscured by actors above it.
|
|
||||||
*
|
|
||||||
* Actors that may have fully opaque parts should also subtract out a region
|
|
||||||
* that is fully opaque from @unobscured_region and @clip_region.
|
|
||||||
*
|
|
||||||
* @unobscured_region and @clip_region are extremely similar. The difference
|
|
||||||
* is that @clip_region starts off with the stage's clip, if Clutter detects
|
|
||||||
* that we're doing a clipped redraw. @unobscured_region, however, starts off
|
|
||||||
* with the full stage size, so actors that may want to record what parts of
|
|
||||||
* their window are unobscured for e.g. scheduling repaints can do so.
|
|
||||||
*
|
|
||||||
* Actors that have children can also use the meta_cullable_cull_out_children()
|
|
||||||
* helper method to do a simple cull across all their children.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
meta_cullable_cull_out (MetaCullable *cullable,
|
|
||||||
cairo_region_t *unobscured_region,
|
|
||||||
cairo_region_t *clip_region)
|
|
||||||
{
|
|
||||||
META_CULLABLE_GET_IFACE (cullable)->cull_out (cullable, unobscured_region, clip_region);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* meta_cullable_reset_culling:
|
|
||||||
* @cullable: The #MetaCullable
|
|
||||||
*
|
|
||||||
* Actors that copied data in their cull_out() implementation can now
|
|
||||||
* reset their data, as the paint is now over. Additional paints may be
|
|
||||||
* done by #ClutterClone or similar, and they should not be affected by
|
|
||||||
* the culling operation.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
meta_cullable_reset_culling (MetaCullable *cullable)
|
|
||||||
{
|
|
||||||
META_CULLABLE_GET_IFACE (cullable)->reset_culling (cullable);
|
|
||||||
}
|
|
@@ -1,68 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2013 Red Hat
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
* 02111-1307, USA.
|
|
||||||
*
|
|
||||||
* Written by:
|
|
||||||
* Owen Taylor <otaylor@redhat.com>
|
|
||||||
* Ray Strode <rstrode@redhat.com>
|
|
||||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __META_CULLABLE_H__
|
|
||||||
#define __META_CULLABLE_H__
|
|
||||||
|
|
||||||
#include <clutter/clutter.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define META_TYPE_CULLABLE (meta_cullable_get_type ())
|
|
||||||
#define META_CULLABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CULLABLE, MetaCullable))
|
|
||||||
#define META_IS_CULLABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CULLABLE))
|
|
||||||
#define META_CULLABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), META_TYPE_CULLABLE, MetaCullableInterface))
|
|
||||||
|
|
||||||
typedef struct _MetaCullable MetaCullable;
|
|
||||||
typedef struct _MetaCullableInterface MetaCullableInterface;
|
|
||||||
|
|
||||||
struct _MetaCullableInterface
|
|
||||||
{
|
|
||||||
GTypeInterface g_iface;
|
|
||||||
|
|
||||||
void (* cull_out) (MetaCullable *cullable,
|
|
||||||
cairo_region_t *unobscured_region,
|
|
||||||
cairo_region_t *clip_region);
|
|
||||||
void (* reset_culling) (MetaCullable *cullable);
|
|
||||||
};
|
|
||||||
|
|
||||||
GType meta_cullable_get_type (void);
|
|
||||||
|
|
||||||
void meta_cullable_cull_out (MetaCullable *cullable,
|
|
||||||
cairo_region_t *unobscured_region,
|
|
||||||
cairo_region_t *clip_region);
|
|
||||||
void meta_cullable_reset_culling (MetaCullable *cullable);
|
|
||||||
|
|
||||||
/* Utility methods for implementations */
|
|
||||||
void meta_cullable_cull_out_children (MetaCullable *cullable,
|
|
||||||
cairo_region_t *unobscured_region,
|
|
||||||
cairo_region_t *clip_region);
|
|
||||||
void meta_cullable_reset_culling_children (MetaCullable *cullable);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __META_CULLABLE_H__ */
|
|
||||||
|
|
@@ -72,7 +72,6 @@ struct _MetaShapedTexturePrivate
|
|||||||
|
|
||||||
cairo_region_t *clip_region;
|
cairo_region_t *clip_region;
|
||||||
cairo_region_t *opaque_region;
|
cairo_region_t *opaque_region;
|
||||||
cairo_region_t *input_shape_region;
|
|
||||||
|
|
||||||
guint tex_width, tex_height;
|
guint tex_width, tex_height;
|
||||||
|
|
||||||
@@ -395,60 +394,45 @@ meta_shaped_texture_pick (ClutterActor *actor,
|
|||||||
MetaShapedTexture *stex = (MetaShapedTexture *) actor;
|
MetaShapedTexture *stex = (MetaShapedTexture *) actor;
|
||||||
MetaShapedTexturePrivate *priv = stex->priv;
|
MetaShapedTexturePrivate *priv = stex->priv;
|
||||||
|
|
||||||
if (!clutter_actor_should_pick_paint (actor) ||
|
|
||||||
(priv->clip_region && cairo_region_is_empty (priv->clip_region)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* If there is no region then use the regular pick */
|
/* If there is no region then use the regular pick */
|
||||||
if (priv->input_shape_region == NULL)
|
if (priv->mask_texture == NULL)
|
||||||
CLUTTER_ACTOR_CLASS (meta_shaped_texture_parent_class)->pick (actor, color);
|
CLUTTER_ACTOR_CLASS (meta_shaped_texture_parent_class)->pick (actor, color);
|
||||||
else
|
else if (clutter_actor_should_pick_paint (actor))
|
||||||
{
|
{
|
||||||
int n_rects;
|
CoglTexture *paint_tex;
|
||||||
float *rectangles;
|
ClutterActorBox alloc;
|
||||||
int i;
|
guint tex_width, tex_height;
|
||||||
CoglPipeline *pipeline;
|
CoglPipeline *pipeline;
|
||||||
CoglContext *ctx;
|
CoglContext *ctx;
|
||||||
CoglFramebuffer *fb;
|
CoglFramebuffer *fb;
|
||||||
CoglColor cogl_color;
|
CoglColor cogl_color;
|
||||||
|
|
||||||
/* Note: We don't bother trying to intersect the pick and clip regions
|
paint_tex = COGL_TEXTURE (priv->texture);
|
||||||
* since needing to copy the region, do the intersection, and probably
|
|
||||||
* increase the number of rectangles seems more likely to have a negative
|
|
||||||
* effect.
|
|
||||||
*
|
|
||||||
* NB: Most of the time when just using rectangles for picking then
|
|
||||||
* picking shouldn't involve any rendering, and minimizing the number of
|
|
||||||
* rectangles has more benefit than reducing the area of the pick
|
|
||||||
* region.
|
|
||||||
*/
|
|
||||||
|
|
||||||
n_rects = cairo_region_num_rectangles (priv->input_shape_region);
|
if (paint_tex == NULL)
|
||||||
rectangles = g_alloca (sizeof (float) * 4 * n_rects);
|
return;
|
||||||
|
|
||||||
for (i = 0; i < n_rects; i++)
|
tex_width = cogl_texture_get_width (paint_tex);
|
||||||
{
|
tex_height = cogl_texture_get_height (paint_tex);
|
||||||
cairo_rectangle_int_t rect;
|
|
||||||
int pos = i * 4;
|
|
||||||
|
|
||||||
cairo_region_get_rectangle (priv->input_shape_region, i, &rect);
|
if (tex_width == 0 || tex_height == 0) /* no contents yet */
|
||||||
|
return;
|
||||||
rectangles[pos] = rect.x;
|
|
||||||
rectangles[pos + 1] = rect.y;
|
|
||||||
rectangles[pos + 2] = rect.x + rect.width;
|
|
||||||
rectangles[pos + 3] = rect.y + rect.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||||
fb = cogl_get_draw_framebuffer ();
|
fb = cogl_get_draw_framebuffer ();
|
||||||
|
|
||||||
cogl_color_init_from_4ub (&cogl_color, color->red, color->green, color->blue, color->alpha);
|
cogl_color_init_from_4ub (&cogl_color, color->red, color->green, color->blue, color->alpha);
|
||||||
|
|
||||||
pipeline = cogl_pipeline_new (ctx);
|
pipeline = get_masked_pipeline (ctx);
|
||||||
|
cogl_pipeline_set_layer_texture (pipeline, 1, priv->mask_texture);
|
||||||
cogl_pipeline_set_color (pipeline, &cogl_color);
|
cogl_pipeline_set_color (pipeline, &cogl_color);
|
||||||
|
|
||||||
cogl_framebuffer_draw_rectangles (fb, pipeline,
|
clutter_actor_get_allocation_box (actor, &alloc);
|
||||||
rectangles, n_rects);
|
|
||||||
|
cogl_framebuffer_draw_rectangle (fb, pipeline,
|
||||||
|
0, 0,
|
||||||
|
alloc.x2 - alloc.x1,
|
||||||
|
alloc.y2 - alloc.y1);
|
||||||
cogl_object_unref (pipeline);
|
cogl_object_unref (pipeline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -707,41 +691,6 @@ meta_shaped_texture_get_texture (MetaShapedTexture *stex)
|
|||||||
return COGL_TEXTURE (stex->priv->texture);
|
return COGL_TEXTURE (stex->priv->texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* meta_shaped_texture_set_input_shape_region:
|
|
||||||
* @stex: a #MetaShapedTexture
|
|
||||||
* @shape_region: the region of the texture that should respond to
|
|
||||||
* input.
|
|
||||||
*
|
|
||||||
* Determines what region of the texture should accept input. For
|
|
||||||
* X based windows this is defined by the ShapeInput region of the
|
|
||||||
* window.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex,
|
|
||||||
cairo_region_t *shape_region)
|
|
||||||
{
|
|
||||||
MetaShapedTexturePrivate *priv;
|
|
||||||
|
|
||||||
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
|
|
||||||
|
|
||||||
priv = stex->priv;
|
|
||||||
|
|
||||||
if (priv->input_shape_region != NULL)
|
|
||||||
{
|
|
||||||
cairo_region_destroy (priv->input_shape_region);
|
|
||||||
priv->input_shape_region = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shape_region != NULL)
|
|
||||||
{
|
|
||||||
cairo_region_reference (shape_region);
|
|
||||||
priv->input_shape_region = shape_region;
|
|
||||||
}
|
|
||||||
|
|
||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_shaped_texture_set_clip_region:
|
* meta_shaped_texture_set_clip_region:
|
||||||
* @stex: a #MetaShapedTexture
|
* @stex: a #MetaShapedTexture
|
||||||
|
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_ */
|
@@ -55,6 +55,14 @@ void meta_window_actor_set_updates_frozen (MetaWindowActor *self,
|
|||||||
void meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
|
void meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
|
||||||
gboolean no_delay_frame);
|
gboolean no_delay_frame);
|
||||||
|
|
||||||
|
cairo_region_t *meta_window_actor_get_obscured_region (MetaWindowActor *self);
|
||||||
|
|
||||||
|
void meta_window_actor_set_clip_region (MetaWindowActor *self,
|
||||||
|
cairo_region_t *clip_region);
|
||||||
|
void meta_window_actor_set_clip_region_beneath (MetaWindowActor *self,
|
||||||
|
cairo_region_t *beneath_region);
|
||||||
|
void meta_window_actor_reset_clip_regions (MetaWindowActor *self);
|
||||||
|
|
||||||
void meta_window_actor_set_unobscured_region (MetaWindowActor *self,
|
void meta_window_actor_set_unobscured_region (MetaWindowActor *self,
|
||||||
cairo_region_t *unobscured_region);
|
cairo_region_t *unobscured_region);
|
||||||
|
|
||||||
|
@@ -32,7 +32,6 @@
|
|||||||
#include "meta-texture-rectangle.h"
|
#include "meta-texture-rectangle.h"
|
||||||
#include "region-utils.h"
|
#include "region-utils.h"
|
||||||
#include "monitor-private.h"
|
#include "monitor-private.h"
|
||||||
#include "meta-cullable.h"
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
POSITION_CHANGED,
|
POSITION_CHANGED,
|
||||||
@@ -46,6 +45,7 @@ static guint signals[LAST_SIGNAL] = {0};
|
|||||||
struct _MetaWindowActorPrivate
|
struct _MetaWindowActorPrivate
|
||||||
{
|
{
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
|
Window xwindow;
|
||||||
MetaScreen *screen;
|
MetaScreen *screen;
|
||||||
|
|
||||||
ClutterActor *actor;
|
ClutterActor *actor;
|
||||||
@@ -68,10 +68,10 @@ struct _MetaWindowActorPrivate
|
|||||||
|
|
||||||
Damage damage;
|
Damage damage;
|
||||||
|
|
||||||
|
guint8 opacity;
|
||||||
|
|
||||||
/* A region that matches the shape of the window, including frame bounds */
|
/* A region that matches the shape of the window, including frame bounds */
|
||||||
cairo_region_t *shape_region;
|
cairo_region_t *shape_region;
|
||||||
/* If the window has an input shape, a region that matches the shape */
|
|
||||||
cairo_region_t *input_region;
|
|
||||||
/* The opaque region, from _NET_WM_OPAQUE_REGION, intersected with
|
/* The opaque region, from _NET_WM_OPAQUE_REGION, intersected with
|
||||||
* the shape region. */
|
* the shape region. */
|
||||||
cairo_region_t *opaque_region;
|
cairo_region_t *opaque_region;
|
||||||
@@ -109,6 +109,7 @@ struct _MetaWindowActorPrivate
|
|||||||
GList *frames;
|
GList *frames;
|
||||||
|
|
||||||
guint visible : 1;
|
guint visible : 1;
|
||||||
|
guint mapped : 1;
|
||||||
guint argb32 : 1;
|
guint argb32 : 1;
|
||||||
guint disposed : 1;
|
guint disposed : 1;
|
||||||
guint redecorating : 1;
|
guint redecorating : 1;
|
||||||
@@ -151,6 +152,8 @@ struct _FrameData
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_META_WINDOW = 1,
|
PROP_META_WINDOW = 1,
|
||||||
|
PROP_META_SCREEN,
|
||||||
|
PROP_X_WINDOW,
|
||||||
PROP_NO_SHADOW,
|
PROP_NO_SHADOW,
|
||||||
PROP_SHADOW_CLASS
|
PROP_SHADOW_CLASS
|
||||||
};
|
};
|
||||||
@@ -186,10 +189,7 @@ static void do_send_frame_timings (MetaWindowActor *self,
|
|||||||
gint refresh_interval,
|
gint refresh_interval,
|
||||||
gint64 presentation_time);
|
gint64 presentation_time);
|
||||||
|
|
||||||
static void cullable_iface_init (MetaCullableInterface *iface);
|
G_DEFINE_TYPE (MetaWindowActor, meta_window_actor, CLUTTER_TYPE_ACTOR);
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (MetaWindowActor, meta_window_actor, CLUTTER_TYPE_ACTOR,
|
|
||||||
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
frame_data_free (FrameData *frame)
|
frame_data_free (FrameData *frame)
|
||||||
@@ -219,12 +219,33 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
|
|||||||
"MetaWindow",
|
"MetaWindow",
|
||||||
"The displayed MetaWindow",
|
"The displayed MetaWindow",
|
||||||
META_TYPE_WINDOW,
|
META_TYPE_WINDOW,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
g_object_class_install_property (object_class,
|
||||||
PROP_META_WINDOW,
|
PROP_META_WINDOW,
|
||||||
pspec);
|
pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_pointer ("meta-screen",
|
||||||
|
"MetaScreen",
|
||||||
|
"MetaScreen",
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_META_SCREEN,
|
||||||
|
pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_ulong ("x-window",
|
||||||
|
"Window",
|
||||||
|
"Window",
|
||||||
|
0,
|
||||||
|
G_MAXULONG,
|
||||||
|
0,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_X_WINDOW,
|
||||||
|
pspec);
|
||||||
|
|
||||||
pspec = g_param_spec_boolean ("no-shadow",
|
pspec = g_param_spec_boolean ("no-shadow",
|
||||||
"No shadow",
|
"No shadow",
|
||||||
"Do not add shaddow to this window",
|
"Do not add shaddow to this window",
|
||||||
@@ -267,6 +288,7 @@ meta_window_actor_init (MetaWindowActor *self)
|
|||||||
priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
||||||
META_TYPE_WINDOW_ACTOR,
|
META_TYPE_WINDOW_ACTOR,
|
||||||
MetaWindowActorPrivate);
|
MetaWindowActorPrivate);
|
||||||
|
priv->opacity = 0xff;
|
||||||
priv->shadow_class = NULL;
|
priv->shadow_class = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,9 +299,11 @@ window_decorated_notify (MetaWindow *mw,
|
|||||||
{
|
{
|
||||||
MetaWindowActor *self = META_WINDOW_ACTOR (data);
|
MetaWindowActor *self = META_WINDOW_ACTOR (data);
|
||||||
MetaWindowActorPrivate *priv = self->priv;
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
|
MetaFrame *frame = meta_window_get_frame (mw);
|
||||||
MetaScreen *screen = priv->screen;
|
MetaScreen *screen = priv->screen;
|
||||||
MetaDisplay *display = meta_screen_get_display (screen);
|
MetaDisplay *display = meta_screen_get_display (screen);
|
||||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||||
|
Window new_xwindow;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Basically, we have to reconstruct the the internals of this object
|
* Basically, we have to reconstruct the the internals of this object
|
||||||
@@ -287,6 +311,11 @@ window_decorated_notify (MetaWindow *mw,
|
|||||||
*/
|
*/
|
||||||
priv->redecorating = TRUE;
|
priv->redecorating = TRUE;
|
||||||
|
|
||||||
|
if (frame)
|
||||||
|
new_xwindow = meta_frame_get_xwindow (frame);
|
||||||
|
else
|
||||||
|
new_xwindow = meta_window_get_xwindow (mw);
|
||||||
|
|
||||||
meta_window_actor_detach (self);
|
meta_window_actor_detach (self);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -301,6 +330,8 @@ window_decorated_notify (MetaWindow *mw,
|
|||||||
priv->damage = None;
|
priv->damage = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->xwindow = new_xwindow;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Recreate the contents.
|
* Recreate the contents.
|
||||||
*/
|
*/
|
||||||
@@ -315,30 +346,18 @@ window_appears_focused_notify (MetaWindow *mw,
|
|||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (data));
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (data));
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
is_non_opaque (MetaWindowActor *self)
|
|
||||||
{
|
|
||||||
MetaWindowActorPrivate *priv = self->priv;
|
|
||||||
MetaWindow *window = priv->window;
|
|
||||||
|
|
||||||
return priv->argb32 || (window->opacity != 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_actor_constructed (GObject *object)
|
meta_window_actor_constructed (GObject *object)
|
||||||
{
|
{
|
||||||
MetaWindowActor *self = META_WINDOW_ACTOR (object);
|
MetaWindowActor *self = META_WINDOW_ACTOR (object);
|
||||||
MetaWindowActorPrivate *priv = self->priv;
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
MetaWindow *window = priv->window;
|
MetaScreen *screen = priv->screen;
|
||||||
MetaScreen *screen = meta_window_get_screen (window);
|
|
||||||
MetaDisplay *display = meta_screen_get_display (screen);
|
MetaDisplay *display = meta_screen_get_display (screen);
|
||||||
|
Window xwindow = priv->xwindow;
|
||||||
|
MetaWindow *window = priv->window;
|
||||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||||
XRenderPictFormat *format;
|
XRenderPictFormat *format;
|
||||||
Window xwindow;
|
|
||||||
|
|
||||||
xwindow = meta_window_get_toplevel_xwindow (window);
|
|
||||||
|
|
||||||
priv->screen = screen;
|
|
||||||
priv->damage = XDamageCreate (xdisplay, xwindow,
|
priv->damage = XDamageCreate (xdisplay, xwindow,
|
||||||
XDamageReportBoundingBox);
|
XDamageReportBoundingBox);
|
||||||
|
|
||||||
@@ -361,6 +380,19 @@ meta_window_actor_constructed (GObject *object)
|
|||||||
* We will release it in dispose().
|
* We will release it in dispose().
|
||||||
*/
|
*/
|
||||||
g_object_ref (priv->actor);
|
g_object_ref (priv->actor);
|
||||||
|
|
||||||
|
g_signal_connect_object (window, "notify::decorated",
|
||||||
|
G_CALLBACK (window_decorated_notify), self, 0);
|
||||||
|
g_signal_connect_object (window, "notify::appears-focused",
|
||||||
|
G_CALLBACK (window_appears_focused_notify), self, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This is the case where existing window is gaining/loosing frame.
|
||||||
|
* Just ensure the actor is top most (i.e., above shadow).
|
||||||
|
*/
|
||||||
|
clutter_actor_set_child_above_sibling (CLUTTER_ACTOR (self), priv->actor, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_window_actor_update_opacity (self);
|
meta_window_actor_update_opacity (self);
|
||||||
@@ -400,7 +432,6 @@ meta_window_actor_dispose (GObject *object)
|
|||||||
|
|
||||||
g_clear_pointer (&priv->unobscured_region, cairo_region_destroy);
|
g_clear_pointer (&priv->unobscured_region, cairo_region_destroy);
|
||||||
g_clear_pointer (&priv->shape_region, cairo_region_destroy);
|
g_clear_pointer (&priv->shape_region, cairo_region_destroy);
|
||||||
g_clear_pointer (&priv->input_region, cairo_region_destroy);
|
|
||||||
g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
|
g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
|
||||||
g_clear_pointer (&priv->shadow_clip, cairo_region_destroy);
|
g_clear_pointer (&priv->shadow_clip, cairo_region_destroy);
|
||||||
|
|
||||||
@@ -453,12 +484,17 @@ meta_window_actor_set_property (GObject *object,
|
|||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_META_WINDOW:
|
case PROP_META_WINDOW:
|
||||||
priv->window = g_value_dup_object (value);
|
{
|
||||||
|
if (priv->window)
|
||||||
g_signal_connect_object (priv->window, "notify::decorated",
|
g_object_unref (priv->window);
|
||||||
G_CALLBACK (window_decorated_notify), self, 0);
|
priv->window = g_value_dup_object (value);
|
||||||
g_signal_connect_object (priv->window, "notify::appears-focused",
|
}
|
||||||
G_CALLBACK (window_appears_focused_notify), self, 0);
|
break;
|
||||||
|
case PROP_META_SCREEN:
|
||||||
|
priv->screen = g_value_get_pointer (value);
|
||||||
|
break;
|
||||||
|
case PROP_X_WINDOW:
|
||||||
|
priv->xwindow = g_value_get_ulong (value);
|
||||||
break;
|
break;
|
||||||
case PROP_NO_SHADOW:
|
case PROP_NO_SHADOW:
|
||||||
{
|
{
|
||||||
@@ -504,6 +540,12 @@ meta_window_actor_get_property (GObject *object,
|
|||||||
case PROP_META_WINDOW:
|
case PROP_META_WINDOW:
|
||||||
g_value_set_object (value, priv->window);
|
g_value_set_object (value, priv->window);
|
||||||
break;
|
break;
|
||||||
|
case PROP_META_SCREEN:
|
||||||
|
g_value_set_pointer (value, priv->screen);
|
||||||
|
break;
|
||||||
|
case PROP_X_WINDOW:
|
||||||
|
g_value_set_ulong (value, priv->xwindow);
|
||||||
|
break;
|
||||||
case PROP_NO_SHADOW:
|
case PROP_NO_SHADOW:
|
||||||
g_value_set_boolean (value, priv->no_shadow);
|
g_value_set_boolean (value, priv->no_shadow);
|
||||||
break;
|
break;
|
||||||
@@ -601,7 +643,7 @@ clip_shadow_under_window (MetaWindowActor *self)
|
|||||||
{
|
{
|
||||||
MetaWindowActorPrivate *priv = self->priv;
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
|
|
||||||
return is_non_opaque (self) && priv->window->frame;
|
return (priv->argb32 || priv->opacity != 0xff) && priv->window->frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -627,7 +669,6 @@ meta_window_actor_paint (ClutterActor *actor)
|
|||||||
MetaShadowParams params;
|
MetaShadowParams params;
|
||||||
cairo_rectangle_int_t shape_bounds;
|
cairo_rectangle_int_t shape_bounds;
|
||||||
cairo_region_t *clip = priv->shadow_clip;
|
cairo_region_t *clip = priv->shadow_clip;
|
||||||
MetaWindow *window = priv->window;
|
|
||||||
|
|
||||||
meta_window_actor_get_shape_bounds (self, &shape_bounds);
|
meta_window_actor_get_shape_bounds (self, &shape_bounds);
|
||||||
meta_window_actor_get_shadow_params (self, appears_focused, ¶ms);
|
meta_window_actor_get_shadow_params (self, appears_focused, ¶ms);
|
||||||
@@ -651,7 +692,7 @@ meta_window_actor_paint (ClutterActor *actor)
|
|||||||
params.y_offset + shape_bounds.y,
|
params.y_offset + shape_bounds.y,
|
||||||
shape_bounds.width,
|
shape_bounds.width,
|
||||||
shape_bounds.height,
|
shape_bounds.height,
|
||||||
(clutter_actor_get_paint_opacity (actor) * params.opacity * window->opacity) / (255 * 255),
|
(clutter_actor_get_paint_opacity (actor) * params.opacity * priv->opacity) / (255 * 255),
|
||||||
clip,
|
clip,
|
||||||
clip_shadow_under_window (self)); /* clip_strictly - not just as an optimization */
|
clip_shadow_under_window (self)); /* clip_strictly - not just as an optimization */
|
||||||
|
|
||||||
@@ -693,8 +734,12 @@ meta_window_actor_get_paint_volume (ClutterActor *actor,
|
|||||||
gdk_rectangle_union (&bounds, &shadow_bounds, &bounds);
|
gdk_rectangle_union (&bounds, &shadow_bounds, &bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->unobscured_region)
|
if (priv->unobscured_region && !clutter_actor_has_mapped_clones (actor))
|
||||||
cairo_region_intersect_rectangle (priv->unobscured_region, &bounds);
|
{
|
||||||
|
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.x = bounds.x;
|
||||||
origin.y = bounds.y;
|
origin.y = bounds.y;
|
||||||
@@ -738,10 +783,10 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do not add shadows to non-opaque windows; eventually we should generate
|
* Do not add shadows to ARGB windows; eventually we should generate a
|
||||||
* a shadow from the input shape for such windows.
|
* shadow from the input shape for such windows.
|
||||||
*/
|
*/
|
||||||
if (is_non_opaque (self))
|
if (priv->argb32 || priv->opacity != 0xff)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -772,6 +817,20 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_window_actor_get_x_window: (skip)
|
||||||
|
* @self: a #MetaWindowActor
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Window
|
||||||
|
meta_window_actor_get_x_window (MetaWindowActor *self)
|
||||||
|
{
|
||||||
|
if (!self)
|
||||||
|
return None;
|
||||||
|
|
||||||
|
return self->priv->xwindow;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_window_actor_get_meta_window:
|
* meta_window_actor_get_meta_window:
|
||||||
* @self: a #MetaWindowActor
|
* @self: a #MetaWindowActor
|
||||||
@@ -939,7 +998,7 @@ meta_window_actor_damage_all (MetaWindowActor *self)
|
|||||||
|
|
||||||
texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor));
|
texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor));
|
||||||
|
|
||||||
if (priv->needs_pixmap)
|
if (!priv->mapped || priv->needs_pixmap)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
|
redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
|
||||||
@@ -1028,7 +1087,7 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
|
|||||||
{
|
{
|
||||||
queue_send_frame_messages_timeout (self);
|
queue_send_frame_messages_timeout (self);
|
||||||
}
|
}
|
||||||
else
|
else if (priv->mapped && !priv->needs_pixmap)
|
||||||
{
|
{
|
||||||
const cairo_rectangle_int_t clip = { 0, 0, 1, 1 };
|
const cairo_rectangle_int_t clip = { 0, 0, 1, 1 };
|
||||||
clutter_actor_queue_redraw_with_clip (priv->actor, &clip);
|
clutter_actor_queue_redraw_with_clip (priv->actor, &clip);
|
||||||
@@ -1060,6 +1119,9 @@ meta_window_actor_queue_create_pixmap (MetaWindowActor *self)
|
|||||||
|
|
||||||
priv->needs_pixmap = TRUE;
|
priv->needs_pixmap = TRUE;
|
||||||
|
|
||||||
|
if (!priv->mapped)
|
||||||
|
return;
|
||||||
|
|
||||||
if (is_frozen (self))
|
if (is_frozen (self))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1273,7 +1335,7 @@ meta_window_actor_should_unredirect (MetaWindowActor *self)
|
|||||||
if (meta_window_requested_dont_bypass_compositor (metaWindow))
|
if (meta_window_requested_dont_bypass_compositor (metaWindow))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (metaWindow->opacity != 0xFF)
|
if (priv->opacity != 0xff)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (metaWindow->shape_region != NULL)
|
if (metaWindow->shape_region != NULL)
|
||||||
@@ -1304,7 +1366,7 @@ meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state)
|
|||||||
MetaDisplay *display = meta_window_get_display (metaWindow);
|
MetaDisplay *display = meta_window_get_display (metaWindow);
|
||||||
|
|
||||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||||
Window xwin = meta_window_get_toplevel_xwindow (metaWindow);
|
Window xwin = meta_window_actor_get_x_window (self);
|
||||||
|
|
||||||
if (state)
|
if (state)
|
||||||
{
|
{
|
||||||
@@ -1337,6 +1399,12 @@ meta_window_actor_destroy (MetaWindowActor *self)
|
|||||||
window_type = meta_window_get_window_type (window);
|
window_type = meta_window_get_window_type (window);
|
||||||
meta_window_set_compositor_private (window, NULL);
|
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
|
* We remove the window from internal lookup hashes and thus any other
|
||||||
* unmap events etc fail
|
* unmap events etc fail
|
||||||
@@ -1558,10 +1626,22 @@ meta_window_actor_new (MetaWindow *window)
|
|||||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||||
MetaWindowActor *self;
|
MetaWindowActor *self;
|
||||||
MetaWindowActorPrivate *priv;
|
MetaWindowActorPrivate *priv;
|
||||||
|
MetaFrame *frame;
|
||||||
|
Window top_window;
|
||||||
ClutterActor *window_group;
|
ClutterActor *window_group;
|
||||||
|
|
||||||
|
frame = meta_window_get_frame (window);
|
||||||
|
if (frame)
|
||||||
|
top_window = meta_frame_get_xwindow (frame);
|
||||||
|
else
|
||||||
|
top_window = meta_window_get_xwindow (window);
|
||||||
|
|
||||||
|
meta_verbose ("add window: Meta %p, xwin 0x%x\n", window, (guint)top_window);
|
||||||
|
|
||||||
self = g_object_new (META_TYPE_WINDOW_ACTOR,
|
self = g_object_new (META_TYPE_WINDOW_ACTOR,
|
||||||
"meta-window", window,
|
"meta-window", window,
|
||||||
|
"x-window", top_window,
|
||||||
|
"meta-screen", screen,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
priv = self->priv;
|
priv = self->priv;
|
||||||
@@ -1569,6 +1649,10 @@ meta_window_actor_new (MetaWindow *window)
|
|||||||
priv->last_width = -1;
|
priv->last_width = -1;
|
||||||
priv->last_height = -1;
|
priv->last_height = -1;
|
||||||
|
|
||||||
|
priv->mapped = meta_window_toplevel_is_mapped (priv->window);
|
||||||
|
if (priv->mapped)
|
||||||
|
meta_window_actor_queue_create_pixmap (self);
|
||||||
|
|
||||||
meta_window_actor_set_updates_frozen (self,
|
meta_window_actor_set_updates_frozen (self,
|
||||||
meta_window_updates_are_frozen (priv->window));
|
meta_window_updates_are_frozen (priv->window));
|
||||||
|
|
||||||
@@ -1602,6 +1686,34 @@ meta_window_actor_new (MetaWindow *window)
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_actor_mapped (MetaWindowActor *self)
|
||||||
|
{
|
||||||
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
g_return_if_fail (!priv->mapped);
|
||||||
|
|
||||||
|
priv->mapped = TRUE;
|
||||||
|
|
||||||
|
meta_window_actor_queue_create_pixmap (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_actor_unmapped (MetaWindowActor *self)
|
||||||
|
{
|
||||||
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
g_return_if_fail (priv->mapped);
|
||||||
|
|
||||||
|
priv->mapped = FALSE;
|
||||||
|
|
||||||
|
if (meta_window_actor_effect_in_progress (self))
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_window_actor_detach (self);
|
||||||
|
priv->needs_pixmap = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_window_actor_get_obscured_region:
|
* meta_window_actor_get_obscured_region:
|
||||||
* @self: a #MetaWindowActor
|
* @self: a #MetaWindowActor
|
||||||
@@ -1612,13 +1724,12 @@ meta_window_actor_new (MetaWindow *window)
|
|||||||
* Return value: (transfer none): the area obscured by the window,
|
* Return value: (transfer none): the area obscured by the window,
|
||||||
* %NULL is the same as an empty region.
|
* %NULL is the same as an empty region.
|
||||||
*/
|
*/
|
||||||
static cairo_region_t *
|
cairo_region_t *
|
||||||
meta_window_actor_get_obscured_region (MetaWindowActor *self)
|
meta_window_actor_get_obscured_region (MetaWindowActor *self)
|
||||||
{
|
{
|
||||||
MetaWindowActorPrivate *priv = self->priv;
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
MetaWindow *window = priv->window;
|
|
||||||
|
|
||||||
if (priv->back_pixmap && window->opacity != 0xFF && !priv->window->shaded)
|
if (priv->back_pixmap && priv->opacity == 0xff && !priv->window->shaded)
|
||||||
return priv->opaque_region;
|
return priv->opaque_region;
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1702,7 +1813,7 @@ meta_window_actor_set_unobscured_region (MetaWindowActor *self,
|
|||||||
* not drawn in this frame.
|
* not drawn in this frame.
|
||||||
* This will be set before painting then unset afterwards.
|
* This will be set before painting then unset afterwards.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
meta_window_actor_set_clip_region (MetaWindowActor *self,
|
meta_window_actor_set_clip_region (MetaWindowActor *self,
|
||||||
cairo_region_t *clip_region)
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
@@ -1724,7 +1835,7 @@ meta_window_actor_set_clip_region (MetaWindowActor *self,
|
|||||||
* shadow hid by the window itself. This will be set before painting
|
* shadow hid by the window itself. This will be set before painting
|
||||||
* then unset afterwards.
|
* then unset afterwards.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
meta_window_actor_set_clip_region_beneath (MetaWindowActor *self,
|
meta_window_actor_set_clip_region_beneath (MetaWindowActor *self,
|
||||||
cairo_region_t *beneath_region)
|
cairo_region_t *beneath_region)
|
||||||
{
|
{
|
||||||
@@ -1744,38 +1855,16 @@ meta_window_actor_set_clip_region_beneath (MetaWindowActor *self,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/**
|
||||||
meta_window_actor_cull_out (MetaCullable *cullable,
|
* meta_window_actor_reset_clip_regions:
|
||||||
cairo_region_t *unobscured_region,
|
* @self: a #MetaWindowActor
|
||||||
cairo_region_t *clip_region)
|
*
|
||||||
|
* Unsets the regions set by meta_window_actor_set_clip_region() and
|
||||||
|
* meta_window_actor_set_clip_region_beneath()
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
meta_window_actor_reset_clip_regions (MetaWindowActor *self)
|
||||||
{
|
{
|
||||||
MetaWindowActor *self = META_WINDOW_ACTOR (cullable);
|
|
||||||
MetaCompScreen *info = meta_screen_get_compositor_data (self->priv->screen);
|
|
||||||
|
|
||||||
/* Don't do any culling for the unredirected window */
|
|
||||||
if (self == info->unredirected_window)
|
|
||||||
return;
|
|
||||||
|
|
||||||
meta_window_actor_set_unobscured_region (self, unobscured_region);
|
|
||||||
meta_window_actor_set_clip_region (self, clip_region);
|
|
||||||
|
|
||||||
if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self)) == 0xff)
|
|
||||||
{
|
|
||||||
cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (self);
|
|
||||||
if (obscured_region)
|
|
||||||
{
|
|
||||||
cairo_region_subtract (unobscured_region, obscured_region);
|
|
||||||
cairo_region_subtract (clip_region, obscured_region);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_window_actor_set_clip_region_beneath (self, clip_region);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_window_actor_reset_culling (MetaCullable *cullable)
|
|
||||||
{
|
|
||||||
MetaWindowActor *self = META_WINDOW_ACTOR (cullable);
|
|
||||||
MetaWindowActorPrivate *priv = self->priv;
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
|
|
||||||
meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor),
|
meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor),
|
||||||
@@ -1783,13 +1872,6 @@ meta_window_actor_reset_culling (MetaCullable *cullable)
|
|||||||
g_clear_pointer (&priv->shadow_clip, cairo_region_destroy);
|
g_clear_pointer (&priv->shadow_clip, cairo_region_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
cullable_iface_init (MetaCullableInterface *iface)
|
|
||||||
{
|
|
||||||
iface->cull_out = meta_window_actor_cull_out;
|
|
||||||
iface->reset_culling = meta_window_actor_reset_culling;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
check_needs_pixmap (MetaWindowActor *self)
|
check_needs_pixmap (MetaWindowActor *self)
|
||||||
{
|
{
|
||||||
@@ -1798,12 +1880,15 @@ check_needs_pixmap (MetaWindowActor *self)
|
|||||||
MetaDisplay *display = meta_screen_get_display (screen);
|
MetaDisplay *display = meta_screen_get_display (screen);
|
||||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||||
Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
|
|
||||||
MetaCompositor *compositor;
|
MetaCompositor *compositor;
|
||||||
|
Window xwindow = priv->xwindow;
|
||||||
|
|
||||||
if (!priv->needs_pixmap)
|
if (!priv->needs_pixmap)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!priv->mapped)
|
||||||
|
return;
|
||||||
|
|
||||||
if (xwindow == meta_screen_get_xroot (screen) ||
|
if (xwindow == meta_screen_get_xroot (screen) ||
|
||||||
xwindow == clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)))
|
xwindow == clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)))
|
||||||
return;
|
return;
|
||||||
@@ -1861,7 +1946,7 @@ check_needs_pixmap (MetaWindowActor *self)
|
|||||||
if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture))))
|
if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture))))
|
||||||
g_warning ("NOTE: Not using GLX TFP!\n");
|
g_warning ("NOTE: Not using GLX TFP!\n");
|
||||||
|
|
||||||
/* ::size-changed is supposed to refer to meta_window_get_frame_rect().
|
/* ::size-changed is supposed to refer to meta_window_get_outer_rect().
|
||||||
* Emitting it here works pretty much OK because a new value of the
|
* Emitting it here works pretty much OK because a new value of the
|
||||||
* *input* rect (which is the outer rect with the addition of invisible
|
* *input* rect (which is the outer rect with the addition of invisible
|
||||||
* borders) forces a new pixmap and we get here. In the rare case where
|
* borders) forces a new pixmap and we get here. In the rare case where
|
||||||
@@ -1889,6 +1974,9 @@ check_needs_shadow (MetaWindowActor *self)
|
|||||||
gboolean should_have_shadow;
|
gboolean should_have_shadow;
|
||||||
gboolean appears_focused;
|
gboolean appears_focused;
|
||||||
|
|
||||||
|
if (!priv->mapped)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Calling meta_window_actor_has_shadow() here at every pre-paint is cheap
|
/* Calling meta_window_actor_has_shadow() here at every pre-paint is cheap
|
||||||
* and avoids the need to explicitly handle window type changes, which
|
* and avoids the need to explicitly handle window type changes, which
|
||||||
* we would do if tried to keep track of when we might be adding or removing
|
* we would do if tried to keep track of when we might be adding or removing
|
||||||
@@ -1954,7 +2042,7 @@ meta_window_actor_process_damage (MetaWindowActor *self,
|
|||||||
if (meta_window_is_fullscreen (priv->window) && g_list_last (info->windows)->data == self && !priv->unredirected)
|
if (meta_window_is_fullscreen (priv->window) && g_list_last (info->windows)->data == self && !priv->unredirected)
|
||||||
{
|
{
|
||||||
MetaRectangle window_rect;
|
MetaRectangle window_rect;
|
||||||
meta_window_get_frame_rect (priv->window, &window_rect);
|
meta_window_get_outer_rect (priv->window, &window_rect);
|
||||||
|
|
||||||
if (window_rect.x == event->area.x &&
|
if (window_rect.x == event->area.x &&
|
||||||
window_rect.y == event->area.y &&
|
window_rect.y == event->area.y &&
|
||||||
@@ -1992,7 +2080,7 @@ meta_window_actor_process_damage (MetaWindowActor *self,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->needs_pixmap)
|
if (!priv->mapped || priv->needs_pixmap)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
|
redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
|
||||||
@@ -2141,7 +2229,8 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
|||||||
|
|
||||||
meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor),
|
meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor),
|
||||||
mask_texture);
|
mask_texture);
|
||||||
cogl_object_unref (mask_texture);
|
if (mask_texture)
|
||||||
|
cogl_object_unref (mask_texture);
|
||||||
|
|
||||||
g_free (mask_data);
|
g_free (mask_data);
|
||||||
}
|
}
|
||||||
@@ -2178,46 +2267,9 @@ meta_window_actor_update_shape_region (MetaWindowActor *self,
|
|||||||
priv->shape_region = region;
|
priv->shape_region = region;
|
||||||
|
|
||||||
g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref);
|
g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref);
|
||||||
|
|
||||||
meta_window_actor_invalidate_shadow (self);
|
meta_window_actor_invalidate_shadow (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
meta_window_actor_update_input_region (MetaWindowActor *self,
|
|
||||||
cairo_rectangle_int_t *client_area)
|
|
||||||
{
|
|
||||||
MetaWindowActorPrivate *priv = self->priv;
|
|
||||||
MetaShapedTexture *stex = META_SHAPED_TEXTURE (priv->actor);
|
|
||||||
cairo_region_t *region = NULL;
|
|
||||||
|
|
||||||
if (priv->window->frame != NULL && priv->window->input_region != NULL)
|
|
||||||
{
|
|
||||||
region = meta_frame_get_frame_bounds (priv->window->frame);
|
|
||||||
|
|
||||||
cairo_region_subtract_rectangle (region, client_area);
|
|
||||||
|
|
||||||
/* input_region is in client window coordinates, so translate the
|
|
||||||
* input region into that coordinate system and back */
|
|
||||||
cairo_region_translate (region, -client_area->x, -client_area->y);
|
|
||||||
cairo_region_union (region, priv->window->input_region);
|
|
||||||
cairo_region_translate (region, client_area->x, client_area->y);
|
|
||||||
}
|
|
||||||
else if (priv->window->input_region != NULL)
|
|
||||||
{
|
|
||||||
region = cairo_region_reference (priv->window->input_region);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* If we don't have a shape on the server, that means that
|
|
||||||
* we have an implicit shape of one rectangle covering the
|
|
||||||
* entire window. */
|
|
||||||
region = cairo_region_create_rectangle (client_area);
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_shaped_texture_set_input_shape_region (stex, region);
|
|
||||||
cairo_region_destroy (region);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_actor_update_opaque_region (MetaWindowActor *self)
|
meta_window_actor_update_opaque_region (MetaWindowActor *self)
|
||||||
{
|
{
|
||||||
@@ -2261,6 +2313,9 @@ check_needs_reshape (MetaWindowActor *self)
|
|||||||
MetaFrameBorders borders;
|
MetaFrameBorders borders;
|
||||||
cairo_rectangle_int_t client_area;
|
cairo_rectangle_int_t client_area;
|
||||||
|
|
||||||
|
if (!priv->mapped)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!priv->needs_reshape)
|
if (!priv->needs_reshape)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -2275,10 +2330,10 @@ check_needs_reshape (MetaWindowActor *self)
|
|||||||
client_area.height = priv->window->rect.height;
|
client_area.height = priv->window->rect.height;
|
||||||
|
|
||||||
meta_window_actor_update_shape_region (self, &client_area);
|
meta_window_actor_update_shape_region (self, &client_area);
|
||||||
meta_window_actor_update_input_region (self, &client_area);
|
|
||||||
meta_window_actor_update_opaque_region (self);
|
meta_window_actor_update_opaque_region (self);
|
||||||
|
|
||||||
priv->needs_reshape = FALSE;
|
priv->needs_reshape = FALSE;
|
||||||
|
meta_window_actor_invalidate_shadow (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2321,26 +2376,6 @@ meta_window_actor_handle_updates (MetaWindowActor *self)
|
|||||||
XDamageSubtract (xdisplay, priv->damage, None, None);
|
XDamageSubtract (xdisplay, priv->damage, None, None);
|
||||||
meta_error_trap_pop (display);
|
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;
|
priv->received_damage = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2523,9 +2558,23 @@ void
|
|||||||
meta_window_actor_update_opacity (MetaWindowActor *self)
|
meta_window_actor_update_opacity (MetaWindowActor *self)
|
||||||
{
|
{
|
||||||
MetaWindowActorPrivate *priv = self->priv;
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
MetaWindow *window = priv->window;
|
MetaDisplay *display = meta_screen_get_display (priv->screen);
|
||||||
|
MetaCompositor *compositor = meta_display_get_compositor (display);
|
||||||
|
Window xwin = meta_window_get_xwindow (priv->window);
|
||||||
|
gulong value;
|
||||||
|
guint8 opacity;
|
||||||
|
|
||||||
clutter_actor_set_opacity (self->priv->actor, window->opacity);
|
if (meta_prop_get_cardinal (display, xwin,
|
||||||
|
compositor->atom_net_wm_window_opacity,
|
||||||
|
&value))
|
||||||
|
{
|
||||||
|
opacity = (guint8)((gfloat)value * 255.0 / ((gfloat)0xffffffff));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
opacity = 255;
|
||||||
|
|
||||||
|
self->priv->opacity = opacity;
|
||||||
|
clutter_actor_set_opacity (self->priv->actor, opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -11,8 +11,8 @@
|
|||||||
#include "compositor-private.h"
|
#include "compositor-private.h"
|
||||||
#include "meta-window-actor-private.h"
|
#include "meta-window-actor-private.h"
|
||||||
#include "meta-window-group.h"
|
#include "meta-window-group.h"
|
||||||
#include "window-private.h"
|
#include "meta-background-actor-private.h"
|
||||||
#include "meta-cullable.h"
|
#include "meta-background-group-private.h"
|
||||||
|
|
||||||
struct _MetaWindowGroupClass
|
struct _MetaWindowGroupClass
|
||||||
{
|
{
|
||||||
@@ -26,10 +26,7 @@ struct _MetaWindowGroup
|
|||||||
MetaScreen *screen;
|
MetaScreen *screen;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void cullable_iface_init (MetaCullableInterface *iface);
|
G_DEFINE_TYPE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR);
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR,
|
|
||||||
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
|
|
||||||
|
|
||||||
/* Help macros to scale from OpenGL <-1,1> coordinates system to
|
/* Help macros to scale from OpenGL <-1,1> coordinates system to
|
||||||
* window coordinates ranging [0,window-size]. Borrowed from clutter-utils.c
|
* window coordinates ranging [0,window-size]. Borrowed from clutter-utils.c
|
||||||
@@ -89,27 +86,6 @@ painting_untransformed (MetaWindowGroup *window_group,
|
|||||||
return meta_actor_vertices_are_untransformed (vertices, width, height, x_origin, y_origin);
|
return meta_actor_vertices_are_untransformed (vertices, width, height, x_origin, y_origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
meta_window_group_cull_out (MetaCullable *cullable,
|
|
||||||
cairo_region_t *unobscured_region,
|
|
||||||
cairo_region_t *clip_region)
|
|
||||||
{
|
|
||||||
meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_window_group_reset_culling (MetaCullable *cullable)
|
|
||||||
{
|
|
||||||
meta_cullable_reset_culling_children (cullable);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cullable_iface_init (MetaCullableInterface *iface)
|
|
||||||
{
|
|
||||||
iface->cull_out = meta_window_group_cull_out;
|
|
||||||
iface->reset_culling = meta_window_group_reset_culling;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_group_paint (ClutterActor *actor)
|
meta_window_group_paint (ClutterActor *actor)
|
||||||
{
|
{
|
||||||
@@ -118,13 +94,13 @@ meta_window_group_paint (ClutterActor *actor)
|
|||||||
ClutterActorIter iter;
|
ClutterActorIter iter;
|
||||||
ClutterActor *child;
|
ClutterActor *child;
|
||||||
cairo_rectangle_int_t visible_rect, clip_rect;
|
cairo_rectangle_int_t visible_rect, clip_rect;
|
||||||
int paint_x_offset, paint_y_offset;
|
|
||||||
int paint_x_origin, paint_y_origin;
|
int paint_x_origin, paint_y_origin;
|
||||||
int actor_x_origin, actor_y_origin;
|
int actor_x_origin, actor_y_origin;
|
||||||
|
int paint_x_offset, paint_y_offset;
|
||||||
|
|
||||||
MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
|
MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
|
||||||
ClutterActor *stage = clutter_actor_get_stage (actor);
|
|
||||||
MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen);
|
MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen);
|
||||||
|
ClutterActor *stage = clutter_actor_get_stage (actor);
|
||||||
|
|
||||||
/* Start off by treating all windows as completely unobscured, so damage anywhere
|
/* Start off by treating all windows as completely unobscured, so damage anywhere
|
||||||
* in a window queues redraws, but confine it more below. */
|
* in a window queues redraws, but confine it more below. */
|
||||||
@@ -158,6 +134,9 @@ meta_window_group_paint (ClutterActor *actor)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
paint_x_offset = paint_x_origin - actor_x_origin;
|
||||||
|
paint_y_offset = paint_y_origin - actor_y_origin;
|
||||||
|
|
||||||
visible_rect.x = visible_rect.y = 0;
|
visible_rect.x = visible_rect.y = 0;
|
||||||
visible_rect.width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
|
visible_rect.width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
|
||||||
visible_rect.height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
|
visible_rect.height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
|
||||||
@@ -175,28 +154,127 @@ meta_window_group_paint (ClutterActor *actor)
|
|||||||
|
|
||||||
clip_region = cairo_region_create_rectangle (&clip_rect);
|
clip_region = cairo_region_create_rectangle (&clip_rect);
|
||||||
|
|
||||||
paint_x_offset = paint_x_origin - actor_x_origin;
|
|
||||||
paint_y_offset = paint_y_origin - actor_y_origin;
|
|
||||||
cairo_region_translate (clip_region, -paint_x_offset, -paint_y_offset);
|
|
||||||
|
|
||||||
if (info->unredirected_window != NULL)
|
if (info->unredirected_window != NULL)
|
||||||
{
|
{
|
||||||
cairo_rectangle_int_t unredirected_rect;
|
cairo_rectangle_int_t unredirected_rect;
|
||||||
MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window);
|
MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window);
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, (MetaRectangle *)&unredirected_rect);
|
meta_window_get_outer_rect (window, (MetaRectangle *)&unredirected_rect);
|
||||||
cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect);
|
cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect);
|
||||||
cairo_region_subtract_rectangle (clip_region, &unredirected_rect);
|
cairo_region_subtract_rectangle (clip_region, &unredirected_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region);
|
/* We walk the list from top to bottom (opposite of painting order),
|
||||||
|
* and subtract the opaque area of each window out of the visible
|
||||||
|
* region that we pass to the windows below.
|
||||||
|
*/
|
||||||
|
clutter_actor_iter_init (&iter, actor);
|
||||||
|
while (clutter_actor_iter_prev (&iter, &child))
|
||||||
|
{
|
||||||
|
if (!CLUTTER_ACTOR_IS_VISIBLE (child))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (info->unredirected_window != NULL &&
|
||||||
|
child == CLUTTER_ACTOR (info->unredirected_window))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* If an actor has effects applied, then that can change the area
|
||||||
|
* it paints and the opacity, so we no longer can figure out what
|
||||||
|
* portion of the actor is obscured and what portion of the screen
|
||||||
|
* it obscures, so we skip the actor.
|
||||||
|
*
|
||||||
|
* This has a secondary beneficial effect: if a ClutterOffscreenEffect
|
||||||
|
* is applied to an actor, then our clipped redraws interfere with the
|
||||||
|
* caching of the FBO - even if we only need to draw a small portion
|
||||||
|
* of the window right now, ClutterOffscreenEffect may use other portions
|
||||||
|
* of the FBO later. So, skipping actors with effects applied also
|
||||||
|
* prevents these bugs.
|
||||||
|
*
|
||||||
|
* Theoretically, we should check clutter_actor_get_offscreen_redirect()
|
||||||
|
* as well for the same reason, but omitted for simplicity in the
|
||||||
|
* hopes that no-one will do that.
|
||||||
|
*/
|
||||||
|
if (clutter_actor_has_effects (child))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (META_IS_WINDOW_ACTOR (child))
|
||||||
|
{
|
||||||
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (child);
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
if (!meta_actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
x += paint_x_offset;
|
||||||
|
y += paint_y_offset;
|
||||||
|
|
||||||
|
|
||||||
|
/* Temporarily move to the coordinate system of the actor */
|
||||||
|
cairo_region_translate (unobscured_region, - x, - y);
|
||||||
|
cairo_region_translate (clip_region, - x, - y);
|
||||||
|
|
||||||
|
meta_window_actor_set_unobscured_region (window_actor, unobscured_region);
|
||||||
|
meta_window_actor_set_clip_region (window_actor, clip_region);
|
||||||
|
|
||||||
|
if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff)
|
||||||
|
{
|
||||||
|
cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (window_actor);
|
||||||
|
if (obscured_region)
|
||||||
|
{
|
||||||
|
cairo_region_subtract (unobscured_region, obscured_region);
|
||||||
|
cairo_region_subtract (clip_region, obscured_region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_window_actor_set_clip_region_beneath (window_actor, clip_region);
|
||||||
|
|
||||||
|
cairo_region_translate (unobscured_region, x, y);
|
||||||
|
cairo_region_translate (clip_region, x, y);
|
||||||
|
}
|
||||||
|
else if (META_IS_BACKGROUND_ACTOR (child) ||
|
||||||
|
META_IS_BACKGROUND_GROUP (child))
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
if (!meta_actor_is_untransformed (child, &x, &y))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
x += paint_x_offset;
|
||||||
|
y += paint_y_offset;
|
||||||
|
|
||||||
|
cairo_region_translate (clip_region, - x, - y);
|
||||||
|
|
||||||
|
if (META_IS_BACKGROUND_GROUP (child))
|
||||||
|
meta_background_group_set_clip_region (META_BACKGROUND_GROUP (child), clip_region);
|
||||||
|
else
|
||||||
|
meta_background_actor_set_clip_region (META_BACKGROUND_ACTOR (child), clip_region);
|
||||||
|
|
||||||
|
cairo_region_translate (clip_region, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cairo_region_destroy (unobscured_region);
|
cairo_region_destroy (unobscured_region);
|
||||||
cairo_region_destroy (clip_region);
|
cairo_region_destroy (clip_region);
|
||||||
|
|
||||||
CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);
|
CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);
|
||||||
|
|
||||||
meta_cullable_reset_culling (META_CULLABLE (window_group));
|
/* Now that we are done painting, unset the visible regions (they will
|
||||||
|
* mess up painting clones of our actors)
|
||||||
|
*/
|
||||||
|
clutter_actor_iter_init (&iter, actor);
|
||||||
|
while (clutter_actor_iter_next (&iter, &child))
|
||||||
|
{
|
||||||
|
if (META_IS_WINDOW_ACTOR (child))
|
||||||
|
{
|
||||||
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (child);
|
||||||
|
meta_window_actor_reset_clip_regions (window_actor);
|
||||||
|
}
|
||||||
|
else if (META_IS_BACKGROUND_ACTOR (child))
|
||||||
|
{
|
||||||
|
MetaBackgroundActor *background_actor = META_BACKGROUND_ACTOR (child);
|
||||||
|
meta_background_actor_set_clip_region (background_actor, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adapted from clutter_actor_update_default_paint_volume() */
|
/* Adapted from clutter_actor_update_default_paint_volume() */
|
||||||
|
@@ -11,9 +11,29 @@
|
|||||||
* MetaWindowGroup:
|
* MetaWindowGroup:
|
||||||
*
|
*
|
||||||
* This class is a subclass of ClutterActor with special handling for
|
* This class is a subclass of ClutterActor with special handling for
|
||||||
* #MetaCullable when painting children. It uses code similar to
|
* MetaWindowActor/MetaBackgroundActor/MetaBackgroundGroup when painting
|
||||||
* meta_cullable_cull_out_children(), but also has additional special
|
* children.
|
||||||
* cases for the undirected window, and similar.
|
*
|
||||||
|
* When we are painting a stack of 5-10 maximized windows, the
|
||||||
|
* standard bottom-to-top method of drawing every actor results in a
|
||||||
|
* tremendous amount of overdraw and can easily max out the available
|
||||||
|
* memory bandwidth on a low-end graphics chipset. It's even worse if
|
||||||
|
* window textures are being accessed over the AGP bus.
|
||||||
|
*
|
||||||
|
* The basic technique applied here is to do a pre-pass before painting
|
||||||
|
* where we walk window from top to bottom and compute the visible area
|
||||||
|
* at each step by subtracting out the windows above it. The visible
|
||||||
|
* area is passed to MetaWindowActor which uses it to clip the portion of
|
||||||
|
* the window which drawn and avoid redrawing the shadow if it is completely
|
||||||
|
* obscured.
|
||||||
|
*
|
||||||
|
* A caveat is that this is ineffective if applications are using ARGB
|
||||||
|
* visuals, since we have no way of knowing whether a window obscures
|
||||||
|
* the windows behind it or not. Alternate approaches using the depth
|
||||||
|
* or stencil buffer rather than client side regions might be able to
|
||||||
|
* handle alpha windows, but the combination of glAlphaFunc and stenciling
|
||||||
|
* tends not to be efficient except on newer cards. (And on newer cards
|
||||||
|
* we have lots of memory and bandwidth.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define META_TYPE_WINDOW_GROUP (meta_window_group_get_type ())
|
#define META_TYPE_WINDOW_GROUP (meta_window_group_get_type ())
|
||||||
|
@@ -118,6 +118,8 @@ typedef struct
|
|||||||
{
|
{
|
||||||
MetaRectangle orig;
|
MetaRectangle orig;
|
||||||
MetaRectangle current;
|
MetaRectangle current;
|
||||||
|
MetaFrameBorders *borders;
|
||||||
|
gboolean must_free_borders;
|
||||||
ActionType action_type;
|
ActionType action_type;
|
||||||
gboolean is_user_action;
|
gboolean is_user_action;
|
||||||
|
|
||||||
@@ -193,6 +195,7 @@ static gboolean constrain_partially_onscreen (MetaWindow *window,
|
|||||||
|
|
||||||
static void setup_constraint_info (ConstraintInfo *info,
|
static void setup_constraint_info (ConstraintInfo *info,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
|
MetaFrameBorders *orig_borders,
|
||||||
MetaMoveResizeFlags flags,
|
MetaMoveResizeFlags flags,
|
||||||
int resize_gravity,
|
int resize_gravity,
|
||||||
const MetaRectangle *orig,
|
const MetaRectangle *orig,
|
||||||
@@ -201,12 +204,13 @@ static void place_window_if_needed (MetaWindow *window,
|
|||||||
ConstraintInfo *info);
|
ConstraintInfo *info);
|
||||||
static void update_onscreen_requirements (MetaWindow *window,
|
static void update_onscreen_requirements (MetaWindow *window,
|
||||||
ConstraintInfo *info);
|
ConstraintInfo *info);
|
||||||
static void extend_by_frame (MetaWindow *window,
|
static void extend_by_frame (MetaRectangle *rect,
|
||||||
MetaRectangle *rect);
|
const MetaFrameBorders *borders);
|
||||||
static void unextend_by_frame (MetaWindow *window,
|
static void unextend_by_frame (MetaRectangle *rect,
|
||||||
MetaRectangle *rect);
|
const MetaFrameBorders *borders);
|
||||||
static inline void get_size_limits (MetaWindow *window,
|
static inline void get_size_limits (const MetaWindow *window,
|
||||||
gboolean include_frame,
|
const MetaFrameBorders *borders,
|
||||||
|
gboolean include_frame,
|
||||||
MetaRectangle *min_size,
|
MetaRectangle *min_size,
|
||||||
MetaRectangle *max_size);
|
MetaRectangle *max_size);
|
||||||
|
|
||||||
@@ -276,6 +280,7 @@ do_all_constraints (MetaWindow *window,
|
|||||||
|
|
||||||
void
|
void
|
||||||
meta_window_constrain (MetaWindow *window,
|
meta_window_constrain (MetaWindow *window,
|
||||||
|
MetaFrameBorders *orig_borders,
|
||||||
MetaMoveResizeFlags flags,
|
MetaMoveResizeFlags flags,
|
||||||
int resize_gravity,
|
int resize_gravity,
|
||||||
const MetaRectangle *orig,
|
const MetaRectangle *orig,
|
||||||
@@ -298,6 +303,7 @@ meta_window_constrain (MetaWindow *window,
|
|||||||
|
|
||||||
setup_constraint_info (&info,
|
setup_constraint_info (&info,
|
||||||
window,
|
window,
|
||||||
|
orig_borders,
|
||||||
flags,
|
flags,
|
||||||
resize_gravity,
|
resize_gravity,
|
||||||
orig,
|
orig,
|
||||||
@@ -327,11 +333,19 @@ meta_window_constrain (MetaWindow *window,
|
|||||||
* if this was a user move or user move-and-resize operation.
|
* if this was a user move or user move-and-resize operation.
|
||||||
*/
|
*/
|
||||||
update_onscreen_requirements (window, &info);
|
update_onscreen_requirements (window, &info);
|
||||||
|
|
||||||
|
/* Ew, what an ugly way to do things. Destructors (in a real OOP language,
|
||||||
|
* not gobject-style--gobject would be more pain than it's worth) or
|
||||||
|
* smart pointers would be so much nicer here. *shrug*
|
||||||
|
*/
|
||||||
|
if (info.must_free_borders)
|
||||||
|
g_free (info.borders);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup_constraint_info (ConstraintInfo *info,
|
setup_constraint_info (ConstraintInfo *info,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
|
MetaFrameBorders *orig_borders,
|
||||||
MetaMoveResizeFlags flags,
|
MetaMoveResizeFlags flags,
|
||||||
int resize_gravity,
|
int resize_gravity,
|
||||||
const MetaRectangle *orig,
|
const MetaRectangle *orig,
|
||||||
@@ -343,6 +357,18 @@ setup_constraint_info (ConstraintInfo *info,
|
|||||||
info->orig = *orig;
|
info->orig = *orig;
|
||||||
info->current = *new;
|
info->current = *new;
|
||||||
|
|
||||||
|
/* Create a fake frame geometry if none really exists */
|
||||||
|
if (orig_borders && !window->fullscreen)
|
||||||
|
{
|
||||||
|
info->borders = orig_borders;
|
||||||
|
info->must_free_borders = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info->borders = g_new0 (MetaFrameBorders, 1);
|
||||||
|
info->must_free_borders = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & META_IS_MOVE_ACTION && flags & META_IS_RESIZE_ACTION)
|
if (flags & META_IS_MOVE_ACTION && flags & META_IS_RESIZE_ACTION)
|
||||||
info->action_type = ACTION_MOVE_AND_RESIZE;
|
info->action_type = ACTION_MOVE_AND_RESIZE;
|
||||||
else if (flags & META_IS_RESIZE_ACTION)
|
else if (flags & META_IS_RESIZE_ACTION)
|
||||||
@@ -493,12 +519,11 @@ place_window_if_needed(MetaWindow *window,
|
|||||||
!window->minimized &&
|
!window->minimized &&
|
||||||
!window->fullscreen)
|
!window->fullscreen)
|
||||||
{
|
{
|
||||||
MetaRectangle placed_rect;
|
MetaRectangle placed_rect = info->orig;
|
||||||
MetaWorkspace *cur_workspace;
|
MetaWorkspace *cur_workspace;
|
||||||
const MetaMonitorInfo *monitor_info;
|
const MetaMonitorInfo *monitor_info;
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, &placed_rect);
|
meta_window_place (window, info->borders, info->orig.x, info->orig.y,
|
||||||
meta_window_place (window, info->orig.x, info->orig.y,
|
|
||||||
&placed_rect.x, &placed_rect.y);
|
&placed_rect.x, &placed_rect.y);
|
||||||
did_placement = TRUE;
|
did_placement = TRUE;
|
||||||
|
|
||||||
@@ -516,7 +541,6 @@ place_window_if_needed(MetaWindow *window,
|
|||||||
meta_workspace_get_onmonitor_region (cur_workspace,
|
meta_workspace_get_onmonitor_region (cur_workspace,
|
||||||
monitor_info->number);
|
monitor_info->number);
|
||||||
|
|
||||||
meta_window_frame_rect_to_client_rect (window, &placed_rect, &placed_rect);
|
|
||||||
|
|
||||||
info->current.x = placed_rect.x;
|
info->current.x = placed_rect.x;
|
||||||
info->current.y = placed_rect.y;
|
info->current.y = placed_rect.y;
|
||||||
@@ -562,6 +586,10 @@ place_window_if_needed(MetaWindow *window,
|
|||||||
(window->maximize_vertically_after_placement ?
|
(window->maximize_vertically_after_placement ?
|
||||||
META_MAXIMIZE_VERTICAL : 0), &info->current);
|
META_MAXIMIZE_VERTICAL : 0), &info->current);
|
||||||
|
|
||||||
|
/* maximization may have changed frame geometry */
|
||||||
|
if (!window->fullscreen)
|
||||||
|
meta_frame_calc_borders (window->frame, info->borders);
|
||||||
|
|
||||||
if (window->fullscreen_after_placement)
|
if (window->fullscreen_after_placement)
|
||||||
{
|
{
|
||||||
window->saved_rect = info->current;
|
window->saved_rect = info->current;
|
||||||
@@ -621,7 +649,7 @@ update_onscreen_requirements (MetaWindow *window,
|
|||||||
/* The require onscreen/on-single-monitor and titlebar_visible
|
/* The require onscreen/on-single-monitor and titlebar_visible
|
||||||
* stuff is relative to the outer window, not the inner
|
* stuff is relative to the outer window, not the inner
|
||||||
*/
|
*/
|
||||||
extend_by_frame (window, &info->current);
|
extend_by_frame (&info->current, info->borders);
|
||||||
|
|
||||||
/* Update whether we want future constraint runs to require the
|
/* Update whether we want future constraint runs to require the
|
||||||
* window to be on fully onscreen.
|
* window to be on fully onscreen.
|
||||||
@@ -654,13 +682,10 @@ update_onscreen_requirements (MetaWindow *window,
|
|||||||
*/
|
*/
|
||||||
if (window->frame && window->decorated)
|
if (window->frame && window->decorated)
|
||||||
{
|
{
|
||||||
MetaFrameBorders borders;
|
|
||||||
MetaRectangle titlebar_rect;
|
MetaRectangle titlebar_rect;
|
||||||
|
|
||||||
meta_frame_calc_borders (window->frame, &borders);
|
|
||||||
|
|
||||||
titlebar_rect = info->current;
|
titlebar_rect = info->current;
|
||||||
titlebar_rect.height = borders.visible.top;
|
titlebar_rect.height = info->borders->visible.top;
|
||||||
old = window->require_titlebar_visible;
|
old = window->require_titlebar_visible;
|
||||||
window->require_titlebar_visible =
|
window->require_titlebar_visible =
|
||||||
meta_rectangle_overlaps_with_region (info->usable_screen_region,
|
meta_rectangle_overlaps_with_region (info->usable_screen_region,
|
||||||
@@ -673,33 +698,39 @@ update_onscreen_requirements (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Don't forget to restore the position of the window */
|
/* Don't forget to restore the position of the window */
|
||||||
unextend_by_frame (window, &info->current);
|
unextend_by_frame (&info->current, info->borders);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
extend_by_frame (MetaWindow *window,
|
extend_by_frame (MetaRectangle *rect,
|
||||||
MetaRectangle *rect)
|
const MetaFrameBorders *borders)
|
||||||
{
|
{
|
||||||
meta_window_client_rect_to_frame_rect (window, rect, rect);
|
rect->x -= borders->visible.left;
|
||||||
|
rect->y -= borders->visible.top;
|
||||||
|
rect->width += borders->visible.left + borders->visible.right;
|
||||||
|
rect->height += borders->visible.top + borders->visible.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
unextend_by_frame (MetaWindow *window,
|
unextend_by_frame (MetaRectangle *rect,
|
||||||
MetaRectangle *rect)
|
const MetaFrameBorders *borders)
|
||||||
{
|
{
|
||||||
meta_window_frame_rect_to_client_rect (window, rect, rect);
|
rect->x += borders->visible.left;
|
||||||
|
rect->y += borders->visible.top;
|
||||||
|
rect->width -= borders->visible.left + borders->visible.right;
|
||||||
|
rect->height -= borders->visible.top + borders->visible.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
get_size_limits (MetaWindow *window,
|
get_size_limits (const MetaWindow *window,
|
||||||
gboolean include_frame,
|
const MetaFrameBorders *borders,
|
||||||
|
gboolean include_frame,
|
||||||
MetaRectangle *min_size,
|
MetaRectangle *min_size,
|
||||||
MetaRectangle *max_size)
|
MetaRectangle *max_size)
|
||||||
{
|
{
|
||||||
/* We pack the results into MetaRectangle structs just for convienience; we
|
/* We pack the results into MetaRectangle structs just for convienience; we
|
||||||
* don't actually use the position of those rects.
|
* don't actually use the position of those rects.
|
||||||
*/
|
*/
|
||||||
min_size->x = min_size->y = max_size->x = max_size->y = 0;
|
|
||||||
min_size->width = window->size_hints.min_width;
|
min_size->width = window->size_hints.min_width;
|
||||||
min_size->height = window->size_hints.min_height;
|
min_size->height = window->size_hints.min_height;
|
||||||
max_size->width = window->size_hints.max_width;
|
max_size->width = window->size_hints.max_width;
|
||||||
@@ -707,8 +738,22 @@ get_size_limits (MetaWindow *window,
|
|||||||
|
|
||||||
if (include_frame)
|
if (include_frame)
|
||||||
{
|
{
|
||||||
meta_window_client_rect_to_frame_rect (window, min_size, min_size);
|
int fw = borders->visible.left + borders->visible.right;
|
||||||
meta_window_client_rect_to_frame_rect (window, max_size, max_size);
|
int fh = borders->visible.top + borders->visible.bottom;
|
||||||
|
|
||||||
|
min_size->width += fw;
|
||||||
|
min_size->height += fh;
|
||||||
|
/* Do check to avoid overflow (e.g. max_size->width & max_size->height
|
||||||
|
* may be set to G_MAXINT by meta_set_normal_hints()).
|
||||||
|
*/
|
||||||
|
if (max_size->width < (G_MAXINT - fw))
|
||||||
|
max_size->width += fw;
|
||||||
|
else
|
||||||
|
max_size->width = G_MAXINT;
|
||||||
|
if (max_size->height < (G_MAXINT - fh))
|
||||||
|
max_size->height += fh;
|
||||||
|
else
|
||||||
|
max_size->height = G_MAXINT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -720,28 +765,18 @@ constrain_modal_dialog (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
MetaWindow *parent = meta_window_get_transient_for (window);
|
MetaWindow *parent = meta_window_get_transient_for (window);
|
||||||
MetaRectangle child_rect, parent_rect;
|
|
||||||
gboolean constraint_already_satisfied;
|
gboolean constraint_already_satisfied;
|
||||||
|
|
||||||
if (!meta_window_is_attached_dialog (window))
|
if (!meta_window_is_attached_dialog (window))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* We want to center the dialog on the parent, including the decorations
|
x = parent->rect.x + (parent->rect.width / 2 - info->current.width / 2);
|
||||||
for both of them. info->current is in client X window coordinates, so we need
|
y = parent->rect.y + (parent->rect.height / 2 - info->current.height / 2);
|
||||||
to convert them to frame coordinates, apply the centering and then
|
if (parent->frame)
|
||||||
convert back to client.
|
{
|
||||||
*/
|
x += parent->frame->rect.x;
|
||||||
|
y += parent->frame->rect.y;
|
||||||
child_rect = info->current;
|
}
|
||||||
extend_by_frame (window, &child_rect);
|
|
||||||
|
|
||||||
meta_window_get_frame_rect (parent, &parent_rect);
|
|
||||||
|
|
||||||
child_rect.x = parent_rect.x + (parent_rect.width / 2 - child_rect.width / 2);
|
|
||||||
child_rect.y = parent_rect.y + (parent_rect.height / 2 - child_rect.height / 2);
|
|
||||||
unextend_by_frame (window, &child_rect);
|
|
||||||
x = child_rect.x;
|
|
||||||
y = child_rect.y;
|
|
||||||
|
|
||||||
constraint_already_satisfied = (x == info->current.x) && (y == info->current.y);
|
constraint_already_satisfied = (x == info->current.x) && (y == info->current.y);
|
||||||
|
|
||||||
@@ -806,19 +841,19 @@ constrain_maximization (MetaWindow *window,
|
|||||||
active_workspace_struts = window->screen->active_workspace->all_struts;
|
active_workspace_struts = window->screen->active_workspace->all_struts;
|
||||||
|
|
||||||
target_size = info->current;
|
target_size = info->current;
|
||||||
extend_by_frame (window, &target_size);
|
extend_by_frame (&target_size, info->borders);
|
||||||
meta_rectangle_expand_to_avoiding_struts (&target_size,
|
meta_rectangle_expand_to_avoiding_struts (&target_size,
|
||||||
&info->entire_monitor,
|
&info->entire_monitor,
|
||||||
direction,
|
direction,
|
||||||
active_workspace_struts);
|
active_workspace_struts);
|
||||||
}
|
}
|
||||||
/* Now make target_size = maximized size of client window */
|
/* Now make target_size = maximized size of client window */
|
||||||
unextend_by_frame (window, &target_size);
|
unextend_by_frame (&target_size, info->borders);
|
||||||
|
|
||||||
/* Check min size constraints; max size constraints are ignored for maximized
|
/* Check min size constraints; max size constraints are ignored for maximized
|
||||||
* windows, as per bug 327543.
|
* windows, as per bug 327543.
|
||||||
*/
|
*/
|
||||||
get_size_limits (window, FALSE, &min_size, &max_size);
|
get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
|
||||||
hminbad = target_size.width < min_size.width && window->maximized_horizontally;
|
hminbad = target_size.width < min_size.width && window->maximized_horizontally;
|
||||||
vminbad = target_size.height < min_size.height && window->maximized_vertically;
|
vminbad = target_size.height < min_size.height && window->maximized_vertically;
|
||||||
if (hminbad || vminbad)
|
if (hminbad || vminbad)
|
||||||
@@ -872,12 +907,12 @@ constrain_tiling (MetaWindow *window,
|
|||||||
* use an external function for the actual calculation
|
* use an external function for the actual calculation
|
||||||
*/
|
*/
|
||||||
meta_window_get_current_tile_area (window, &target_size);
|
meta_window_get_current_tile_area (window, &target_size);
|
||||||
unextend_by_frame (window, &target_size);
|
unextend_by_frame (&target_size, info->borders);
|
||||||
|
|
||||||
/* Check min size constraints; max size constraints are ignored as for
|
/* Check min size constraints; max size constraints are ignored as for
|
||||||
* maximized windows.
|
* maximized windows.
|
||||||
*/
|
*/
|
||||||
get_size_limits (window, FALSE, &min_size, &max_size);
|
get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
|
||||||
hminbad = target_size.width < min_size.width;
|
hminbad = target_size.width < min_size.width;
|
||||||
vminbad = target_size.height < min_size.height;
|
vminbad = target_size.height < min_size.height;
|
||||||
if (hminbad || vminbad)
|
if (hminbad || vminbad)
|
||||||
@@ -920,7 +955,7 @@ constrain_fullscreen (MetaWindow *window,
|
|||||||
|
|
||||||
monitor = info->entire_monitor;
|
monitor = info->entire_monitor;
|
||||||
|
|
||||||
get_size_limits (window, FALSE, &min_size, &max_size);
|
get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
|
||||||
too_big = !meta_rectangle_could_fit_rect (&monitor, &min_size);
|
too_big = !meta_rectangle_could_fit_rect (&monitor, &min_size);
|
||||||
too_small = !meta_rectangle_could_fit_rect (&max_size, &monitor);
|
too_small = !meta_rectangle_could_fit_rect (&max_size, &monitor);
|
||||||
if (too_big || too_small)
|
if (too_big || too_small)
|
||||||
@@ -1029,7 +1064,7 @@ constrain_size_limits (MetaWindow *window,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* Determine whether constraint is already satisfied; exit if it is */
|
/* Determine whether constraint is already satisfied; exit if it is */
|
||||||
get_size_limits (window, FALSE, &min_size, &max_size);
|
get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
|
||||||
/* We ignore max-size limits for maximized windows; see #327543 */
|
/* We ignore max-size limits for maximized windows; see #327543 */
|
||||||
if (window->maximized_horizontally)
|
if (window->maximized_horizontally)
|
||||||
max_size.width = MAX (max_size.width, info->current.width);
|
max_size.width = MAX (max_size.width, info->current.width);
|
||||||
@@ -1221,8 +1256,8 @@ do_screen_and_monitor_relative_constraints (
|
|||||||
|
|
||||||
/* Determine whether constraint applies; exit if it doesn't */
|
/* Determine whether constraint applies; exit if it doesn't */
|
||||||
how_far_it_can_be_smushed = info->current;
|
how_far_it_can_be_smushed = info->current;
|
||||||
get_size_limits (window, TRUE, &min_size, &max_size);
|
get_size_limits (window, info->borders, TRUE, &min_size, &max_size);
|
||||||
extend_by_frame (window, &info->current);
|
extend_by_frame (&info->current, info->borders);
|
||||||
|
|
||||||
if (info->action_type != ACTION_MOVE)
|
if (info->action_type != ACTION_MOVE)
|
||||||
{
|
{
|
||||||
@@ -1242,7 +1277,7 @@ do_screen_and_monitor_relative_constraints (
|
|||||||
&info->current);
|
&info->current);
|
||||||
if (exit_early || constraint_satisfied || check_only)
|
if (exit_early || constraint_satisfied || check_only)
|
||||||
{
|
{
|
||||||
unextend_by_frame (window, &info->current);
|
unextend_by_frame (&info->current, info->borders);
|
||||||
return constraint_satisfied;
|
return constraint_satisfied;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1266,7 +1301,7 @@ do_screen_and_monitor_relative_constraints (
|
|||||||
info->fixed_directions,
|
info->fixed_directions,
|
||||||
&info->current);
|
&info->current);
|
||||||
|
|
||||||
unextend_by_frame (window, &info->current);
|
unextend_by_frame (&info->current, info->borders);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1355,7 +1390,6 @@ constrain_titlebar_visible (MetaWindow *window,
|
|||||||
window->type == META_WINDOW_DOCK ||
|
window->type == META_WINDOW_DOCK ||
|
||||||
window->fullscreen ||
|
window->fullscreen ||
|
||||||
!window->require_titlebar_visible ||
|
!window->require_titlebar_visible ||
|
||||||
!window->decorated ||
|
|
||||||
unconstrained_user_action)
|
unconstrained_user_action)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
@@ -1379,11 +1413,8 @@ constrain_titlebar_visible (MetaWindow *window,
|
|||||||
*/
|
*/
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
{
|
{
|
||||||
MetaFrameBorders borders;
|
bottom_amount = info->current.height + info->borders->visible.bottom;
|
||||||
meta_frame_calc_borders (window->frame, &borders);
|
vert_amount_onscreen = info->borders->visible.top;
|
||||||
|
|
||||||
bottom_amount = info->current.height + borders.visible.bottom;
|
|
||||||
vert_amount_onscreen = borders.visible.top;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
bottom_amount = vert_amount_offscreen;
|
bottom_amount = vert_amount_offscreen;
|
||||||
@@ -1457,11 +1488,8 @@ constrain_partially_onscreen (MetaWindow *window,
|
|||||||
*/
|
*/
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
{
|
{
|
||||||
MetaFrameBorders borders;
|
bottom_amount = info->current.height + info->borders->visible.bottom;
|
||||||
meta_frame_calc_borders (window->frame, &borders);
|
vert_amount_onscreen = info->borders->visible.top;
|
||||||
|
|
||||||
bottom_amount = info->current.height + borders.visible.bottom;
|
|
||||||
vert_amount_onscreen = borders.visible.top;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
bottom_amount = vert_amount_offscreen;
|
bottom_amount = vert_amount_offscreen;
|
||||||
|
@@ -39,6 +39,7 @@ typedef enum
|
|||||||
} MetaMoveResizeFlags;
|
} MetaMoveResizeFlags;
|
||||||
|
|
||||||
void meta_window_constrain (MetaWindow *window,
|
void meta_window_constrain (MetaWindow *window,
|
||||||
|
MetaFrameBorders *orig_borders,
|
||||||
MetaMoveResizeFlags flags,
|
MetaMoveResizeFlags flags,
|
||||||
int resize_gravity,
|
int resize_gravity,
|
||||||
const MetaRectangle *orig,
|
const MetaRectangle *orig,
|
||||||
|
@@ -171,7 +171,6 @@ meta_core_queue_frame_resize (Display *xdisplay,
|
|||||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||||
|
|
||||||
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
|
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
|
||||||
meta_window_frame_size_changed (window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -280,7 +279,8 @@ meta_core_lower_beneath_grab_window (Display *xdisplay,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
changes.stack_mode = Below;
|
changes.stack_mode = Below;
|
||||||
changes.sibling = meta_window_get_toplevel_xwindow (grab_window);
|
changes.sibling = grab_window->frame ? grab_window->frame->xwindow
|
||||||
|
: grab_window->xwindow;
|
||||||
|
|
||||||
meta_stack_tracker_record_lower_below (screen->stack_tracker,
|
meta_stack_tracker_record_lower_below (screen->stack_tracker,
|
||||||
xwindow,
|
xwindow,
|
||||||
@@ -469,6 +469,26 @@ meta_core_change_workspace (Display *xdisplay,
|
|||||||
new_workspace));
|
new_workspace));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
meta_core_get_num_workspaces (Screen *xscreen)
|
||||||
|
{
|
||||||
|
MetaScreen *screen;
|
||||||
|
|
||||||
|
screen = meta_screen_for_x_screen (xscreen);
|
||||||
|
|
||||||
|
return meta_screen_get_n_workspaces (screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
meta_core_get_active_workspace (Screen *xscreen)
|
||||||
|
{
|
||||||
|
MetaScreen *screen;
|
||||||
|
|
||||||
|
screen = meta_screen_for_x_screen (xscreen);
|
||||||
|
|
||||||
|
return meta_workspace_index (screen->active_workspace);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_core_show_window_menu (Display *xdisplay,
|
meta_core_show_window_menu (Display *xdisplay,
|
||||||
Window frame_xwindow,
|
Window frame_xwindow,
|
||||||
|
@@ -153,6 +153,8 @@ void meta_core_change_workspace (Display *xdisplay,
|
|||||||
Window frame_xwindow,
|
Window frame_xwindow,
|
||||||
int new_workspace);
|
int new_workspace);
|
||||||
|
|
||||||
|
int meta_core_get_num_workspaces (Screen *xscreen);
|
||||||
|
int meta_core_get_active_workspace (Screen *xscreen);
|
||||||
int meta_core_get_frame_workspace (Display *xdisplay,
|
int meta_core_get_frame_workspace (Display *xdisplay,
|
||||||
Window frame_xwindow);
|
Window frame_xwindow);
|
||||||
const char* meta_core_get_workspace_name_with_index (Display *xdisplay,
|
const char* meta_core_get_workspace_name_with_index (Display *xdisplay,
|
||||||
|
@@ -138,6 +138,14 @@ struct _MetaDisplay
|
|||||||
*/
|
*/
|
||||||
guint allow_terminal_deactivation : 1;
|
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;
|
guint static_gravity_works : 1;
|
||||||
|
|
||||||
/*< private-ish >*/
|
/*< private-ish >*/
|
||||||
|
@@ -51,6 +51,7 @@
|
|||||||
#include <meta/compositor.h>
|
#include <meta/compositor.h>
|
||||||
#include <meta/compositor-mutter.h>
|
#include <meta/compositor-mutter.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/cursorfont.h>
|
||||||
#include "mutter-enum-types.h"
|
#include "mutter-enum-types.h"
|
||||||
#include "meta-idle-monitor-private.h"
|
#include "meta-idle-monitor-private.h"
|
||||||
|
|
||||||
@@ -117,6 +118,12 @@ typedef struct
|
|||||||
guint ping_timeout_id;
|
guint ping_timeout_id;
|
||||||
} MetaPingData;
|
} MetaPingData;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MetaDisplay *display;
|
||||||
|
Window xwindow;
|
||||||
|
} MetaAutoRaiseData;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
MetaDisplay *display;
|
MetaDisplay *display;
|
||||||
@@ -918,8 +925,6 @@ meta_display_open (void)
|
|||||||
|
|
||||||
enable_compositor (the_display);
|
enable_compositor (the_display);
|
||||||
|
|
||||||
meta_display_grab (the_display);
|
|
||||||
|
|
||||||
/* Now manage all existing windows */
|
/* Now manage all existing windows */
|
||||||
tmp = the_display->screens;
|
tmp = the_display->screens;
|
||||||
while (tmp != NULL)
|
while (tmp != NULL)
|
||||||
@@ -971,8 +976,6 @@ meta_display_open (void)
|
|||||||
|
|
||||||
meta_idle_monitor_init_dbus ();
|
meta_idle_monitor_init_dbus ();
|
||||||
|
|
||||||
meta_display_ungrab (the_display);
|
|
||||||
|
|
||||||
/* Done opening new display */
|
/* Done opening new display */
|
||||||
the_display->display_opening = FALSE;
|
the_display->display_opening = FALSE;
|
||||||
|
|
||||||
@@ -1217,7 +1220,18 @@ meta_display_screen_for_x_screen (MetaDisplay *display,
|
|||||||
return NULL;
|
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
|
void
|
||||||
meta_display_grab (MetaDisplay *display)
|
meta_display_grab (MetaDisplay *display)
|
||||||
{
|
{
|
||||||
@@ -1579,10 +1593,23 @@ reset_ignored_crossing_serials (MetaDisplay *display)
|
|||||||
static gboolean
|
static gboolean
|
||||||
window_raise_with_delay_callback (void *data)
|
window_raise_with_delay_callback (void *data)
|
||||||
{
|
{
|
||||||
MetaWindow *window = data;
|
MetaWindow *window;
|
||||||
|
MetaAutoRaiseData *auto_raise;
|
||||||
|
|
||||||
window->display->autoraise_timeout_id = 0;
|
auto_raise = data;
|
||||||
window->display->autoraise_window = NULL;
|
|
||||||
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
|
"In autoraise callback for window 0x%lx\n",
|
||||||
|
auto_raise->xwindow);
|
||||||
|
|
||||||
|
auto_raise->display->autoraise_timeout_id = 0;
|
||||||
|
auto_raise->display->autoraise_window = NULL;
|
||||||
|
|
||||||
|
window = meta_display_lookup_x_window (auto_raise->display,
|
||||||
|
auto_raise->xwindow);
|
||||||
|
|
||||||
|
if (window == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
/* If we aren't already on top, check whether the pointer is inside
|
/* If we aren't already on top, check whether the pointer is inside
|
||||||
* the window and raise the window if so.
|
* the window and raise the window if so.
|
||||||
@@ -1591,7 +1618,6 @@ window_raise_with_delay_callback (void *data)
|
|||||||
{
|
{
|
||||||
int x, y, root_x, root_y;
|
int x, y, root_x, root_y;
|
||||||
Window root, child;
|
Window root, child;
|
||||||
MetaRectangle frame_rect;
|
|
||||||
unsigned int mask;
|
unsigned int mask;
|
||||||
gboolean same_screen;
|
gboolean same_screen;
|
||||||
gboolean point_in_window;
|
gboolean point_in_window;
|
||||||
@@ -1603,8 +1629,9 @@ window_raise_with_delay_callback (void *data)
|
|||||||
&root_x, &root_y, &x, &y, &mask);
|
&root_x, &root_y, &x, &y, &mask);
|
||||||
meta_error_trap_pop (window->display);
|
meta_error_trap_pop (window->display);
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, &frame_rect);
|
point_in_window =
|
||||||
point_in_window = POINT_IN_RECT (root_x, root_y, frame_rect);
|
(window->frame && POINT_IN_RECT (root_x, root_y, window->frame->rect)) ||
|
||||||
|
(window->frame == NULL && POINT_IN_RECT (root_x, root_y, window->rect));
|
||||||
if (same_screen && point_in_window)
|
if (same_screen && point_in_window)
|
||||||
meta_window_raise (window);
|
meta_window_raise (window);
|
||||||
else
|
else
|
||||||
@@ -1619,8 +1646,7 @@ window_raise_with_delay_callback (void *data)
|
|||||||
static void
|
static void
|
||||||
meta_display_mouse_mode_focus (MetaDisplay *display,
|
meta_display_mouse_mode_focus (MetaDisplay *display,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
guint32 timestamp)
|
guint32 timestamp) {
|
||||||
{
|
|
||||||
if (window->type != META_WINDOW_DESKTOP)
|
if (window->type != META_WINDOW_DESKTOP)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
@@ -1659,8 +1685,7 @@ meta_display_mouse_mode_focus (MetaDisplay *display,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
window_focus_on_pointer_rest_callback (gpointer data)
|
window_focus_on_pointer_rest_callback (gpointer data) {
|
||||||
{
|
|
||||||
MetaFocusData *focus_data;
|
MetaFocusData *focus_data;
|
||||||
MetaDisplay *display;
|
MetaDisplay *display;
|
||||||
MetaScreen *screen;
|
MetaScreen *screen;
|
||||||
@@ -1705,9 +1730,9 @@ window_focus_on_pointer_rest_callback (gpointer data)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
window =
|
window =
|
||||||
meta_stack_get_default_focus_window_at_point (screen->stack,
|
meta_stack_get_default_focus_window_at_point (screen->stack,
|
||||||
screen->active_workspace,
|
screen->active_workspace,
|
||||||
None, root_x, root_y);
|
None, root_x, root_y);
|
||||||
|
|
||||||
if (window == NULL)
|
if (window == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1715,7 +1740,7 @@ window_focus_on_pointer_rest_callback (gpointer data)
|
|||||||
timestamp = meta_display_get_current_time_roundtrip (display);
|
timestamp = meta_display_get_current_time_roundtrip (display);
|
||||||
meta_display_mouse_mode_focus (display, window, timestamp);
|
meta_display_mouse_mode_focus (display, window, timestamp);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
display->focus_timeout_id = 0;
|
display->focus_timeout_id = 0;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1724,11 +1749,17 @@ void
|
|||||||
meta_display_queue_autoraise_callback (MetaDisplay *display,
|
meta_display_queue_autoraise_callback (MetaDisplay *display,
|
||||||
MetaWindow *window)
|
MetaWindow *window)
|
||||||
{
|
{
|
||||||
|
MetaAutoRaiseData *auto_raise_data;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Queuing an autoraise timeout for %s with delay %d\n",
|
"Queuing an autoraise timeout for %s with delay %d\n",
|
||||||
window->desc,
|
window->desc,
|
||||||
meta_prefs_get_auto_raise_delay ());
|
meta_prefs_get_auto_raise_delay ());
|
||||||
|
|
||||||
|
auto_raise_data = g_new (MetaAutoRaiseData, 1);
|
||||||
|
auto_raise_data->display = window->display;
|
||||||
|
auto_raise_data->xwindow = window->xwindow;
|
||||||
|
|
||||||
if (display->autoraise_timeout_id != 0)
|
if (display->autoraise_timeout_id != 0)
|
||||||
g_source_remove (display->autoraise_timeout_id);
|
g_source_remove (display->autoraise_timeout_id);
|
||||||
|
|
||||||
@@ -1736,7 +1767,8 @@ meta_display_queue_autoraise_callback (MetaDisplay *display,
|
|||||||
g_timeout_add_full (G_PRIORITY_DEFAULT,
|
g_timeout_add_full (G_PRIORITY_DEFAULT,
|
||||||
meta_prefs_get_auto_raise_delay (),
|
meta_prefs_get_auto_raise_delay (),
|
||||||
window_raise_with_delay_callback,
|
window_raise_with_delay_callback,
|
||||||
window, NULL);
|
auto_raise_data,
|
||||||
|
g_free);
|
||||||
display->autoraise_window = window;
|
display->autoraise_window = window;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1865,9 +1897,11 @@ static void
|
|||||||
update_focus_window (MetaDisplay *display,
|
update_focus_window (MetaDisplay *display,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
Window xwindow,
|
Window xwindow,
|
||||||
gulong serial)
|
gulong serial,
|
||||||
|
gboolean focused_by_us)
|
||||||
{
|
{
|
||||||
display->focus_serial = serial;
|
display->focus_serial = serial;
|
||||||
|
display->focused_by_us = focused_by_us;
|
||||||
|
|
||||||
if (display->focus_xwindow == xwindow)
|
if (display->focus_xwindow == xwindow)
|
||||||
return;
|
return;
|
||||||
@@ -1978,7 +2012,8 @@ request_xserver_input_focus_change (MetaDisplay *display,
|
|||||||
update_focus_window (display,
|
update_focus_window (display,
|
||||||
meta_window,
|
meta_window,
|
||||||
xwindow,
|
xwindow,
|
||||||
serial);
|
serial,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
meta_error_trap_pop (display);
|
meta_error_trap_pop (display);
|
||||||
|
|
||||||
@@ -2092,28 +2127,23 @@ handle_window_focus_event (MetaDisplay *display,
|
|||||||
else
|
else
|
||||||
g_return_if_reached ();
|
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,
|
update_focus_window (display,
|
||||||
focus_window,
|
focus_window,
|
||||||
focus_window ? focus_window->xwindow : None,
|
focus_window ? focus_window->xwindow : None,
|
||||||
display->server_focus_serial);
|
display->server_focus_serial,
|
||||||
|
FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
window_has_xwindow (MetaWindow *window,
|
|
||||||
Window xwindow)
|
|
||||||
{
|
|
||||||
if (window->xwindow == xwindow)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (window->frame && window->frame->xwindow == xwindow)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* event_callback:
|
* event_callback:
|
||||||
* @event: The event that just happened
|
* @event: The event that just happened
|
||||||
@@ -2167,16 +2197,18 @@ event_callback (XEvent *event,
|
|||||||
display->current_time = event_get_time (display, event);
|
display->current_time = event_get_time (display, event);
|
||||||
display->monitor_cache_invalidated = TRUE;
|
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 &&
|
||||||
!window_has_xwindow (display->focus_window, display->server_focus_window))
|
display->focus_window->xwindow != display->server_focus_window)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n",
|
meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n",
|
||||||
display->focus_window->desc);
|
display->focus_window->desc);
|
||||||
update_focus_window (display,
|
update_focus_window (display,
|
||||||
meta_display_lookup_x_window (display, display->server_focus_window),
|
meta_display_lookup_x_window (display, display->server_focus_window),
|
||||||
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);
|
screen = meta_display_screen_for_root (display, event->xany.window);
|
||||||
@@ -2424,15 +2456,15 @@ event_callback (XEvent *event,
|
|||||||
{
|
{
|
||||||
gboolean north, south;
|
gboolean north, south;
|
||||||
gboolean west, east;
|
gboolean west, east;
|
||||||
MetaRectangle frame_rect;
|
int root_x, root_y;
|
||||||
MetaGrabOp op;
|
MetaGrabOp op;
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, &frame_rect);
|
meta_window_get_position (window, &root_x, &root_y);
|
||||||
|
|
||||||
west = device_event->root_x < (frame_rect.x + 1 * frame_rect.width / 3);
|
west = device_event->root_x < (root_x + 1 * window->rect.width / 3);
|
||||||
east = device_event->root_x > (frame_rect.x + 2 * frame_rect.width / 3);
|
east = device_event->root_x > (root_x + 2 * window->rect.width / 3);
|
||||||
north = device_event->root_y < (frame_rect.y + 1 * frame_rect.height / 3);
|
north = device_event->root_y < (root_y + 1 * window->rect.height / 3);
|
||||||
south = device_event->root_y > (frame_rect.y + 2 * frame_rect.height / 3);
|
south = device_event->root_y > (root_y + 2 * window->rect.height / 3);
|
||||||
|
|
||||||
if (north && west)
|
if (north && west)
|
||||||
op = META_GRAB_OP_RESIZING_NW;
|
op = META_GRAB_OP_RESIZING_NW;
|
||||||
@@ -2762,14 +2794,14 @@ event_callback (XEvent *event,
|
|||||||
&& meta_display_screen_for_root (display, event->xmap.event))
|
&& meta_display_screen_for_root (display, event->xmap.event))
|
||||||
{
|
{
|
||||||
window = meta_window_new (display, event->xmap.window,
|
window = meta_window_new (display, event->xmap.window,
|
||||||
FALSE);
|
FALSE, META_COMP_EFFECT_CREATE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MapRequest:
|
case MapRequest:
|
||||||
if (window == NULL)
|
if (window == NULL)
|
||||||
{
|
{
|
||||||
window = meta_window_new (display, event->xmaprequest.window,
|
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 */
|
/* if frame was receiver it's some malicious send event or something */
|
||||||
else if (!frame_was_receiver && window)
|
else if (!frame_was_receiver && window)
|
||||||
@@ -3847,6 +3879,85 @@ meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
|
|||||||
return is_a_no_focus_window;
|
return is_a_no_focus_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cursor
|
||||||
|
meta_display_create_x_cursor (MetaDisplay *display,
|
||||||
|
MetaCursor cursor)
|
||||||
|
{
|
||||||
|
Cursor xcursor;
|
||||||
|
guint glyph = XC_num_glyphs;
|
||||||
|
const char *name = NULL;
|
||||||
|
|
||||||
|
switch (cursor)
|
||||||
|
{
|
||||||
|
case META_CURSOR_DEFAULT:
|
||||||
|
glyph = XC_left_ptr;
|
||||||
|
break;
|
||||||
|
case META_CURSOR_NORTH_RESIZE:
|
||||||
|
glyph = XC_top_side;
|
||||||
|
break;
|
||||||
|
case META_CURSOR_SOUTH_RESIZE:
|
||||||
|
glyph = XC_bottom_side;
|
||||||
|
break;
|
||||||
|
case META_CURSOR_WEST_RESIZE:
|
||||||
|
glyph = XC_left_side;
|
||||||
|
break;
|
||||||
|
case META_CURSOR_EAST_RESIZE:
|
||||||
|
glyph = XC_right_side;
|
||||||
|
break;
|
||||||
|
case META_CURSOR_SE_RESIZE:
|
||||||
|
glyph = XC_bottom_right_corner;
|
||||||
|
break;
|
||||||
|
case META_CURSOR_SW_RESIZE:
|
||||||
|
glyph = XC_bottom_left_corner;
|
||||||
|
break;
|
||||||
|
case META_CURSOR_NE_RESIZE:
|
||||||
|
glyph = XC_top_right_corner;
|
||||||
|
break;
|
||||||
|
case META_CURSOR_NW_RESIZE:
|
||||||
|
glyph = XC_top_left_corner;
|
||||||
|
break;
|
||||||
|
case META_CURSOR_MOVE_OR_RESIZE_WINDOW:
|
||||||
|
glyph = XC_fleur;
|
||||||
|
break;
|
||||||
|
case META_CURSOR_BUSY:
|
||||||
|
glyph = XC_watch;
|
||||||
|
break;
|
||||||
|
case META_CURSOR_DND_IN_DRAG:
|
||||||
|
name = "dnd-none";
|
||||||
|
break;
|
||||||
|
case META_CURSOR_DND_MOVE:
|
||||||
|
name = "dnd-move";
|
||||||
|
break;
|
||||||
|
case META_CURSOR_DND_COPY:
|
||||||
|
name = "dnd-copy";
|
||||||
|
break;
|
||||||
|
case META_CURSOR_DND_UNSUPPORTED_TARGET:
|
||||||
|
name = "dnd-none";
|
||||||
|
break;
|
||||||
|
case META_CURSOR_POINTING_HAND:
|
||||||
|
glyph = XC_hand2;
|
||||||
|
break;
|
||||||
|
case META_CURSOR_CROSSHAIR:
|
||||||
|
glyph = XC_crosshair;
|
||||||
|
break;
|
||||||
|
case META_CURSOR_IBEAM:
|
||||||
|
glyph = XC_xterm;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
glyph = 0; /* silence compiler */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
xcursor = XcursorLibraryLoadCursor (display->xdisplay, name);
|
||||||
|
else
|
||||||
|
xcursor = XCreateFontCursor (display->xdisplay, glyph);
|
||||||
|
|
||||||
|
return xcursor;
|
||||||
|
}
|
||||||
|
|
||||||
static Cursor
|
static Cursor
|
||||||
xcursor_for_op (MetaDisplay *display,
|
xcursor_for_op (MetaDisplay *display,
|
||||||
MetaGrabOp op)
|
MetaGrabOp op)
|
||||||
@@ -4008,7 +4119,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
|||||||
* key grab on the RootWindow.
|
* key grab on the RootWindow.
|
||||||
*/
|
*/
|
||||||
if (grab_window)
|
if (grab_window)
|
||||||
grab_xwindow = meta_window_get_toplevel_xwindow (grab_window);
|
grab_xwindow = grab_window->frame ? grab_window->frame->xwindow : grab_window->xwindow;
|
||||||
else
|
else
|
||||||
grab_xwindow = screen->xroot;
|
grab_xwindow = screen->xroot;
|
||||||
|
|
||||||
@@ -4536,7 +4647,6 @@ meta_display_queue_retheme_all_windows (MetaDisplay *display)
|
|||||||
MetaWindow *window = tmp->data;
|
MetaWindow *window = tmp->data;
|
||||||
|
|
||||||
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
|
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
|
||||||
meta_window_frame_size_changed (window);
|
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
{
|
{
|
||||||
meta_frame_queue_draw (window->frame);
|
meta_frame_queue_draw (window->frame);
|
||||||
@@ -5860,6 +5970,12 @@ meta_display_has_shape (MetaDisplay *display)
|
|||||||
return META_DISPLAY_HAS_SHAPE (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:
|
* meta_display_get_focus_window:
|
||||||
* @display: a #MetaDisplay
|
* @display: a #MetaDisplay
|
||||||
@@ -5906,6 +6022,12 @@ meta_display_get_leader_window (MetaDisplay *display)
|
|||||||
return display->leader_window;
|
return display->leader_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
meta_display_get_sync_event_base (MetaDisplay *display)
|
||||||
|
{
|
||||||
|
return display->xsync_event_base;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_display_clear_mouse_mode:
|
* meta_display_clear_mouse_mode:
|
||||||
* @display: a #MetaDisplay
|
* @display: a #MetaDisplay
|
||||||
|
@@ -985,7 +985,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
|
|||||||
{
|
{
|
||||||
MetaRectangle *new_rect;
|
MetaRectangle *new_rect;
|
||||||
new_rect = g_new (MetaRectangle, 1);
|
new_rect = g_new (MetaRectangle, 1);
|
||||||
meta_window_get_frame_rect (cur_window, new_rect);
|
meta_window_get_outer_rect (cur_window, new_rect);
|
||||||
obscuring_windows = g_slist_prepend (obscuring_windows, new_rect);
|
obscuring_windows = g_slist_prepend (obscuring_windows, new_rect);
|
||||||
window_stacking =
|
window_stacking =
|
||||||
g_slist_prepend (window_stacking, GINT_TO_POINTER (stack_position));
|
g_slist_prepend (window_stacking, GINT_TO_POINTER (stack_position));
|
||||||
@@ -1010,7 +1010,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
|
|||||||
{
|
{
|
||||||
MetaRectangle cur_rect;
|
MetaRectangle cur_rect;
|
||||||
MetaWindow *cur_window = cur_window_iter->data;
|
MetaWindow *cur_window = cur_window_iter->data;
|
||||||
meta_window_get_frame_rect (cur_window, &cur_rect);
|
meta_window_get_outer_rect (cur_window, &cur_rect);
|
||||||
|
|
||||||
/* Check if we want to use this window's edges for edge
|
/* Check if we want to use this window's edges for edge
|
||||||
* resistance (note that dock edges are considered screen edges
|
* resistance (note that dock edges are considered screen edges
|
||||||
@@ -1151,7 +1151,7 @@ meta_window_edge_resistance_for_move (MetaWindow *window,
|
|||||||
MetaRectangle old_outer, proposed_outer, new_outer;
|
MetaRectangle old_outer, proposed_outer, new_outer;
|
||||||
gboolean is_resize;
|
gboolean is_resize;
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, &old_outer);
|
meta_window_get_outer_rect (window, &old_outer);
|
||||||
|
|
||||||
proposed_outer = old_outer;
|
proposed_outer = old_outer;
|
||||||
proposed_outer.x += (*new_x - old_x);
|
proposed_outer.x += (*new_x - old_x);
|
||||||
@@ -1237,7 +1237,7 @@ meta_window_edge_resistance_for_resize (MetaWindow *window,
|
|||||||
int proposed_outer_width, proposed_outer_height;
|
int proposed_outer_width, proposed_outer_height;
|
||||||
gboolean is_resize;
|
gboolean is_resize;
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, &old_outer);
|
meta_window_get_outer_rect (window, &old_outer);
|
||||||
proposed_outer_width = old_outer.width + (*new_width - old_width);
|
proposed_outer_width = old_outer.width + (*new_width - old_width);
|
||||||
proposed_outer_height = old_outer.height + (*new_height - old_height);
|
proposed_outer_height = old_outer.height + (*new_height - old_height);
|
||||||
meta_rectangle_resize_with_gravity (&old_outer,
|
meta_rectangle_resize_with_gravity (&old_outer,
|
||||||
|
@@ -51,9 +51,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
if (window->frame)
|
if (window->frame)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* See comment below for why this is required. */
|
|
||||||
meta_display_grab (window->display);
|
|
||||||
|
|
||||||
frame = g_new (MetaFrame, 1);
|
frame = g_new (MetaFrame, 1);
|
||||||
|
|
||||||
frame->window = window;
|
frame->window = window;
|
||||||
@@ -68,7 +65,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
|
|
||||||
frame->mapped = FALSE;
|
frame->mapped = FALSE;
|
||||||
frame->is_flashing = FALSE;
|
frame->is_flashing = FALSE;
|
||||||
frame->borders_cached = FALSE;
|
|
||||||
|
|
||||||
meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
|
meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
|
||||||
window->desc,
|
window->desc,
|
||||||
@@ -117,14 +113,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
|
|
||||||
meta_display_register_x_window (window->display, &frame->xwindow, 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);
|
meta_error_trap_push (window->display);
|
||||||
if (window->mapped)
|
if (window->mapped)
|
||||||
{
|
{
|
||||||
@@ -166,8 +154,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
|
|
||||||
/* Move keybindings to frame instead of window */
|
/* Move keybindings to frame instead of window */
|
||||||
meta_window_grab_keys (window);
|
meta_window_grab_keys (window);
|
||||||
|
|
||||||
meta_display_ungrab (window->display);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -328,23 +314,9 @@ meta_frame_calc_borders (MetaFrame *frame,
|
|||||||
if (frame == NULL)
|
if (frame == NULL)
|
||||||
meta_frame_borders_clear (borders);
|
meta_frame_borders_clear (borders);
|
||||||
else
|
else
|
||||||
{
|
meta_ui_get_frame_borders (frame->window->screen->ui,
|
||||||
if (!frame->borders_cached)
|
frame->xwindow,
|
||||||
{
|
borders);
|
||||||
meta_ui_get_frame_borders (frame->window->screen->ui,
|
|
||||||
frame->xwindow,
|
|
||||||
&frame->cached_borders);
|
|
||||||
frame->borders_cached = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*borders = frame->cached_borders;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_frame_clear_cached_borders (MetaFrame *frame)
|
|
||||||
{
|
|
||||||
frame->borders_cached = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@@ -41,8 +41,6 @@ struct _MetaFrame
|
|||||||
*/
|
*/
|
||||||
MetaRectangle rect;
|
MetaRectangle rect;
|
||||||
|
|
||||||
MetaFrameBorders cached_borders; /* valid if borders_cached is set */
|
|
||||||
|
|
||||||
/* position of client, size of frame */
|
/* position of client, size of frame */
|
||||||
int child_x;
|
int child_x;
|
||||||
int child_y;
|
int child_y;
|
||||||
@@ -52,7 +50,6 @@ struct _MetaFrame
|
|||||||
guint mapped : 1;
|
guint mapped : 1;
|
||||||
guint need_reapply_frame_shape : 1;
|
guint need_reapply_frame_shape : 1;
|
||||||
guint is_flashing : 1; /* used by the visual bell flash */
|
guint is_flashing : 1; /* used by the visual bell flash */
|
||||||
guint borders_cached : 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void meta_window_ensure_frame (MetaWindow *window);
|
void meta_window_ensure_frame (MetaWindow *window);
|
||||||
@@ -71,8 +68,6 @@ gboolean meta_frame_sync_to_window (MetaFrame *frame,
|
|||||||
gboolean need_move,
|
gboolean need_move,
|
||||||
gboolean need_resize);
|
gboolean need_resize);
|
||||||
|
|
||||||
void meta_frame_clear_cached_borders (MetaFrame *frame);
|
|
||||||
|
|
||||||
cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame);
|
cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame);
|
||||||
|
|
||||||
void meta_frame_get_mask (MetaFrame *frame,
|
void meta_frame_get_mask (MetaFrame *frame,
|
||||||
|
@@ -1277,7 +1277,7 @@ meta_window_grab_keys (MetaWindow *window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
meta_window_change_keygrabs (window,
|
meta_window_change_keygrabs (window,
|
||||||
meta_window_get_toplevel_xwindow (window),
|
window->frame ? window->frame->xwindow : window->xwindow,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
window->keys_grabbed = TRUE;
|
window->keys_grabbed = TRUE;
|
||||||
@@ -1580,7 +1580,7 @@ meta_window_grab_all_keys (MetaWindow *window,
|
|||||||
window->desc);
|
window->desc);
|
||||||
meta_window_focus (window, timestamp);
|
meta_window_focus (window, timestamp);
|
||||||
|
|
||||||
grabwindow = meta_window_get_toplevel_xwindow (window);
|
grabwindow = window->frame ? window->frame->xwindow : window->xwindow;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||||
"Grabbing all keys on window %s\n", window->desc);
|
"Grabbing all keys on window %s\n", window->desc);
|
||||||
@@ -1835,6 +1835,7 @@ invoke_handler_by_name (MetaDisplay *display,
|
|||||||
invoke_handler (display, screen, handler, window, event, NULL);
|
invoke_handler (display, screen, handler, window, event, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* now called from only one place, may be worth merging */
|
||||||
static gboolean
|
static gboolean
|
||||||
process_event (MetaKeyBinding *bindings,
|
process_event (MetaKeyBinding *bindings,
|
||||||
int n_bindings,
|
int n_bindings,
|
||||||
@@ -1842,6 +1843,7 @@ process_event (MetaKeyBinding *bindings,
|
|||||||
MetaScreen *screen,
|
MetaScreen *screen,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
XIDeviceEvent *event,
|
XIDeviceEvent *event,
|
||||||
|
KeySym keysym,
|
||||||
gboolean on_window)
|
gboolean on_window)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -1859,6 +1861,7 @@ process_event (MetaKeyBinding *bindings,
|
|||||||
MetaKeyHandler *handler = bindings[i].handler;
|
MetaKeyHandler *handler = bindings[i].handler;
|
||||||
|
|
||||||
if ((!on_window && handler->flags & META_KEY_BINDING_PER_WINDOW) ||
|
if ((!on_window && handler->flags & META_KEY_BINDING_PER_WINDOW) ||
|
||||||
|
event->evtype != XI_KeyPress ||
|
||||||
bindings[i].keycode != event->detail ||
|
bindings[i].keycode != event->detail ||
|
||||||
((event->mods.effective & 0xff & ~(display->ignored_modifier_mask)) !=
|
((event->mods.effective & 0xff & ~(display->ignored_modifier_mask)) !=
|
||||||
bindings[i].mask) ||
|
bindings[i].mask) ||
|
||||||
@@ -1925,7 +1928,7 @@ process_overlay_key (MetaDisplay *display,
|
|||||||
*/
|
*/
|
||||||
if (process_event (display->key_bindings,
|
if (process_event (display->key_bindings,
|
||||||
display->n_key_bindings,
|
display->n_key_bindings,
|
||||||
display, screen, NULL, event,
|
display, screen, NULL, event, keysym,
|
||||||
FALSE))
|
FALSE))
|
||||||
{
|
{
|
||||||
/* As normally, after we've handled a global key
|
/* As normally, after we've handled a global key
|
||||||
@@ -2189,7 +2192,7 @@ meta_display_process_key_event (MetaDisplay *display,
|
|||||||
/* Do the normal keybindings */
|
/* Do the normal keybindings */
|
||||||
return process_event (display->key_bindings,
|
return process_event (display->key_bindings,
|
||||||
display->n_key_bindings,
|
display->n_key_bindings,
|
||||||
display, screen, window, event,
|
display, screen, window, event, keysym,
|
||||||
!all_keys_grabbed && window);
|
!all_keys_grabbed && window);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3137,20 +3140,6 @@ handle_maximize_horizontally (MetaDisplay *display,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
handle_always_on_top (MetaDisplay *display,
|
|
||||||
MetaScreen *screen,
|
|
||||||
MetaWindow *window,
|
|
||||||
XIDeviceEvent *event,
|
|
||||||
MetaKeyBinding *binding,
|
|
||||||
gpointer dummy)
|
|
||||||
{
|
|
||||||
if (window->wm_state_above == FALSE)
|
|
||||||
meta_window_make_above (window);
|
|
||||||
else
|
|
||||||
meta_window_unmake_above (window);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move a window to a corner; to_bottom/to_right are FALSE for the
|
/* Move a window to a corner; to_bottom/to_right are FALSE for the
|
||||||
* top or left edge, or TRUE for the bottom/right edge. xchange/ychange
|
* top or left edge, or TRUE for the bottom/right edge. xchange/ychange
|
||||||
* are FALSE if that dimension is not to be changed, TRUE otherwise.
|
* are FALSE if that dimension is not to be changed, TRUE otherwise.
|
||||||
@@ -3168,17 +3157,17 @@ handle_move_to_corner_backend (MetaDisplay *display,
|
|||||||
gpointer dummy)
|
gpointer dummy)
|
||||||
{
|
{
|
||||||
MetaRectangle work_area;
|
MetaRectangle work_area;
|
||||||
MetaRectangle frame_rect;
|
MetaRectangle outer;
|
||||||
int orig_x, orig_y;
|
int orig_x, orig_y;
|
||||||
int new_x, new_y;
|
int new_x, new_y;
|
||||||
|
|
||||||
meta_window_get_work_area_all_monitors (window, &work_area);
|
meta_window_get_work_area_all_monitors (window, &work_area);
|
||||||
meta_window_get_frame_rect (window, &frame_rect);
|
meta_window_get_outer_rect (window, &outer);
|
||||||
meta_window_get_position (window, &orig_x, &orig_y);
|
meta_window_get_position (window, &orig_x, &orig_y);
|
||||||
|
|
||||||
if (xchange) {
|
if (xchange) {
|
||||||
new_x = work_area.x + (to_right ?
|
new_x = work_area.x + (to_right ?
|
||||||
work_area.width - frame_rect.width :
|
work_area.width - outer.width :
|
||||||
0);
|
0);
|
||||||
} else {
|
} else {
|
||||||
new_x = orig_x;
|
new_x = orig_x;
|
||||||
@@ -3186,7 +3175,7 @@ handle_move_to_corner_backend (MetaDisplay *display,
|
|||||||
|
|
||||||
if (ychange) {
|
if (ychange) {
|
||||||
new_y = work_area.y + (to_bottom ?
|
new_y = work_area.y + (to_bottom ?
|
||||||
work_area.height - frame_rect.height :
|
work_area.height - outer.height :
|
||||||
0);
|
0);
|
||||||
} else {
|
} else {
|
||||||
new_y = orig_y;
|
new_y = orig_y;
|
||||||
@@ -3295,12 +3284,12 @@ handle_move_to_center (MetaDisplay *display,
|
|||||||
gpointer dummy)
|
gpointer dummy)
|
||||||
{
|
{
|
||||||
MetaRectangle work_area;
|
MetaRectangle work_area;
|
||||||
MetaRectangle frame_rect;
|
MetaRectangle outer;
|
||||||
int orig_x, orig_y;
|
int orig_x, orig_y;
|
||||||
int frame_width, frame_height;
|
int frame_width, frame_height;
|
||||||
|
|
||||||
meta_window_get_work_area_all_monitors (window, &work_area);
|
meta_window_get_work_area_all_monitors (window, &work_area);
|
||||||
meta_window_get_frame_rect (window, &frame_rect);
|
meta_window_get_outer_rect (window, &outer);
|
||||||
meta_window_get_position (window, &orig_x, &orig_y);
|
meta_window_get_position (window, &orig_x, &orig_y);
|
||||||
|
|
||||||
frame_width = (window->frame ? window->frame->child_x : 0);
|
frame_width = (window->frame ? window->frame->child_x : 0);
|
||||||
@@ -3308,8 +3297,8 @@ handle_move_to_center (MetaDisplay *display,
|
|||||||
|
|
||||||
meta_window_move_resize (window,
|
meta_window_move_resize (window,
|
||||||
TRUE,
|
TRUE,
|
||||||
work_area.x + (work_area.width +frame_width -frame_rect.width )/2,
|
work_area.x + (work_area.width +frame_width -outer.width )/2,
|
||||||
work_area.y + (work_area.height+frame_height-frame_rect.height)/2,
|
work_area.y + (work_area.height+frame_height-outer.height)/2,
|
||||||
window->rect.width,
|
window->rect.width,
|
||||||
window->rect.height);
|
window->rect.height);
|
||||||
}
|
}
|
||||||
@@ -4002,8 +3991,8 @@ handle_raise_or_lower (MetaDisplay *display,
|
|||||||
|
|
||||||
if (above->mapped)
|
if (above->mapped)
|
||||||
{
|
{
|
||||||
meta_window_get_frame_rect (window, &win_rect);
|
meta_window_get_outer_rect (window, &win_rect);
|
||||||
meta_window_get_frame_rect (above, &above_rect);
|
meta_window_get_outer_rect (above, &above_rect);
|
||||||
|
|
||||||
/* Check if obscured */
|
/* Check if obscured */
|
||||||
if (meta_rectangle_intersect (&win_rect, &above_rect, &tmp))
|
if (meta_rectangle_intersect (&win_rect, &above_rect, &tmp))
|
||||||
@@ -4143,6 +4132,28 @@ meta_keybindings_set_custom_handler (const gchar *name,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_keybindings_switch_window: (skip)
|
||||||
|
* @display: a #MetaDisplay
|
||||||
|
* @screen: a #MetaScreen
|
||||||
|
* @event_window: a #MetaWindow
|
||||||
|
* @event: a #XIDeviceEvent
|
||||||
|
* @binding: a #MetaKeyBinding
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
meta_keybindings_switch_window (MetaDisplay *display,
|
||||||
|
MetaScreen *screen,
|
||||||
|
MetaWindow *event_window,
|
||||||
|
XIDeviceEvent *event,
|
||||||
|
MetaKeyBinding *binding)
|
||||||
|
{
|
||||||
|
gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
|
||||||
|
|
||||||
|
do_choose_window (display, screen, event_window, event, binding,
|
||||||
|
backwards, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_builtin_key_bindings (MetaDisplay *display)
|
init_builtin_key_bindings (MetaDisplay *display)
|
||||||
{
|
{
|
||||||
@@ -4664,13 +4675,6 @@ init_builtin_key_bindings (MetaDisplay *display)
|
|||||||
META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY,
|
META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY,
|
||||||
handle_maximize_horizontally, 0);
|
handle_maximize_horizontally, 0);
|
||||||
|
|
||||||
add_builtin_keybinding (display,
|
|
||||||
"always-on-top",
|
|
||||||
common_keybindings,
|
|
||||||
META_KEY_BINDING_PER_WINDOW,
|
|
||||||
META_KEYBINDING_ACTION_ALWAYS_ON_TOP,
|
|
||||||
handle_always_on_top, 0);
|
|
||||||
|
|
||||||
add_builtin_keybinding (display,
|
add_builtin_keybinding (display,
|
||||||
"move-to-corner-nw",
|
"move-to-corner-nw",
|
||||||
common_keybindings,
|
common_keybindings,
|
||||||
|
@@ -37,9 +37,7 @@
|
|||||||
|
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
|
|
||||||
#include <X11/cursorfont.h>
|
|
||||||
#include <X11/extensions/Xfixes.h>
|
#include <X11/extensions/Xfixes.h>
|
||||||
#include <X11/Xcursor/Xcursor.h>
|
|
||||||
|
|
||||||
#include "meta-cursor-tracker-private.h"
|
#include "meta-cursor-tracker-private.h"
|
||||||
#include "screen-private.h"
|
#include "screen-private.h"
|
||||||
@@ -71,106 +69,6 @@ enum {
|
|||||||
|
|
||||||
static guint signals[LAST_SIGNAL];
|
static guint signals[LAST_SIGNAL];
|
||||||
|
|
||||||
static void
|
|
||||||
translate_meta_cursor (MetaCursor cursor,
|
|
||||||
guint *glyph_out,
|
|
||||||
const char **name_out)
|
|
||||||
{
|
|
||||||
guint glyph = XC_num_glyphs;
|
|
||||||
const char *name = NULL;
|
|
||||||
|
|
||||||
switch (cursor)
|
|
||||||
{
|
|
||||||
case META_CURSOR_DEFAULT:
|
|
||||||
glyph = XC_left_ptr;
|
|
||||||
break;
|
|
||||||
case META_CURSOR_NORTH_RESIZE:
|
|
||||||
glyph = XC_top_side;
|
|
||||||
break;
|
|
||||||
case META_CURSOR_SOUTH_RESIZE:
|
|
||||||
glyph = XC_bottom_side;
|
|
||||||
break;
|
|
||||||
case META_CURSOR_WEST_RESIZE:
|
|
||||||
glyph = XC_left_side;
|
|
||||||
break;
|
|
||||||
case META_CURSOR_EAST_RESIZE:
|
|
||||||
glyph = XC_right_side;
|
|
||||||
break;
|
|
||||||
case META_CURSOR_SE_RESIZE:
|
|
||||||
glyph = XC_bottom_right_corner;
|
|
||||||
break;
|
|
||||||
case META_CURSOR_SW_RESIZE:
|
|
||||||
glyph = XC_bottom_left_corner;
|
|
||||||
break;
|
|
||||||
case META_CURSOR_NE_RESIZE:
|
|
||||||
glyph = XC_top_right_corner;
|
|
||||||
break;
|
|
||||||
case META_CURSOR_NW_RESIZE:
|
|
||||||
glyph = XC_top_left_corner;
|
|
||||||
break;
|
|
||||||
case META_CURSOR_MOVE_OR_RESIZE_WINDOW:
|
|
||||||
glyph = XC_fleur;
|
|
||||||
break;
|
|
||||||
case META_CURSOR_BUSY:
|
|
||||||
glyph = XC_watch;
|
|
||||||
break;
|
|
||||||
case META_CURSOR_DND_IN_DRAG:
|
|
||||||
name = "dnd-none";
|
|
||||||
break;
|
|
||||||
case META_CURSOR_DND_MOVE:
|
|
||||||
name = "dnd-move";
|
|
||||||
break;
|
|
||||||
case META_CURSOR_DND_COPY:
|
|
||||||
name = "dnd-copy";
|
|
||||||
break;
|
|
||||||
case META_CURSOR_DND_UNSUPPORTED_TARGET:
|
|
||||||
name = "dnd-none";
|
|
||||||
break;
|
|
||||||
case META_CURSOR_POINTING_HAND:
|
|
||||||
glyph = XC_hand2;
|
|
||||||
break;
|
|
||||||
case META_CURSOR_CROSSHAIR:
|
|
||||||
glyph = XC_crosshair;
|
|
||||||
break;
|
|
||||||
case META_CURSOR_IBEAM:
|
|
||||||
glyph = XC_xterm;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
glyph = 0; /* silence compiler */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
*glyph_out = glyph;
|
|
||||||
*name_out = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Cursor
|
|
||||||
load_cursor_on_server (MetaDisplay *display,
|
|
||||||
MetaCursor cursor)
|
|
||||||
{
|
|
||||||
Cursor xcursor;
|
|
||||||
guint glyph;
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
translate_meta_cursor (cursor, &glyph, &name);
|
|
||||||
|
|
||||||
if (name != NULL)
|
|
||||||
xcursor = XcursorLibraryLoadCursor (display->xdisplay, name);
|
|
||||||
else
|
|
||||||
xcursor = XCreateFontCursor (display->xdisplay, glyph);
|
|
||||||
|
|
||||||
return xcursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
Cursor
|
|
||||||
meta_display_create_x_cursor (MetaDisplay *display,
|
|
||||||
MetaCursor cursor)
|
|
||||||
{
|
|
||||||
return load_cursor_on_server (display, cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_cursor_tracker_init (MetaCursorTracker *self)
|
meta_cursor_tracker_init (MetaCursorTracker *self)
|
||||||
{
|
{
|
||||||
|
@@ -501,7 +501,7 @@ make_watch (MetaIdleMonitor *monitor,
|
|||||||
if (meta_idle_monitor_get_idletime (monitor) > (gint64)timeout_msec)
|
if (meta_idle_monitor_get_idletime (monitor) > (gint64)timeout_msec)
|
||||||
watch->idle_source_id = g_idle_add (fire_watch_idle, watch);
|
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;
|
watch->xalarm = monitor->user_active_alarm;
|
||||||
|
|
||||||
@@ -842,8 +842,6 @@ on_bus_acquired (GDBusConnection *connection,
|
|||||||
for (iter = devices; iter; iter = iter->next)
|
for (iter = devices; iter; iter = iter->next)
|
||||||
on_device_added (device_manager, iter->data, manager);
|
on_device_added (device_manager, iter->data, manager);
|
||||||
|
|
||||||
g_slist_free (devices);
|
|
||||||
|
|
||||||
g_signal_connect_object (device_manager, "device-added",
|
g_signal_connect_object (device_manager, "device-added",
|
||||||
G_CALLBACK (on_device_added), manager, 0);
|
G_CALLBACK (on_device_added), manager, 0);
|
||||||
g_signal_connect_object (device_manager, "device-removed",
|
g_signal_connect_object (device_manager, "device-removed",
|
||||||
|
@@ -99,9 +99,8 @@ static gboolean meta_monitor_config_assign_crtcs (MetaConfiguration *config,
|
|||||||
GPtrArray *crtcs,
|
GPtrArray *crtcs,
|
||||||
GPtrArray *outputs);
|
GPtrArray *outputs);
|
||||||
|
|
||||||
static void power_client_changed_cb (UpClient *client,
|
static void power_client_changed_cb (UpClient *client,
|
||||||
GParamSpec *pspec,
|
gpointer user_data);
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_output_key (MetaOutputKey *key)
|
free_output_key (MetaOutputKey *key)
|
||||||
@@ -233,7 +232,7 @@ meta_monitor_config_init (MetaMonitorConfig *self)
|
|||||||
self->up_client = up_client_new ();
|
self->up_client = up_client_new ();
|
||||||
self->lid_is_closed = up_client_get_lid_is_closed (self->up_client);
|
self->lid_is_closed = up_client_get_lid_is_closed (self->up_client);
|
||||||
|
|
||||||
g_signal_connect_object (self->up_client, "notify::lid-is-closed",
|
g_signal_connect_object (self->up_client, "changed",
|
||||||
G_CALLBACK (power_client_changed_cb), self, 0);
|
G_CALLBACK (power_client_changed_cb), self, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1361,9 +1360,8 @@ turn_off_laptop_display (MetaMonitorConfig *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
power_client_changed_cb (UpClient *client,
|
power_client_changed_cb (UpClient *client,
|
||||||
GParamSpec *pspec,
|
gpointer user_data)
|
||||||
gpointer user_data)
|
|
||||||
{
|
{
|
||||||
MetaMonitorManager *manager = meta_monitor_manager_get ();
|
MetaMonitorManager *manager = meta_monitor_manager_get ();
|
||||||
MetaMonitorConfig *self = user_data;
|
MetaMonitorConfig *self = user_data;
|
||||||
|
@@ -187,7 +187,7 @@ output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
|||||||
|
|
||||||
XRRGetOutputProperty (manager_xrandr->xdisplay,
|
XRRGetOutputProperty (manager_xrandr->xdisplay,
|
||||||
(XID)output->output_id,
|
(XID)output->output_id,
|
||||||
display->atom_BACKLIGHT,
|
display->atom_Backlight,
|
||||||
0, G_MAXLONG, False, False, XA_INTEGER,
|
0, G_MAXLONG, False, False, XA_INTEGER,
|
||||||
&actual_type, &actual_format,
|
&actual_type, &actual_format,
|
||||||
&nitems, &bytes_after, &buffer);
|
&nitems, &bytes_after, &buffer);
|
||||||
@@ -212,7 +212,7 @@ output_get_backlight_limits_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
|||||||
meta_error_trap_push (display);
|
meta_error_trap_push (display);
|
||||||
info = XRRQueryOutputProperty (manager_xrandr->xdisplay,
|
info = XRRQueryOutputProperty (manager_xrandr->xdisplay,
|
||||||
(XID)output->output_id,
|
(XID)output->output_id,
|
||||||
display->atom_BACKLIGHT);
|
display->atom_Backlight);
|
||||||
meta_error_trap_pop (display);
|
meta_error_trap_pop (display);
|
||||||
|
|
||||||
if (info == NULL)
|
if (info == NULL)
|
||||||
@@ -950,7 +950,7 @@ meta_monitor_manager_xrandr_change_backlight (MetaMonitorManager *manager,
|
|||||||
meta_error_trap_push (display);
|
meta_error_trap_push (display);
|
||||||
XRRChangeOutputProperty (manager_xrandr->xdisplay,
|
XRRChangeOutputProperty (manager_xrandr->xdisplay,
|
||||||
(XID)output->output_id,
|
(XID)output->output_id,
|
||||||
display->atom_BACKLIGHT,
|
display->atom_Backlight,
|
||||||
XA_INTEGER, 32, PropModeReplace,
|
XA_INTEGER, 32, PropModeReplace,
|
||||||
(unsigned char *) &hw_value, 1);
|
(unsigned char *) &hw_value, 1);
|
||||||
meta_error_trap_pop (display);
|
meta_error_trap_pop (display);
|
||||||
|
@@ -406,7 +406,7 @@ make_logical_config (MetaMonitorManager *manager)
|
|||||||
|
|
||||||
for (j = 0; j < monitor_infos->len; j++)
|
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,
|
if (meta_rectangle_equal (&crtc->rect,
|
||||||
&info->rect))
|
&info->rect))
|
||||||
{
|
{
|
||||||
@@ -806,9 +806,6 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
|||||||
g_variant_new_take_string (make_display_name (manager, output)));
|
g_variant_new_take_string (make_display_name (manager, output)));
|
||||||
g_variant_builder_add (&properties, "{sv}", "backlight",
|
g_variant_builder_add (&properties, "{sv}", "backlight",
|
||||||
g_variant_new_int32 (output->backlight));
|
g_variant_new_int32 (output->backlight));
|
||||||
g_variant_builder_add (&properties, "{sv}", "min-backlight-step",
|
|
||||||
g_variant_new_int32 ((output->backlight_max - output->backlight_min) ?
|
|
||||||
100 / (output->backlight_max - output->backlight_min) : -1));
|
|
||||||
g_variant_builder_add (&properties, "{sv}", "primary",
|
g_variant_builder_add (&properties, "{sv}", "primary",
|
||||||
g_variant_new_boolean (output->is_primary));
|
g_variant_new_boolean (output->is_primary));
|
||||||
g_variant_builder_add (&properties, "{sv}", "presentation",
|
g_variant_builder_add (&properties, "{sv}", "presentation",
|
||||||
|
299
src/core/place.c
299
src/core/place.c
@@ -47,18 +47,34 @@ northwestcmp (gconstpointer a, gconstpointer b)
|
|||||||
{
|
{
|
||||||
MetaWindow *aw = (gpointer) a;
|
MetaWindow *aw = (gpointer) a;
|
||||||
MetaWindow *bw = (gpointer) b;
|
MetaWindow *bw = (gpointer) b;
|
||||||
MetaRectangle a_frame;
|
|
||||||
MetaRectangle b_frame;
|
|
||||||
int from_origin_a;
|
int from_origin_a;
|
||||||
int from_origin_b;
|
int from_origin_b;
|
||||||
int ax, ay, bx, by;
|
int ax, ay, bx, by;
|
||||||
|
|
||||||
meta_window_get_frame_rect (aw, &a_frame);
|
/* we're interested in the frame position for cascading,
|
||||||
meta_window_get_frame_rect (bw, &b_frame);
|
* not meta_window_get_position()
|
||||||
ax = a_frame.x;
|
*/
|
||||||
ay = a_frame.y;
|
if (aw->frame)
|
||||||
bx = b_frame.x;
|
{
|
||||||
by = b_frame.y;
|
ax = aw->frame->rect.x;
|
||||||
|
ay = aw->frame->rect.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ax = aw->rect.x;
|
||||||
|
ay = aw->rect.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bw->frame)
|
||||||
|
{
|
||||||
|
bx = bw->frame->rect.x;
|
||||||
|
by = bw->frame->rect.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bx = bw->rect.x;
|
||||||
|
by = bw->rect.y;
|
||||||
|
}
|
||||||
|
|
||||||
/* probably there's a fast good-enough-guess we could use here. */
|
/* probably there's a fast good-enough-guess we could use here. */
|
||||||
from_origin_a = sqrt (ax * ax + ay * ay);
|
from_origin_a = sqrt (ax * ax + ay * ay);
|
||||||
@@ -74,6 +90,7 @@ northwestcmp (gconstpointer a, gconstpointer b)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
find_next_cascade (MetaWindow *window,
|
find_next_cascade (MetaWindow *window,
|
||||||
|
MetaFrameBorders *borders,
|
||||||
/* visible windows on relevant workspaces */
|
/* visible windows on relevant workspaces */
|
||||||
GList *windows,
|
GList *windows,
|
||||||
int x,
|
int x,
|
||||||
@@ -85,7 +102,6 @@ find_next_cascade (MetaWindow *window,
|
|||||||
GList *sorted;
|
GList *sorted;
|
||||||
int cascade_x, cascade_y;
|
int cascade_x, cascade_y;
|
||||||
int x_threshold, y_threshold;
|
int x_threshold, y_threshold;
|
||||||
MetaRectangle frame_rect;
|
|
||||||
int window_width, window_height;
|
int window_width, window_height;
|
||||||
int cascade_stage;
|
int cascade_stage;
|
||||||
MetaRectangle work_area;
|
MetaRectangle work_area;
|
||||||
@@ -104,13 +120,10 @@ find_next_cascade (MetaWindow *window,
|
|||||||
* manually cascade.
|
* manually cascade.
|
||||||
*/
|
*/
|
||||||
#define CASCADE_FUZZ 15
|
#define CASCADE_FUZZ 15
|
||||||
if (window->frame)
|
if (borders)
|
||||||
{
|
{
|
||||||
MetaFrameBorders borders;
|
x_threshold = MAX (borders->visible.left, CASCADE_FUZZ);
|
||||||
|
y_threshold = MAX (borders->visible.top, CASCADE_FUZZ);
|
||||||
meta_frame_calc_borders (window->frame, &borders);
|
|
||||||
x_threshold = MAX (borders.visible.left, CASCADE_FUZZ);
|
|
||||||
y_threshold = MAX (borders.visible.top, CASCADE_FUZZ);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -130,25 +143,30 @@ find_next_cascade (MetaWindow *window,
|
|||||||
cascade_y = MAX (0, work_area.y);
|
cascade_y = MAX (0, work_area.y);
|
||||||
|
|
||||||
/* Find first cascade position that's not used. */
|
/* Find first cascade position that's not used. */
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, &frame_rect);
|
window_width = window->frame ? window->frame->rect.width : window->rect.width;
|
||||||
window_width = frame_rect.width;
|
window_height = window->frame ? window->frame->rect.height : window->rect.height;
|
||||||
window_height = frame_rect.height;
|
|
||||||
|
|
||||||
cascade_stage = 0;
|
cascade_stage = 0;
|
||||||
tmp = sorted;
|
tmp = sorted;
|
||||||
while (tmp != NULL)
|
while (tmp != NULL)
|
||||||
{
|
{
|
||||||
MetaWindow *w;
|
MetaWindow *w;
|
||||||
MetaRectangle w_frame_rect;
|
|
||||||
int wx, wy;
|
int wx, wy;
|
||||||
|
|
||||||
w = tmp->data;
|
w = tmp->data;
|
||||||
|
|
||||||
/* we want frame position, not window position */
|
/* we want frame position, not window position */
|
||||||
meta_window_get_frame_rect (w, &w_frame_rect);
|
if (w->frame)
|
||||||
wx = w_frame_rect.x;
|
{
|
||||||
wy = w_frame_rect.y;
|
wx = w->frame->rect.x;
|
||||||
|
wy = w->frame->rect.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wx = w->rect.x;
|
||||||
|
wy = w->rect.y;
|
||||||
|
}
|
||||||
|
|
||||||
if (ABS (wx - cascade_x) < x_threshold &&
|
if (ABS (wx - cascade_x) < x_threshold &&
|
||||||
ABS (wy - cascade_y) < y_threshold)
|
ABS (wy - cascade_y) < y_threshold)
|
||||||
@@ -205,12 +223,22 @@ find_next_cascade (MetaWindow *window,
|
|||||||
|
|
||||||
g_list_free (sorted);
|
g_list_free (sorted);
|
||||||
|
|
||||||
*new_x = cascade_x;
|
/* Convert coords to position of window, not position of frame. */
|
||||||
*new_y = cascade_y;
|
if (borders == NULL)
|
||||||
|
{
|
||||||
|
*new_x = cascade_x;
|
||||||
|
*new_y = cascade_y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*new_x = cascade_x + borders->visible.left;
|
||||||
|
*new_y = cascade_y + borders->visible.top;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
find_most_freespace (MetaWindow *window,
|
find_most_freespace (MetaWindow *window,
|
||||||
|
MetaFrameBorders *borders,
|
||||||
/* visible windows on relevant workspaces */
|
/* visible windows on relevant workspaces */
|
||||||
MetaWindow *focus_window,
|
MetaWindow *focus_window,
|
||||||
int x,
|
int x,
|
||||||
@@ -222,25 +250,29 @@ find_most_freespace (MetaWindow *window,
|
|||||||
int max_area;
|
int max_area;
|
||||||
int max_width, max_height, left, right, top, bottom;
|
int max_width, max_height, left, right, top, bottom;
|
||||||
int left_space, right_space, top_space, bottom_space;
|
int left_space, right_space, top_space, bottom_space;
|
||||||
|
int frame_size_left, frame_size_top;
|
||||||
MetaRectangle work_area;
|
MetaRectangle work_area;
|
||||||
MetaRectangle avoid;
|
MetaRectangle avoid;
|
||||||
MetaRectangle frame_rect;
|
MetaRectangle outer;
|
||||||
|
|
||||||
|
frame_size_left = borders ? borders->visible.left : 0;
|
||||||
|
frame_size_top = borders ? borders->visible.top : 0;
|
||||||
|
|
||||||
meta_window_get_work_area_current_monitor (focus_window, &work_area);
|
meta_window_get_work_area_current_monitor (focus_window, &work_area);
|
||||||
meta_window_get_frame_rect (focus_window, &avoid);
|
meta_window_get_outer_rect (focus_window, &avoid);
|
||||||
meta_window_get_frame_rect (window, &frame_rect);
|
meta_window_get_outer_rect (window, &outer);
|
||||||
|
|
||||||
/* Find the areas of choosing the various sides of the focus window */
|
/* Find the areas of choosing the various sides of the focus window */
|
||||||
max_width = MIN (avoid.width, frame_rect.width);
|
max_width = MIN (avoid.width, outer.width);
|
||||||
max_height = MIN (avoid.height, frame_rect.height);
|
max_height = MIN (avoid.height, outer.height);
|
||||||
left_space = avoid.x - work_area.x;
|
left_space = avoid.x - work_area.x;
|
||||||
right_space = work_area.width - (avoid.x + avoid.width - work_area.x);
|
right_space = work_area.width - (avoid.x + avoid.width - work_area.x);
|
||||||
top_space = avoid.y - work_area.y;
|
top_space = avoid.y - work_area.y;
|
||||||
bottom_space = work_area.height - (avoid.y + avoid.height - work_area.y);
|
bottom_space = work_area.height - (avoid.y + avoid.height - work_area.y);
|
||||||
left = MIN (left_space, frame_rect.width);
|
left = MIN (left_space, outer.width);
|
||||||
right = MIN (right_space, frame_rect.width);
|
right = MIN (right_space, outer.width);
|
||||||
top = MIN (top_space, frame_rect.height);
|
top = MIN (top_space, outer.height);
|
||||||
bottom = MIN (bottom_space, frame_rect.height);
|
bottom = MIN (bottom_space, outer.height);
|
||||||
|
|
||||||
/* Find out which side of the focus_window can show the most of the window */
|
/* Find out which side of the focus_window can show the most of the window */
|
||||||
side = META_LEFT;
|
side = META_LEFT;
|
||||||
@@ -272,56 +304,39 @@ find_most_freespace (MetaWindow *window,
|
|||||||
switch (side)
|
switch (side)
|
||||||
{
|
{
|
||||||
case META_LEFT:
|
case META_LEFT:
|
||||||
*new_y = avoid.y;
|
*new_y = avoid.y + frame_size_top;
|
||||||
if (left_space > frame_rect.width)
|
if (left_space > outer.width)
|
||||||
*new_x = avoid.x - frame_rect.width;
|
*new_x = avoid.x - outer.width + frame_size_left;
|
||||||
else
|
else
|
||||||
*new_x = work_area.x;
|
*new_x = work_area.x + frame_size_left;
|
||||||
break;
|
break;
|
||||||
case META_RIGHT:
|
case META_RIGHT:
|
||||||
*new_y = avoid.y;
|
*new_y = avoid.y + frame_size_top;
|
||||||
if (right_space > frame_rect.width)
|
if (right_space > outer.width)
|
||||||
*new_x = avoid.x + avoid.width;
|
*new_x = avoid.x + avoid.width + frame_size_left;
|
||||||
else
|
else
|
||||||
*new_x = work_area.x + work_area.width - frame_rect.width;
|
*new_x = work_area.x + work_area.width - outer.width + frame_size_left;
|
||||||
break;
|
break;
|
||||||
case META_TOP:
|
case META_TOP:
|
||||||
*new_x = avoid.x;
|
*new_x = avoid.x + frame_size_left;
|
||||||
if (top_space > frame_rect.height)
|
if (top_space > outer.height)
|
||||||
*new_y = avoid.y - frame_rect.height;
|
*new_y = avoid.y - outer.height + frame_size_top;
|
||||||
else
|
else
|
||||||
*new_y = work_area.y;
|
*new_y = work_area.y + frame_size_top;
|
||||||
break;
|
break;
|
||||||
case META_BOTTOM:
|
case META_BOTTOM:
|
||||||
*new_x = avoid.x;
|
*new_x = avoid.x + frame_size_left;
|
||||||
if (bottom_space > frame_rect.height)
|
if (bottom_space > outer.height)
|
||||||
*new_y = avoid.y + avoid.height;
|
*new_y = avoid.y + avoid.height + frame_size_top;
|
||||||
else
|
else
|
||||||
*new_y = work_area.y + work_area.height - frame_rect.height;
|
*new_y = work_area.y + work_area.height - outer.height + frame_size_top;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
window_overlaps_focus_window (MetaWindow *window)
|
|
||||||
{
|
|
||||||
MetaWindow *focus_window;
|
|
||||||
MetaRectangle window_frame, focus_frame, overlap;
|
|
||||||
|
|
||||||
focus_window = window->display->focus_window;
|
|
||||||
if (focus_window == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, &window_frame);
|
|
||||||
meta_window_get_frame_rect (focus_window, &focus_frame);
|
|
||||||
|
|
||||||
return meta_rectangle_intersect (&window_frame,
|
|
||||||
&focus_frame,
|
|
||||||
&overlap);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
avoid_being_obscured_as_second_modal_dialog (MetaWindow *window,
|
avoid_being_obscured_as_second_modal_dialog (MetaWindow *window,
|
||||||
|
MetaFrameBorders *borders,
|
||||||
int *x,
|
int *x,
|
||||||
int *y)
|
int *y)
|
||||||
{
|
{
|
||||||
@@ -340,17 +355,18 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
MetaWindow *focus_window;
|
MetaWindow *focus_window;
|
||||||
|
MetaRectangle overlap;
|
||||||
|
|
||||||
focus_window = window->display->focus_window;
|
focus_window = window->display->focus_window;
|
||||||
|
|
||||||
/* denied_focus_and_not_transient is only set when focus_window != NULL */
|
|
||||||
|
|
||||||
if (window->denied_focus_and_not_transient &&
|
if (window->denied_focus_and_not_transient &&
|
||||||
window->wm_state_modal && /* FIXME: Maybe do this for all transients? */
|
window->wm_state_modal && /* FIXME: Maybe do this for all transients? */
|
||||||
meta_window_same_application (window, focus_window) &&
|
meta_window_same_application (window, focus_window) &&
|
||||||
window_overlaps_focus_window (window))
|
meta_rectangle_intersect (&window->rect,
|
||||||
|
&focus_window->rect,
|
||||||
|
&overlap))
|
||||||
{
|
{
|
||||||
find_most_freespace (window, focus_window, *x, *y, x, y);
|
find_most_freespace (window, borders, focus_window, *x, *y, x, y);
|
||||||
meta_topic (META_DEBUG_PLACEMENT,
|
meta_topic (META_DEBUG_PLACEMENT,
|
||||||
"Dialog window %s was denied focus but may be modal "
|
"Dialog window %s was denied focus but may be modal "
|
||||||
"to the focus window; had to move it to avoid the "
|
"to the focus window; had to move it to avoid the "
|
||||||
@@ -393,7 +409,7 @@ rectangle_overlaps_some_window (MetaRectangle *rect,
|
|||||||
case META_WINDOW_UTILITY:
|
case META_WINDOW_UTILITY:
|
||||||
case META_WINDOW_TOOLBAR:
|
case META_WINDOW_TOOLBAR:
|
||||||
case META_WINDOW_MENU:
|
case META_WINDOW_MENU:
|
||||||
meta_window_get_frame_rect (other, &other_rect);
|
meta_window_get_outer_rect (other, &other_rect);
|
||||||
|
|
||||||
if (meta_rectangle_intersect (rect, &other_rect, &dest))
|
if (meta_rectangle_intersect (rect, &other_rect, &dest))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -411,14 +427,20 @@ leftmost_cmp (gconstpointer a, gconstpointer b)
|
|||||||
{
|
{
|
||||||
MetaWindow *aw = (gpointer) a;
|
MetaWindow *aw = (gpointer) a;
|
||||||
MetaWindow *bw = (gpointer) b;
|
MetaWindow *bw = (gpointer) b;
|
||||||
MetaRectangle a_frame;
|
|
||||||
MetaRectangle b_frame;
|
|
||||||
int ax, bx;
|
int ax, bx;
|
||||||
|
|
||||||
meta_window_get_frame_rect (aw, &a_frame);
|
/* we're interested in the frame position for cascading,
|
||||||
meta_window_get_frame_rect (bw, &b_frame);
|
* not meta_window_get_position()
|
||||||
ax = a_frame.x;
|
*/
|
||||||
bx = b_frame.x;
|
if (aw->frame)
|
||||||
|
ax = aw->frame->rect.x;
|
||||||
|
else
|
||||||
|
ax = aw->rect.x;
|
||||||
|
|
||||||
|
if (bw->frame)
|
||||||
|
bx = bw->frame->rect.x;
|
||||||
|
else
|
||||||
|
bx = bw->rect.x;
|
||||||
|
|
||||||
if (ax < bx)
|
if (ax < bx)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -433,14 +455,20 @@ topmost_cmp (gconstpointer a, gconstpointer b)
|
|||||||
{
|
{
|
||||||
MetaWindow *aw = (gpointer) a;
|
MetaWindow *aw = (gpointer) a;
|
||||||
MetaWindow *bw = (gpointer) b;
|
MetaWindow *bw = (gpointer) b;
|
||||||
MetaRectangle a_frame;
|
|
||||||
MetaRectangle b_frame;
|
|
||||||
int ay, by;
|
int ay, by;
|
||||||
|
|
||||||
meta_window_get_frame_rect (aw, &a_frame);
|
/* we're interested in the frame position for cascading,
|
||||||
meta_window_get_frame_rect (bw, &b_frame);
|
* not meta_window_get_position()
|
||||||
ay = a_frame.y;
|
*/
|
||||||
by = b_frame.y;
|
if (aw->frame)
|
||||||
|
ay = aw->frame->rect.y;
|
||||||
|
else
|
||||||
|
ay = aw->rect.y;
|
||||||
|
|
||||||
|
if (bw->frame)
|
||||||
|
by = bw->frame->rect.y;
|
||||||
|
else
|
||||||
|
by = bw->rect.y;
|
||||||
|
|
||||||
if (ay < by)
|
if (ay < by)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -478,6 +506,7 @@ center_tile_rect_in_area (MetaRectangle *rect,
|
|||||||
*/
|
*/
|
||||||
static gboolean
|
static gboolean
|
||||||
find_first_fit (MetaWindow *window,
|
find_first_fit (MetaWindow *window,
|
||||||
|
MetaFrameBorders *borders,
|
||||||
/* visible windows on relevant workspaces */
|
/* visible windows on relevant workspaces */
|
||||||
GList *windows,
|
GList *windows,
|
||||||
int monitor,
|
int monitor,
|
||||||
@@ -511,8 +540,15 @@ find_first_fit (MetaWindow *window,
|
|||||||
right_sorted = g_list_copy (windows);
|
right_sorted = g_list_copy (windows);
|
||||||
right_sorted = g_list_sort (right_sorted, topmost_cmp);
|
right_sorted = g_list_sort (right_sorted, topmost_cmp);
|
||||||
right_sorted = g_list_sort (right_sorted, leftmost_cmp);
|
right_sorted = g_list_sort (right_sorted, leftmost_cmp);
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, &rect);
|
rect.width = window->rect.width;
|
||||||
|
rect.height = window->rect.height;
|
||||||
|
|
||||||
|
if (borders)
|
||||||
|
{
|
||||||
|
rect.width += borders->visible.left + borders->visible.right;
|
||||||
|
rect.height += borders->visible.top + borders->visible.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WITH_VERBOSE_MODE
|
#ifdef WITH_VERBOSE_MODE
|
||||||
{
|
{
|
||||||
@@ -534,6 +570,11 @@ find_first_fit (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
*new_x = rect.x;
|
*new_x = rect.x;
|
||||||
*new_y = rect.y;
|
*new_y = rect.y;
|
||||||
|
if (borders)
|
||||||
|
{
|
||||||
|
*new_x += borders->visible.left;
|
||||||
|
*new_y += borders->visible.top;
|
||||||
|
}
|
||||||
|
|
||||||
retval = TRUE;
|
retval = TRUE;
|
||||||
|
|
||||||
@@ -545,18 +586,23 @@ find_first_fit (MetaWindow *window,
|
|||||||
while (tmp != NULL)
|
while (tmp != NULL)
|
||||||
{
|
{
|
||||||
MetaWindow *w = tmp->data;
|
MetaWindow *w = tmp->data;
|
||||||
MetaRectangle frame_rect;
|
MetaRectangle outer_rect;
|
||||||
|
|
||||||
meta_window_get_frame_rect (w, &frame_rect);
|
meta_window_get_outer_rect (w, &outer_rect);
|
||||||
|
|
||||||
rect.x = frame_rect.x;
|
rect.x = outer_rect.x;
|
||||||
rect.y = frame_rect.y + frame_rect.height;
|
rect.y = outer_rect.y + outer_rect.height;
|
||||||
|
|
||||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||||
!rectangle_overlaps_some_window (&rect, below_sorted))
|
!rectangle_overlaps_some_window (&rect, below_sorted))
|
||||||
{
|
{
|
||||||
*new_x = rect.x;
|
*new_x = rect.x;
|
||||||
*new_y = rect.y;
|
*new_y = rect.y;
|
||||||
|
if (borders)
|
||||||
|
{
|
||||||
|
*new_x += borders->visible.left;
|
||||||
|
*new_y += borders->visible.top;
|
||||||
|
}
|
||||||
|
|
||||||
retval = TRUE;
|
retval = TRUE;
|
||||||
|
|
||||||
@@ -571,18 +617,23 @@ find_first_fit (MetaWindow *window,
|
|||||||
while (tmp != NULL)
|
while (tmp != NULL)
|
||||||
{
|
{
|
||||||
MetaWindow *w = tmp->data;
|
MetaWindow *w = tmp->data;
|
||||||
MetaRectangle frame_rect;
|
MetaRectangle outer_rect;
|
||||||
|
|
||||||
meta_window_get_frame_rect (w, &frame_rect);
|
meta_window_get_outer_rect (w, &outer_rect);
|
||||||
|
|
||||||
rect.x = frame_rect.x + frame_rect.width;
|
rect.x = outer_rect.x + outer_rect.width;
|
||||||
rect.y = frame_rect.y;
|
rect.y = outer_rect.y;
|
||||||
|
|
||||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||||
!rectangle_overlaps_some_window (&rect, right_sorted))
|
!rectangle_overlaps_some_window (&rect, right_sorted))
|
||||||
{
|
{
|
||||||
*new_x = rect.x;
|
*new_x = rect.x;
|
||||||
*new_y = rect.y;
|
*new_y = rect.y;
|
||||||
|
if (borders)
|
||||||
|
{
|
||||||
|
*new_x += borders->visible.left;
|
||||||
|
*new_y += borders->visible.top;
|
||||||
|
}
|
||||||
|
|
||||||
retval = TRUE;
|
retval = TRUE;
|
||||||
|
|
||||||
@@ -601,6 +652,7 @@ find_first_fit (MetaWindow *window,
|
|||||||
|
|
||||||
void
|
void
|
||||||
meta_window_place (MetaWindow *window,
|
meta_window_place (MetaWindow *window,
|
||||||
|
MetaFrameBorders *borders,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
int *new_x,
|
int *new_x,
|
||||||
@@ -609,6 +661,13 @@ meta_window_place (MetaWindow *window,
|
|||||||
GList *windows;
|
GList *windows;
|
||||||
const MetaMonitorInfo *xi;
|
const MetaMonitorInfo *xi;
|
||||||
|
|
||||||
|
/* frame member variables should NEVER be used in here, only
|
||||||
|
* MetaFrameBorders. But remember borders == NULL
|
||||||
|
* for undecorated windows. Also, this function should
|
||||||
|
* NEVER have side effects other than computing the
|
||||||
|
* placement coordinates.
|
||||||
|
*/
|
||||||
|
|
||||||
meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc);
|
meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc);
|
||||||
|
|
||||||
windows = NULL;
|
windows = NULL;
|
||||||
@@ -697,7 +756,7 @@ meta_window_place (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_PLACEMENT,
|
meta_topic (META_DEBUG_PLACEMENT,
|
||||||
"Not placing window with PPosition or USPosition set\n");
|
"Not placing window with PPosition or USPosition set\n");
|
||||||
avoid_being_obscured_as_second_modal_dialog (window, &x, &y);
|
avoid_being_obscured_as_second_modal_dialog (window, borders, &x, &y);
|
||||||
goto done_no_constraints;
|
goto done_no_constraints;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -716,27 +775,29 @@ meta_window_place (MetaWindow *window,
|
|||||||
|
|
||||||
if (parent)
|
if (parent)
|
||||||
{
|
{
|
||||||
MetaRectangle frame_rect, parent_frame_rect;
|
int w;
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, &frame_rect);
|
meta_window_get_position (parent, &x, &y);
|
||||||
meta_window_get_frame_rect (parent, &parent_frame_rect);
|
w = parent->rect.width;
|
||||||
|
|
||||||
y = parent_frame_rect.y;
|
|
||||||
|
|
||||||
/* center of parent */
|
/* center of parent */
|
||||||
x = parent_frame_rect.x + parent_frame_rect.width / 2;
|
x = x + w / 2;
|
||||||
/* center of child over center of parent */
|
/* center of child over center of parent */
|
||||||
x -= frame_rect.width / 2;
|
x -= window->rect.width / 2;
|
||||||
|
|
||||||
/* "visually" center window over parent, leaving twice as
|
/* "visually" center window over parent, leaving twice as
|
||||||
* much space below as on top.
|
* much space below as on top.
|
||||||
*/
|
*/
|
||||||
y += (parent_frame_rect.height - frame_rect.height)/3;
|
y += (parent->rect.height - window->rect.height)/3;
|
||||||
|
|
||||||
|
/* put top of child's frame, not top of child's client */
|
||||||
|
if (borders)
|
||||||
|
y += borders->visible.top;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_PLACEMENT, "Centered window %s over transient parent\n",
|
meta_topic (META_DEBUG_PLACEMENT, "Centered window %s over transient parent\n",
|
||||||
window->desc);
|
window->desc);
|
||||||
|
|
||||||
avoid_being_obscured_as_second_modal_dialog (window, &x, &y);
|
avoid_being_obscured_as_second_modal_dialog (window, borders, &x, &y);
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -752,9 +813,6 @@ meta_window_place (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
/* Center on current monitor */
|
/* Center on current monitor */
|
||||||
int w, h;
|
int w, h;
|
||||||
MetaRectangle frame_rect;
|
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, &frame_rect);
|
|
||||||
|
|
||||||
/* Warning, this function is a round trip! */
|
/* Warning, this function is a round trip! */
|
||||||
xi = meta_screen_get_current_monitor_info (window->screen);
|
xi = meta_screen_get_current_monitor_info (window->screen);
|
||||||
@@ -762,8 +820,8 @@ meta_window_place (MetaWindow *window,
|
|||||||
w = xi->rect.width;
|
w = xi->rect.width;
|
||||||
h = xi->rect.height;
|
h = xi->rect.height;
|
||||||
|
|
||||||
x = (w - frame_rect.width) / 2;
|
x = (w - window->rect.width) / 2;
|
||||||
y = (h - frame_rect.height) / 2;
|
y = (h - window->rect.height) / 2;
|
||||||
|
|
||||||
x += xi->rect.x;
|
x += xi->rect.x;
|
||||||
y += xi->rect.y;
|
y += xi->rect.y;
|
||||||
@@ -807,7 +865,7 @@ meta_window_place (MetaWindow *window,
|
|||||||
x = xi->rect.x;
|
x = xi->rect.x;
|
||||||
y = xi->rect.y;
|
y = xi->rect.y;
|
||||||
|
|
||||||
if (find_first_fit (window, windows,
|
if (find_first_fit (window, borders, windows,
|
||||||
xi->number,
|
xi->number,
|
||||||
x, y, &x, &y))
|
x, y, &x, &y))
|
||||||
goto done_check_denied_focus;
|
goto done_check_denied_focus;
|
||||||
@@ -820,17 +878,17 @@ meta_window_place (MetaWindow *window,
|
|||||||
!window->fullscreen)
|
!window->fullscreen)
|
||||||
{
|
{
|
||||||
MetaRectangle workarea;
|
MetaRectangle workarea;
|
||||||
MetaRectangle frame_rect;
|
MetaRectangle outer;
|
||||||
|
|
||||||
meta_window_get_work_area_for_monitor (window,
|
meta_window_get_work_area_for_monitor (window,
|
||||||
xi->number,
|
xi->number,
|
||||||
&workarea);
|
&workarea);
|
||||||
meta_window_get_frame_rect (window, &frame_rect);
|
meta_window_get_outer_rect (window, &outer);
|
||||||
|
|
||||||
/* If the window is bigger than the screen, then automaximize. Do NOT
|
/* If the window is bigger than the screen, then automaximize. Do NOT
|
||||||
* auto-maximize the directions independently. See #419810.
|
* auto-maximize the directions independently. See #419810.
|
||||||
*/
|
*/
|
||||||
if (frame_rect.width >= workarea.width && frame_rect.height >= workarea.height)
|
if (outer.width >= workarea.width && outer.height >= workarea.height)
|
||||||
{
|
{
|
||||||
window->maximize_horizontally_after_placement = TRUE;
|
window->maximize_horizontally_after_placement = TRUE;
|
||||||
window->maximize_vertically_after_placement = TRUE;
|
window->maximize_vertically_after_placement = TRUE;
|
||||||
@@ -841,7 +899,7 @@ meta_window_place (MetaWindow *window,
|
|||||||
* fully overlapping window (e.g. starting multiple terminals)
|
* fully overlapping window (e.g. starting multiple terminals)
|
||||||
* */
|
* */
|
||||||
if (x == xi->rect.x && y == xi->rect.y)
|
if (x == xi->rect.x && y == xi->rect.y)
|
||||||
find_next_cascade (window, windows, x, y, &x, &y);
|
find_next_cascade (window, borders, windows, x, y, &x, &y);
|
||||||
|
|
||||||
done_check_denied_focus:
|
done_check_denied_focus:
|
||||||
/* If the window is being denied focus and isn't a transient of the
|
/* If the window is being denied focus and isn't a transient of the
|
||||||
@@ -851,14 +909,17 @@ meta_window_place (MetaWindow *window,
|
|||||||
*/
|
*/
|
||||||
if (window->denied_focus_and_not_transient)
|
if (window->denied_focus_and_not_transient)
|
||||||
{
|
{
|
||||||
MetaWindow *focus_window;
|
|
||||||
gboolean found_fit;
|
gboolean found_fit;
|
||||||
|
MetaWindow *focus_window;
|
||||||
|
MetaRectangle overlap;
|
||||||
|
|
||||||
focus_window = window->display->focus_window;
|
focus_window = window->display->focus_window;
|
||||||
g_assert (focus_window != NULL);
|
g_assert (focus_window != NULL);
|
||||||
|
|
||||||
/* No need to do anything if the window doesn't overlap at all */
|
/* No need to do anything if the window doesn't overlap at all */
|
||||||
found_fit = !window_overlaps_focus_window (window);
|
found_fit = !meta_rectangle_intersect (&window->rect,
|
||||||
|
&focus_window->rect,
|
||||||
|
&overlap);
|
||||||
|
|
||||||
/* Try to do a first fit again, this time only taking into account the
|
/* Try to do a first fit again, this time only taking into account the
|
||||||
* focus window.
|
* focus window.
|
||||||
@@ -872,7 +933,7 @@ meta_window_place (MetaWindow *window,
|
|||||||
x = xi->rect.x;
|
x = xi->rect.x;
|
||||||
y = xi->rect.y;
|
y = xi->rect.y;
|
||||||
|
|
||||||
found_fit = find_first_fit (window, focus_window_list,
|
found_fit = find_first_fit (window, borders, focus_window_list,
|
||||||
xi->number,
|
xi->number,
|
||||||
x, y, &x, &y);
|
x, y, &x, &y);
|
||||||
g_list_free (focus_window_list);
|
g_list_free (focus_window_list);
|
||||||
@@ -882,7 +943,7 @@ meta_window_place (MetaWindow *window,
|
|||||||
* as possible.
|
* as possible.
|
||||||
*/
|
*/
|
||||||
if (!found_fit)
|
if (!found_fit)
|
||||||
find_most_freespace (window, focus_window, x, y, &x, &y);
|
find_most_freespace (window, borders, focus_window, x, y, &x, &y);
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
|
|
||||||
void meta_window_place (MetaWindow *window,
|
void meta_window_place (MetaWindow *window,
|
||||||
|
MetaFrameBorders *borders,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
int *new_x,
|
int *new_x,
|
||||||
|
@@ -392,6 +392,8 @@ int
|
|||||||
meta_screen_monitor_index_to_xinerama_index (MetaScreen *screen,
|
meta_screen_monitor_index_to_xinerama_index (MetaScreen *screen,
|
||||||
int index)
|
int index)
|
||||||
{
|
{
|
||||||
|
g_return_val_if_fail (index >= 0 && index < screen->n_monitor_infos, -1);
|
||||||
|
|
||||||
meta_screen_ensure_xinerama_indices (screen);
|
meta_screen_ensure_xinerama_indices (screen);
|
||||||
|
|
||||||
return screen->monitor_infos[index].xinerama_index;
|
return screen->monitor_infos[index].xinerama_index;
|
||||||
@@ -476,9 +478,6 @@ create_guard_window (Display *xdisplay, MetaScreen *screen)
|
|||||||
CWEventMask|CWOverrideRedirect|CWBackPixel,
|
CWEventMask|CWOverrideRedirect|CWBackPixel,
|
||||||
&attributes);
|
&attributes);
|
||||||
|
|
||||||
/* https://bugzilla.gnome.org/show_bug.cgi?id=710346 */
|
|
||||||
XStoreName (xdisplay, guard_window, "mutter guard window");
|
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||||
@@ -859,9 +858,9 @@ meta_screen_free (MetaScreen *screen,
|
|||||||
screen->wm_sn_selection_window);
|
screen->wm_sn_selection_window);
|
||||||
|
|
||||||
if (screen->work_area_later != 0)
|
if (screen->work_area_later != 0)
|
||||||
meta_later_remove (screen->work_area_later);
|
g_source_remove (screen->work_area_later);
|
||||||
if (screen->check_fullscreen_later != 0)
|
if (screen->check_fullscreen_later != 0)
|
||||||
meta_later_remove (screen->check_fullscreen_later);
|
g_source_remove (screen->check_fullscreen_later);
|
||||||
|
|
||||||
if (screen->monitor_infos)
|
if (screen->monitor_infos)
|
||||||
g_free (screen->monitor_infos);
|
g_free (screen->monitor_infos);
|
||||||
@@ -880,83 +879,31 @@ meta_screen_free (MetaScreen *screen,
|
|||||||
meta_display_ungrab (display);
|
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
|
void
|
||||||
meta_screen_manage_all_windows (MetaScreen *screen)
|
meta_screen_manage_all_windows (MetaScreen *screen)
|
||||||
{
|
{
|
||||||
GList *windows;
|
Window *_children;
|
||||||
GList *list;
|
Window *children;
|
||||||
|
int n_children, i;
|
||||||
meta_display_grab (screen->display);
|
|
||||||
|
|
||||||
if (screen->guard_window == None)
|
if (screen->guard_window == None)
|
||||||
screen->guard_window = create_guard_window (screen->display->xdisplay,
|
screen->guard_window = create_guard_window (screen->display->xdisplay,
|
||||||
screen);
|
screen);
|
||||||
|
|
||||||
windows = list_windows (screen);
|
|
||||||
|
|
||||||
meta_stack_freeze (screen->stack);
|
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 (screen->display, children[i], TRUE,
|
||||||
|
META_COMP_EFFECT_NONE);
|
||||||
meta_window_new_with_attrs (screen->display, info->xwindow, TRUE,
|
|
||||||
META_COMP_EFFECT_NONE,
|
|
||||||
&info->attrs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free (children);
|
||||||
meta_stack_thaw (screen->stack);
|
meta_stack_thaw (screen->stack);
|
||||||
|
|
||||||
g_list_foreach (windows, (GFunc)g_free, NULL);
|
|
||||||
g_list_free (windows);
|
|
||||||
|
|
||||||
meta_display_ungrab (screen->display);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1528,7 +1475,7 @@ meta_screen_tab_popup_create (MetaScreen *screen,
|
|||||||
if (show_type == META_TAB_SHOW_INSTANTLY ||
|
if (show_type == META_TAB_SHOW_INSTANTLY ||
|
||||||
!entries[i].hidden ||
|
!entries[i].hidden ||
|
||||||
!meta_window_get_icon_geometry (window, &r))
|
!meta_window_get_icon_geometry (window, &r))
|
||||||
meta_window_get_frame_rect (window, &r);
|
meta_window_get_outer_rect (window, &r);
|
||||||
|
|
||||||
entries[i].rect = r;
|
entries[i].rect = r;
|
||||||
|
|
||||||
@@ -1911,7 +1858,7 @@ meta_screen_get_monitor_for_window (MetaScreen *screen,
|
|||||||
{
|
{
|
||||||
MetaRectangle window_rect;
|
MetaRectangle window_rect;
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, &window_rect);
|
meta_window_get_outer_rect (window, &window_rect);
|
||||||
|
|
||||||
return meta_screen_get_monitor_for_rect (screen, &window_rect);
|
return meta_screen_get_monitor_for_rect (screen, &window_rect);
|
||||||
}
|
}
|
||||||
|
@@ -1465,7 +1465,7 @@ window_contains_point (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
MetaRectangle rect;
|
MetaRectangle rect;
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, &rect);
|
meta_window_get_outer_rect (window, &rect);
|
||||||
|
|
||||||
return POINT_IN_RECT (root_x, root_y, rect);
|
return POINT_IN_RECT (root_x, root_y, rect);
|
||||||
}
|
}
|
||||||
|
@@ -352,12 +352,6 @@ struct _MetaWindow
|
|||||||
/* if non-NULL, the opaque region _NET_WM_OPAQUE_REGION */
|
/* if non-NULL, the opaque region _NET_WM_OPAQUE_REGION */
|
||||||
cairo_region_t *opaque_region;
|
cairo_region_t *opaque_region;
|
||||||
|
|
||||||
/* the input shape region for picking */
|
|
||||||
cairo_region_t *input_region;
|
|
||||||
|
|
||||||
/* _NET_WM_WINDOW_OPACITY */
|
|
||||||
guint opacity;
|
|
||||||
|
|
||||||
/* if TRUE, the we have the new form of sync request counter which
|
/* if TRUE, the we have the new form of sync request counter which
|
||||||
* also handles application frames */
|
* also handles application frames */
|
||||||
guint extended_sync_request_counter : 1;
|
guint extended_sync_request_counter : 1;
|
||||||
@@ -490,12 +484,8 @@ struct _MetaWindowClass
|
|||||||
|
|
||||||
MetaWindow* meta_window_new (MetaDisplay *display,
|
MetaWindow* meta_window_new (MetaDisplay *display,
|
||||||
Window xwindow,
|
Window xwindow,
|
||||||
gboolean must_be_viewable);
|
gboolean must_be_viewable,
|
||||||
MetaWindow* meta_window_new_with_attrs (MetaDisplay *display,
|
MetaCompEffect effect);
|
||||||
Window xwindow,
|
|
||||||
gboolean must_be_viewable,
|
|
||||||
MetaCompEffect effect,
|
|
||||||
XWindowAttributes *attrs);
|
|
||||||
void meta_window_unmanage (MetaWindow *window,
|
void meta_window_unmanage (MetaWindow *window,
|
||||||
guint32 timestamp);
|
guint32 timestamp);
|
||||||
void meta_window_calc_showing (MetaWindow *window);
|
void meta_window_calc_showing (MetaWindow *window);
|
||||||
@@ -518,7 +508,6 @@ void meta_window_update_fullscreen_monitors (MetaWindow *window,
|
|||||||
unsigned long left,
|
unsigned long left,
|
||||||
unsigned long right);
|
unsigned long right);
|
||||||
|
|
||||||
|
|
||||||
/* args to move are window pos, not frame pos */
|
/* args to move are window pos, not frame pos */
|
||||||
void meta_window_move (MetaWindow *window,
|
void meta_window_move (MetaWindow *window,
|
||||||
gboolean user_op,
|
gboolean user_op,
|
||||||
@@ -662,8 +651,6 @@ void meta_window_recalc_features (MetaWindow *window);
|
|||||||
|
|
||||||
void meta_window_recalc_window_type (MetaWindow *window);
|
void meta_window_recalc_window_type (MetaWindow *window);
|
||||||
|
|
||||||
void meta_window_frame_size_changed (MetaWindow *window);
|
|
||||||
|
|
||||||
void meta_window_stack_just_below (MetaWindow *window,
|
void meta_window_stack_just_below (MetaWindow *window,
|
||||||
MetaWindow *below_this_one);
|
MetaWindow *below_this_one);
|
||||||
|
|
||||||
@@ -691,16 +678,8 @@ void meta_window_set_opaque_region (MetaWindow *window,
|
|||||||
cairo_region_t *region);
|
cairo_region_t *region);
|
||||||
void meta_window_update_opaque_region_x11 (MetaWindow *window);
|
void meta_window_update_opaque_region_x11 (MetaWindow *window);
|
||||||
|
|
||||||
void meta_window_set_input_region (MetaWindow *window,
|
|
||||||
cairo_region_t *region);
|
|
||||||
void meta_window_update_input_region_x11 (MetaWindow *window);
|
|
||||||
|
|
||||||
void meta_window_set_shape_region (MetaWindow *window,
|
void meta_window_set_shape_region (MetaWindow *window,
|
||||||
cairo_region_t *region);
|
cairo_region_t *region);
|
||||||
void meta_window_update_shape_region_x11 (MetaWindow *window);
|
void meta_window_update_shape_region_x11 (MetaWindow *window);
|
||||||
void meta_window_set_opacity (MetaWindow *window,
|
|
||||||
guint opacity);
|
|
||||||
|
|
||||||
Window meta_window_get_toplevel_xwindow (MetaWindow *window);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -316,9 +316,6 @@ reload_gtk_frame_extents (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
window->has_custom_frame_extents = FALSE;
|
window->has_custom_frame_extents = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!initial)
|
|
||||||
meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1709,20 +1706,6 @@ reload_bypass_compositor (MetaWindow *window,
|
|||||||
window->bypass_compositor = requested_value;
|
window->bypass_compositor = requested_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
reload_window_opacity (MetaWindow *window,
|
|
||||||
MetaPropValue *value,
|
|
||||||
gboolean initial)
|
|
||||||
|
|
||||||
{
|
|
||||||
int requested_value = 0xFF;
|
|
||||||
|
|
||||||
if (value->type != META_PROP_VALUE_INVALID)
|
|
||||||
requested_value = (int) value->v.cardinal;
|
|
||||||
|
|
||||||
meta_window_set_opacity (window, requested_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define RELOAD_STRING(var_name, propname) \
|
#define RELOAD_STRING(var_name, propname) \
|
||||||
static void \
|
static void \
|
||||||
reload_ ## var_name (MetaWindow *window, \
|
reload_ ## var_name (MetaWindow *window, \
|
||||||
@@ -1825,7 +1808,6 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
|
|||||||
{ display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE },
|
{ display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE },
|
||||||
{ display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE },
|
{ display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE },
|
||||||
{ display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, FALSE, FALSE },
|
{ display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, FALSE, FALSE },
|
||||||
{ display->atom__NET_WM_WINDOW_OPACITY, META_PROP_VALUE_CARDINAL, reload_window_opacity, TRUE, TRUE },
|
|
||||||
{ 0 },
|
{ 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -80,7 +80,7 @@ item(MULTIPLE)
|
|||||||
item(TIMESTAMP)
|
item(TIMESTAMP)
|
||||||
item(VERSION)
|
item(VERSION)
|
||||||
item(ATOM_PAIR)
|
item(ATOM_PAIR)
|
||||||
item(BACKLIGHT)
|
item(Backlight)
|
||||||
item(hotplug_mode_update)
|
item(hotplug_mode_update)
|
||||||
|
|
||||||
/* Oddities: These are used, and we need atoms for them,
|
/* Oddities: These are used, and we need atoms for them,
|
||||||
@@ -179,7 +179,6 @@ item(_NET_WM_BYPASS_COMPOSITOR)
|
|||||||
item(_NET_WM_OPAQUE_REGION)
|
item(_NET_WM_OPAQUE_REGION)
|
||||||
item(_NET_WM_FRAME_DRAWN)
|
item(_NET_WM_FRAME_DRAWN)
|
||||||
item(_NET_WM_FRAME_TIMINGS)
|
item(_NET_WM_FRAME_TIMINGS)
|
||||||
item(_NET_WM_WINDOW_OPACITY)
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* We apparently never use: */
|
/* We apparently never use: */
|
||||||
|
@@ -66,8 +66,6 @@ void meta_compositor_unmanage_screen (MetaCompositor *compositor,
|
|||||||
|
|
||||||
void meta_compositor_window_shape_changed (MetaCompositor *compositor,
|
void meta_compositor_window_shape_changed (MetaCompositor *compositor,
|
||||||
MetaWindow *window);
|
MetaWindow *window);
|
||||||
void meta_compositor_window_opacity_changed (MetaCompositor *compositor,
|
|
||||||
MetaWindow *window);
|
|
||||||
|
|
||||||
gboolean meta_compositor_process_event (MetaCompositor *compositor,
|
gboolean meta_compositor_process_event (MetaCompositor *compositor,
|
||||||
XEvent *event,
|
XEvent *event,
|
||||||
@@ -77,10 +75,11 @@ gboolean meta_compositor_filter_keybinding (MetaCompositor *compositor,
|
|||||||
MetaScreen *screen,
|
MetaScreen *screen,
|
||||||
MetaKeyBinding *binding);
|
MetaKeyBinding *binding);
|
||||||
|
|
||||||
void meta_compositor_add_window (MetaCompositor *compositor,
|
void meta_compositor_add_window (MetaCompositor *compositor,
|
||||||
MetaWindow *window);
|
MetaWindow *window);
|
||||||
void meta_compositor_remove_window (MetaCompositor *compositor,
|
void meta_compositor_remove_window (MetaCompositor *compositor,
|
||||||
MetaWindow *window);
|
MetaWindow *window);
|
||||||
|
|
||||||
void meta_compositor_show_window (MetaCompositor *compositor,
|
void meta_compositor_show_window (MetaCompositor *compositor,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
MetaCompEffect effect);
|
MetaCompEffect effect);
|
||||||
@@ -102,6 +101,10 @@ void meta_compositor_unmaximize_window (MetaCompositor *compositor,
|
|||||||
MetaRectangle *old_rect,
|
MetaRectangle *old_rect,
|
||||||
MetaRectangle *new_rect);
|
MetaRectangle *new_rect);
|
||||||
|
|
||||||
|
void meta_compositor_window_mapped (MetaCompositor *compositor,
|
||||||
|
MetaWindow *window);
|
||||||
|
void meta_compositor_window_unmapped (MetaCompositor *compositor,
|
||||||
|
MetaWindow *window);
|
||||||
void meta_compositor_sync_window_geometry (MetaCompositor *compositor,
|
void meta_compositor_sync_window_geometry (MetaCompositor *compositor,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
gboolean did_placement);
|
gboolean did_placement);
|
||||||
|
@@ -78,6 +78,7 @@ MetaCompositor *meta_display_get_compositor (MetaDisplay *display);
|
|||||||
GSList *meta_display_get_screens (MetaDisplay *display);
|
GSList *meta_display_get_screens (MetaDisplay *display);
|
||||||
|
|
||||||
gboolean meta_display_has_shape (MetaDisplay *display);
|
gboolean meta_display_has_shape (MetaDisplay *display);
|
||||||
|
gboolean meta_display_has_sync (MetaDisplay *display);
|
||||||
|
|
||||||
MetaScreen *meta_display_screen_for_root (MetaDisplay *display,
|
MetaScreen *meta_display_screen_for_root (MetaDisplay *display,
|
||||||
Window xroot);
|
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_damage_event_base (MetaDisplay *display);
|
||||||
int meta_display_get_shape_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,
|
gboolean meta_display_xserver_time_is_before (MetaDisplay *display,
|
||||||
guint32 time1,
|
guint32 time1,
|
||||||
|
@@ -35,6 +35,13 @@ gboolean meta_keybindings_set_custom_handler (const gchar *name,
|
|||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify free_data);
|
GDestroyNotify free_data);
|
||||||
|
|
||||||
|
void meta_keybindings_switch_window (MetaDisplay *display,
|
||||||
|
MetaScreen *screen,
|
||||||
|
MetaWindow *event_window,
|
||||||
|
XIDeviceEvent *event,
|
||||||
|
MetaKeyBinding *binding);
|
||||||
|
|
||||||
|
|
||||||
void meta_screen_ungrab_all_keys (MetaScreen *screen, guint32 timestamp);
|
void meta_screen_ungrab_all_keys (MetaScreen *screen, guint32 timestamp);
|
||||||
gboolean meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp);
|
gboolean meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -83,8 +83,6 @@ CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
|
|||||||
|
|
||||||
void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
|
void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
|
||||||
CoglTexture *mask_texture);
|
CoglTexture *mask_texture);
|
||||||
void meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex,
|
|
||||||
cairo_region_t *shape_region);
|
|
||||||
|
|
||||||
void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
|
void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
|
||||||
cairo_region_t *clip_region);
|
cairo_region_t *clip_region);
|
||||||
|
@@ -258,7 +258,6 @@ void meta_prefs_set_ignore_request_hide_titlebar (gboolean whether);
|
|||||||
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_W: FILLME
|
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_W: FILLME
|
||||||
* @META_KEYBINDING_ACTION_MOVE_TO_CENTER: FILLME
|
* @META_KEYBINDING_ACTION_MOVE_TO_CENTER: FILLME
|
||||||
* @META_KEYBINDING_ACTION_OVERLAY_KEY: FILLME
|
* @META_KEYBINDING_ACTION_OVERLAY_KEY: FILLME
|
||||||
* @META_KEYBINDING_ACTION_ALWAYS_ON_TOP: FILLME
|
|
||||||
* @META_KEYBINDING_ACTION_LAST: FILLME
|
* @META_KEYBINDING_ACTION_LAST: FILLME
|
||||||
*/
|
*/
|
||||||
/* XXX FIXME This should be x-macroed, but isn't yet because it would be
|
/* XXX FIXME This should be x-macroed, but isn't yet because it would be
|
||||||
@@ -352,7 +351,6 @@ typedef enum _MetaKeyBindingAction
|
|||||||
META_KEYBINDING_ACTION_MOVE_TO_CENTER,
|
META_KEYBINDING_ACTION_MOVE_TO_CENTER,
|
||||||
META_KEYBINDING_ACTION_OVERLAY_KEY,
|
META_KEYBINDING_ACTION_OVERLAY_KEY,
|
||||||
META_KEYBINDING_ACTION_ISO_NEXT_GROUP,
|
META_KEYBINDING_ACTION_ISO_NEXT_GROUP,
|
||||||
META_KEYBINDING_ACTION_ALWAYS_ON_TOP,
|
|
||||||
|
|
||||||
META_KEYBINDING_ACTION_LAST
|
META_KEYBINDING_ACTION_LAST
|
||||||
} MetaKeyBindingAction;
|
} MetaKeyBindingAction;
|
||||||
|
@@ -100,17 +100,7 @@ gboolean meta_window_is_override_redirect (MetaWindow *window);
|
|||||||
gboolean meta_window_is_skip_taskbar (MetaWindow *window);
|
gboolean meta_window_is_skip_taskbar (MetaWindow *window);
|
||||||
MetaRectangle *meta_window_get_rect (MetaWindow *window);
|
MetaRectangle *meta_window_get_rect (MetaWindow *window);
|
||||||
void meta_window_get_input_rect (const MetaWindow *window, MetaRectangle *rect);
|
void meta_window_get_input_rect (const MetaWindow *window, MetaRectangle *rect);
|
||||||
|
void meta_window_get_outer_rect (const MetaWindow *window, MetaRectangle *rect);
|
||||||
void meta_window_get_frame_rect (const MetaWindow *window, MetaRectangle *rect);
|
|
||||||
void meta_window_get_outer_rect (const MetaWindow *window, MetaRectangle *rect) G_GNUC_DEPRECATED;
|
|
||||||
|
|
||||||
void meta_window_client_rect_to_frame_rect (MetaWindow *window,
|
|
||||||
MetaRectangle *client_rect,
|
|
||||||
MetaRectangle *frame_rect);
|
|
||||||
void meta_window_frame_rect_to_client_rect (MetaWindow *window,
|
|
||||||
MetaRectangle *frame_rect,
|
|
||||||
MetaRectangle *client_rect);
|
|
||||||
|
|
||||||
MetaScreen *meta_window_get_screen (MetaWindow *window);
|
MetaScreen *meta_window_get_screen (MetaWindow *window);
|
||||||
MetaDisplay *meta_window_get_display (MetaWindow *window);
|
MetaDisplay *meta_window_get_display (MetaWindow *window);
|
||||||
Window meta_window_get_xwindow (MetaWindow *window);
|
Window meta_window_get_xwindow (MetaWindow *window);
|
||||||
@@ -150,7 +140,8 @@ void meta_window_unset_demands_attention (MetaWindow *window);
|
|||||||
const char* meta_window_get_startup_id (MetaWindow *window);
|
const char* meta_window_get_startup_id (MetaWindow *window);
|
||||||
void meta_window_change_workspace_by_index (MetaWindow *window,
|
void meta_window_change_workspace_by_index (MetaWindow *window,
|
||||||
gint space_index,
|
gint space_index,
|
||||||
gboolean append);
|
gboolean append,
|
||||||
|
guint32 timestamp);
|
||||||
void meta_window_change_workspace (MetaWindow *window,
|
void meta_window_change_workspace (MetaWindow *window,
|
||||||
MetaWorkspace *workspace);
|
MetaWorkspace *workspace);
|
||||||
GObject *meta_window_get_compositor_private (MetaWindow *window);
|
GObject *meta_window_get_compositor_private (MetaWindow *window);
|
||||||
|
Reference in New Issue
Block a user