Compare commits
220 Commits
3.10.1-way
...
3.11.4-way
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1d61a0f9b5 | ||
![]() |
788bd59857 | ||
![]() |
2391606cc5 | ||
![]() |
7155d7e043 | ||
![]() |
419dfd333a | ||
![]() |
b4535f2622 | ||
![]() |
9b21346427 | ||
![]() |
7b15d21e40 | ||
![]() |
7b597b8c62 | ||
![]() |
7a4adce44f | ||
![]() |
a5f0db5ecb | ||
![]() |
577624adef | ||
![]() |
af46ef3b96 | ||
![]() |
39d26be941 | ||
![]() |
7bfc9109f7 | ||
![]() |
becbad56ef | ||
![]() |
384a34c27d | ||
![]() |
002c5b8f87 | ||
![]() |
1d3dbea20c | ||
![]() |
ebe6e3180e | ||
![]() |
a3de799939 | ||
![]() |
0caf7381bb | ||
![]() |
a42305edab | ||
![]() |
732c059235 | ||
![]() |
ef2b6e7d00 | ||
![]() |
9c1b972ca1 | ||
![]() |
cb33e1942a | ||
![]() |
7009d1e470 | ||
![]() |
c54a19825b | ||
![]() |
8131f34eb6 | ||
![]() |
f29241d90e | ||
![]() |
bad48ea815 | ||
![]() |
66af41f4a9 | ||
![]() |
e30be380dd | ||
![]() |
65f2e29375 | ||
![]() |
98dbba1e17 | ||
![]() |
422648e2eb | ||
![]() |
f0fa4d831a | ||
![]() |
1b600f5867 | ||
![]() |
fd8cc9b7a8 | ||
![]() |
ca5b5e6bc4 | ||
![]() |
ee683ff187 | ||
![]() |
57602adfe7 | ||
![]() |
1481836ed6 | ||
![]() |
309f78ff52 | ||
![]() |
6436459381 | ||
![]() |
65b39212d5 | ||
![]() |
283649b8d7 | ||
![]() |
fa65c380db | ||
![]() |
58b39233f5 | ||
![]() |
82066e02c5 | ||
![]() |
c36aa5e696 | ||
![]() |
29197d40c6 | ||
![]() |
8d5ab6b5b3 | ||
![]() |
a796938b39 | ||
![]() |
3813113f1a | ||
![]() |
1be117e430 | ||
![]() |
622c7a021b | ||
![]() |
4d2d2f285b | ||
![]() |
0924c7d61b | ||
![]() |
2746608eb2 | ||
![]() |
fe26cb5989 | ||
![]() |
602307e694 | ||
![]() |
b2c18c4a78 | ||
![]() |
1e211722c7 | ||
![]() |
461f74ef18 | ||
![]() |
3f022ca963 | ||
![]() |
20e92c5a72 | ||
![]() |
0850da44d7 | ||
![]() |
37ba264190 | ||
![]() |
6c12c928df | ||
![]() |
9c5733caf0 | ||
![]() |
21d8b8310a | ||
![]() |
c46af91d54 | ||
![]() |
d44574f738 | ||
![]() |
a9424255a5 | ||
![]() |
5089a63d76 | ||
![]() |
f9a2c64460 | ||
![]() |
7841042a85 | ||
![]() |
ea1b8cdc22 | ||
![]() |
52b48cfbef | ||
![]() |
644f3e1275 | ||
![]() |
304005e04f | ||
![]() |
025ab35af7 | ||
![]() |
a27744503b | ||
![]() |
1011331caf | ||
![]() |
0ccef81789 | ||
![]() |
4780f74a40 | ||
![]() |
57866fb267 | ||
![]() |
d3bc7570d0 | ||
![]() |
74e43a4702 | ||
![]() |
0764b2058a | ||
![]() |
7a787d7946 | ||
![]() |
eec0f5df47 | ||
![]() |
ba3968a822 | ||
![]() |
762fa0e116 | ||
![]() |
0be57b621b | ||
![]() |
7d88b3593b | ||
![]() |
858db7081a | ||
![]() |
5af7f619c8 | ||
![]() |
e5e35e5a7f | ||
![]() |
6d639ac528 | ||
![]() |
aa3643cdde | ||
![]() |
8a3501ffe1 | ||
![]() |
5ea443eb4b | ||
![]() |
a37a8c6497 | ||
![]() |
ebf6862a10 | ||
![]() |
6c0e16c482 | ||
![]() |
40b1e7312d | ||
![]() |
1c0e6f26e2 | ||
![]() |
f4fc498e65 | ||
![]() |
a8632c2546 | ||
![]() |
600a0f836f | ||
![]() |
0ac142d39e | ||
![]() |
abd368be00 | ||
![]() |
a8ac2cc275 | ||
![]() |
2f14b5cc3f | ||
![]() |
2930612e64 | ||
![]() |
2952d3671d | ||
![]() |
1b5ace8256 | ||
![]() |
2ebecc5370 | ||
![]() |
02144d17e9 | ||
![]() |
71496c8909 | ||
![]() |
594b15abf1 | ||
![]() |
bbe3641844 | ||
![]() |
0cc5cf940b | ||
![]() |
153d8efcf5 | ||
![]() |
be744775c1 | ||
![]() |
5959457c73 | ||
![]() |
0824eb7c96 | ||
![]() |
d945501be6 | ||
![]() |
ca342c4573 | ||
![]() |
4326d0bf3a | ||
![]() |
a6ebc70170 | ||
![]() |
3025cb7c48 | ||
![]() |
17f48baf3a | ||
![]() |
333661a9d8 | ||
![]() |
b9da43b753 | ||
![]() |
097ee776c7 | ||
![]() |
a4a8f1f863 | ||
![]() |
f36a627330 | ||
![]() |
a1087c3f30 | ||
![]() |
aad275b9a2 | ||
![]() |
f0397eab94 | ||
![]() |
392e224831 | ||
![]() |
6867d44573 | ||
![]() |
a841fff2ac | ||
![]() |
26aa10a974 | ||
![]() |
f6144082b1 | ||
![]() |
957513242c | ||
![]() |
17fd25e216 | ||
![]() |
e91268a250 | ||
![]() |
82cb4e8267 | ||
![]() |
68eb87cc58 | ||
![]() |
f3e52d5b18 | ||
![]() |
2b2b2d3191 | ||
![]() |
9461c612de | ||
![]() |
f0280a8868 | ||
![]() |
c749f7b6fb | ||
![]() |
74462133ca | ||
![]() |
7c45d6594c | ||
![]() |
ea916b6c49 | ||
![]() |
a02d734243 | ||
![]() |
735b736110 | ||
![]() |
bbbb9ac53c | ||
![]() |
8dd97b4998 | ||
![]() |
73a9082062 | ||
![]() |
4091f5493d | ||
![]() |
d96b053c9d | ||
![]() |
1f569bef76 | ||
![]() |
1a88176cc0 | ||
![]() |
662c9729bc | ||
![]() |
56a0dd6b2c | ||
![]() |
9dc6028b3d | ||
![]() |
932e913d88 | ||
![]() |
b72315e27a | ||
![]() |
3c7cd1f38c | ||
![]() |
1946c548bf | ||
![]() |
cf181fe109 | ||
![]() |
63b9110f93 | ||
![]() |
ae44bff0b1 | ||
![]() |
23ba3e527f | ||
![]() |
08df9bf559 | ||
![]() |
648639fffe | ||
![]() |
6cc014a941 | ||
![]() |
b7b95123ed | ||
![]() |
153463790a | ||
![]() |
875bbec949 | ||
![]() |
666e5f1f98 | ||
![]() |
e6790038dd | ||
![]() |
e86c53230f | ||
![]() |
4ea4658abf | ||
![]() |
58f6ab0a27 | ||
![]() |
9c0cc664d1 | ||
![]() |
84d26e31f1 | ||
![]() |
64a848fcb7 | ||
![]() |
429583ae8b | ||
![]() |
93ae868987 | ||
![]() |
72a900787f | ||
![]() |
7186841db0 | ||
![]() |
ab080e3e6b | ||
![]() |
ad84aef766 | ||
![]() |
7908eca579 | ||
![]() |
237d990dea | ||
![]() |
78fcfec5c1 | ||
![]() |
1bd3a162f8 | ||
![]() |
918cfdcbda | ||
![]() |
cd76313297 | ||
![]() |
dc8231c2cf | ||
![]() |
4d01eb3a23 | ||
![]() |
35f47b211d | ||
![]() |
77046edf21 | ||
![]() |
488df061c7 | ||
![]() |
21d511e50f | ||
![]() |
15e83f0c2f | ||
![]() |
a23830fd13 | ||
![]() |
c8bf8c17be | ||
![]() |
d82e24981b | ||
![]() |
01b8ffac5d | ||
![]() |
1fa56bd7e0 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -81,6 +81,9 @@ src/mutter-plugins.pc
|
||||
src/wayland/gtk-shell-protocol.c
|
||||
src/wayland/gtk-shell-client-protocol.h
|
||||
src/wayland/gtk-shell-server-protocol.h
|
||||
src/wayland/xdg-shell-protocol.c
|
||||
src/wayland/xdg-shell-client-protocol.h
|
||||
src/wayland/xdg-shell-server-protocol.h
|
||||
src/wayland/xserver-protocol.c
|
||||
src/wayland/xserver-client-protocol.h
|
||||
src/wayland/xserver-server-protocol.h
|
||||
|
41
COPYING
41
COPYING
@@ -1,12 +1,12 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
@@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
@@ -225,7 +225,7 @@ impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
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
|
||||
|
||||
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.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
@@ -6,3 +6,5 @@ EXTRA_DIST = HACKING MAINTAINERS rationales.txt
|
||||
DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache
|
||||
|
||||
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||
|
57
NEWS
57
NEWS
@@ -1,3 +1,60 @@
|
||||
3.11.4
|
||||
======
|
||||
* Don't leave focus on windows that are being unmanaged [Owen; #711618]
|
||||
* Reduce server grabs [Daniel Drake; #721345, #721709]
|
||||
* Improve heuristic to determine display output name [Cosimo Cecchi; #721674]
|
||||
* Atomically unmaximize both directions [Jasper; #722108]
|
||||
* Misc bug fixes [Debarshi, Andika, Florian; #721517, #721674, #722347]
|
||||
|
||||
Contributors:
|
||||
Cosimo Cecchi, Daniel Drake, Florian Müllner, Debarshi Ray, Jasper St. Pierre,
|
||||
Andika Triwidada, Owen W. Taylor
|
||||
|
||||
3.11.3
|
||||
======
|
||||
* Fix focus issues with external OSKs[Jasper; #715030]
|
||||
* Add a MetaCullable interface [Jasper; #714706]
|
||||
* Fix window keybindings [Rui; #719724]
|
||||
* Fix settings keyboard/pointer focus for new clients [Rui; #719725]
|
||||
* Fix window group paint volume [Owen; #719669]
|
||||
* Fix frame extents problems [Owen; #714707]
|
||||
* Add shortcut to move windows between monitors [Florian; #671054]
|
||||
* Fix problems with focus tracking [Owen; #720558]
|
||||
* Misc. bug fixes and cleanups: [Rui, Colin, Lionel, Jasper, Owen; #712833,
|
||||
#719557, #719695, #719833, #678989, #720417, #720630]
|
||||
|
||||
Contributors:
|
||||
Lionel Landwerlin, Rui Matos, Alberto Milone, Florian Müllner,
|
||||
Jasper St. Pierre, Rico Tzschichholz, Owen W. Taylor, Colin Walters
|
||||
|
||||
3.11.2
|
||||
======
|
||||
* Support setting a NULL opaque region [Andreas; #711518]
|
||||
* Sync keymap from X to wayland [Giovanni; #707446]
|
||||
* Implement support for subsurfaces [Jonas; #705502]
|
||||
* Don't focus the no-focus-window for globally active windows [Jasper; #710296]
|
||||
* Support "hotplug_mode_update" property [Marc-André; #711216]
|
||||
* Fix resize operations using mouse-button-modifier [Lionel; #710251]
|
||||
* Fix position of attached modals for CSD windows [Giovanni, Owen; #707194]
|
||||
* Misc. bug fixes [Rui, Jasper, Neil, Florian; #712247, #711731]
|
||||
|
||||
Contributors:
|
||||
Giovanni Campagna, Andreas Heider, Lionel Landwerlin, Marc-André Lureau,
|
||||
Rui Matos, Florian Müllner, Neil Roberts, Sindhu S, Jasper St. Pierre,
|
||||
Rico Tzschichholz, Owen W. Taylor, Jonas Ådahl
|
||||
|
||||
3.11.1
|
||||
======
|
||||
* Fix tile previews getting stuck on right click during drags [Lionel; #704759]
|
||||
* Use new UPower API [Bastien]
|
||||
* Set hot spot when cursor set from wl_buffer [Jonas; #709593]
|
||||
* Expose min-backlight-step [Asad; #710380]
|
||||
* Misc. bug fixes and cleanups [Jasper, Olav, Magdalen; #709776]
|
||||
|
||||
Contributors:
|
||||
Magdalen Berns, Lionel Landwerlin, Asad Mehmood, Bastien Nocera,
|
||||
Jasper St. Pierre, Olav Vitters, Jonas Ådahl
|
||||
|
||||
3.10.1
|
||||
======
|
||||
* Don't apply fullscreen workarounds to CSD windows [Giovanni; #708718]
|
||||
|
11
configure.ac
11
configure.ac
@@ -1,8 +1,9 @@
|
||||
AC_PREREQ(2.50)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [10])
|
||||
m4_define([mutter_micro_version], [1])
|
||||
m4_define([mutter_minor_version], [11])
|
||||
m4_define([mutter_micro_version], [4])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
@@ -77,9 +78,9 @@ MUTTER_PC_MODULES="
|
||||
cairo >= 1.10.0
|
||||
gsettings-desktop-schemas >= 3.7.3
|
||||
xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0
|
||||
$CLUTTER_PACKAGE >= 1.15.94
|
||||
cogl-1.0 >= 1.13.3
|
||||
upower-glib > 0.9.11
|
||||
$CLUTTER_PACKAGE >= 1.17.1
|
||||
cogl-1.0 >= 1.17.1
|
||||
upower-glib >= 0.99.0
|
||||
gnome-desktop-3.0
|
||||
"
|
||||
|
||||
|
@@ -49,8 +49,8 @@ FIXXREF_OPTIONS=
|
||||
# Used for dependencies. The docs will be rebuilt if any of these change.
|
||||
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
|
||||
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
|
||||
HFILE_GLOB=$(top_srcdir)/src/*.h
|
||||
CFILE_GLOB=$(top_srcdir)/src/*.c
|
||||
HFILE_GLOB=$(top_srcdir)/src/*/*.h
|
||||
CFILE_GLOB=$(top_srcdir)/src/*/*.c
|
||||
|
||||
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
|
||||
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
|
||||
|
@@ -207,7 +207,6 @@ meta_key_binding_get_modifiers
|
||||
meta_key_binding_get_mask
|
||||
meta_key_binding_is_builtin
|
||||
meta_keybindings_set_custom_handler
|
||||
meta_keybindings_switch_window
|
||||
meta_screen_ungrab_all_keys
|
||||
meta_screen_grab_all_keys
|
||||
</SECTION>
|
||||
@@ -389,6 +388,23 @@ MetaWindowActorPrivate
|
||||
meta_window_actor_get_type
|
||||
</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>
|
||||
<FILE>prefs</FILE>
|
||||
MetaPreference
|
||||
@@ -542,7 +558,10 @@ meta_window_is_override_redirect
|
||||
meta_window_is_skip_taskbar
|
||||
meta_window_get_rect
|
||||
meta_window_get_input_rect
|
||||
meta_window_get_frame_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_display
|
||||
meta_window_get_xwindow
|
||||
|
@@ -21,6 +21,7 @@ environment.</description>
|
||||
-->
|
||||
<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-wayland/" />
|
||||
<bug-database rdf:resource="http://bugzilla.gnome.org/browse.cgi?product=mutter" />
|
||||
|
||||
<category rdf:resource="http://api.gnome.org/doap-extensions#desktop" />
|
||||
|
@@ -1 +1,7 @@
|
||||
EXTRA_DIST = xserver.xml
|
||||
NULL =
|
||||
|
||||
EXTRA_DIST = \
|
||||
gtk-shell.xml \
|
||||
xdg-shell.xml \
|
||||
xserver.xml \
|
||||
$(NULL)
|
||||
|
438
protocol/xdg-shell.xml
Normal file
438
protocol/xdg-shell.xml
Normal file
@@ -0,0 +1,438 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="xdg_shell">
|
||||
|
||||
<copyright>
|
||||
Copyright © 2008-2013 Kristian Høgsberg
|
||||
Copyright © 2013 Rafael Antognolli
|
||||
Copyright © 2013 Jasper St. Pierre
|
||||
Copyright © 2010-2013 Intel 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
|
||||
the copyright holders not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific,
|
||||
written prior permission. The copyright holders make no
|
||||
representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied
|
||||
warranty.
|
||||
|
||||
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
|
||||
</copyright>
|
||||
|
||||
<interface name="xdg_shell" version="1">
|
||||
<description summary="create desktop-style surfaces">
|
||||
This interface is implemented by servers that provide
|
||||
desktop-style user interfaces.
|
||||
|
||||
It allows clients to associate a xdg_surface with
|
||||
a basic surface.
|
||||
</description>
|
||||
|
||||
<enum name="version">
|
||||
<description summary="latest protocol version">
|
||||
Use this enum to check the protocol version, and it will be updated
|
||||
automatically.
|
||||
</description>
|
||||
<entry name="current" value="1" summary="Always the latest version"/>
|
||||
</enum>
|
||||
|
||||
|
||||
<request name="use_unstable_version">
|
||||
<description summary="enable use of this unstable version">
|
||||
Use this request in order to enable use of this interface.
|
||||
|
||||
Understand and agree that one is using an unstable interface,
|
||||
that will likely change in the future, breaking the API.
|
||||
</description>
|
||||
<arg name="version" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="get_xdg_surface">
|
||||
<description summary="create a shell surface from a surface">
|
||||
Create a shell surface for an existing surface.
|
||||
|
||||
Only one shell or popup surface can be associated with a given
|
||||
surface.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="xdg_surface"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"/>
|
||||
</request>
|
||||
|
||||
<request name="get_xdg_popup">
|
||||
<description summary="create a shell surface from a surface">
|
||||
Create a popup surface for an existing surface.
|
||||
|
||||
Only one shell or popup surface can be associated with a given
|
||||
surface.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="xdg_popup"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"/>
|
||||
<arg name="parent" type="object" interface="wl_surface"/>
|
||||
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
|
||||
<arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
|
||||
<arg name="x" type="int"/>
|
||||
<arg name="y" type="int"/>
|
||||
<arg name="flags" type="uint"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_surface" version="1">
|
||||
|
||||
<description summary="desktop-style metadata interface">
|
||||
An interface that may be implemented by a wl_surface, for
|
||||
implementations that provide a desktop-style user interface.
|
||||
|
||||
It provides requests to treat surfaces like windows, allowing to set
|
||||
properties like maximized, fullscreen, minimized, and to move and resize
|
||||
them, and associate metadata like title and app id.
|
||||
|
||||
On the server side the object is automatically destroyed when
|
||||
the related wl_surface is destroyed. On client side,
|
||||
xdg_surface.destroy() must be called before destroying
|
||||
the wl_surface object.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="remove xdg_surface interface">
|
||||
The xdg_surface interface is removed from the wl_surface object
|
||||
that was turned into a xdg_surface with
|
||||
xdg_shell.get_xdg_surface request. The xdg_surface properties,
|
||||
like maximized and fullscreen, are lost. The wl_surface loses
|
||||
its role as a xdg_surface. The wl_surface is unmapped.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="set_transient_for">
|
||||
<description summary="surface is a child of another surface">
|
||||
Setting a surface as transient of another means that it is child
|
||||
of another surface.
|
||||
|
||||
Child surfaces are stacked above their parents, and will be
|
||||
unmapped if the parent is unmapped too. They should not appear
|
||||
on task bars and alt+tab.
|
||||
</description>
|
||||
<arg name="parent" type="object" interface="wl_surface" allow-null="true"/>
|
||||
</request>
|
||||
|
||||
<request name="set_title">
|
||||
<description summary="set surface title">
|
||||
Set a short title for the surface.
|
||||
|
||||
This string may be used to identify the surface in a task bar,
|
||||
window list, or other user interface elements provided by the
|
||||
compositor.
|
||||
|
||||
The string must be encoded in UTF-8.
|
||||
</description>
|
||||
<arg name="title" type="string"/>
|
||||
</request>
|
||||
|
||||
<request name="set_app_id">
|
||||
<description summary="set surface class">
|
||||
Set an id for the surface.
|
||||
|
||||
The app id identifies the general class of applications to which
|
||||
the surface belongs.
|
||||
|
||||
It should be the ID that appears in the new desktop entry
|
||||
specification, the interface name.
|
||||
</description>
|
||||
<arg name="app_id" type="string"/>
|
||||
</request>
|
||||
|
||||
<request name="pong">
|
||||
<description summary="respond to a ping event">
|
||||
A client must respond to a ping event with a pong request or
|
||||
the client may be deemed unresponsive.
|
||||
</description>
|
||||
<arg name="serial" type="uint" summary="serial of the ping event"/>
|
||||
</request>
|
||||
|
||||
<event name="ping">
|
||||
<description summary="ping client">
|
||||
Ping a client to check if it is receiving events and sending
|
||||
requests. A client is expected to reply with a pong request.
|
||||
</description>
|
||||
<arg name="serial" type="uint"/>
|
||||
</event>
|
||||
|
||||
<request name="move">
|
||||
<description summary="start an interactive move">
|
||||
Start a pointer-driven move of the surface.
|
||||
|
||||
This request must be used in response to a button press event.
|
||||
The server may ignore move requests depending on the state of
|
||||
the surface (e.g. fullscreen or maximized).
|
||||
</description>
|
||||
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
|
||||
<arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
|
||||
</request>
|
||||
|
||||
<enum name="resize_edge">
|
||||
<description summary="edge values for resizing">
|
||||
These values are used to indicate which edge of a surface
|
||||
is being dragged in a resize operation. The server may
|
||||
use this information to adapt its behavior, e.g. choose
|
||||
an appropriate cursor image.
|
||||
</description>
|
||||
<entry name="none" value="0"/>
|
||||
<entry name="top" value="1"/>
|
||||
<entry name="bottom" value="2"/>
|
||||
<entry name="left" value="4"/>
|
||||
<entry name="top_left" value="5"/>
|
||||
<entry name="bottom_left" value="6"/>
|
||||
<entry name="right" value="8"/>
|
||||
<entry name="top_right" value="9"/>
|
||||
<entry name="bottom_right" value="10"/>
|
||||
</enum>
|
||||
|
||||
<request name="resize">
|
||||
<description summary="start an interactive resize">
|
||||
Start a pointer-driven resizing of the surface.
|
||||
|
||||
This request must be used in response to a button press event.
|
||||
The server may ignore resize requests depending on the state of
|
||||
the surface (e.g. fullscreen or maximized).
|
||||
</description>
|
||||
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
|
||||
<arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
|
||||
<arg name="edges" type="uint" summary="which edge or corner is being dragged"/>
|
||||
</request>
|
||||
|
||||
<event name="configure">
|
||||
<description summary="suggest resize">
|
||||
The configure event asks the client to resize its surface.
|
||||
|
||||
The size is a hint, in the sense that the client is free to
|
||||
ignore it if it doesn't resize, pick a smaller size (to
|
||||
satisfy aspect ratio or resize in steps of NxM pixels).
|
||||
|
||||
The edges parameter provides a hint about how the surface
|
||||
was resized. The client may use this information to decide
|
||||
how to adjust its content to the new size (e.g. a scrolling
|
||||
area might adjust its content position to leave the viewable
|
||||
content unmoved). Valid edge values are from resize_edge enum.
|
||||
|
||||
The client is free to dismiss all but the last configure
|
||||
event it received.
|
||||
|
||||
The width and height arguments specify the size of the window
|
||||
in surface local coordinates.
|
||||
</description>
|
||||
|
||||
<arg name="edges" type="uint"/>
|
||||
<arg name="width" type="int"/>
|
||||
<arg name="height" type="int"/>
|
||||
</event>
|
||||
|
||||
<request name="set_output">
|
||||
<description summary="set the default output used by this surface">
|
||||
Set the default output used by this surface when it is first mapped.
|
||||
|
||||
If this value is NULL (default), it's up to the compositor to choose
|
||||
which display will be used to map this surface.
|
||||
|
||||
When fullscreen or maximized state are set on this surface, and it
|
||||
wasn't mapped yet, the output set with this method will be used.
|
||||
Otherwise, the output where the surface is currently mapped will be
|
||||
used.
|
||||
</description>
|
||||
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
|
||||
</request>
|
||||
|
||||
<event name="request_set_fullscreen">
|
||||
<description summary="server requests that the client set fullscreen">
|
||||
Event sent from the compositor to the client requesting that the client
|
||||
goes to a fullscreen state. It's the client job to call set_fullscreen
|
||||
and really trigger the fullscreen state.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<event name="request_unset_fullscreen">
|
||||
<description summary="server requests that the client unset fullscreen">
|
||||
Event sent from the compositor to the client requesting that the client
|
||||
leaves the fullscreen state. It's the client job to call
|
||||
unset_fullscreen and really leave the fullscreen state.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<request name="set_fullscreen">
|
||||
<description summary="set the surface state as fullscreen">
|
||||
Set the surface as fullscreen.
|
||||
|
||||
After this request, the compositor should send a configure event
|
||||
informing the output size.
|
||||
|
||||
This request informs the compositor that the next attached buffer
|
||||
committed will be in a fullscreen state. The buffer size should be the
|
||||
same size as the size informed in the configure event, if the client
|
||||
doesn't want to leave any empty area.
|
||||
|
||||
In other words: the next attached buffer after set_maximized is the new
|
||||
maximized buffer. And the surface will be positioned at the maximized
|
||||
position on commit.
|
||||
|
||||
A simple way to synchronize and wait for the correct configure event is
|
||||
to use a wl_display.sync request right after the set_fullscreen
|
||||
request. When the sync callback returns, the last configure event
|
||||
received just before it will be the correct one, and should contain the
|
||||
right size for the surface to maximize.
|
||||
|
||||
Setting one state won't unset another state. Use
|
||||
xdg_surface.unset_fullscreen for unsetting it.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="unset_fullscreen">
|
||||
<description summary="unset the surface state as fullscreen">
|
||||
Unset the surface fullscreen state.
|
||||
|
||||
Same negotiation as set_fullscreen must be used.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="request_set_maximized">
|
||||
<description summary="server requests that the client set maximized">
|
||||
Event sent from the compositor to the client requesting that the client
|
||||
goes to a maximized state. It's the client job to call set_maximized
|
||||
and really trigger the maximized state.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<event name="request_unset_maximized">
|
||||
<description summary="server requests that the client unset maximized">
|
||||
Event sent from the compositor to the client requesting that the client
|
||||
leaves the maximized state. It's the client job to call unset_maximized
|
||||
and really leave the maximized state.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<request name="set_maximized">
|
||||
<description summary="set the surface state as maximized">
|
||||
Set the surface as maximized.
|
||||
|
||||
After this request, the compositor will send a configure event
|
||||
informing the output size minus panel and other MW decorations.
|
||||
|
||||
This request informs the compositor that the next attached buffer
|
||||
committed will be in a maximized state. The buffer size should be the
|
||||
same size as the size informed in the configure event, if the client
|
||||
doesn't want to leave any empty area.
|
||||
|
||||
In other words: the next attached buffer after set_maximized is the new
|
||||
maximized buffer. And the surface will be positioned at the maximized
|
||||
position on commit.
|
||||
|
||||
A simple way to synchronize and wait for the correct configure event is
|
||||
to use a wl_display.sync request right after the set_maximized request.
|
||||
When the sync callback returns, the last configure event received just
|
||||
before it will be the correct one, and should contain the right size
|
||||
for the surface to maximize.
|
||||
|
||||
Setting one state won't unset another state. Use
|
||||
xdg_surface.unset_maximized for unsetting it.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="unset_maximized">
|
||||
<description summary="unset the surface state as maximized">
|
||||
Unset the surface maximized state.
|
||||
|
||||
Same negotiation as set_maximized must be used.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="set_minimized">
|
||||
<description summary="set the surface state as minimized">
|
||||
Set the surface minimized state.
|
||||
|
||||
Setting one state won't unset another state.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="focused_set">
|
||||
<description summary="surface was focused">
|
||||
The focused_set event is sent when this surface has been
|
||||
activated. Window decorations should be updated accordingly.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<event name="focused_unset">
|
||||
<description summary="surface was unfocused">
|
||||
The focused_unset event is sent when this surface has been
|
||||
deactivated, because another surface has been activated. Window
|
||||
decorations should be updated accordingly.
|
||||
</description>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="xdg_popup" version="1">
|
||||
<description summary="desktop-style metadata interface">
|
||||
An interface that may be implemented by a wl_surface, for
|
||||
implementations that provide a desktop-style popups/menus. A popup
|
||||
surface is a transient surface with an added pointer grab.
|
||||
|
||||
An existing implicit grab will be changed to owner-events mode,
|
||||
and the popup grab will continue after the implicit grab ends
|
||||
(i.e. releasing the mouse button does not cause the popup to be
|
||||
unmapped).
|
||||
|
||||
The popup grab continues until the window is destroyed or a mouse
|
||||
button is pressed in any other clients window. A click in any of
|
||||
the clients surfaces is reported as normal, however, clicks in
|
||||
other clients surfaces will be discarded and trigger the callback.
|
||||
|
||||
The x and y arguments specify the locations of the upper left
|
||||
corner of the surface relative to the upper left corner of the
|
||||
parent surface, in surface local coordinates.
|
||||
|
||||
xdg_popup surfaces are always transient for another surface.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="remove xdg_surface interface">
|
||||
The xdg_surface interface is removed from the wl_surface object
|
||||
that was turned into a xdg_surface with
|
||||
xdg_shell.get_xdg_surface request. The xdg_surface properties,
|
||||
like maximized and fullscreen, are lost. The wl_surface loses
|
||||
its role as a xdg_surface. The wl_surface is unmapped.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="pong">
|
||||
<description summary="respond to a ping event">
|
||||
A client must respond to a ping event with a pong request or
|
||||
the client may be deemed unresponsive.
|
||||
</description>
|
||||
<arg name="serial" type="uint" summary="serial of the ping event"/>
|
||||
</request>
|
||||
|
||||
<event name="ping">
|
||||
<description summary="ping client">
|
||||
Ping a client to check if it is receiving events and sending
|
||||
requests. A client is expected to reply with a pong request.
|
||||
</description>
|
||||
<arg name="serial" type="uint"/>
|
||||
</event>
|
||||
|
||||
<event name="popup_done">
|
||||
<description summary="popup interaction is done">
|
||||
The popup_done event is sent out when a popup grab is broken,
|
||||
that is, when the users clicks a surface that doesn't belong
|
||||
to the client owning the popup surface.
|
||||
</description>
|
||||
<arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
|
||||
</event>
|
||||
|
||||
</interface>
|
||||
</protocol>
|
@@ -43,6 +43,9 @@ mutter_built_sources = \
|
||||
wayland/gtk-shell-protocol.c \
|
||||
wayland/gtk-shell-server-protocol.h \
|
||||
wayland/gtk-shell-client-protocol.h \
|
||||
wayland/xdg-shell-protocol.c \
|
||||
wayland/xdg-shell-server-protocol.h \
|
||||
wayland/xdg-shell-client-protocol.h \
|
||||
wayland/xserver-protocol.c \
|
||||
wayland/xserver-server-protocol.h \
|
||||
wayland/xserver-client-protocol.h
|
||||
@@ -67,7 +70,8 @@ libmutter_wayland_la_SOURCES = \
|
||||
compositor/meta-background-actor.c \
|
||||
compositor/meta-background-actor-private.h \
|
||||
compositor/meta-background-group.c \
|
||||
compositor/meta-background-group-private.h \
|
||||
compositor/meta-cullable.c \
|
||||
compositor/meta-cullable.h \
|
||||
compositor/meta-module.c \
|
||||
compositor/meta-module.h \
|
||||
compositor/meta-plugin.c \
|
||||
@@ -77,6 +81,8 @@ libmutter_wayland_la_SOURCES = \
|
||||
compositor/meta-shadow-factory-private.h \
|
||||
compositor/meta-shaped-texture.c \
|
||||
compositor/meta-shaped-texture-private.h \
|
||||
compositor/meta-surface-actor.c \
|
||||
compositor/meta-surface-actor.h \
|
||||
compositor/meta-texture-rectangle.c \
|
||||
compositor/meta-texture-rectangle.h \
|
||||
compositor/meta-texture-tower.c \
|
||||
@@ -183,7 +189,9 @@ libmutter_wayland_la_SOURCES = \
|
||||
ui/theme.c \
|
||||
meta/theme.h \
|
||||
ui/theme-private.h \
|
||||
ui/ui.c \
|
||||
ui/ui.c
|
||||
|
||||
nodist_libmutter_wayland_la_SOURCES = \
|
||||
$(mutter_built_sources)
|
||||
|
||||
libmutter_wayland_la_SOURCES += \
|
||||
@@ -297,7 +305,7 @@ Meta-$(api_version).gir: libmutter-wayland.la
|
||||
@META_GIR@_FILES = \
|
||||
mutter-enum-types.h \
|
||||
$(libmutterinclude_base_headers) \
|
||||
$(filter %.c,$(libmutter_wayland_la_SOURCES))
|
||||
$(filter %.c,$(libmutter_wayland_la_SOURCES) $(nodist_libmutter_wayland_la_SOURCES))
|
||||
@META_GIR@_SCANNERFLAGS = --warn-all --warn-error
|
||||
|
||||
endif
|
||||
@@ -395,7 +403,6 @@ $(dbus_xrandr_built_sources) : Makefile.am xrandr.xml
|
||||
--generate-c-code meta-dbus-xrandr \
|
||||
$(srcdir)/xrandr.xml
|
||||
|
||||
dbus_idle_built_sources = meta-dbus-idle-monitor.c meta-dbus-idle-monitor.h
|
||||
|
||||
$(dbus_idle_built_sources) : Makefile.am idle-monitor.xml
|
||||
$(AM_V_GEN)gdbus-codegen \
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "clutter-utils.h"
|
||||
@@ -95,8 +93,10 @@ meta_actor_vertices_are_untransformed (ClutterVertex *verts,
|
||||
v3x != v1x || v3y != v2y)
|
||||
return FALSE;
|
||||
|
||||
*x_origin = x;
|
||||
*y_origin = y;
|
||||
if (x_origin)
|
||||
*x_origin = x;
|
||||
if (y_origin)
|
||||
*y_origin = y;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -15,9 +15,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __META_CLUTTER_UTILS_H__
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
@@ -15,9 +15,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __META_COGL_UTILS_H__
|
||||
|
@@ -17,8 +17,6 @@ struct _MetaCompositor
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
Atom atom_x_root_pixmap;
|
||||
Atom atom_net_wm_window_opacity;
|
||||
guint repaint_func_id;
|
||||
|
||||
ClutterActor *shadow_src;
|
||||
|
@@ -179,31 +179,6 @@ process_damage (MetaCompositor *compositor,
|
||||
meta_window_actor_process_x11_damage (window_actor, event);
|
||||
}
|
||||
|
||||
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
|
||||
get_output_window (MetaScreen *screen)
|
||||
{
|
||||
@@ -637,6 +612,9 @@ after_stage_paint (ClutterStage *stage,
|
||||
|
||||
for (l = info->windows; l; l = l->next)
|
||||
meta_window_actor_post_paint (l->data);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_wayland_compositor_paint_finished (meta_wayland_compositor_get_default ());
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -650,11 +628,6 @@ redirect_windows (MetaCompositor *compositor,
|
||||
guint n_retries;
|
||||
guint max_retries;
|
||||
|
||||
/* If we're running with wayland, connected to a headless xwayland
|
||||
* server then all the windows are implicitly redirected offscreen
|
||||
* already and it would generate an error to try and explicitly
|
||||
* redirect them via XCompositeRedirectSubwindows() */
|
||||
|
||||
if (meta_get_replace_current_wm ())
|
||||
max_retries = 5;
|
||||
else
|
||||
@@ -792,8 +765,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||
clutter_actor_add_child (info->stage, info->window_group);
|
||||
clutter_actor_add_child (info->stage, info->top_window_group);
|
||||
|
||||
info->plugin_mgr = meta_plugin_manager_new (screen);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
/* NB: When running as a wayland compositor we don't need an X
|
||||
@@ -803,13 +774,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* 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);
|
||||
XReparentWindow (xdisplay, xwin, info->output, 0, 0);
|
||||
|
||||
@@ -834,9 +798,11 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||
* contents until we show the stage.
|
||||
*/
|
||||
XMapWindow (xdisplay, info->output);
|
||||
|
||||
redirect_windows (compositor, screen);
|
||||
}
|
||||
|
||||
redirect_windows (compositor, screen);
|
||||
|
||||
info->plugin_mgr = meta_plugin_manager_new (screen);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -876,7 +842,7 @@ meta_shape_cow_for_window (MetaScreen *screen,
|
||||
int width, height;
|
||||
MetaRectangle rect;
|
||||
|
||||
meta_window_get_outer_rect (metaWindow, &rect);
|
||||
meta_window_get_frame_rect (metaWindow, &rect);
|
||||
|
||||
window_bounds.x = rect.x;
|
||||
window_bounds.y = rect.y;
|
||||
@@ -1007,23 +973,30 @@ meta_compositor_window_shape_changed (MetaCompositor *compositor,
|
||||
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
|
||||
* per stage, which is a valid assumption to make for a generic
|
||||
* application toolkit. As such, it will ignore any events sent
|
||||
* to the a stage that isn't its X window.
|
||||
*
|
||||
* When a user clicks on what she thinks is the wallpaper, she
|
||||
* is actually clicking on the guard window, which is an entirely
|
||||
* separate top-level override-redirect window in the hierarchy.
|
||||
* We want to recieve events on this guard window so that users
|
||||
* can right-click on the background actor. We do this by telling
|
||||
* Clutter a little white lie, by transforming clicks on the guard
|
||||
* window to become clicks on the stage window, allowing Clutter
|
||||
* to process the event normally.
|
||||
* When running as an X window manager, we need to respond to
|
||||
* events from lots of windows. Trick Clutter into translating
|
||||
* these events by pretending we got an event on the stage window.
|
||||
*/
|
||||
static void
|
||||
maybe_spoof_guard_window_event_as_stage_event (MetaCompScreen *info,
|
||||
XEvent *event)
|
||||
maybe_spoof_event_as_stage_event (MetaCompScreen *info,
|
||||
XEvent *event)
|
||||
{
|
||||
MetaDisplay *display = meta_screen_get_display (info->screen);
|
||||
|
||||
@@ -1032,19 +1005,22 @@ maybe_spoof_guard_window_event_as_stage_event (MetaCompScreen *info,
|
||||
{
|
||||
XIEvent *input_event = (XIEvent *) event->xcookie.data;
|
||||
|
||||
/* Only care about pointer events for now. */
|
||||
switch (input_event->evtype)
|
||||
{
|
||||
case XI_Motion:
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
case XI_KeyPress:
|
||||
case XI_KeyRelease:
|
||||
{
|
||||
XIDeviceEvent *device_event = ((XIDeviceEvent *) input_event);
|
||||
if (device_event->event == info->screen->guard_window)
|
||||
{
|
||||
Window xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
|
||||
device_event->event = xwin;
|
||||
}
|
||||
|
||||
/* If this is a GTK+ widget, like a window menu, let GTK+ handle
|
||||
* it as-is without mangling. */
|
||||
if (meta_ui_window_is_widget (info->screen->ui, device_event->event))
|
||||
break;
|
||||
|
||||
device_event->event = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1101,7 +1077,7 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
||||
|
||||
info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
maybe_spoof_guard_window_event_as_stage_event (info, event);
|
||||
maybe_spoof_event_as_stage_event (info, event);
|
||||
|
||||
if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event))
|
||||
{
|
||||
@@ -1113,29 +1089,20 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
||||
}
|
||||
}
|
||||
|
||||
switch (event->type)
|
||||
if (!meta_is_wayland_compositor () &&
|
||||
event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify)
|
||||
{
|
||||
case PropertyNotify:
|
||||
process_property_notify (compositor, (XPropertyEvent *) event, window);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!meta_is_wayland_compositor () &&
|
||||
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)
|
||||
{
|
||||
/* 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);
|
||||
Window xwin = ((XDamageNotifyEvent *) event)->drawable;
|
||||
window = meta_display_lookup_x_window (compositor->display, xwin);
|
||||
}
|
||||
break;
|
||||
|
||||
DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n");
|
||||
process_damage (compositor, (XDamageNotifyEvent *) event, window);
|
||||
}
|
||||
|
||||
/* Clutter needs to know about MapNotify events otherwise it will
|
||||
@@ -1660,13 +1627,7 @@ on_shadow_factory_changed (MetaShadowFactory *factory,
|
||||
MetaCompositor *
|
||||
meta_compositor_new (MetaDisplay *display)
|
||||
{
|
||||
char *atom_names[] = {
|
||||
"_XROOTPMAP_ID",
|
||||
"_NET_WM_WINDOW_OPACITY",
|
||||
};
|
||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||
MetaCompositor *compositor;
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
|
||||
if (!composite_at_least_version (display, 0, 3))
|
||||
return NULL;
|
||||
@@ -1678,18 +1639,11 @@ meta_compositor_new (MetaDisplay *display)
|
||||
if (g_getenv("META_DISABLE_MIPMAPS"))
|
||||
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 (),
|
||||
"changed",
|
||||
G_CALLBACK (on_shadow_factory_changed),
|
||||
compositor);
|
||||
|
||||
compositor->atom_x_root_pixmap = atoms[0];
|
||||
compositor->atom_net_wm_window_opacity = atoms[1];
|
||||
|
||||
compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func,
|
||||
compositor,
|
||||
NULL);
|
||||
|
@@ -6,9 +6,6 @@
|
||||
#include <meta/screen.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);
|
||||
|
||||
#endif /* META_BACKGROUND_ACTOR_PRIVATE_H */
|
||||
|
@@ -14,9 +14,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Portions adapted from gnome-shell/src/shell-global.c
|
||||
*/
|
||||
@@ -41,20 +39,35 @@
|
||||
#include <meta/errors.h>
|
||||
#include <meta/meta-background.h>
|
||||
#include "meta-background-actor-private.h"
|
||||
#include "meta-cullable.h"
|
||||
|
||||
struct _MetaBackgroundActorPrivate
|
||||
{
|
||||
cairo_region_t *clip_region;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR);
|
||||
static void cullable_iface_init (MetaCullableInterface *iface);
|
||||
|
||||
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
|
||||
meta_background_actor_dispose (GObject *object)
|
||||
{
|
||||
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
|
||||
|
||||
meta_background_actor_set_clip_region (self, NULL);
|
||||
set_clip_region (self, NULL);
|
||||
|
||||
G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -104,26 +117,6 @@ meta_background_actor_get_preferred_height (ClutterActor *actor,
|
||||
*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
|
||||
meta_background_actor_class_init (MetaBackgroundActorClass *klass)
|
||||
{
|
||||
@@ -136,7 +129,6 @@ meta_background_actor_class_init (MetaBackgroundActorClass *klass)
|
||||
|
||||
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_paint_volume = meta_background_actor_get_paint_volume;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -166,31 +158,27 @@ meta_background_actor_new (void)
|
||||
return CLUTTER_ACTOR (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_background_actor_set_clip_region:
|
||||
* @self: a #MetaBackgroundActor
|
||||
* @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)
|
||||
static void
|
||||
meta_background_actor_cull_out (MetaCullable *cullable,
|
||||
cairo_region_t *unobscured_region,
|
||||
cairo_region_t *clip_region)
|
||||
{
|
||||
MetaBackgroundActorPrivate *priv;
|
||||
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable);
|
||||
set_clip_region (self, clip_region);
|
||||
}
|
||||
|
||||
g_return_if_fail (META_IS_BACKGROUND_ACTOR (self));
|
||||
static void
|
||||
meta_background_actor_reset_culling (MetaCullable *cullable)
|
||||
{
|
||||
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable);
|
||||
set_clip_region (self, NULL);
|
||||
}
|
||||
|
||||
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
|
||||
cullable_iface_init (MetaCullableInterface *iface)
|
||||
{
|
||||
iface->cull_out = meta_background_actor_cull_out;
|
||||
iface->reset_culling = meta_background_actor_reset_culling;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,11 +0,0 @@
|
||||
/* -*- 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,87 +16,43 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "compositor-private.h"
|
||||
#include "clutter-utils.h"
|
||||
#include "meta-background-actor-private.h"
|
||||
#include "meta-background-group-private.h"
|
||||
#include <meta/meta-background-group.h>
|
||||
#include "meta-cullable.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR);
|
||||
static void cullable_iface_init (MetaCullableInterface *iface);
|
||||
|
||||
struct _MetaBackgroundGroupPrivate
|
||||
{
|
||||
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);
|
||||
}
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR,
|
||||
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
|
||||
|
||||
static void
|
||||
meta_background_group_class_init (MetaBackgroundGroupClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
}
|
||||
|
||||
actor_class->get_paint_volume = meta_background_group_get_paint_volume;
|
||||
object_class->dispose = meta_background_group_dispose;
|
||||
static void
|
||||
meta_background_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);
|
||||
}
|
||||
|
||||
g_type_class_add_private (klass, sizeof (MetaBackgroundGroupPrivate));
|
||||
static void
|
||||
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
|
||||
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 *
|
||||
|
@@ -14,9 +14,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
191
src/compositor/meta-cullable.c
Normal file
191
src/compositor/meta-cullable.c
Normal file
@@ -0,0 +1,191 @@
|
||||
/* -*- 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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))
|
||||
{
|
||||
float 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, NULL, NULL))
|
||||
continue;
|
||||
|
||||
clutter_actor_get_position (child, &x, &y);
|
||||
|
||||
/* 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);
|
||||
}
|
66
src/compositor/meta-cullable.h
Normal file
66
src/compositor/meta-cullable.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* -*- 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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__ */
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <meta/meta-plugin.h>
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_MODULE_H_
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_PLUGIN_MANAGER_H_
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -17,9 +17,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __META_SHADOW_FACTORY_PRIVATE_H__
|
||||
|
@@ -13,9 +13,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -28,17 +28,9 @@
|
||||
#define __META_SHAPED_TEXTURE_PRIVATE_H__
|
||||
|
||||
#include <meta/meta-shaped-texture.h>
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
ClutterActor *meta_shaped_texture_new_with_xwindow (Window xwindow);
|
||||
ClutterActor *meta_shaped_texture_new_with_wayland_surface (MetaWaylandSurface *surface);
|
||||
void meta_shaped_texture_set_wayland_surface (MetaShapedTexture *stex,
|
||||
MetaWaylandSurface *surface);
|
||||
MetaWaylandSurface *meta_shaped_texture_get_wayland_surface (MetaShapedTexture *stex);
|
||||
|
||||
void meta_shaped_texture_set_pixmap (MetaShapedTexture *stex,
|
||||
Pixmap pixmap);
|
||||
void meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture *stex,
|
||||
MetaWaylandBuffer *buffer);
|
||||
ClutterActor *meta_shaped_texture_new (void);
|
||||
void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
|
||||
CoglTexture *texture);
|
||||
|
||||
#endif
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -35,13 +33,11 @@
|
||||
#include "meta-texture-tower.h"
|
||||
|
||||
#include "meta-shaped-texture-private.h"
|
||||
#include "meta-wayland-private.h"
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <cogl/cogl-texture-pixmap-x11.h>
|
||||
#include <gdk/gdk.h> /* for gdk_rectangle_intersect() */
|
||||
#include "meta-cullable.h"
|
||||
|
||||
static void meta_shaped_texture_dispose (GObject *object);
|
||||
|
||||
@@ -61,15 +57,10 @@ static void meta_shaped_texture_get_preferred_height (ClutterActor *self,
|
||||
|
||||
static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume);
|
||||
|
||||
typedef enum _MetaShapedTextureType
|
||||
{
|
||||
META_SHAPED_TEXTURE_TYPE_X11_PIXMAP,
|
||||
META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE,
|
||||
} MetaShapedTextureType;
|
||||
static void cullable_iface_init (MetaCullableInterface *iface);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_ACTOR,
|
||||
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
|
||||
|
||||
#define META_SHAPED_TEXTURE_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_SHAPED_TEXTURE, \
|
||||
@@ -79,18 +70,7 @@ struct _MetaShapedTexturePrivate
|
||||
{
|
||||
MetaTextureTower *paint_tower;
|
||||
|
||||
MetaShapedTextureType type;
|
||||
union {
|
||||
struct {
|
||||
Pixmap pixmap;
|
||||
} x11;
|
||||
struct {
|
||||
MetaWaylandSurface *surface;
|
||||
} wayland;
|
||||
};
|
||||
|
||||
CoglTexture *texture;
|
||||
|
||||
CoglTexture *mask_texture;
|
||||
|
||||
cairo_region_t *clip_region;
|
||||
@@ -128,13 +108,22 @@ meta_shaped_texture_init (MetaShapedTexture *self)
|
||||
|
||||
priv->paint_tower = meta_texture_tower_new ();
|
||||
|
||||
priv->type = META_SHAPED_TEXTURE_TYPE_X11_PIXMAP;
|
||||
priv->texture = NULL;
|
||||
|
||||
priv->mask_texture = NULL;
|
||||
priv->create_mipmaps = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
set_clip_region (MetaShapedTexture *self,
|
||||
cairo_region_t *clip_region)
|
||||
{
|
||||
MetaShapedTexturePrivate *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
|
||||
meta_shaped_texture_dispose (GObject *object)
|
||||
{
|
||||
@@ -149,7 +138,7 @@ meta_shaped_texture_dispose (GObject *object)
|
||||
g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
|
||||
|
||||
meta_shaped_texture_set_mask_texture (self, NULL);
|
||||
meta_shaped_texture_set_clip_region (self, NULL);
|
||||
set_clip_region (self, NULL);
|
||||
|
||||
G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -220,10 +209,8 @@ paint_clipped_rectangle (CoglFramebuffer *fb,
|
||||
cogl_framebuffer_draw_multitextured_rectangle (fb, pipeline,
|
||||
x1, y1, x2, y2,
|
||||
&coords[0], 8);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_cogl_texture (MetaShapedTexture *stex,
|
||||
CoglTexture *cogl_tex)
|
||||
@@ -238,10 +225,11 @@ set_cogl_texture (MetaShapedTexture *stex,
|
||||
if (priv->texture)
|
||||
cogl_object_unref (priv->texture);
|
||||
|
||||
priv->texture = cogl_object_ref (cogl_tex);
|
||||
priv->texture = cogl_tex;
|
||||
|
||||
if (cogl_tex != NULL)
|
||||
{
|
||||
cogl_object_ref (cogl_tex);
|
||||
width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex));
|
||||
height = cogl_texture_get_height (COGL_TEXTURE (cogl_tex));
|
||||
|
||||
@@ -266,6 +254,9 @@ set_cogl_texture (MetaShapedTexture *stex,
|
||||
* know how much of the buffer has changed with respect to the
|
||||
* previous buffer. We only queue a redraw in response to surface
|
||||
* damage. */
|
||||
|
||||
if (priv->create_mipmaps)
|
||||
meta_texture_tower_set_base_texture (priv->paint_tower, cogl_tex);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -324,15 +315,8 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
|
||||
filter = COGL_PIPELINE_FILTER_LINEAR;
|
||||
|
||||
if (!clutter_actor_is_in_clone_paint (actor))
|
||||
{
|
||||
int x_origin, y_origin;
|
||||
|
||||
if (meta_actor_is_untransformed (actor,
|
||||
&x_origin,
|
||||
&y_origin))
|
||||
filter = COGL_PIPELINE_FILTER_NEAREST;
|
||||
}
|
||||
if (!clutter_actor_is_in_clone_paint (actor) && meta_actor_is_untransformed (actor, NULL, NULL))
|
||||
filter = COGL_PIPELINE_FILTER_NEAREST;
|
||||
|
||||
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
fb = cogl_get_draw_framebuffer ();
|
||||
@@ -568,48 +552,6 @@ meta_shaped_texture_get_paint_volume (ClutterActor *self,
|
||||
return clutter_paint_volume_set_from_allocation (volume, self);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
meta_shaped_texture_new_with_wayland_surface (MetaWaylandSurface *surface)
|
||||
{
|
||||
ClutterActor *actor = g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
|
||||
MetaShapedTexturePrivate *priv = META_SHAPED_TEXTURE (actor)->priv;
|
||||
|
||||
/* XXX: it could probably be better to have a "type" construct-only
|
||||
* property or create wayland/x11 subclasses */
|
||||
priv->type = META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE;
|
||||
|
||||
meta_shaped_texture_set_wayland_surface (META_SHAPED_TEXTURE (actor),
|
||||
surface);
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
||||
void
|
||||
meta_shaped_texture_set_wayland_surface (MetaShapedTexture *stex,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaShapedTexturePrivate *priv = stex->priv;
|
||||
|
||||
priv->wayland.surface = surface;
|
||||
|
||||
if (surface && surface->buffer_ref.buffer)
|
||||
meta_shaped_texture_attach_wayland_buffer (stex,
|
||||
surface->buffer_ref.buffer);
|
||||
}
|
||||
|
||||
MetaWaylandSurface *
|
||||
meta_shaped_texture_get_wayland_surface (MetaShapedTexture *stex)
|
||||
{
|
||||
MetaShapedTexturePrivate *priv = stex->priv;
|
||||
return priv->wayland.surface;
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
meta_shaped_texture_new_with_xwindow (Window xwindow)
|
||||
{
|
||||
return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
|
||||
gboolean create_mipmaps)
|
||||
@@ -652,66 +594,6 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
|
||||
}
|
||||
|
||||
static void
|
||||
wayland_surface_update_area (MetaShapedTexture *stex,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
MetaShapedTexturePrivate *priv;
|
||||
MetaWaylandBuffer *buffer;
|
||||
|
||||
priv = stex->priv;
|
||||
|
||||
g_return_if_fail (priv->type == META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE);
|
||||
g_return_if_fail (priv->texture != NULL);
|
||||
|
||||
buffer = priv->wayland.surface->buffer_ref.buffer;
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
struct wl_resource *resource = buffer->resource;
|
||||
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource);
|
||||
|
||||
if (shm_buffer)
|
||||
{
|
||||
CoglPixelFormat format;
|
||||
|
||||
switch (wl_shm_buffer_get_format (shm_buffer))
|
||||
{
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
format = COGL_PIXEL_FORMAT_ARGB_8888;
|
||||
break;
|
||||
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
format = COGL_PIXEL_FORMAT_BGRA_8888;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
format = COGL_PIXEL_FORMAT_ARGB_8888;
|
||||
}
|
||||
|
||||
cogl_texture_set_region (priv->texture,
|
||||
x, y,
|
||||
x, y,
|
||||
width, height,
|
||||
width, height,
|
||||
format,
|
||||
wl_shm_buffer_get_stride (shm_buffer),
|
||||
wl_shm_buffer_get_data (shm_buffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_clip (MetaShapedTexture *stex,
|
||||
int x,
|
||||
@@ -770,8 +652,8 @@ get_clip (MetaShapedTexture *stex,
|
||||
* has a mapped clone)
|
||||
*
|
||||
* Repairs the damaged area indicated by @x, @y, @width and @height
|
||||
* and queues a redraw for the intersection @visibible_region and
|
||||
* the damage area. If @visibible_region is %NULL a redraw will always
|
||||
* and queues a redraw for the intersection @unobscured_region and
|
||||
* the damage area. If @unobscured_region is %NULL a redraw will always
|
||||
* get queued.
|
||||
*
|
||||
* Return value: Whether a redraw have been queued or not
|
||||
@@ -793,17 +675,6 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
||||
if (priv->texture == NULL)
|
||||
return FALSE;
|
||||
|
||||
switch (priv->type)
|
||||
{
|
||||
case META_SHAPED_TEXTURE_TYPE_X11_PIXMAP:
|
||||
cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (priv->texture),
|
||||
x, y, width, height);
|
||||
break;
|
||||
case META_SHAPED_TEXTURE_TYPE_WAYLAND_SURFACE:
|
||||
wayland_surface_update_area (stex, x, y, width, height);
|
||||
break;
|
||||
}
|
||||
|
||||
meta_texture_tower_update_area (priv->paint_tower, x, y, width, height);
|
||||
|
||||
has_clip = get_clip (stex, x, y, width, height, &clip);
|
||||
@@ -843,66 +714,17 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_shaped_texture_set_pixmap:
|
||||
* meta_shaped_texture_set_texture:
|
||||
* @stex: The #MetaShapedTexture
|
||||
* @pixmap: The pixmap you want the stex to assume
|
||||
* @pixmap: The #CoglTexture to display
|
||||
*/
|
||||
void
|
||||
meta_shaped_texture_set_pixmap (MetaShapedTexture *stex,
|
||||
Pixmap pixmap)
|
||||
meta_shaped_texture_set_texture (MetaShapedTexture *stex,
|
||||
CoglTexture *texture)
|
||||
{
|
||||
MetaShapedTexturePrivate *priv;
|
||||
|
||||
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
|
||||
|
||||
priv = stex->priv;
|
||||
|
||||
if (priv->x11.pixmap == pixmap)
|
||||
return;
|
||||
|
||||
priv->x11.pixmap = pixmap;
|
||||
|
||||
if (pixmap != None)
|
||||
{
|
||||
CoglContext *ctx =
|
||||
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
CoglTexture *texture =
|
||||
COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, NULL));
|
||||
set_cogl_texture (stex, texture);
|
||||
}
|
||||
else
|
||||
set_cogl_texture (stex, NULL);
|
||||
|
||||
if (priv->create_mipmaps)
|
||||
meta_texture_tower_set_base_texture (priv->paint_tower,
|
||||
COGL_TEXTURE (priv->texture));
|
||||
}
|
||||
|
||||
void
|
||||
meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture *stex,
|
||||
MetaWaylandBuffer *buffer)
|
||||
{
|
||||
MetaShapedTexturePrivate *priv;
|
||||
|
||||
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
|
||||
|
||||
priv = stex->priv;
|
||||
|
||||
/* TODO: we should change this api to be something like
|
||||
* meta_shaped_texture_notify_buffer_attach() since we now maintain
|
||||
* a reference to the MetaWaylandSurface where we can access the
|
||||
* buffer without it being explicitly passed as an argument.
|
||||
*/
|
||||
g_return_if_fail (priv->wayland.surface->buffer_ref.buffer == buffer);
|
||||
|
||||
if (buffer)
|
||||
set_cogl_texture (stex, buffer->texture);
|
||||
else
|
||||
set_cogl_texture (stex, NULL);
|
||||
|
||||
if (priv->create_mipmaps)
|
||||
meta_texture_tower_set_base_texture (priv->paint_tower,
|
||||
COGL_TEXTURE (priv->texture));
|
||||
set_cogl_texture (stex, texture);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -953,39 +775,6 @@ meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex,
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_shaped_texture_set_clip_region:
|
||||
* @stex: a #MetaShapedTexture
|
||||
* @clip_region: the region of the texture that is visible and
|
||||
* should be painted.
|
||||
*
|
||||
* Provides a hint to the texture about what areas of the texture
|
||||
* are not completely obscured and thus need to be painted. This
|
||||
* is an optimization and is not supposed to have any effect on
|
||||
* the output.
|
||||
*
|
||||
* Typically a parent container will set the clip region before
|
||||
* painting its children, and then unset it afterwards.
|
||||
*/
|
||||
void
|
||||
meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
|
||||
cairo_region_t *clip_region)
|
||||
{
|
||||
MetaShapedTexturePrivate *priv;
|
||||
|
||||
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
|
||||
|
||||
priv = stex->priv;
|
||||
|
||||
if (priv->clip_region)
|
||||
cairo_region_destroy (priv->clip_region);
|
||||
|
||||
if (clip_region)
|
||||
priv->clip_region = cairo_region_copy (clip_region);
|
||||
else
|
||||
priv->clip_region = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_shaped_texture_set_opaque_region:
|
||||
* @stex: a #MetaShapedTexture
|
||||
@@ -1113,3 +902,43 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_shaped_texture_cull_out (MetaCullable *cullable,
|
||||
cairo_region_t *unobscured_region,
|
||||
cairo_region_t *clip_region)
|
||||
{
|
||||
MetaShapedTexture *self = META_SHAPED_TEXTURE (cullable);
|
||||
MetaShapedTexturePrivate *priv = self->priv;
|
||||
|
||||
set_clip_region (self, clip_region);
|
||||
|
||||
if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self)) == 0xff)
|
||||
{
|
||||
if (priv->opaque_region)
|
||||
{
|
||||
cairo_region_subtract (unobscured_region, priv->opaque_region);
|
||||
cairo_region_subtract (clip_region, priv->opaque_region);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_shaped_texture_reset_culling (MetaCullable *cullable)
|
||||
{
|
||||
MetaShapedTexture *self = META_SHAPED_TEXTURE (cullable);
|
||||
set_clip_region (self, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
cullable_iface_init (MetaCullableInterface *iface)
|
||||
{
|
||||
iface->cull_out = meta_shaped_texture_cull_out;
|
||||
iface->reset_culling = meta_shaped_texture_reset_culling;
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
meta_shaped_texture_new (void)
|
||||
{
|
||||
return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
|
||||
}
|
||||
|
183
src/compositor/meta-surface-actor.c
Normal file
183
src/compositor/meta-surface-actor.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/**
|
||||
* SECTION:meta-surface-actor
|
||||
* @title: MetaSurfaceActor
|
||||
* @short_description: An actor representing a surface in the scene graph
|
||||
*
|
||||
* A surface can be either a shaped texture, or a group of shaped texture,
|
||||
* used to draw the content of a window.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
#include <cogl/cogl-texture-pixmap-x11.h>
|
||||
#include <meta/meta-shaped-texture.h>
|
||||
#include "meta-surface-actor.h"
|
||||
#include "meta-wayland-private.h"
|
||||
#include "meta-cullable.h"
|
||||
|
||||
#include "meta-shaped-texture-private.h"
|
||||
|
||||
struct _MetaSurfaceActorPrivate
|
||||
{
|
||||
MetaShapedTexture *texture;
|
||||
MetaWaylandBuffer *buffer;
|
||||
};
|
||||
|
||||
static void cullable_iface_init (MetaCullableInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR,
|
||||
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
|
||||
|
||||
static void
|
||||
meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
|
||||
{
|
||||
g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_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_surface_actor_reset_culling (MetaCullable *cullable)
|
||||
{
|
||||
meta_cullable_reset_culling_children (cullable);
|
||||
}
|
||||
|
||||
static void
|
||||
cullable_iface_init (MetaCullableInterface *iface)
|
||||
{
|
||||
iface->cull_out = meta_surface_actor_cull_out;
|
||||
iface->reset_culling = meta_surface_actor_reset_culling;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_init (MetaSurfaceActor *self)
|
||||
{
|
||||
MetaSurfaceActorPrivate *priv;
|
||||
|
||||
priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
||||
META_TYPE_SURFACE_ACTOR,
|
||||
MetaSurfaceActorPrivate);
|
||||
|
||||
priv->texture = META_SHAPED_TEXTURE (meta_shaped_texture_new ());
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->texture));
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
meta_surface_actor_get_image (MetaSurfaceActor *self,
|
||||
cairo_rectangle_int_t *clip)
|
||||
{
|
||||
return meta_shaped_texture_get_image (self->priv->texture, clip);
|
||||
}
|
||||
|
||||
MetaShapedTexture *
|
||||
meta_surface_actor_get_texture (MetaSurfaceActor *self)
|
||||
{
|
||||
return self->priv->texture;
|
||||
}
|
||||
|
||||
static void
|
||||
update_area (MetaSurfaceActor *self,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
MetaSurfaceActorPrivate *priv = self->priv;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
struct wl_resource *resource = priv->buffer->resource;
|
||||
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource);
|
||||
|
||||
if (shm_buffer)
|
||||
{
|
||||
CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture);
|
||||
cogl_wayland_texture_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, x, y, 0, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CoglTexturePixmapX11 *texture = COGL_TEXTURE_PIXMAP_X11 (meta_shaped_texture_get_texture (priv->texture));
|
||||
cogl_texture_pixmap_x11_update_area (texture, x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_surface_actor_damage_all (MetaSurfaceActor *self,
|
||||
cairo_region_t *unobscured_region)
|
||||
{
|
||||
MetaSurfaceActorPrivate *priv = self->priv;
|
||||
CoglTexture *texture = meta_shaped_texture_get_texture (priv->texture);
|
||||
|
||||
update_area (self, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture));
|
||||
return meta_shaped_texture_update_area (priv->texture,
|
||||
0, 0,
|
||||
cogl_texture_get_width (texture),
|
||||
cogl_texture_get_height (texture),
|
||||
unobscured_region);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_surface_actor_damage_area (MetaSurfaceActor *self,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
cairo_region_t *unobscured_region)
|
||||
{
|
||||
MetaSurfaceActorPrivate *priv = self->priv;
|
||||
|
||||
update_area (self, x, y, width, height);
|
||||
return meta_shaped_texture_update_area (priv->texture,
|
||||
x, y, width, height,
|
||||
unobscured_region);
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self,
|
||||
MetaWaylandBuffer *buffer)
|
||||
{
|
||||
MetaSurfaceActorPrivate *priv = self->priv;
|
||||
priv->buffer = buffer;
|
||||
|
||||
if (buffer)
|
||||
meta_shaped_texture_set_texture (priv->texture, buffer->texture);
|
||||
else
|
||||
meta_shaped_texture_set_texture (priv->texture, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_set_texture (MetaSurfaceActor *self,
|
||||
CoglTexture *texture)
|
||||
{
|
||||
MetaSurfaceActorPrivate *priv = self->priv;
|
||||
meta_shaped_texture_set_texture (priv->texture, texture);
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_set_input_region (MetaSurfaceActor *self,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
MetaSurfaceActorPrivate *priv = self->priv;
|
||||
meta_shaped_texture_set_input_shape_region (priv->texture, region);
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
MetaSurfaceActorPrivate *priv = self->priv;
|
||||
meta_shaped_texture_set_opaque_region (priv->texture, region);
|
||||
}
|
||||
|
||||
MetaSurfaceActor *
|
||||
meta_surface_actor_new (void)
|
||||
{
|
||||
return g_object_new (META_TYPE_SURFACE_ACTOR, NULL);
|
||||
}
|
67
src/compositor/meta-surface-actor.h
Normal file
67
src/compositor/meta-surface-actor.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
#ifndef META_SURFACE_ACTOR_PRIVATE_H
|
||||
#define META_SURFACE_ACTOR_PRIVATE_H
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <meta/meta-shaped-texture.h>
|
||||
#include "meta-wayland-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define META_TYPE_SURFACE_ACTOR (meta_surface_actor_get_type())
|
||||
#define META_SURFACE_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SURFACE_ACTOR, MetaSurfaceActor))
|
||||
#define META_SURFACE_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_SURFACE_ACTOR, MetaSurfaceActorClass))
|
||||
#define META_IS_SURFACE_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_SURFACE_ACTOR))
|
||||
#define META_IS_SURFACE_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_SURFACE_ACTOR))
|
||||
#define META_SURFACE_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_SURFACE_ACTOR, MetaSurfaceActorClass))
|
||||
|
||||
typedef struct _MetaSurfaceActor MetaSurfaceActor;
|
||||
typedef struct _MetaSurfaceActorClass MetaSurfaceActorClass;
|
||||
typedef struct _MetaSurfaceActorPrivate MetaSurfaceActorPrivate;
|
||||
|
||||
struct _MetaSurfaceActorClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActorClass parent_class;
|
||||
};
|
||||
|
||||
struct _MetaSurfaceActor
|
||||
{
|
||||
ClutterActor parent;
|
||||
|
||||
MetaSurfaceActorPrivate *priv;
|
||||
};
|
||||
|
||||
GType meta_surface_actor_get_type (void);
|
||||
|
||||
MetaSurfaceActor *meta_surface_actor_new (void);
|
||||
|
||||
cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self,
|
||||
cairo_rectangle_int_t *clip);
|
||||
|
||||
MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self);
|
||||
|
||||
gboolean meta_surface_actor_damage_all (MetaSurfaceActor *self,
|
||||
cairo_region_t *unobscured_region);
|
||||
|
||||
gboolean meta_surface_actor_damage_area (MetaSurfaceActor *self,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
cairo_region_t *unobscured_region);
|
||||
|
||||
void meta_surface_actor_set_texture (MetaSurfaceActor *self,
|
||||
CoglTexture *texture);
|
||||
void meta_surface_actor_attach_wayland_buffer (MetaSurfaceActor *self,
|
||||
MetaWaylandBuffer *buffer);
|
||||
void meta_surface_actor_set_input_region (MetaSurfaceActor *self,
|
||||
cairo_region_t *region);
|
||||
void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
|
||||
cairo_region_t *region);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* META_SURFACE_ACTOR_PRIVATE_H */
|
@@ -18,9 +18,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -28,41 +26,6 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include "meta-texture-rectangle.h"
|
||||
|
||||
CoglTexture *
|
||||
meta_texture_rectangle_new (unsigned int width,
|
||||
unsigned int height,
|
||||
CoglPixelFormat format,
|
||||
CoglPixelFormat internal_format,
|
||||
unsigned int rowstride,
|
||||
const guint8 *data,
|
||||
GError **error)
|
||||
{
|
||||
ClutterBackend *backend =
|
||||
clutter_get_default_backend ();
|
||||
CoglContext *context =
|
||||
clutter_backend_get_cogl_context (backend);
|
||||
CoglTextureRectangle *tex_rect;
|
||||
|
||||
tex_rect = cogl_texture_rectangle_new_with_size (context,
|
||||
width, height,
|
||||
internal_format,
|
||||
error);
|
||||
if (tex_rect == NULL)
|
||||
return NULL;
|
||||
|
||||
if (data)
|
||||
cogl_texture_set_region (COGL_TEXTURE (tex_rect),
|
||||
0, 0, /* src_x/y */
|
||||
0, 0, /* dst_x/y */
|
||||
width, height, /* dst_width/height */
|
||||
width, height, /* width/height */
|
||||
format,
|
||||
rowstride,
|
||||
data);
|
||||
|
||||
return COGL_TEXTURE (tex_rect);
|
||||
}
|
||||
|
||||
static void
|
||||
texture_rectangle_check_cb (CoglTexture *sub_texture,
|
||||
const float *sub_texture_coords,
|
||||
|
@@ -18,9 +18,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __META_TEXTURE_RECTANGLE_H__
|
||||
@@ -30,15 +28,6 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
CoglTexture *
|
||||
meta_texture_rectangle_new (unsigned int width,
|
||||
unsigned int height,
|
||||
CoglPixelFormat format,
|
||||
CoglPixelFormat internal_format,
|
||||
unsigned int rowstride,
|
||||
const guint8 *data,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
meta_texture_rectangle_check (CoglTexture *texture);
|
||||
|
||||
|
@@ -17,9 +17,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
@@ -357,18 +355,10 @@ texture_tower_create_texture (MetaTextureTower *tower,
|
||||
if ((!is_power_of_two (width) || !is_power_of_two (height)) &&
|
||||
meta_texture_rectangle_check (tower->textures[level - 1]))
|
||||
{
|
||||
tower->textures[level] =
|
||||
meta_texture_rectangle_new (width, height,
|
||||
/* data format */
|
||||
TEXTURE_FORMAT,
|
||||
/* internal cogl format */
|
||||
TEXTURE_FORMAT,
|
||||
/* rowstride */
|
||||
width * 4,
|
||||
/* data */
|
||||
NULL,
|
||||
/* error */
|
||||
NULL);
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *context = clutter_backend_get_cogl_context (backend);
|
||||
|
||||
tower->textures[level] = cogl_texture_rectangle_new_with_size (context, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -17,9 +17,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __META_TEXTURE_TOWER_H__
|
||||
|
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <X11/extensions/Xdamage.h>
|
||||
#include <meta/compositor-mutter.h>
|
||||
#include "meta-surface-actor.h"
|
||||
|
||||
MetaWindowActor *meta_window_actor_new (MetaWindow *window);
|
||||
|
||||
@@ -30,16 +31,6 @@ void meta_window_actor_unmaximize (MetaWindowActor *self,
|
||||
void meta_window_actor_process_x11_damage (MetaWindowActor *self,
|
||||
XDamageNotifyEvent *event);
|
||||
|
||||
void meta_window_actor_process_wayland_damage (MetaWindowActor *self,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
void meta_window_actor_set_wayland_surface (MetaWindowActor *self,
|
||||
MetaWaylandSurface *surface);
|
||||
void meta_window_actor_attach_wayland_buffer (MetaWindowActor *self,
|
||||
MetaWaylandBuffer *buffer);
|
||||
|
||||
void meta_window_actor_pre_paint (MetaWindowActor *self);
|
||||
void meta_window_actor_post_paint (MetaWindowActor *self);
|
||||
void meta_window_actor_frame_complete (MetaWindowActor *self,
|
||||
@@ -68,18 +59,12 @@ void meta_window_actor_set_updates_frozen (MetaWindowActor *self,
|
||||
void meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
|
||||
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,
|
||||
cairo_region_t *unobscured_region);
|
||||
|
||||
void meta_window_actor_effect_completed (MetaWindowActor *actor,
|
||||
gulong event);
|
||||
|
||||
MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self);
|
||||
|
||||
#endif /* META_WINDOW_ACTOR_PRIVATE_H */
|
||||
|
@@ -30,10 +30,12 @@
|
||||
#include "meta-shaped-texture-private.h"
|
||||
#include "meta-shadow-factory-private.h"
|
||||
#include "meta-window-actor-private.h"
|
||||
#include "meta-surface-actor.h"
|
||||
#include "meta-texture-rectangle.h"
|
||||
#include "region-utils.h"
|
||||
#include "meta-wayland-private.h"
|
||||
#include "monitor-private.h"
|
||||
#include "meta-cullable.h"
|
||||
|
||||
enum {
|
||||
POSITION_CHANGED,
|
||||
@@ -47,10 +49,9 @@ static guint signals[LAST_SIGNAL] = {0};
|
||||
struct _MetaWindowActorPrivate
|
||||
{
|
||||
MetaWindow *window;
|
||||
Window xwindow;
|
||||
MetaScreen *screen;
|
||||
|
||||
ClutterActor *actor;
|
||||
MetaSurfaceActor *surface;
|
||||
|
||||
/* MetaShadowFactory only caches shadows that are actually in use;
|
||||
* to avoid unnecessary recomputation we do two things: 1) we store
|
||||
@@ -66,15 +67,8 @@ struct _MetaWindowActorPrivate
|
||||
MetaShadow *focused_shadow;
|
||||
MetaShadow *unfocused_shadow;
|
||||
|
||||
guint8 opacity;
|
||||
|
||||
/* A region that matches the shape of the window, including frame bounds */
|
||||
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 shape region. */
|
||||
cairo_region_t *opaque_region;
|
||||
/* The region we should clip to when painting the shadow */
|
||||
cairo_region_t *shadow_clip;
|
||||
|
||||
@@ -162,8 +156,6 @@ struct _FrameData
|
||||
enum
|
||||
{
|
||||
PROP_META_WINDOW = 1,
|
||||
PROP_META_SCREEN,
|
||||
PROP_X_WINDOW,
|
||||
PROP_NO_SHADOW,
|
||||
PROP_SHADOW_CLASS
|
||||
};
|
||||
@@ -199,7 +191,10 @@ static void do_send_frame_timings (MetaWindowActor *self,
|
||||
gint refresh_interval,
|
||||
gint64 presentation_time);
|
||||
|
||||
G_DEFINE_TYPE (MetaWindowActor, meta_window_actor, CLUTTER_TYPE_ACTOR);
|
||||
static void cullable_iface_init (MetaCullableInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaWindowActor, meta_window_actor, CLUTTER_TYPE_ACTOR,
|
||||
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
|
||||
|
||||
static void
|
||||
frame_data_free (FrameData *frame)
|
||||
@@ -229,33 +224,12 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
|
||||
"MetaWindow",
|
||||
"The displayed MetaWindow",
|
||||
META_TYPE_WINDOW,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_META_WINDOW,
|
||||
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",
|
||||
"No shadow",
|
||||
"Do not add shaddow to this window",
|
||||
@@ -298,7 +272,6 @@ meta_window_actor_init (MetaWindowActor *self)
|
||||
priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
||||
META_TYPE_WINDOW_ACTOR,
|
||||
MetaWindowActorPrivate);
|
||||
priv->opacity = 0xff;
|
||||
priv->shadow_class = NULL;
|
||||
}
|
||||
|
||||
@@ -309,11 +282,9 @@ window_decorated_notify (MetaWindow *mw,
|
||||
{
|
||||
MetaWindowActor *self = META_WINDOW_ACTOR (data);
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaFrame *frame = meta_window_get_frame (mw);
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
Window new_xwindow;
|
||||
|
||||
/*
|
||||
* Basically, we have to reconstruct the the internals of this object
|
||||
@@ -321,11 +292,6 @@ window_decorated_notify (MetaWindow *mw,
|
||||
*/
|
||||
priv->redecorating = TRUE;
|
||||
|
||||
if (frame)
|
||||
new_xwindow = meta_frame_get_xwindow (frame);
|
||||
else
|
||||
new_xwindow = meta_window_get_xwindow (mw);
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
meta_window_actor_detach_x11_pixmap (self);
|
||||
@@ -343,8 +309,6 @@ window_decorated_notify (MetaWindow *mw,
|
||||
}
|
||||
}
|
||||
|
||||
priv->xwindow = new_xwindow;
|
||||
|
||||
/*
|
||||
* Recreate the contents.
|
||||
*/
|
||||
@@ -359,17 +323,40 @@ window_appears_focused_notify (MetaWindow *mw,
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (data));
|
||||
}
|
||||
|
||||
static void
|
||||
surface_allocation_changed_notify (ClutterActor *actor,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags,
|
||||
MetaWindowActor *self)
|
||||
{
|
||||
meta_window_actor_sync_actor_geometry (self, FALSE);
|
||||
meta_window_actor_update_shape (self);
|
||||
|
||||
g_signal_emit (self, signals[SIZE_CHANGED], 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_non_opaque (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaWindow *window = priv->window;
|
||||
|
||||
return priv->argb32 || (window->opacity != 0xFF);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_constructed (GObject *object)
|
||||
{
|
||||
MetaWindowActor *self = META_WINDOW_ACTOR (object);
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Window xwindow = priv->xwindow;
|
||||
MetaWindow *window = priv->window;
|
||||
Window xwindow = meta_window_get_toplevel_xwindow (window);
|
||||
MetaScreen *screen = meta_window_get_screen (window);
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
|
||||
priv->screen = screen;
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
priv->damage = XDamageCreate (xdisplay, xwindow,
|
||||
XDamageReportBoundingBox);
|
||||
@@ -389,47 +376,26 @@ meta_window_actor_constructed (GObject *object)
|
||||
priv->argb32 = TRUE;
|
||||
}
|
||||
|
||||
if (!priv->actor)
|
||||
if (!priv->surface)
|
||||
{
|
||||
if (meta_is_wayland_compositor ())
|
||||
priv->actor = meta_shaped_texture_new_with_wayland_surface (window->surface);
|
||||
if (window->surface)
|
||||
priv->surface = window->surface->surface_actor;
|
||||
else
|
||||
priv->actor = meta_shaped_texture_new_with_xwindow (xwindow);
|
||||
priv->surface = meta_surface_actor_new ();
|
||||
g_object_ref_sink (priv->surface);
|
||||
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (self), priv->actor);
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
clutter_actor_set_reactive (priv->actor, TRUE);
|
||||
|
||||
/*
|
||||
* Since we are holding a pointer to this actor independently of the
|
||||
* ClutterContainer internals, and provide a public API to access it,
|
||||
* add a reference here, so that if someone is messing about with us
|
||||
* via the container interface, we do not end up with a dangling pointer.
|
||||
* We will release it in dispose().
|
||||
*/
|
||||
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);
|
||||
g_signal_connect_object (priv->surface, "allocation-changed",
|
||||
G_CALLBACK (surface_allocation_changed_notify), self, 0);
|
||||
meta_window_actor_update_shape (self);
|
||||
}
|
||||
|
||||
meta_window_actor_update_opacity (self);
|
||||
|
||||
/* Start off with empty regions to maintain the invariant that
|
||||
these regions are always set */
|
||||
/* Start off with an empty shape region to maintain the invariant
|
||||
* that it's always set */
|
||||
priv->shape_region = cairo_region_create ();
|
||||
priv->input_region = cairo_region_create ();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -461,8 +427,6 @@ meta_window_actor_dispose (GObject *object)
|
||||
|
||||
g_clear_pointer (&priv->unobscured_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->shadow_clip, cairo_region_destroy);
|
||||
|
||||
g_clear_pointer (&priv->shadow_class, g_free);
|
||||
@@ -489,7 +453,7 @@ meta_window_actor_dispose (GObject *object)
|
||||
/*
|
||||
* Release the extra reference we took on the actor.
|
||||
*/
|
||||
g_clear_object (&priv->actor);
|
||||
g_clear_object (&priv->surface);
|
||||
|
||||
G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -517,17 +481,12 @@ meta_window_actor_set_property (GObject *object,
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_META_WINDOW:
|
||||
{
|
||||
if (priv->window)
|
||||
g_object_unref (priv->window);
|
||||
priv->window = g_value_dup_object (value);
|
||||
}
|
||||
break;
|
||||
case PROP_META_SCREEN:
|
||||
priv->screen = g_value_get_pointer (value);
|
||||
break;
|
||||
case PROP_X_WINDOW:
|
||||
priv->xwindow = g_value_get_ulong (value);
|
||||
priv->window = g_value_dup_object (value);
|
||||
|
||||
g_signal_connect_object (priv->window, "notify::decorated",
|
||||
G_CALLBACK (window_decorated_notify), self, 0);
|
||||
g_signal_connect_object (priv->window, "notify::appears-focused",
|
||||
G_CALLBACK (window_appears_focused_notify), self, 0);
|
||||
break;
|
||||
case PROP_NO_SHADOW:
|
||||
{
|
||||
@@ -573,12 +532,6 @@ meta_window_actor_get_property (GObject *object,
|
||||
case PROP_META_WINDOW:
|
||||
g_value_set_object (value, priv->window);
|
||||
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:
|
||||
g_value_set_boolean (value, priv->no_shadow);
|
||||
break;
|
||||
@@ -676,7 +629,7 @@ clip_shadow_under_window (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
return (priv->argb32 || priv->opacity != 0xff) && priv->window->frame;
|
||||
return is_non_opaque (self) && priv->window->frame;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -702,6 +655,7 @@ meta_window_actor_paint (ClutterActor *actor)
|
||||
MetaShadowParams params;
|
||||
cairo_rectangle_int_t shape_bounds;
|
||||
cairo_region_t *clip = priv->shadow_clip;
|
||||
MetaWindow *window = priv->window;
|
||||
|
||||
meta_window_actor_get_shape_bounds (self, &shape_bounds);
|
||||
meta_window_actor_get_shadow_params (self, appears_focused, ¶ms);
|
||||
@@ -725,7 +679,7 @@ meta_window_actor_paint (ClutterActor *actor)
|
||||
params.y_offset + shape_bounds.y,
|
||||
shape_bounds.width,
|
||||
shape_bounds.height,
|
||||
(clutter_actor_get_paint_opacity (actor) * params.opacity * priv->opacity) / (255 * 255),
|
||||
(clutter_actor_get_paint_opacity (actor) * params.opacity * window->opacity) / (255 * 255),
|
||||
clip,
|
||||
clip_shadow_under_window (self)); /* clip_strictly - not just as an optimization */
|
||||
|
||||
@@ -768,7 +722,11 @@ meta_window_actor_get_paint_volume (ClutterActor *actor,
|
||||
}
|
||||
|
||||
if (priv->unobscured_region)
|
||||
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.y = bounds.y;
|
||||
@@ -812,10 +770,10 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
|
||||
return TRUE;
|
||||
|
||||
/*
|
||||
* Do not add shadows to ARGB windows; eventually we should generate a
|
||||
* shadow from the input shape for such windows.
|
||||
* Do not add shadows to non-opaque windows; eventually we should generate
|
||||
* a shadow from the input shape for such windows.
|
||||
*/
|
||||
if (priv->argb32 || priv->opacity != 0xff)
|
||||
if (is_non_opaque (self))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
@@ -846,20 +804,6 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
|
||||
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:
|
||||
* @self: a #MetaWindowActor
|
||||
@@ -885,7 +829,21 @@ meta_window_actor_get_meta_window (MetaWindowActor *self)
|
||||
ClutterActor *
|
||||
meta_window_actor_get_texture (MetaWindowActor *self)
|
||||
{
|
||||
return self->priv->actor;
|
||||
return CLUTTER_ACTOR (meta_surface_actor_get_texture (self->priv->surface));
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_actor_get_surface:
|
||||
* @self: a #MetaWindowActor
|
||||
*
|
||||
* Gets the MetaSurfaceActor that draws the content of this window
|
||||
*
|
||||
* Return value: (transfer none): the #MetaSurfaceActor for the contents
|
||||
*/
|
||||
MetaSurfaceActor *
|
||||
meta_window_actor_get_surface (MetaWindowActor *self)
|
||||
{
|
||||
return self->priv->surface;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -962,8 +920,8 @@ meta_window_actor_freeze (MetaWindowActor *self)
|
||||
self->priv->freeze_count++;
|
||||
}
|
||||
|
||||
static
|
||||
gboolean send_frame_messages_timeout (gpointer data)
|
||||
static gboolean
|
||||
send_frame_messages_timeout (gpointer data)
|
||||
{
|
||||
MetaWindowActor *self = (MetaWindowActor *) data;
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
@@ -1020,26 +978,22 @@ static void
|
||||
meta_window_actor_damage_all (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
CoglTexture *texture;
|
||||
cairo_region_t *unobscured_region;
|
||||
gboolean redraw_queued;
|
||||
|
||||
if (!priv->needs_damage_all)
|
||||
return;
|
||||
|
||||
texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor));
|
||||
|
||||
if (!priv->mapped || priv->needs_pixmap)
|
||||
return;
|
||||
|
||||
redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
|
||||
0, 0,
|
||||
cogl_texture_get_width (texture),
|
||||
cogl_texture_get_height (texture),
|
||||
clutter_actor_has_mapped_clones (priv->actor) ?
|
||||
NULL : priv->unobscured_region);
|
||||
unobscured_region =
|
||||
clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface))
|
||||
? NULL : priv->unobscured_region;
|
||||
|
||||
priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued;
|
||||
redraw_queued = meta_surface_actor_damage_all (priv->surface, unobscured_region);
|
||||
|
||||
priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued;
|
||||
priv->needs_damage_all = FALSE;
|
||||
}
|
||||
|
||||
@@ -1123,7 +1077,7 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
|
||||
else if (priv->mapped && (!meta_is_wayland_compositor () || !priv->needs_pixmap))
|
||||
{
|
||||
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 (CLUTTER_ACTOR (priv->surface), &clip);
|
||||
priv->repaint_scheduled = TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1166,7 +1120,7 @@ meta_window_actor_queue_create_x11_pixmap (MetaWindowActor *self)
|
||||
*
|
||||
* The compositor paint function repairs all windows.
|
||||
*/
|
||||
clutter_actor_queue_redraw (priv->actor);
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1256,7 +1210,7 @@ meta_window_actor_after_effects (MetaWindowActor *self)
|
||||
meta_window_actor_detach_x11_pixmap (self);
|
||||
|
||||
if (priv->needs_pixmap)
|
||||
clutter_actor_queue_redraw (priv->actor);
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1352,8 +1306,7 @@ meta_window_actor_detach_x11_pixmap (MetaWindowActor *self)
|
||||
* you are supposed to be able to free a GLXPixmap after freeing the underlying
|
||||
* pixmap, but it certainly doesn't work with current DRI/Mesa
|
||||
*/
|
||||
meta_shaped_texture_set_pixmap (META_SHAPED_TEXTURE (priv->actor),
|
||||
None);
|
||||
meta_surface_actor_set_texture (priv->surface, NULL);
|
||||
cogl_flush();
|
||||
|
||||
XFreePixmap (xdisplay, priv->back_pixmap);
|
||||
@@ -1371,7 +1324,7 @@ meta_window_actor_should_unredirect (MetaWindowActor *self)
|
||||
if (meta_window_requested_dont_bypass_compositor (metaWindow))
|
||||
return FALSE;
|
||||
|
||||
if (priv->opacity != 0xff)
|
||||
if (metaWindow->opacity != 0xFF)
|
||||
return FALSE;
|
||||
|
||||
if (metaWindow->shape_region != NULL)
|
||||
@@ -1402,7 +1355,7 @@ meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state)
|
||||
MetaDisplay *display = meta_window_get_display (metaWindow);
|
||||
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
Window xwin = meta_window_actor_get_x_window (self);
|
||||
Window xwin = meta_window_get_toplevel_xwindow (metaWindow);
|
||||
|
||||
if (state)
|
||||
{
|
||||
@@ -1431,9 +1384,6 @@ meta_window_actor_destroy (MetaWindowActor *self)
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_shaped_texture_set_wayland_surface (META_SHAPED_TEXTURE (priv->actor), NULL);
|
||||
|
||||
window = priv->window;
|
||||
window_type = meta_window_get_window_type (window);
|
||||
meta_window_set_compositor_private (window, NULL);
|
||||
@@ -1575,6 +1525,7 @@ meta_window_actor_hide (MetaWindowActor *self,
|
||||
g_return_if_fail (priv->visible);
|
||||
|
||||
priv->visible = FALSE;
|
||||
clutter_actor_set_reactive (CLUTTER_ACTOR (self), FALSE);
|
||||
|
||||
/* If a plugin is animating a workspace transition, we have to
|
||||
* hold off on hiding the window, and do it after the workspace
|
||||
@@ -1668,31 +1619,10 @@ meta_window_actor_new (MetaWindow *window)
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
MetaWindowActor *self;
|
||||
MetaWindowActorPrivate *priv;
|
||||
MetaFrame *frame;
|
||||
Window top_window = None;
|
||||
ClutterActor *window_group;
|
||||
|
||||
if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_verbose ("add window: Meta %p, wayland surface %p\n",
|
||||
window, window->surface);
|
||||
top_window = None;
|
||||
}
|
||||
|
||||
self = g_object_new (META_TYPE_WINDOW_ACTOR,
|
||||
"meta-window", window,
|
||||
"x-window", top_window,
|
||||
"meta-screen", screen,
|
||||
"meta-window", window,
|
||||
NULL);
|
||||
|
||||
priv = self->priv;
|
||||
@@ -1772,38 +1702,6 @@ meta_window_actor_unmapped (MetaWindowActor *self)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_actor_get_obscured_region:
|
||||
* @self: a #MetaWindowActor
|
||||
*
|
||||
* Gets the region that is completely obscured by the window. Coordinates
|
||||
* are relative to the upper-left of the window.
|
||||
*
|
||||
* Return value: (transfer none): the area obscured by the window,
|
||||
* %NULL is the same as an empty region.
|
||||
*/
|
||||
cairo_region_t *
|
||||
meta_window_actor_get_obscured_region (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
if (!priv->window->shaded)
|
||||
{
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
if (priv->opacity == 0xff)
|
||||
return priv->opaque_region;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (priv->back_pixmap && priv->opacity == 0xff)
|
||||
return priv->opaque_region;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Print out a region; useful for debugging */
|
||||
static void
|
||||
@@ -1853,8 +1751,6 @@ see_region (cairo_region_t *region,
|
||||
*
|
||||
* Provides a hint as to what areas of the window need to queue
|
||||
* redraws when damaged. Regions not in @unobscured_region are completely obscured.
|
||||
* Unlike meta_window_actor_set_clip_region(), the region here
|
||||
* doesn't take into account any clipping that is in effect while drawing.
|
||||
*/
|
||||
void
|
||||
meta_window_actor_set_unobscured_region (MetaWindowActor *self,
|
||||
@@ -1871,27 +1767,6 @@ meta_window_actor_set_unobscured_region (MetaWindowActor *self,
|
||||
priv->unobscured_region = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_actor_set_clip_region:
|
||||
* @self: a #MetaWindowActor
|
||||
* @clip_region: the region of the screen that isn't completely
|
||||
* obscured.
|
||||
*
|
||||
* Provides a hint as to what areas of the window need to be
|
||||
* drawn. Regions not in @clip_region are completely obscured or
|
||||
* not drawn in this frame.
|
||||
* This will be set before painting then unset afterwards.
|
||||
*/
|
||||
void
|
||||
meta_window_actor_set_clip_region (MetaWindowActor *self,
|
||||
cairo_region_t *clip_region)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor),
|
||||
clip_region);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_actor_set_clip_region_beneath:
|
||||
* @self: a #MetaWindowActor
|
||||
@@ -1904,7 +1779,7 @@ meta_window_actor_set_clip_region (MetaWindowActor *self,
|
||||
* shadow hid by the window itself. This will be set before painting
|
||||
* then unset afterwards.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
meta_window_actor_set_clip_region_beneath (MetaWindowActor *self,
|
||||
cairo_region_t *beneath_region)
|
||||
{
|
||||
@@ -1924,21 +1799,43 @@ meta_window_actor_set_clip_region_beneath (MetaWindowActor *self,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_actor_reset_clip_regions:
|
||||
* @self: a #MetaWindowActor
|
||||
*
|
||||
* 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)
|
||||
static void
|
||||
meta_window_actor_cull_out (MetaCullable *cullable,
|
||||
cairo_region_t *unobscured_region,
|
||||
cairo_region_t *clip_region)
|
||||
{
|
||||
MetaWindowActor *self = META_WINDOW_ACTOR (cullable);
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
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_cullable_cull_out_children (cullable, unobscured_region, clip_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;
|
||||
|
||||
meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor),
|
||||
NULL);
|
||||
g_clear_pointer (&priv->shadow_clip, cairo_region_destroy);
|
||||
|
||||
meta_cullable_reset_culling_children (cullable);
|
||||
}
|
||||
|
||||
static void
|
||||
cullable_iface_init (MetaCullableInterface *iface)
|
||||
{
|
||||
iface->cull_out = meta_window_actor_cull_out;
|
||||
iface->reset_culling = meta_window_actor_reset_culling;
|
||||
}
|
||||
|
||||
/* When running as a wayland compositor we don't make requests for
|
||||
@@ -1952,8 +1849,7 @@ check_needs_x11_pixmap (MetaWindowActor *self)
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
MetaCompositor *compositor;
|
||||
Window xwindow = priv->xwindow;
|
||||
Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
|
||||
|
||||
if (!priv->needs_pixmap)
|
||||
return;
|
||||
@@ -1965,8 +1861,6 @@ check_needs_x11_pixmap (MetaWindowActor *self)
|
||||
xwindow == clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)))
|
||||
return;
|
||||
|
||||
compositor = meta_display_get_compositor (display);
|
||||
|
||||
if (priv->x11_size_changed)
|
||||
{
|
||||
meta_window_actor_detach_x11_pixmap (self);
|
||||
@@ -1977,6 +1871,7 @@ check_needs_x11_pixmap (MetaWindowActor *self)
|
||||
|
||||
if (priv->back_pixmap == None)
|
||||
{
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
CoglTexture *texture;
|
||||
|
||||
meta_error_trap_push (display);
|
||||
@@ -2001,24 +1896,13 @@ check_needs_x11_pixmap (MetaWindowActor *self)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (compositor->no_mipmaps)
|
||||
meta_shaped_texture_set_create_mipmaps (META_SHAPED_TEXTURE (priv->actor),
|
||||
FALSE);
|
||||
|
||||
meta_shaped_texture_set_pixmap (META_SHAPED_TEXTURE (priv->actor),
|
||||
priv->back_pixmap);
|
||||
|
||||
texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor));
|
||||
|
||||
/*
|
||||
* This only works *after* actually setting the pixmap, so we have to
|
||||
* do it here.
|
||||
* See: http://bugzilla.clutter-project.org/show_bug.cgi?id=2236
|
||||
*/
|
||||
texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->back_pixmap, FALSE, NULL));
|
||||
if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture))))
|
||||
g_warning ("NOTE: Not using GLX TFP!\n");
|
||||
|
||||
/* ::size-changed is supposed to refer to meta_window_get_outer_rect().
|
||||
meta_surface_actor_set_texture (META_SURFACE_ACTOR (priv->surface), texture);
|
||||
|
||||
/* ::size-changed is supposed to refer to meta_window_get_frame_rect().
|
||||
* 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
|
||||
* borders) forces a new pixmap and we get here. In the rare case where
|
||||
@@ -2108,13 +1992,14 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self,
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen);
|
||||
gboolean redraw_queued;
|
||||
cairo_region_t *unobscured_region;
|
||||
|
||||
priv->received_x11_damage = TRUE;
|
||||
|
||||
if (meta_window_is_fullscreen (priv->window) && g_list_last (info->windows)->data == self && !priv->unredirected)
|
||||
{
|
||||
MetaRectangle window_rect;
|
||||
meta_window_get_outer_rect (priv->window, &window_rect);
|
||||
meta_window_get_frame_rect (priv->window, &window_rect);
|
||||
|
||||
if (window_rect.x == event->area.x &&
|
||||
window_rect.y == event->area.y &&
|
||||
@@ -2155,39 +2040,20 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self,
|
||||
if (!priv->mapped || priv->needs_pixmap)
|
||||
return;
|
||||
|
||||
redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
|
||||
event->area.x,
|
||||
event->area.y,
|
||||
event->area.width,
|
||||
event->area.height,
|
||||
clutter_actor_has_mapped_clones (priv->actor) ?
|
||||
NULL : priv->unobscured_region);
|
||||
unobscured_region =
|
||||
clutter_actor_has_mapped_clones (CLUTTER_ACTOR (priv->surface))
|
||||
? NULL : priv->unobscured_region;
|
||||
redraw_queued = meta_surface_actor_damage_area (priv->surface,
|
||||
event->area.x,
|
||||
event->area.y,
|
||||
event->area.width,
|
||||
event->area.height,
|
||||
unobscured_region);
|
||||
|
||||
priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_process_wayland_damage (MetaWindowActor *self,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
gboolean redraw_queued;
|
||||
|
||||
if (!priv->mapped)
|
||||
return;
|
||||
|
||||
redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
|
||||
x, y, width, height,
|
||||
clutter_actor_has_mapped_clones (priv->actor) ?
|
||||
NULL : priv->unobscured_region);
|
||||
|
||||
priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_sync_visibility (MetaWindowActor *self)
|
||||
{
|
||||
@@ -2247,12 +2113,18 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
guchar *mask_data;
|
||||
guint tex_width, tex_height;
|
||||
MetaShapedTexture *stex;
|
||||
CoglTexture *paint_tex, *mask_texture;
|
||||
int stride;
|
||||
cairo_t *cr;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
paint_tex = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor));
|
||||
stex = meta_surface_actor_get_texture (priv->surface);
|
||||
g_return_if_fail (stex);
|
||||
|
||||
meta_shaped_texture_set_mask_texture (stex, NULL);
|
||||
|
||||
paint_tex = meta_shaped_texture_get_texture (stex);
|
||||
if (paint_tex == NULL)
|
||||
return;
|
||||
|
||||
@@ -2300,12 +2172,18 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
||||
|
||||
if (meta_texture_rectangle_check (paint_tex))
|
||||
{
|
||||
mask_texture = meta_texture_rectangle_new (tex_width, tex_height,
|
||||
COGL_PIXEL_FORMAT_A_8,
|
||||
COGL_PIXEL_FORMAT_A_8,
|
||||
stride,
|
||||
mask_data,
|
||||
NULL /* error */);
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *context = clutter_backend_get_cogl_context (backend);
|
||||
|
||||
mask_texture = COGL_TEXTURE (cogl_texture_rectangle_new_with_size (context, tex_width, tex_height));
|
||||
cogl_texture_set_components (mask_texture, COGL_TEXTURE_COMPONENTS_A);
|
||||
cogl_texture_set_region (mask_texture,
|
||||
0, 0, /* src_x/y */
|
||||
0, 0, /* dst_x/y */
|
||||
tex_width, tex_height, /* dst_width/height */
|
||||
tex_width, tex_height, /* width/height */
|
||||
COGL_PIXEL_FORMAT_A_8,
|
||||
stride, mask_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2320,8 +2198,7 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
||||
mask_data);
|
||||
}
|
||||
|
||||
meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor),
|
||||
mask_texture);
|
||||
meta_shaped_texture_set_mask_texture (stex, mask_texture);
|
||||
cogl_object_unref (mask_texture);
|
||||
|
||||
g_free (mask_data);
|
||||
@@ -2351,7 +2228,6 @@ meta_window_actor_update_shape_region (MetaWindowActor *self,
|
||||
region = cairo_region_create_rectangle (client_area);
|
||||
}
|
||||
|
||||
meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor), NULL);
|
||||
if ((priv->window->shape_region != NULL) || (priv->window->frame != NULL))
|
||||
build_and_scan_frame_mask (self, client_area, region);
|
||||
|
||||
@@ -2368,7 +2244,6 @@ 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)
|
||||
@@ -2383,7 +2258,7 @@ meta_window_actor_update_input_region (MetaWindowActor *self,
|
||||
cairo_region_union (region, priv->window->input_region);
|
||||
cairo_region_translate (region, client_area->x, client_area->y);
|
||||
}
|
||||
else if (priv->window->shape_region != NULL)
|
||||
else if (priv->window->input_region != NULL)
|
||||
{
|
||||
region = cairo_region_reference (priv->window->input_region);
|
||||
}
|
||||
@@ -2395,7 +2270,7 @@ meta_window_actor_update_input_region (MetaWindowActor *self,
|
||||
region = cairo_region_create_rectangle (client_area);
|
||||
}
|
||||
|
||||
meta_shaped_texture_set_input_shape_region (stex, region);
|
||||
meta_surface_actor_set_input_region (priv->surface, region);
|
||||
cairo_region_destroy (region);
|
||||
}
|
||||
|
||||
@@ -2403,8 +2278,7 @@ static void
|
||||
meta_window_actor_update_opaque_region (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
|
||||
cairo_region_t *opaque_region;
|
||||
|
||||
if (priv->argb32 && priv->window->opaque_region != NULL)
|
||||
{
|
||||
@@ -2422,17 +2296,17 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self)
|
||||
* to be undefined, and considered a client bug. In mutter's
|
||||
* case, graphical glitches will occur.
|
||||
*/
|
||||
priv->opaque_region = cairo_region_copy (priv->window->opaque_region);
|
||||
cairo_region_translate (priv->opaque_region, borders.total.left, borders.total.top);
|
||||
cairo_region_intersect (priv->opaque_region, priv->shape_region);
|
||||
opaque_region = cairo_region_copy (priv->window->opaque_region);
|
||||
cairo_region_translate (opaque_region, borders.total.left, borders.total.top);
|
||||
cairo_region_intersect (opaque_region, priv->shape_region);
|
||||
}
|
||||
else if (priv->argb32)
|
||||
priv->opaque_region = NULL;
|
||||
opaque_region = NULL;
|
||||
else
|
||||
priv->opaque_region = cairo_region_reference (priv->shape_region);
|
||||
opaque_region = cairo_region_reference (priv->shape_region);
|
||||
|
||||
meta_shaped_texture_set_opaque_region (META_SHAPED_TEXTURE (priv->actor),
|
||||
priv->opaque_region);
|
||||
meta_surface_actor_set_opaque_region (priv->surface, opaque_region);
|
||||
cairo_region_destroy (opaque_region);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2459,8 +2333,12 @@ check_needs_reshape (MetaWindowActor *self)
|
||||
client_area.height = priv->window->rect.height;
|
||||
|
||||
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);
|
||||
|
||||
if (priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||
{
|
||||
meta_window_actor_update_input_region (self, &client_area);
|
||||
meta_window_actor_update_opaque_region (self);
|
||||
}
|
||||
|
||||
priv->needs_reshape = FALSE;
|
||||
}
|
||||
@@ -2475,68 +2353,7 @@ meta_window_actor_update_shape (MetaWindowActor *self)
|
||||
if (is_frozen (self))
|
||||
return;
|
||||
|
||||
clutter_actor_queue_redraw (priv->actor);
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_emit_size_changed (MetaWindowActor *self,
|
||||
MetaWaylandBuffer *new_buffer)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
int width = 0, height = 0;
|
||||
|
||||
if (new_buffer)
|
||||
{
|
||||
width = new_buffer->width;
|
||||
height = new_buffer->height;
|
||||
}
|
||||
|
||||
if (priv->last_width != width || priv->last_height != height)
|
||||
{
|
||||
meta_window_actor_update_shape (self);
|
||||
|
||||
/* ::size-changed is supposed to refer to meta_window_get_outer_rect()
|
||||
* but here we are only looking at buffer size changes.
|
||||
*
|
||||
* Emitting it here works pretty much OK because a new buffer size (which
|
||||
* will correspond to the outer rect with the addition of invisible
|
||||
* borders) also normally implies a change to the outer rect. In the rare
|
||||
* case where a change to the window size was exactly balanced by a
|
||||
* change to the invisible borders, we would miss emitting the signal.
|
||||
*/
|
||||
g_signal_emit (self, signals[SIZE_CHANGED], 0);
|
||||
|
||||
priv->last_width = width;
|
||||
priv->last_height = height;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_set_wayland_surface (MetaWindowActor *self,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
meta_shaped_texture_set_wayland_surface (META_SHAPED_TEXTURE (priv->actor),
|
||||
surface);
|
||||
if (surface && surface->buffer_ref.buffer)
|
||||
maybe_emit_size_changed (self, surface->buffer_ref.buffer);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_attach_wayland_buffer (MetaWindowActor *self,
|
||||
MetaWaylandBuffer *buffer)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaShapedTexture *stex = META_SHAPED_TEXTURE (priv->actor);
|
||||
CoglTexture *prev_tex = meta_shaped_texture_get_texture (stex);
|
||||
|
||||
meta_shaped_texture_attach_wayland_buffer (stex, buffer);
|
||||
|
||||
if (!prev_tex)
|
||||
meta_window_actor_sync_actor_geometry (self, FALSE);
|
||||
|
||||
maybe_emit_size_changed (self, buffer);
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->surface));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2772,23 +2589,9 @@ void
|
||||
meta_window_actor_update_opacity (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
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;
|
||||
MetaWindow *window = priv->window;
|
||||
|
||||
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);
|
||||
clutter_actor_set_opacity (CLUTTER_ACTOR (self->priv->surface), window->opacity);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -11,9 +11,8 @@
|
||||
#include "compositor-private.h"
|
||||
#include "meta-window-actor-private.h"
|
||||
#include "meta-window-group.h"
|
||||
#include "meta-background-actor-private.h"
|
||||
#include "meta-background-group-private.h"
|
||||
#include "window-private.h"
|
||||
#include "meta-cullable.h"
|
||||
|
||||
struct _MetaWindowGroupClass
|
||||
{
|
||||
@@ -27,7 +26,10 @@ struct _MetaWindowGroup
|
||||
MetaScreen *screen;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR);
|
||||
static void cullable_iface_init (MetaCullableInterface *iface);
|
||||
|
||||
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
|
||||
* window coordinates ranging [0,window-size]. Borrowed from clutter-utils.c
|
||||
@@ -87,6 +89,27 @@ painting_untransformed (MetaWindowGroup *window_group,
|
||||
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
|
||||
meta_window_group_paint (ClutterActor *actor)
|
||||
{
|
||||
@@ -95,12 +118,11 @@ meta_window_group_paint (ClutterActor *actor)
|
||||
ClutterActorIter iter;
|
||||
ClutterActor *child;
|
||||
cairo_rectangle_int_t visible_rect, clip_rect;
|
||||
int paint_x_offset, paint_y_offset;
|
||||
int paint_x_origin, paint_y_origin;
|
||||
int actor_x_origin, actor_y_origin;
|
||||
int paint_x_offset, paint_y_offset;
|
||||
|
||||
MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
|
||||
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
|
||||
@@ -135,9 +157,6 @@ meta_window_group_paint (ClutterActor *actor)
|
||||
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.width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
|
||||
visible_rect.height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
|
||||
@@ -155,138 +174,58 @@ meta_window_group_paint (ClutterActor *actor)
|
||||
|
||||
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 (!meta_is_wayland_compositor ())
|
||||
{
|
||||
info = meta_screen_get_compositor_data (window_group->screen);
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen);
|
||||
if (info->unredirected_window != NULL)
|
||||
{
|
||||
cairo_rectangle_int_t unredirected_rect;
|
||||
MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window);
|
||||
|
||||
meta_window_get_outer_rect (window, (MetaRectangle *)&unredirected_rect);
|
||||
meta_window_get_frame_rect (window, (MetaRectangle *)&unredirected_rect);
|
||||
cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect);
|
||||
cairo_region_subtract_rectangle (clip_region, &unredirected_rect);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 (!meta_is_wayland_compositor () &&
|
||||
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);
|
||||
}
|
||||
}
|
||||
meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region);
|
||||
|
||||
cairo_region_destroy (unobscured_region);
|
||||
cairo_region_destroy (clip_region);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
meta_cullable_reset_culling (META_CULLABLE (window_group));
|
||||
}
|
||||
|
||||
/* Adapted from clutter_actor_update_default_paint_volume() */
|
||||
static gboolean
|
||||
meta_window_group_get_paint_volume (ClutterActor *actor,
|
||||
meta_window_group_get_paint_volume (ClutterActor *self,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
return clutter_paint_volume_set_from_allocation (volume, actor);
|
||||
ClutterActorIter iter;
|
||||
ClutterActor *child;
|
||||
|
||||
clutter_actor_iter_init (&iter, self);
|
||||
while (clutter_actor_iter_next (&iter, &child))
|
||||
{
|
||||
const ClutterPaintVolume *child_volume;
|
||||
|
||||
if (!CLUTTER_ACTOR_IS_MAPPED (child))
|
||||
continue;
|
||||
|
||||
child_volume = clutter_actor_get_transformed_paint_volume (child, self);
|
||||
if (child_volume == NULL)
|
||||
return FALSE;
|
||||
|
||||
clutter_paint_volume_union (volume, child_volume);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -11,29 +11,9 @@
|
||||
* MetaWindowGroup:
|
||||
*
|
||||
* This class is a subclass of ClutterActor with special handling for
|
||||
* MetaWindowActor/MetaBackgroundActor/MetaBackgroundGroup when painting
|
||||
* children.
|
||||
*
|
||||
* 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.)
|
||||
* #MetaCullable when painting children. It uses code similar to
|
||||
* meta_cullable_cull_out_children(), but also has additional special
|
||||
* cases for the undirected window, and similar.
|
||||
*/
|
||||
|
||||
#define META_TYPE_WINDOW_GROUP (meta_window_group_get_type ())
|
||||
|
@@ -17,9 +17,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <string.h>
|
||||
|
||||
|
@@ -17,9 +17,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __META_WINDOW_SHAPE_H__
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
@@ -15,9 +15,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "region-utils.h"
|
||||
|
@@ -15,9 +15,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __META_REGION_UTILS_H__
|
||||
|
@@ -15,9 +15,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* The standard cycle-windows keybinding should be the key above the
|
||||
|
@@ -366,11 +366,25 @@ meta_barrier_fire_event (MetaBarrier *barrier,
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_display_process_barrier_event (MetaDisplay *display,
|
||||
XIBarrierEvent *xev)
|
||||
meta_display_process_barrier_event (MetaDisplay *display,
|
||||
XIEvent *event)
|
||||
{
|
||||
MetaBarrier *barrier;
|
||||
XIBarrierEvent *xev;
|
||||
|
||||
if (event == NULL)
|
||||
return FALSE;
|
||||
|
||||
switch (event->evtype)
|
||||
{
|
||||
case XI_BarrierHit:
|
||||
case XI_BarrierLeave:
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xev = (XIBarrierEvent *) event;
|
||||
barrier = g_hash_table_lookup (display->xids, &xev->barrier);
|
||||
if (barrier != NULL)
|
||||
{
|
||||
|
@@ -17,9 +17,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@@ -14,9 +14,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_BOXES_PRIVATE_H
|
||||
|
@@ -25,9 +25,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "boxes-private.h"
|
||||
|
@@ -18,9 +18,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -118,8 +116,6 @@ typedef struct
|
||||
{
|
||||
MetaRectangle orig;
|
||||
MetaRectangle current;
|
||||
MetaFrameBorders *borders;
|
||||
gboolean must_free_borders;
|
||||
ActionType action_type;
|
||||
gboolean is_user_action;
|
||||
|
||||
@@ -195,7 +191,6 @@ static gboolean constrain_partially_onscreen (MetaWindow *window,
|
||||
|
||||
static void setup_constraint_info (ConstraintInfo *info,
|
||||
MetaWindow *window,
|
||||
MetaFrameBorders *orig_borders,
|
||||
MetaMoveResizeFlags flags,
|
||||
int resize_gravity,
|
||||
const MetaRectangle *orig,
|
||||
@@ -204,13 +199,12 @@ static void place_window_if_needed (MetaWindow *window,
|
||||
ConstraintInfo *info);
|
||||
static void update_onscreen_requirements (MetaWindow *window,
|
||||
ConstraintInfo *info);
|
||||
static void extend_by_frame (MetaRectangle *rect,
|
||||
const MetaFrameBorders *borders);
|
||||
static void unextend_by_frame (MetaRectangle *rect,
|
||||
const MetaFrameBorders *borders);
|
||||
static inline void get_size_limits (const MetaWindow *window,
|
||||
const MetaFrameBorders *borders,
|
||||
gboolean include_frame,
|
||||
static void extend_by_frame (MetaWindow *window,
|
||||
MetaRectangle *rect);
|
||||
static void unextend_by_frame (MetaWindow *window,
|
||||
MetaRectangle *rect);
|
||||
static inline void get_size_limits (MetaWindow *window,
|
||||
gboolean include_frame,
|
||||
MetaRectangle *min_size,
|
||||
MetaRectangle *max_size);
|
||||
|
||||
@@ -280,7 +274,6 @@ do_all_constraints (MetaWindow *window,
|
||||
|
||||
void
|
||||
meta_window_constrain (MetaWindow *window,
|
||||
MetaFrameBorders *orig_borders,
|
||||
MetaMoveResizeFlags flags,
|
||||
int resize_gravity,
|
||||
const MetaRectangle *orig,
|
||||
@@ -303,7 +296,6 @@ meta_window_constrain (MetaWindow *window,
|
||||
|
||||
setup_constraint_info (&info,
|
||||
window,
|
||||
orig_borders,
|
||||
flags,
|
||||
resize_gravity,
|
||||
orig,
|
||||
@@ -333,19 +325,11 @@ meta_window_constrain (MetaWindow *window,
|
||||
* if this was a user move or user move-and-resize operation.
|
||||
*/
|
||||
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
|
||||
setup_constraint_info (ConstraintInfo *info,
|
||||
MetaWindow *window,
|
||||
MetaFrameBorders *orig_borders,
|
||||
MetaMoveResizeFlags flags,
|
||||
int resize_gravity,
|
||||
const MetaRectangle *orig,
|
||||
@@ -357,18 +341,6 @@ setup_constraint_info (ConstraintInfo *info,
|
||||
info->orig = *orig;
|
||||
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)
|
||||
info->action_type = ACTION_MOVE_AND_RESIZE;
|
||||
else if (flags & META_IS_RESIZE_ACTION)
|
||||
@@ -519,11 +491,12 @@ place_window_if_needed(MetaWindow *window,
|
||||
!window->minimized &&
|
||||
!window->fullscreen)
|
||||
{
|
||||
MetaRectangle placed_rect = info->orig;
|
||||
MetaRectangle placed_rect;
|
||||
MetaWorkspace *cur_workspace;
|
||||
const MetaMonitorInfo *monitor_info;
|
||||
|
||||
meta_window_place (window, info->borders, info->orig.x, info->orig.y,
|
||||
meta_window_get_frame_rect (window, &placed_rect);
|
||||
meta_window_place (window, info->orig.x, info->orig.y,
|
||||
&placed_rect.x, &placed_rect.y);
|
||||
did_placement = TRUE;
|
||||
|
||||
@@ -541,6 +514,7 @@ place_window_if_needed(MetaWindow *window,
|
||||
meta_workspace_get_onmonitor_region (cur_workspace,
|
||||
monitor_info->number);
|
||||
|
||||
meta_window_frame_rect_to_client_rect (window, &placed_rect, &placed_rect);
|
||||
|
||||
info->current.x = placed_rect.x;
|
||||
info->current.y = placed_rect.y;
|
||||
@@ -586,10 +560,6 @@ place_window_if_needed(MetaWindow *window,
|
||||
(window->maximize_vertically_after_placement ?
|
||||
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)
|
||||
{
|
||||
window->saved_rect = info->current;
|
||||
@@ -649,7 +619,7 @@ update_onscreen_requirements (MetaWindow *window,
|
||||
/* The require onscreen/on-single-monitor and titlebar_visible
|
||||
* stuff is relative to the outer window, not the inner
|
||||
*/
|
||||
extend_by_frame (&info->current, info->borders);
|
||||
extend_by_frame (window, &info->current);
|
||||
|
||||
/* Update whether we want future constraint runs to require the
|
||||
* window to be on fully onscreen.
|
||||
@@ -682,10 +652,13 @@ update_onscreen_requirements (MetaWindow *window,
|
||||
*/
|
||||
if (window->frame && window->decorated)
|
||||
{
|
||||
MetaFrameBorders borders;
|
||||
MetaRectangle titlebar_rect;
|
||||
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
|
||||
titlebar_rect = info->current;
|
||||
titlebar_rect.height = info->borders->visible.top;
|
||||
titlebar_rect.height = borders.visible.top;
|
||||
old = window->require_titlebar_visible;
|
||||
window->require_titlebar_visible =
|
||||
meta_rectangle_overlaps_with_region (info->usable_screen_region,
|
||||
@@ -698,39 +671,33 @@ update_onscreen_requirements (MetaWindow *window,
|
||||
}
|
||||
|
||||
/* Don't forget to restore the position of the window */
|
||||
unextend_by_frame (&info->current, info->borders);
|
||||
unextend_by_frame (window, &info->current);
|
||||
}
|
||||
|
||||
static void
|
||||
extend_by_frame (MetaRectangle *rect,
|
||||
const MetaFrameBorders *borders)
|
||||
extend_by_frame (MetaWindow *window,
|
||||
MetaRectangle *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;
|
||||
meta_window_client_rect_to_frame_rect (window, rect, rect);
|
||||
}
|
||||
|
||||
static void
|
||||
unextend_by_frame (MetaRectangle *rect,
|
||||
const MetaFrameBorders *borders)
|
||||
unextend_by_frame (MetaWindow *window,
|
||||
MetaRectangle *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;
|
||||
meta_window_frame_rect_to_client_rect (window, rect, rect);
|
||||
}
|
||||
|
||||
static inline void
|
||||
get_size_limits (const MetaWindow *window,
|
||||
const MetaFrameBorders *borders,
|
||||
gboolean include_frame,
|
||||
get_size_limits (MetaWindow *window,
|
||||
gboolean include_frame,
|
||||
MetaRectangle *min_size,
|
||||
MetaRectangle *max_size)
|
||||
{
|
||||
/* We pack the results into MetaRectangle structs just for convienience; we
|
||||
* 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->height = window->size_hints.min_height;
|
||||
max_size->width = window->size_hints.max_width;
|
||||
@@ -738,22 +705,8 @@ get_size_limits (const MetaWindow *window,
|
||||
|
||||
if (include_frame)
|
||||
{
|
||||
int fw = borders->visible.left + borders->visible.right;
|
||||
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;
|
||||
meta_window_client_rect_to_frame_rect (window, min_size, min_size);
|
||||
meta_window_client_rect_to_frame_rect (window, max_size, max_size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,18 +718,28 @@ constrain_modal_dialog (MetaWindow *window,
|
||||
{
|
||||
int x, y;
|
||||
MetaWindow *parent = meta_window_get_transient_for (window);
|
||||
MetaRectangle child_rect, parent_rect;
|
||||
gboolean constraint_already_satisfied;
|
||||
|
||||
if (!meta_window_is_attached_dialog (window))
|
||||
return TRUE;
|
||||
|
||||
x = parent->rect.x + (parent->rect.width / 2 - info->current.width / 2);
|
||||
y = parent->rect.y + (parent->rect.height / 2 - info->current.height / 2);
|
||||
if (parent->frame)
|
||||
{
|
||||
x += parent->frame->rect.x;
|
||||
y += parent->frame->rect.y;
|
||||
}
|
||||
/* We want to center the dialog on the parent, including the decorations
|
||||
for both of them. info->current is in client X window coordinates, so we need
|
||||
to convert them to frame coordinates, apply the centering and then
|
||||
convert back to client.
|
||||
*/
|
||||
|
||||
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);
|
||||
|
||||
@@ -841,19 +804,19 @@ constrain_maximization (MetaWindow *window,
|
||||
active_workspace_struts = window->screen->active_workspace->all_struts;
|
||||
|
||||
target_size = info->current;
|
||||
extend_by_frame (&target_size, info->borders);
|
||||
extend_by_frame (window, &target_size);
|
||||
meta_rectangle_expand_to_avoiding_struts (&target_size,
|
||||
&info->entire_monitor,
|
||||
direction,
|
||||
active_workspace_struts);
|
||||
}
|
||||
/* Now make target_size = maximized size of client window */
|
||||
unextend_by_frame (&target_size, info->borders);
|
||||
unextend_by_frame (window, &target_size);
|
||||
|
||||
/* Check min size constraints; max size constraints are ignored for maximized
|
||||
* windows, as per bug 327543.
|
||||
*/
|
||||
get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
|
||||
get_size_limits (window, FALSE, &min_size, &max_size);
|
||||
hminbad = target_size.width < min_size.width && window->maximized_horizontally;
|
||||
vminbad = target_size.height < min_size.height && window->maximized_vertically;
|
||||
if (hminbad || vminbad)
|
||||
@@ -907,12 +870,12 @@ constrain_tiling (MetaWindow *window,
|
||||
* use an external function for the actual calculation
|
||||
*/
|
||||
meta_window_get_current_tile_area (window, &target_size);
|
||||
unextend_by_frame (&target_size, info->borders);
|
||||
unextend_by_frame (window, &target_size);
|
||||
|
||||
/* Check min size constraints; max size constraints are ignored as for
|
||||
* maximized windows.
|
||||
*/
|
||||
get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
|
||||
get_size_limits (window, FALSE, &min_size, &max_size);
|
||||
hminbad = target_size.width < min_size.width;
|
||||
vminbad = target_size.height < min_size.height;
|
||||
if (hminbad || vminbad)
|
||||
@@ -955,7 +918,7 @@ constrain_fullscreen (MetaWindow *window,
|
||||
|
||||
monitor = info->entire_monitor;
|
||||
|
||||
get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
|
||||
get_size_limits (window, FALSE, &min_size, &max_size);
|
||||
too_big = !meta_rectangle_could_fit_rect (&monitor, &min_size);
|
||||
too_small = !meta_rectangle_could_fit_rect (&max_size, &monitor);
|
||||
if (too_big || too_small)
|
||||
@@ -1064,7 +1027,7 @@ constrain_size_limits (MetaWindow *window,
|
||||
return TRUE;
|
||||
|
||||
/* Determine whether constraint is already satisfied; exit if it is */
|
||||
get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
|
||||
get_size_limits (window, FALSE, &min_size, &max_size);
|
||||
/* We ignore max-size limits for maximized windows; see #327543 */
|
||||
if (window->maximized_horizontally)
|
||||
max_size.width = MAX (max_size.width, info->current.width);
|
||||
@@ -1256,8 +1219,8 @@ do_screen_and_monitor_relative_constraints (
|
||||
|
||||
/* Determine whether constraint applies; exit if it doesn't */
|
||||
how_far_it_can_be_smushed = info->current;
|
||||
get_size_limits (window, info->borders, TRUE, &min_size, &max_size);
|
||||
extend_by_frame (&info->current, info->borders);
|
||||
get_size_limits (window, TRUE, &min_size, &max_size);
|
||||
extend_by_frame (window, &info->current);
|
||||
|
||||
if (info->action_type != ACTION_MOVE)
|
||||
{
|
||||
@@ -1277,7 +1240,7 @@ do_screen_and_monitor_relative_constraints (
|
||||
&info->current);
|
||||
if (exit_early || constraint_satisfied || check_only)
|
||||
{
|
||||
unextend_by_frame (&info->current, info->borders);
|
||||
unextend_by_frame (window, &info->current);
|
||||
return constraint_satisfied;
|
||||
}
|
||||
|
||||
@@ -1301,7 +1264,7 @@ do_screen_and_monitor_relative_constraints (
|
||||
info->fixed_directions,
|
||||
&info->current);
|
||||
|
||||
unextend_by_frame (&info->current, info->borders);
|
||||
unextend_by_frame (window, &info->current);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1414,8 +1377,11 @@ constrain_titlebar_visible (MetaWindow *window,
|
||||
*/
|
||||
if (window->frame)
|
||||
{
|
||||
bottom_amount = info->current.height + info->borders->visible.bottom;
|
||||
vert_amount_onscreen = info->borders->visible.top;
|
||||
MetaFrameBorders borders;
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
|
||||
bottom_amount = info->current.height + borders.visible.bottom;
|
||||
vert_amount_onscreen = borders.visible.top;
|
||||
}
|
||||
else
|
||||
bottom_amount = vert_amount_offscreen;
|
||||
@@ -1489,8 +1455,11 @@ constrain_partially_onscreen (MetaWindow *window,
|
||||
*/
|
||||
if (window->frame)
|
||||
{
|
||||
bottom_amount = info->current.height + info->borders->visible.bottom;
|
||||
vert_amount_onscreen = info->borders->visible.top;
|
||||
MetaFrameBorders borders;
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
|
||||
bottom_amount = info->current.height + borders.visible.bottom;
|
||||
vert_amount_onscreen = borders.visible.top;
|
||||
}
|
||||
else
|
||||
bottom_amount = vert_amount_offscreen;
|
||||
|
@@ -17,9 +17,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_CONSTRAINTS_H
|
||||
@@ -40,7 +38,6 @@ typedef enum
|
||||
} MetaMoveResizeFlags;
|
||||
|
||||
void meta_window_constrain (MetaWindow *window,
|
||||
MetaFrameBorders *orig_borders,
|
||||
MetaMoveResizeFlags flags,
|
||||
int resize_gravity,
|
||||
const MetaRectangle *orig,
|
||||
|
@@ -18,9 +18,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -172,6 +170,7 @@ meta_core_queue_frame_resize (Display *xdisplay,
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
|
||||
meta_window_frame_size_changed (window);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -282,8 +281,7 @@ meta_core_lower_beneath_grab_window (Display *xdisplay,
|
||||
return;
|
||||
|
||||
changes.stack_mode = Below;
|
||||
changes.sibling = grab_window->frame ? grab_window->frame->xwindow
|
||||
: grab_window->xwindow;
|
||||
changes.sibling = meta_window_get_toplevel_xwindow (grab_window);
|
||||
|
||||
stack_window.any.type = META_WINDOW_CLIENT_TYPE_X11;
|
||||
stack_window.x11.xwindow = xwindow;
|
||||
@@ -476,26 +474,6 @@ meta_core_change_workspace (Display *xdisplay,
|
||||
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
|
||||
meta_core_show_window_menu (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
|
@@ -17,9 +17,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_CORE_H
|
||||
@@ -153,8 +151,6 @@ void meta_core_change_workspace (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
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,
|
||||
Window frame_xwindow);
|
||||
const char* meta_core_get_workspace_name_with_index (Display *xdisplay,
|
||||
|
@@ -17,9 +17,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE /* for kill() */
|
||||
@@ -43,14 +41,11 @@ static void meta_window_present_delete_dialog (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
|
||||
static void
|
||||
delete_ping_reply_func (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
delete_ping_reply_func (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
void *user_data)
|
||||
{
|
||||
meta_topic (META_DEBUG_PING,
|
||||
"Got reply to delete ping for %s\n",
|
||||
((MetaWindow*)user_data)->desc);
|
||||
meta_topic (META_DEBUG_PING, "Got reply to delete ping for %s\n", window->desc);
|
||||
|
||||
/* we do nothing */
|
||||
}
|
||||
@@ -68,12 +63,10 @@ dialog_exited (GPid pid, int status, gpointer user_data)
|
||||
}
|
||||
|
||||
static void
|
||||
delete_ping_timeout_func (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
delete_ping_timeout_func (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
void *user_data)
|
||||
{
|
||||
MetaWindow *window = user_data;
|
||||
char *window_title;
|
||||
gchar *window_content, *tmp;
|
||||
GPid dialog_pid;
|
||||
@@ -137,12 +130,11 @@ void
|
||||
meta_window_check_alive (MetaWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
meta_display_ping_window (window->display,
|
||||
window,
|
||||
timestamp,
|
||||
delete_ping_reply_func,
|
||||
delete_ping_timeout_func,
|
||||
window);
|
||||
meta_window_ping (window,
|
||||
timestamp,
|
||||
delete_ping_reply_func,
|
||||
delete_ping_timeout_func,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -19,9 +19,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_DISPLAY_PRIVATE_H
|
||||
@@ -39,6 +37,7 @@
|
||||
#include "keybindings-private.h"
|
||||
#include <meta/prefs.h>
|
||||
#include <meta/barrier.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
#include <libsn/sn.h>
|
||||
@@ -56,11 +55,6 @@ typedef struct _MetaWindowPropHooks MetaWindowPropHooks;
|
||||
|
||||
typedef struct MetaEdgeResistanceData MetaEdgeResistanceData;
|
||||
|
||||
typedef void (* MetaWindowPingFunc) (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
guint32 timestamp,
|
||||
gpointer user_data);
|
||||
|
||||
typedef enum {
|
||||
META_LIST_DEFAULT = 0, /* normal windows */
|
||||
META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */
|
||||
@@ -101,6 +95,8 @@ struct _MetaDisplay
|
||||
char *name;
|
||||
Display *xdisplay;
|
||||
|
||||
int clutter_event_filter;
|
||||
|
||||
Window leader_window;
|
||||
Window timestamp_pinging_window;
|
||||
|
||||
@@ -147,6 +143,14 @@ struct _MetaDisplay
|
||||
*/
|
||||
guint allow_terminal_deactivation : 1;
|
||||
|
||||
/* If true, server->focus_serial refers to us changing the focus; in
|
||||
* this case, we can ignore focus events that have exactly focus_serial,
|
||||
* since we take care to make another request immediately afterwards.
|
||||
* But if focus is being changed by another client, we have to accept
|
||||
* multiple events with the same serial.
|
||||
*/
|
||||
guint focused_by_us : 1;
|
||||
|
||||
guint static_gravity_works : 1;
|
||||
|
||||
/*< private-ish >*/
|
||||
@@ -179,7 +183,7 @@ struct _MetaDisplay
|
||||
guint32 window_sequence_counter;
|
||||
|
||||
/* Pings which we're waiting for a reply from */
|
||||
GSList *pending_pings;
|
||||
GHashTable *pending_pings;
|
||||
|
||||
/* Pending focus change */
|
||||
guint focus_timeout_id;
|
||||
@@ -189,7 +193,7 @@ struct _MetaDisplay
|
||||
MetaWindow* autoraise_window;
|
||||
|
||||
/* Alt+click button grabs */
|
||||
unsigned int window_grab_modifiers;
|
||||
ClutterModifierType window_grab_modifiers;
|
||||
|
||||
/* current window operation */
|
||||
MetaGrabOp grab_op;
|
||||
@@ -445,15 +449,6 @@ void meta_display_retheme_all (void);
|
||||
void meta_display_set_cursor_theme (const char *theme,
|
||||
int size);
|
||||
|
||||
void meta_display_ping_window (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
MetaWindowPingFunc ping_reply_func,
|
||||
MetaWindowPingFunc ping_timeout_func,
|
||||
void *user_data);
|
||||
gboolean meta_display_window_has_pending_pings (MetaDisplay *display,
|
||||
MetaWindow *window);
|
||||
|
||||
int meta_resize_gravity_from_grab_op (MetaGrabOp op);
|
||||
|
||||
gboolean meta_grab_op_is_moving (MetaGrabOp op);
|
||||
@@ -473,21 +468,17 @@ void meta_display_queue_autoraise_callback (MetaDisplay *display,
|
||||
void meta_display_remove_autoraise_callback (MetaDisplay *display);
|
||||
|
||||
void meta_display_overlay_key_activate (MetaDisplay *display);
|
||||
void meta_display_accelerator_activate (MetaDisplay *display,
|
||||
guint action,
|
||||
guint deviceid,
|
||||
guint timestamp);
|
||||
void meta_display_accelerator_activate (MetaDisplay *display,
|
||||
guint action,
|
||||
ClutterKeyEvent *event);
|
||||
gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display);
|
||||
|
||||
/* In above-tab-keycode.c */
|
||||
guint meta_display_get_above_tab_keycode (MetaDisplay *display);
|
||||
|
||||
gboolean meta_display_handle_event (MetaDisplay *display,
|
||||
XEvent *event);
|
||||
|
||||
#ifdef HAVE_XI23
|
||||
gboolean meta_display_process_barrier_event (MetaDisplay *display,
|
||||
XIBarrierEvent *event);
|
||||
gboolean meta_display_process_barrier_event (MetaDisplay *display,
|
||||
XIEvent *event);
|
||||
#endif /* HAVE_XI23 */
|
||||
|
||||
void meta_display_set_input_focus_xwindow (MetaDisplay *display,
|
||||
|
2864
src/core/display.c
2864
src/core/display.c
File diff suppressed because it is too large
Load Diff
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -985,7 +983,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
|
||||
{
|
||||
MetaRectangle *new_rect;
|
||||
new_rect = g_new (MetaRectangle, 1);
|
||||
meta_window_get_outer_rect (cur_window, new_rect);
|
||||
meta_window_get_frame_rect (cur_window, new_rect);
|
||||
obscuring_windows = g_slist_prepend (obscuring_windows, new_rect);
|
||||
window_stacking =
|
||||
g_slist_prepend (window_stacking, GINT_TO_POINTER (stack_position));
|
||||
@@ -1010,7 +1008,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
|
||||
{
|
||||
MetaRectangle cur_rect;
|
||||
MetaWindow *cur_window = cur_window_iter->data;
|
||||
meta_window_get_outer_rect (cur_window, &cur_rect);
|
||||
meta_window_get_frame_rect (cur_window, &cur_rect);
|
||||
|
||||
/* Check if we want to use this window's edges for edge
|
||||
* resistance (note that dock edges are considered screen edges
|
||||
@@ -1151,7 +1149,7 @@ meta_window_edge_resistance_for_move (MetaWindow *window,
|
||||
MetaRectangle old_outer, proposed_outer, new_outer;
|
||||
gboolean is_resize;
|
||||
|
||||
meta_window_get_outer_rect (window, &old_outer);
|
||||
meta_window_get_frame_rect (window, &old_outer);
|
||||
|
||||
proposed_outer = old_outer;
|
||||
proposed_outer.x += (*new_x - old_x);
|
||||
@@ -1237,7 +1235,7 @@ meta_window_edge_resistance_for_resize (MetaWindow *window,
|
||||
int proposed_outer_width, proposed_outer_height;
|
||||
gboolean is_resize;
|
||||
|
||||
meta_window_get_outer_rect (window, &old_outer);
|
||||
meta_window_get_frame_rect (window, &old_outer);
|
||||
proposed_outer_width = old_outer.width + (*new_width - old_width);
|
||||
proposed_outer_height = old_outer.height + (*new_height - old_height);
|
||||
meta_rectangle_resize_with_gravity (&old_outer,
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_EDGE_RESISTANCE_H
|
||||
|
@@ -15,9 +15,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -18,9 +18,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -52,9 +50,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
if (window->frame)
|
||||
return;
|
||||
|
||||
/* See comment below for why this is required. */
|
||||
meta_display_grab (window->display);
|
||||
|
||||
frame = g_new (MetaFrame, 1);
|
||||
|
||||
frame->window = window;
|
||||
@@ -69,6 +64,7 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
|
||||
frame->mapped = FALSE;
|
||||
frame->is_flashing = FALSE;
|
||||
frame->borders_cached = FALSE;
|
||||
|
||||
meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
|
||||
window->desc,
|
||||
@@ -119,14 +115,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
|
||||
meta_display_register_x_window (window->display, &frame->xwindow, window);
|
||||
|
||||
/* Reparent the client window; it may be destroyed,
|
||||
* thus the error trap. We'll get a destroy notify later
|
||||
* and free everything. Comment in FVWM source code says
|
||||
* we need a server grab or the child can get its MapNotify
|
||||
* before we've finished reparenting and getting the decoration
|
||||
* window onscreen, so ensure_frame must be called with
|
||||
* a grab.
|
||||
*/
|
||||
meta_error_trap_push (window->display);
|
||||
if (window->mapped)
|
||||
{
|
||||
@@ -169,8 +157,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
|
||||
/* Move keybindings to frame instead of window */
|
||||
meta_window_grab_keys (window);
|
||||
|
||||
meta_display_ungrab (window->display);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -334,9 +320,23 @@ meta_frame_calc_borders (MetaFrame *frame,
|
||||
if (frame == NULL)
|
||||
meta_frame_borders_clear (borders);
|
||||
else
|
||||
meta_ui_get_frame_borders (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
borders);
|
||||
{
|
||||
if (!frame->borders_cached)
|
||||
{
|
||||
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
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_FRAME_PRIVATE_H
|
||||
@@ -41,6 +39,8 @@ struct _MetaFrame
|
||||
*/
|
||||
MetaRectangle rect;
|
||||
|
||||
MetaFrameBorders cached_borders; /* valid if borders_cached is set */
|
||||
|
||||
/* position of client, size of frame */
|
||||
int child_x;
|
||||
int child_y;
|
||||
@@ -50,6 +50,7 @@ struct _MetaFrame
|
||||
guint mapped : 1;
|
||||
guint need_reapply_frame_shape : 1;
|
||||
guint is_flashing : 1; /* used by the visual bell flash */
|
||||
guint borders_cached : 1;
|
||||
};
|
||||
|
||||
void meta_window_ensure_frame (MetaWindow *window);
|
||||
@@ -68,6 +69,8 @@ gboolean meta_frame_sync_to_window (MetaFrame *frame,
|
||||
gboolean need_move,
|
||||
gboolean need_resize);
|
||||
|
||||
void meta_frame_clear_cached_borders (MetaFrame *frame);
|
||||
|
||||
cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame);
|
||||
|
||||
void meta_frame_get_mask (MetaFrame *frame,
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_GROUP_PRIVATE_H
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_GROUP_PROPS_H
|
||||
|
@@ -15,9 +15,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_ICON_CACHE_H
|
||||
|
@@ -21,9 +21,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_KEYBINDINGS_PRIVATE_H
|
||||
@@ -66,9 +64,9 @@ gboolean meta_window_grab_all_keys (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
void meta_window_ungrab_all_keys (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
gboolean meta_display_process_key_event (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XIDeviceEvent *event);
|
||||
gboolean meta_display_process_key_event (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
ClutterKeyEvent *event);
|
||||
void meta_display_process_mapping_event (MetaDisplay *display,
|
||||
XEvent *event);
|
||||
|
||||
@@ -81,7 +79,3 @@ gboolean meta_prefs_remove_keybinding (const char *name);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -17,9 +17,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -14,9 +14,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Giovanni Campagna <gcampagn@redhat.com>
|
||||
*/
|
||||
@@ -31,18 +29,18 @@
|
||||
gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
XEvent *xevent);
|
||||
|
||||
void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursor cursor);
|
||||
void meta_cursor_tracker_revert_root (MetaCursorTracker *tracker);
|
||||
void meta_cursor_tracker_set_buffer (MetaCursorTracker *tracker,
|
||||
struct wl_resource *buffer,
|
||||
int hot_x,
|
||||
int hot_y);
|
||||
void meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursor cursor);
|
||||
void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
|
||||
struct wl_resource *buffer,
|
||||
int hot_x,
|
||||
int hot_y);
|
||||
void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker);
|
||||
void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursor cursor);
|
||||
|
||||
void meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
|
||||
int new_x,
|
||||
int new_y);
|
||||
void meta_cursor_tracker_paint (MetaCursorTracker *tracker);
|
||||
void meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker,
|
||||
ClutterActor *stage);
|
||||
#endif
|
||||
|
@@ -14,9 +14,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Giovanni Campagna <gcampagn@redhat.com>
|
||||
*/
|
||||
@@ -68,11 +66,34 @@ struct _MetaCursorTracker {
|
||||
MetaScreen *screen;
|
||||
|
||||
gboolean is_showing;
|
||||
gboolean has_cursor;
|
||||
gboolean has_hw_cursor;
|
||||
|
||||
MetaCursorReference *sprite;
|
||||
/* The cursor tracker stores the cursor for the current grab
|
||||
* operation, the cursor for the window with pointer focus, and
|
||||
* the cursor for the root window, which contains either the
|
||||
* default arrow cursor or the 'busy' hourglass if we're launching
|
||||
* an app.
|
||||
*
|
||||
* We choose the first one available -- if there's a grab cursor,
|
||||
* we choose that cursor, if there's window cursor, we choose that,
|
||||
* otherwise we choose the root cursor.
|
||||
*
|
||||
* The displayed_cursor contains the chosen cursor.
|
||||
*/
|
||||
MetaCursorReference *displayed_cursor;
|
||||
|
||||
MetaCursorReference *grab_cursor;
|
||||
|
||||
/* Wayland clients can set a NULL buffer as their cursor
|
||||
* explicitly, which means that we shouldn't display anything.
|
||||
* So, we can't simply store a NULL in window_cursor to
|
||||
* determine an unset window cursor; we need an extra boolean.
|
||||
*/
|
||||
gboolean has_window_cursor;
|
||||
MetaCursorReference *window_cursor;
|
||||
|
||||
MetaCursorReference *root_cursor;
|
||||
|
||||
MetaCursorReference *default_cursors[META_CURSOR_LAST];
|
||||
|
||||
int current_x, current_y;
|
||||
@@ -98,12 +119,10 @@ enum {
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
static void meta_cursor_tracker_set_sprite (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *sprite);
|
||||
|
||||
static void meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker,
|
||||
MetaCRTC *crtc,
|
||||
gboolean has_hw_cursor);
|
||||
static void sync_cursor (MetaCursorTracker *tracker);
|
||||
|
||||
static MetaCursorReference *
|
||||
meta_cursor_reference_ref (MetaCursorReference *self)
|
||||
@@ -286,7 +305,6 @@ meta_cursor_reference_from_theme (MetaCursorTracker *tracker,
|
||||
self->texture = cogl_texture_2d_new_from_data (cogl_context,
|
||||
width, height,
|
||||
cogl_format,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
rowstride,
|
||||
(uint8_t*)image->pixels,
|
||||
NULL);
|
||||
@@ -346,13 +364,15 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
|
||||
ClutterBackend *backend;
|
||||
CoglContext *cogl_context;
|
||||
MetaCursorReference *self;
|
||||
CoglPixelFormat cogl_format, cogl_internal_format;
|
||||
CoglPixelFormat cogl_format;
|
||||
struct wl_shm_buffer *shm_buffer;
|
||||
uint32_t gbm_format;
|
||||
|
||||
self = g_slice_new0 (MetaCursorReference);
|
||||
self->ref_count = 1;
|
||||
|
||||
self->hot_x = hot_x;
|
||||
self->hot_y = hot_y;
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
|
||||
@@ -368,37 +388,31 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
|
||||
cogl_internal_format = COGL_PIXEL_FORMAT_ANY;
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
|
||||
cogl_internal_format = COGL_PIXEL_FORMAT_RGB_888;
|
||||
gbm_format = GBM_FORMAT_XRGB8888;
|
||||
break;
|
||||
#else
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
|
||||
cogl_internal_format = COGL_PIXEL_FORMAT_ANY;
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
cogl_format = COGL_PIXEL_FORMAT_BGRA_8888;
|
||||
cogl_internal_format = COGL_PIXEL_FORMAT_BGR_888;
|
||||
gbm_format = GBM_FORMAT_XRGB8888;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
|
||||
cogl_internal_format = COGL_PIXEL_FORMAT_ANY;
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
}
|
||||
|
||||
self->texture = cogl_texture_2d_new_from_data (cogl_context,
|
||||
width, height,
|
||||
cogl_format,
|
||||
cogl_internal_format,
|
||||
rowstride,
|
||||
wl_shm_buffer_get_data (shm_buffer),
|
||||
NULL);
|
||||
@@ -454,47 +468,10 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
|
||||
|
||||
if (tracker->gbm)
|
||||
{
|
||||
cogl_format = cogl_texture_get_format (COGL_TEXTURE (self->texture));
|
||||
switch (cogl_format)
|
||||
{
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
case COGL_PIXEL_FORMAT_ARGB_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_ARGB_8888:
|
||||
gbm_format = GBM_FORMAT_BGRA8888;
|
||||
break;
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888:
|
||||
break;
|
||||
case COGL_PIXEL_FORMAT_RGB_888:
|
||||
break;
|
||||
#else
|
||||
case COGL_PIXEL_FORMAT_ARGB_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_ARGB_8888:
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888:
|
||||
gbm_format = GBM_FORMAT_BGRA8888;
|
||||
break;
|
||||
case COGL_PIXEL_FORMAT_RGB_888:
|
||||
gbm_format = GBM_FORMAT_RGB888;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
meta_warning ("Unknown cogl format %d\n", cogl_format);
|
||||
return self;
|
||||
}
|
||||
|
||||
if (gbm_device_is_format_supported (tracker->gbm, gbm_format,
|
||||
GBM_BO_USE_CURSOR_64X64))
|
||||
{
|
||||
self->bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER,
|
||||
buffer, GBM_BO_USE_CURSOR_64X64);
|
||||
if (!self->bo)
|
||||
meta_warning ("Importing HW cursor from wl_buffer failed\n");
|
||||
}
|
||||
else
|
||||
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
|
||||
self->bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER,
|
||||
buffer, GBM_BO_USE_CURSOR_64X64);
|
||||
if (!self->bo)
|
||||
meta_warning ("Importing HW cursor from wl_buffer failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -518,8 +495,8 @@ meta_cursor_tracker_finalize (GObject *object)
|
||||
MetaCursorTracker *self = META_CURSOR_TRACKER (object);
|
||||
int i;
|
||||
|
||||
if (self->sprite)
|
||||
meta_cursor_reference_unref (self->sprite);
|
||||
if (self->displayed_cursor)
|
||||
meta_cursor_reference_unref (self->displayed_cursor);
|
||||
if (self->root_cursor)
|
||||
meta_cursor_reference_unref (self->root_cursor);
|
||||
|
||||
@@ -593,9 +570,12 @@ make_wayland_cursor_tracker (MetaScreen *screen)
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
compositor->seat->cursor_tracker = self;
|
||||
|
||||
self->drm_fd = compositor->drm_fd;
|
||||
if (self->drm_fd >= 0)
|
||||
self->gbm = gbm_create_device (compositor->drm_fd);
|
||||
if (meta_wayland_compositor_is_native (compositor))
|
||||
{
|
||||
CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (ctx));
|
||||
self->drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
|
||||
self->gbm = gbm_create_device (self->drm_fd);
|
||||
}
|
||||
|
||||
monitors = meta_monitor_manager_get ();
|
||||
g_signal_connect_object (monitors, "monitors-changed",
|
||||
@@ -644,6 +624,18 @@ meta_cursor_tracker_get_for_screen (MetaScreen *screen)
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
set_window_cursor (MetaCursorTracker *tracker,
|
||||
gboolean has_cursor,
|
||||
MetaCursorReference *cursor)
|
||||
{
|
||||
g_clear_pointer (&tracker->window_cursor, meta_cursor_reference_unref);
|
||||
if (cursor)
|
||||
tracker->window_cursor = meta_cursor_reference_ref (cursor);
|
||||
tracker->has_window_cursor = has_cursor;
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
XEvent *xevent)
|
||||
@@ -660,8 +652,7 @@ meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
if (notify_event->subtype != XFixesDisplayCursorNotify)
|
||||
return FALSE;
|
||||
|
||||
g_clear_pointer (&tracker->sprite, meta_cursor_reference_unref);
|
||||
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
|
||||
set_window_cursor (tracker, FALSE, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -675,7 +666,7 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
gboolean free_cursor_data;
|
||||
CoglContext *ctx;
|
||||
|
||||
if (tracker->sprite)
|
||||
if (tracker->has_window_cursor)
|
||||
return;
|
||||
|
||||
cursor_image = XFixesGetCursorImage (tracker->screen->display->xdisplay);
|
||||
@@ -713,7 +704,6 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
cursor_image->width,
|
||||
cursor_image->height,
|
||||
CLUTTER_CAIRO_FORMAT_ARGB32,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
cursor_image->width * 4, /* stride */
|
||||
cursor_data,
|
||||
NULL);
|
||||
@@ -723,9 +713,11 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
|
||||
if (sprite != NULL)
|
||||
{
|
||||
tracker->sprite = meta_cursor_reference_take_texture (sprite);
|
||||
tracker->sprite->hot_x = cursor_image->xhot;
|
||||
tracker->sprite->hot_y = cursor_image->yhot;
|
||||
MetaCursorReference *cursor = meta_cursor_reference_take_texture (sprite);
|
||||
cursor->hot_x = cursor_image->xhot;
|
||||
cursor->hot_y = cursor_image->yhot;
|
||||
|
||||
set_window_cursor (tracker, TRUE, cursor);
|
||||
}
|
||||
XFree (cursor_image);
|
||||
}
|
||||
@@ -743,8 +735,8 @@ meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
|
||||
if (!meta_is_wayland_compositor ())
|
||||
ensure_xfixes_cursor (tracker);
|
||||
|
||||
if (tracker->sprite)
|
||||
return COGL_TEXTURE (tracker->sprite->texture);
|
||||
if (tracker->displayed_cursor)
|
||||
return COGL_TEXTURE (tracker->displayed_cursor->texture);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@@ -766,12 +758,13 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
|
||||
if (!meta_is_wayland_compositor ())
|
||||
ensure_xfixes_cursor (tracker);
|
||||
|
||||
if (tracker->sprite)
|
||||
if (tracker->displayed_cursor)
|
||||
{
|
||||
MetaCursorReference *displayed_cursor = tracker->displayed_cursor;
|
||||
if (x)
|
||||
*x = tracker->sprite->hot_x;
|
||||
*x = displayed_cursor->hot_x;
|
||||
if (y)
|
||||
*y = tracker->sprite->hot_y;
|
||||
*y = displayed_cursor->hot_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -786,14 +779,46 @@ static MetaCursorReference *
|
||||
ensure_wayland_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursor cursor)
|
||||
{
|
||||
if (tracker->default_cursors[cursor])
|
||||
return tracker->default_cursors[cursor];
|
||||
|
||||
tracker->default_cursors[cursor] = meta_cursor_reference_from_theme (tracker, cursor);
|
||||
if (!tracker->default_cursors[cursor])
|
||||
meta_warning ("Failed to load cursor from theme\n");
|
||||
{
|
||||
tracker->default_cursors[cursor] = meta_cursor_reference_from_theme (tracker, cursor);
|
||||
if (!tracker->default_cursors[cursor])
|
||||
meta_warning ("Failed to load cursor from theme\n");
|
||||
}
|
||||
|
||||
return tracker->default_cursors[cursor];
|
||||
return meta_cursor_reference_ref (tracker->default_cursors[cursor]);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursor cursor)
|
||||
{
|
||||
g_clear_pointer (&tracker->grab_cursor, meta_cursor_reference_unref);
|
||||
if (cursor != META_CURSOR_DEFAULT)
|
||||
tracker->grab_cursor = ensure_wayland_cursor (tracker, cursor);
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
|
||||
struct wl_resource *buffer,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
MetaCursorReference *cursor;
|
||||
|
||||
if (buffer)
|
||||
cursor = meta_cursor_reference_from_buffer (tracker, buffer, hot_x, hot_y);
|
||||
else
|
||||
cursor = NULL;
|
||||
|
||||
set_window_cursor (tracker, TRUE, cursor);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
set_window_cursor (tracker, FALSE, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -813,21 +838,12 @@ meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
||||
/* Now update the real root cursor */
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaCursorReference *ref;
|
||||
|
||||
ref = ensure_wayland_cursor (tracker, cursor);
|
||||
|
||||
g_clear_pointer (&tracker->root_cursor, meta_cursor_reference_unref);
|
||||
tracker->root_cursor = meta_cursor_reference_ref (ref);
|
||||
tracker->root_cursor = ensure_wayland_cursor (tracker, cursor);
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_revert_root (MetaCursorTracker *tracker)
|
||||
{
|
||||
meta_cursor_tracker_set_sprite (tracker, tracker->root_cursor);
|
||||
}
|
||||
|
||||
static void
|
||||
update_hw_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
@@ -836,7 +852,7 @@ update_hw_cursor (MetaCursorTracker *tracker)
|
||||
unsigned int i, n_crtcs;
|
||||
gboolean enabled;
|
||||
|
||||
enabled = tracker->has_cursor && tracker->sprite->bo != NULL;
|
||||
enabled = tracker->displayed_cursor && tracker->displayed_cursor->bo != NULL;
|
||||
tracker->has_hw_cursor = enabled;
|
||||
|
||||
monitors = meta_monitor_manager_get ();
|
||||
@@ -882,105 +898,51 @@ move_hw_cursor (MetaCursorTracker *tracker)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_set_buffer (MetaCursorTracker *tracker,
|
||||
struct wl_resource *buffer,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
static MetaCursorReference *
|
||||
get_displayed_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaCursorReference *new_cursor;
|
||||
if (!tracker->is_showing)
|
||||
return NULL;
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
new_cursor = meta_cursor_reference_from_buffer (tracker, buffer, hot_x, hot_y);
|
||||
meta_cursor_tracker_set_sprite (tracker, new_cursor);
|
||||
meta_cursor_reference_unref (new_cursor);
|
||||
}
|
||||
else
|
||||
meta_cursor_tracker_set_sprite (tracker, NULL);
|
||||
if (tracker->grab_cursor)
|
||||
return tracker->grab_cursor;
|
||||
|
||||
if (tracker->has_window_cursor)
|
||||
return tracker->window_cursor;
|
||||
|
||||
return tracker->root_cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_tracker_set_sprite (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *sprite)
|
||||
sync_displayed_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
MetaCursorReference *displayed_cursor = get_displayed_cursor (tracker);
|
||||
|
||||
if (sprite == tracker->sprite)
|
||||
if (tracker->displayed_cursor == displayed_cursor)
|
||||
return;
|
||||
|
||||
g_clear_pointer (&tracker->sprite, meta_cursor_reference_unref);
|
||||
g_clear_pointer (&tracker->displayed_cursor, meta_cursor_reference_unref);
|
||||
if (displayed_cursor)
|
||||
tracker->displayed_cursor = meta_cursor_reference_ref (displayed_cursor);
|
||||
|
||||
if (sprite)
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
tracker->sprite = meta_cursor_reference_ref (sprite);
|
||||
cogl_pipeline_set_layer_texture (tracker->pipeline, 0, COGL_TEXTURE (tracker->sprite->texture));
|
||||
}
|
||||
else
|
||||
cogl_pipeline_set_layer_texture (tracker->pipeline, 0, NULL);
|
||||
if (displayed_cursor)
|
||||
cogl_pipeline_set_layer_texture (tracker->pipeline, 0, COGL_TEXTURE (displayed_cursor->texture));
|
||||
else
|
||||
cogl_pipeline_set_layer_texture (tracker->pipeline, 0, NULL);
|
||||
|
||||
tracker->has_cursor = tracker->sprite != NULL && tracker->is_showing;
|
||||
update_hw_cursor (tracker);
|
||||
update_hw_cursor (tracker);
|
||||
}
|
||||
|
||||
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
|
||||
|
||||
meta_cursor_tracker_update_position (tracker, tracker->current_x, tracker->current_y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
|
||||
int new_x,
|
||||
int new_y)
|
||||
{
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
|
||||
tracker->current_x = new_x;
|
||||
tracker->current_y = new_y;
|
||||
|
||||
if (tracker->sprite)
|
||||
{
|
||||
tracker->current_rect.x = tracker->current_x - tracker->sprite->hot_x;
|
||||
tracker->current_rect.y = tracker->current_y - tracker->sprite->hot_y;
|
||||
tracker->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (tracker->sprite->texture));
|
||||
tracker->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (tracker->sprite->texture));
|
||||
}
|
||||
else
|
||||
{
|
||||
tracker->current_rect.x = 0;
|
||||
tracker->current_rect.y = 0;
|
||||
tracker->current_rect.width = 0;
|
||||
tracker->current_rect.height = 0;
|
||||
}
|
||||
|
||||
if (tracker->has_hw_cursor)
|
||||
move_hw_cursor (tracker);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_paint (MetaCursorTracker *tracker)
|
||||
{
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
|
||||
if (tracker->has_hw_cursor || !tracker->has_cursor)
|
||||
return;
|
||||
|
||||
cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
|
||||
tracker->pipeline,
|
||||
tracker->current_rect.x,
|
||||
tracker->current_rect.y,
|
||||
tracker->current_rect.x +
|
||||
tracker->current_rect.width,
|
||||
tracker->current_rect.y +
|
||||
tracker->current_rect.height);
|
||||
|
||||
tracker->previous_rect = tracker->current_rect;
|
||||
tracker->previous_is_valid = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker,
|
||||
ClutterActor *stage)
|
||||
static void
|
||||
meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
ClutterActor *stage = compositor->stage;
|
||||
cairo_rectangle_int_t clip;
|
||||
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
@@ -997,7 +959,7 @@ meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker,
|
||||
tracker->previous_is_valid = FALSE;
|
||||
}
|
||||
|
||||
if (tracker->has_hw_cursor || !tracker->has_cursor)
|
||||
if (tracker->has_hw_cursor || !tracker->displayed_cursor)
|
||||
return;
|
||||
|
||||
clip.x = tracker->current_rect.x;
|
||||
@@ -1007,6 +969,72 @@ meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker,
|
||||
clutter_actor_queue_redraw_with_clip (stage, &clip);
|
||||
}
|
||||
|
||||
static void
|
||||
sync_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaCursorReference *displayed_cursor;
|
||||
|
||||
sync_displayed_cursor (tracker);
|
||||
displayed_cursor = tracker->displayed_cursor;
|
||||
|
||||
if (displayed_cursor)
|
||||
{
|
||||
tracker->current_rect.x = tracker->current_x - displayed_cursor->hot_x;
|
||||
tracker->current_rect.y = tracker->current_y - displayed_cursor->hot_y;
|
||||
tracker->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (displayed_cursor->texture));
|
||||
tracker->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (displayed_cursor->texture));
|
||||
}
|
||||
else
|
||||
{
|
||||
tracker->current_rect.x = 0;
|
||||
tracker->current_rect.y = 0;
|
||||
tracker->current_rect.width = 0;
|
||||
tracker->current_rect.height = 0;
|
||||
}
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
if (tracker->has_hw_cursor)
|
||||
move_hw_cursor (tracker);
|
||||
else
|
||||
meta_cursor_tracker_queue_redraw (tracker);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
|
||||
int new_x,
|
||||
int new_y)
|
||||
{
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
|
||||
tracker->current_x = new_x;
|
||||
tracker->current_y = new_y;
|
||||
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_paint (MetaCursorTracker *tracker)
|
||||
{
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
|
||||
if (tracker->has_hw_cursor || !tracker->displayed_cursor)
|
||||
return;
|
||||
|
||||
cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
|
||||
tracker->pipeline,
|
||||
tracker->current_rect.x,
|
||||
tracker->current_rect.y,
|
||||
tracker->current_rect.x +
|
||||
tracker->current_rect.width,
|
||||
tracker->current_rect.y +
|
||||
tracker->current_rect.height);
|
||||
|
||||
tracker->previous_rect = tracker->current_rect;
|
||||
tracker->previous_is_valid = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker,
|
||||
MetaCRTC *crtc,
|
||||
@@ -1014,15 +1042,16 @@ meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker,
|
||||
{
|
||||
if (has)
|
||||
{
|
||||
MetaCursorReference *displayed_cursor = tracker->displayed_cursor;
|
||||
union gbm_bo_handle handle;
|
||||
int width, height;
|
||||
int hot_x, hot_y;
|
||||
|
||||
handle = gbm_bo_get_handle (tracker->sprite->bo);
|
||||
width = gbm_bo_get_width (tracker->sprite->bo);
|
||||
height = gbm_bo_get_height (tracker->sprite->bo);
|
||||
hot_x = tracker->sprite->hot_x;
|
||||
hot_y = tracker->sprite->hot_y;
|
||||
handle = gbm_bo_get_handle (displayed_cursor->bo);
|
||||
width = gbm_bo_get_width (displayed_cursor->bo);
|
||||
height = gbm_bo_get_height (displayed_cursor->bo);
|
||||
hot_x = displayed_cursor->hot_x;
|
||||
hot_y = displayed_cursor->hot_y;
|
||||
|
||||
drmModeSetCursor2 (tracker->drm_fd, crtc->crtc_id, handle.u32,
|
||||
width, height, hot_x, hot_y);
|
||||
@@ -1098,13 +1127,7 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaWaylandCompositor *compositor;
|
||||
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
|
||||
tracker->has_cursor = tracker->sprite != NULL && visible;
|
||||
update_hw_cursor (tracker);
|
||||
meta_cursor_tracker_queue_redraw (tracker, compositor->stage);
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -14,9 +14,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Adapted from gnome-session/gnome-session/gs-idle-monitor.c and
|
||||
* from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c
|
||||
|
@@ -14,9 +14,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Adapted from gnome-session/gnome-session/gs-idle-monitor.c and
|
||||
* from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c
|
||||
@@ -949,6 +947,8 @@ on_bus_acquired (GDBusConnection *connection,
|
||||
for (iter = devices; iter; iter = iter->next)
|
||||
on_device_added (device_manager, iter->data, manager);
|
||||
|
||||
g_slist_free (devices);
|
||||
|
||||
g_signal_connect_object (device_manager, "device-added",
|
||||
G_CALLBACK (on_device_added), manager, 0);
|
||||
g_signal_connect_object (device_manager, "device-removed",
|
||||
|
@@ -13,9 +13,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* This file is shared between mutter (src/core/meta-xrandr-shared.h)
|
||||
|
@@ -20,9 +20,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -99,8 +97,9 @@ static gboolean meta_monitor_config_assign_crtcs (MetaConfiguration *config,
|
||||
GPtrArray *crtcs,
|
||||
GPtrArray *outputs);
|
||||
|
||||
static void power_client_changed_cb (UpClient *client,
|
||||
gpointer user_data);
|
||||
static void power_client_changed_cb (UpClient *client,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data);
|
||||
|
||||
static void
|
||||
free_output_key (MetaOutputKey *key)
|
||||
@@ -232,7 +231,7 @@ meta_monitor_config_init (MetaMonitorConfig *self)
|
||||
self->up_client = up_client_new ();
|
||||
self->lid_is_closed = up_client_get_lid_is_closed (self->up_client);
|
||||
|
||||
g_signal_connect_object (self->up_client, "changed",
|
||||
g_signal_connect_object (self->up_client, "notify::lid-is-closed",
|
||||
G_CALLBACK (power_client_changed_cb), self, 0);
|
||||
}
|
||||
|
||||
@@ -816,6 +815,22 @@ meta_monitor_config_match_current (MetaMonitorConfig *self,
|
||||
return ok;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager)
|
||||
{
|
||||
MetaOutput *outputs;
|
||||
unsigned n_outputs;
|
||||
unsigned int i;
|
||||
|
||||
outputs = meta_monitor_manager_get_outputs (manager, &n_outputs);
|
||||
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
if (outputs[i].hotplug_mode_update)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static MetaConfiguration *
|
||||
meta_monitor_config_get_stored (MetaMonitorConfig *self,
|
||||
MetaOutput *outputs,
|
||||
@@ -1335,8 +1350,9 @@ turn_off_laptop_display (MetaMonitorConfig *self,
|
||||
}
|
||||
|
||||
static void
|
||||
power_client_changed_cb (UpClient *client,
|
||||
gpointer user_data)
|
||||
power_client_changed_cb (UpClient *client,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaMonitorManager *manager = meta_monitor_manager_get ();
|
||||
MetaMonitorConfig *self = user_data;
|
||||
|
@@ -29,9 +29,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_MONITOR_PRIVATE_H
|
||||
@@ -119,6 +117,9 @@ struct _MetaOutput
|
||||
|
||||
gpointer driver_private;
|
||||
GDestroyNotify driver_notify;
|
||||
|
||||
/* get a new preferred mode on hotplug events, to handle dynamic guest resizing */
|
||||
gboolean hotplug_mode_update;
|
||||
};
|
||||
|
||||
struct _MetaCRTC
|
||||
@@ -407,6 +408,7 @@ void meta_monitor_manager_free_output_array (MetaOutput *old_outpu
|
||||
int n_old_outputs);
|
||||
void meta_monitor_manager_free_mode_array (MetaMonitorMode *old_modes,
|
||||
int n_old_modes);
|
||||
gboolean meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager);
|
||||
|
||||
/* Returns true if transform causes width and height to be inverted
|
||||
This is true for the odd transforms in the enum */
|
||||
|
@@ -20,9 +20,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -311,6 +309,29 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
XID output_id)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
XRRPropertyInfo *info;
|
||||
gboolean result = FALSE;
|
||||
|
||||
meta_error_trap_push (display);
|
||||
info = XRRQueryOutputProperty (manager_xrandr->xdisplay, output_id,
|
||||
display->atom_hotplug_mode_update);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
if (info)
|
||||
{
|
||||
result = TRUE;
|
||||
XFree (info);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
{
|
||||
@@ -430,8 +451,10 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
XRRFreeCrtcInfo (crtc);
|
||||
}
|
||||
|
||||
meta_error_trap_push (meta_get_display ());
|
||||
primary_output = XRRGetOutputPrimary (manager_xrandr->xdisplay,
|
||||
DefaultRootWindow (manager_xrandr->xdisplay));
|
||||
meta_error_trap_pop (meta_get_display ());
|
||||
|
||||
n_actual_outputs = 0;
|
||||
for (i = 0; i < (unsigned)resources->noutput; i++)
|
||||
@@ -484,6 +507,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
meta_output->width_mm = output->mm_width;
|
||||
meta_output->height_mm = output->mm_height;
|
||||
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||
meta_output->hotplug_mode_update =
|
||||
output_get_hotplug_mode_update (manager_xrandr, meta_output->output_id);
|
||||
|
||||
meta_output->n_modes = output->nmode;
|
||||
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
|
||||
@@ -666,10 +691,11 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
unsigned int n_outputs)
|
||||
{
|
||||
MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
unsigned i;
|
||||
int width, height, width_mm, height_mm;
|
||||
|
||||
meta_display_grab (meta_get_display ());
|
||||
meta_display_grab (display);
|
||||
|
||||
/* First compute the new size of the screen (framebuffer) */
|
||||
width = 0; height = 0;
|
||||
@@ -763,10 +789,10 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
*/
|
||||
width_mm = (width / DPI_FALLBACK) * 25.4 + 0.5;
|
||||
height_mm = (height / DPI_FALLBACK) * 25.4 + 0.5;
|
||||
meta_error_trap_push (meta_get_display ());
|
||||
meta_error_trap_push (display);
|
||||
XRRSetScreenSize (manager_xrandr->xdisplay, DefaultRootWindow (manager_xrandr->xdisplay),
|
||||
width, height, width_mm, height_mm);
|
||||
meta_error_trap_pop (meta_get_display ());
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
{
|
||||
@@ -823,7 +849,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
goto next;
|
||||
}
|
||||
|
||||
meta_error_trap_push (meta_get_display ());
|
||||
meta_error_trap_push (display);
|
||||
ok = XRRSetCrtcConfig (manager_xrandr->xdisplay,
|
||||
manager_xrandr->resources,
|
||||
(XID)crtc->crtc_id,
|
||||
@@ -832,7 +858,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
(XID)mode->mode_id,
|
||||
wl_transform_to_xrandr (crtc_info->transform),
|
||||
outputs, n_outputs);
|
||||
meta_error_trap_pop (meta_get_display ());
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
if (ok != Success)
|
||||
{
|
||||
@@ -873,9 +899,11 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
|
||||
if (output_info->is_primary)
|
||||
{
|
||||
meta_error_trap_push (display);
|
||||
XRRSetOutputPrimary (manager_xrandr->xdisplay,
|
||||
DefaultRootWindow (manager_xrandr->xdisplay),
|
||||
(XID)output_info->output->output_id);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
|
||||
output_set_presentation_xrandr (manager_xrandr,
|
||||
@@ -901,7 +929,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
output->is_primary = FALSE;
|
||||
}
|
||||
|
||||
meta_display_ungrab (meta_get_display ());
|
||||
meta_display_ungrab (display);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -969,6 +997,16 @@ meta_monitor_manager_xrandr_set_crtc_gamma (MetaMonitorManager *manager,
|
||||
XRRFreeGamma (gamma);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_xrandr_rebuild_derived (MetaMonitorManager *manager)
|
||||
{
|
||||
/* This will be a no-op if the change was from our side, as
|
||||
we already called it in the DBus method handler */
|
||||
meta_monitor_config_update_current (manager->config, manager);
|
||||
|
||||
meta_monitor_manager_rebuild_derived (manager);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager,
|
||||
XEvent *event)
|
||||
@@ -978,6 +1016,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager,
|
||||
MetaCRTC *old_crtcs;
|
||||
MetaMonitorMode *old_modes;
|
||||
unsigned int n_old_outputs, n_old_modes;
|
||||
gboolean new_config;
|
||||
|
||||
if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
|
||||
return FALSE;
|
||||
@@ -994,31 +1033,36 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager,
|
||||
manager->serial++;
|
||||
meta_monitor_manager_xrandr_read_current (manager);
|
||||
|
||||
/* Check if the current intended configuration has the same outputs
|
||||
as the new real one, or if the event is a result of an XRandR call.
|
||||
If so, we can go straight to rebuild the logical config and tell
|
||||
the outside world.
|
||||
Otherwise, this event was caused by hotplug, so give a chance to
|
||||
MetaMonitorConfig.
|
||||
new_config = manager_xrandr->resources->timestamp >=
|
||||
manager_xrandr->resources->configTimestamp;
|
||||
if (meta_monitor_manager_has_hotplug_mode_update (manager))
|
||||
|
||||
Note that we need to check both the timestamps and the list of
|
||||
outputs, because the X server might emit spurious events with
|
||||
new configTimestamps (bug 702804), and the driver may have
|
||||
changed the EDID for some other reason (old broken qxl and vbox
|
||||
drivers...).
|
||||
*/
|
||||
if (manager_xrandr->resources->timestamp >= manager_xrandr->resources->configTimestamp ||
|
||||
meta_monitor_config_match_current (manager->config, manager))
|
||||
{
|
||||
/* This will be a no-op if the change was from our side, as
|
||||
we already called it in the DBus method handler */
|
||||
meta_monitor_config_update_current (manager->config, manager);
|
||||
|
||||
meta_monitor_manager_rebuild_derived (manager);
|
||||
/* Check if the current intended configuration is a result of an
|
||||
XRandR call. Otherwise, hotplug_mode_update tells us to get
|
||||
a new preferred mode on hotplug events to handle dynamic
|
||||
guest resizing. */
|
||||
if (new_config)
|
||||
meta_monitor_manager_xrandr_rebuild_derived (manager);
|
||||
else
|
||||
meta_monitor_config_make_default (manager->config, manager);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!meta_monitor_config_apply_stored (manager->config, manager))
|
||||
/* Check if the current intended configuration has the same outputs
|
||||
as the new real one, or if the event is a result of an XRandR call.
|
||||
If so, we can go straight to rebuild the logical config and tell
|
||||
the outside world.
|
||||
Otherwise, this event was caused by hotplug, so give a chance to
|
||||
MetaMonitorConfig.
|
||||
|
||||
Note that we need to check both the timestamps and the list of
|
||||
outputs, because the X server might emit spurious events with new
|
||||
configTimestamps (bug 702804), and the driver may have changed
|
||||
the EDID for some other reason (old qxl and vbox drivers). */
|
||||
if (new_config || meta_monitor_config_match_current (manager->config, manager))
|
||||
meta_monitor_manager_xrandr_rebuild_derived (manager);
|
||||
else if (!meta_monitor_config_apply_stored (manager->config, manager))
|
||||
meta_monitor_config_make_default (manager->config, manager);
|
||||
}
|
||||
|
||||
|
@@ -20,9 +20,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -614,46 +612,60 @@ static char *
|
||||
make_display_name (MetaMonitorManager *manager,
|
||||
MetaOutput *output)
|
||||
{
|
||||
char *inches = NULL;
|
||||
char *vendor_name = NULL;
|
||||
char *ret;
|
||||
|
||||
if (g_str_has_prefix (output->name, "LVDS") ||
|
||||
g_str_has_prefix (output->name, "eDP"))
|
||||
return g_strdup (_("Built-in display"));
|
||||
{
|
||||
ret = g_strdup (_("Built-in display"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (output->width_mm != -1 && output->height_mm != -1)
|
||||
if (output->width_mm > 0 && output->height_mm > 0)
|
||||
{
|
||||
double d = sqrt (output->width_mm * output->width_mm +
|
||||
output->height_mm * output->height_mm);
|
||||
char *inches = diagonal_to_str (d / 25.4);
|
||||
char *vendor_name;
|
||||
char *ret;
|
||||
inches = diagonal_to_str (d / 25.4);
|
||||
}
|
||||
|
||||
if (g_strcmp0 (output->vendor, "unknown") != 0)
|
||||
{
|
||||
if (!manager->pnp_ids)
|
||||
manager->pnp_ids = gnome_pnp_ids_new ();
|
||||
if (g_strcmp0 (output->vendor, "unknown") != 0)
|
||||
{
|
||||
if (!manager->pnp_ids)
|
||||
manager->pnp_ids = gnome_pnp_ids_new ();
|
||||
|
||||
vendor_name = gnome_pnp_ids_get_pnp_id (manager->pnp_ids,
|
||||
output->vendor);
|
||||
vendor_name = gnome_pnp_ids_get_pnp_id (manager->pnp_ids,
|
||||
output->vendor);
|
||||
|
||||
ret = g_strdup_printf ("%s %s", vendor_name, inches);
|
||||
|
||||
g_free (vendor_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TRANSLATORS: this is a monitor name (in case we don't know
|
||||
the vendor), it's Unknown followed by a size in inches,
|
||||
like 'Unknown 15"'
|
||||
*/
|
||||
ret = g_strdup_printf (_("Unknown %s"), inches);
|
||||
}
|
||||
|
||||
g_free (inches);
|
||||
return ret;
|
||||
if (!vendor_name)
|
||||
vendor_name = g_strdup (output->vendor);
|
||||
}
|
||||
else
|
||||
{
|
||||
return g_strdup (output->vendor);
|
||||
if (inches != NULL)
|
||||
vendor_name = g_strdup (_("Unknown"));
|
||||
else
|
||||
vendor_name = g_strdup (_("Unknown Display"));
|
||||
}
|
||||
|
||||
if (inches != NULL)
|
||||
{
|
||||
/* TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
* size in inches, like 'Dell 15"'
|
||||
*/
|
||||
ret = g_strdup_printf (_("%s %s"), vendor_name, inches);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = g_strdup (vendor_name);
|
||||
}
|
||||
|
||||
out:
|
||||
g_free (inches);
|
||||
g_free (vendor_name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -729,6 +741,9 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
g_variant_new_take_string (make_display_name (manager, output)));
|
||||
g_variant_builder_add (&properties, "{sv}", "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_new_boolean (output->is_primary));
|
||||
g_variant_builder_add (&properties, "{sv}", "presentation",
|
||||
|
@@ -14,9 +14,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
303
src/core/place.c
303
src/core/place.c
@@ -19,9 +19,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -47,34 +45,18 @@ northwestcmp (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
MetaWindow *aw = (gpointer) a;
|
||||
MetaWindow *bw = (gpointer) b;
|
||||
MetaRectangle a_frame;
|
||||
MetaRectangle b_frame;
|
||||
int from_origin_a;
|
||||
int from_origin_b;
|
||||
int ax, ay, bx, by;
|
||||
|
||||
/* we're interested in the frame position for cascading,
|
||||
* not meta_window_get_position()
|
||||
*/
|
||||
if (aw->frame)
|
||||
{
|
||||
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;
|
||||
}
|
||||
meta_window_get_frame_rect (aw, &a_frame);
|
||||
meta_window_get_frame_rect (bw, &b_frame);
|
||||
ax = a_frame.x;
|
||||
ay = a_frame.y;
|
||||
bx = b_frame.x;
|
||||
by = b_frame.y;
|
||||
|
||||
/* probably there's a fast good-enough-guess we could use here. */
|
||||
from_origin_a = sqrt (ax * ax + ay * ay);
|
||||
@@ -90,7 +72,6 @@ northwestcmp (gconstpointer a, gconstpointer b)
|
||||
|
||||
static void
|
||||
find_next_cascade (MetaWindow *window,
|
||||
MetaFrameBorders *borders,
|
||||
/* visible windows on relevant workspaces */
|
||||
GList *windows,
|
||||
int x,
|
||||
@@ -102,6 +83,7 @@ find_next_cascade (MetaWindow *window,
|
||||
GList *sorted;
|
||||
int cascade_x, cascade_y;
|
||||
int x_threshold, y_threshold;
|
||||
MetaRectangle frame_rect;
|
||||
int window_width, window_height;
|
||||
int cascade_stage;
|
||||
MetaRectangle work_area;
|
||||
@@ -120,10 +102,13 @@ find_next_cascade (MetaWindow *window,
|
||||
* manually cascade.
|
||||
*/
|
||||
#define CASCADE_FUZZ 15
|
||||
if (borders)
|
||||
if (window->frame)
|
||||
{
|
||||
x_threshold = MAX (borders->visible.left, CASCADE_FUZZ);
|
||||
y_threshold = MAX (borders->visible.top, CASCADE_FUZZ);
|
||||
MetaFrameBorders borders;
|
||||
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
x_threshold = MAX (borders.visible.left, CASCADE_FUZZ);
|
||||
y_threshold = MAX (borders.visible.top, CASCADE_FUZZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -143,30 +128,25 @@ find_next_cascade (MetaWindow *window,
|
||||
cascade_y = MAX (0, work_area.y);
|
||||
|
||||
/* Find first cascade position that's not used. */
|
||||
|
||||
window_width = window->frame ? window->frame->rect.width : window->rect.width;
|
||||
window_height = window->frame ? window->frame->rect.height : window->rect.height;
|
||||
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
window_width = frame_rect.width;
|
||||
window_height = frame_rect.height;
|
||||
|
||||
cascade_stage = 0;
|
||||
tmp = sorted;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w;
|
||||
MetaRectangle w_frame_rect;
|
||||
int wx, wy;
|
||||
|
||||
w = tmp->data;
|
||||
|
||||
/* we want frame position, not window position */
|
||||
if (w->frame)
|
||||
{
|
||||
wx = w->frame->rect.x;
|
||||
wy = w->frame->rect.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
wx = w->rect.x;
|
||||
wy = w->rect.y;
|
||||
}
|
||||
meta_window_get_frame_rect (w, &w_frame_rect);
|
||||
wx = w_frame_rect.x;
|
||||
wy = w_frame_rect.y;
|
||||
|
||||
if (ABS (wx - cascade_x) < x_threshold &&
|
||||
ABS (wy - cascade_y) < y_threshold)
|
||||
@@ -223,22 +203,12 @@ find_next_cascade (MetaWindow *window,
|
||||
|
||||
g_list_free (sorted);
|
||||
|
||||
/* Convert coords to position of window, not position of frame. */
|
||||
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;
|
||||
}
|
||||
*new_x = cascade_x;
|
||||
*new_y = cascade_y;
|
||||
}
|
||||
|
||||
static void
|
||||
find_most_freespace (MetaWindow *window,
|
||||
MetaFrameBorders *borders,
|
||||
/* visible windows on relevant workspaces */
|
||||
MetaWindow *focus_window,
|
||||
int x,
|
||||
@@ -250,29 +220,25 @@ find_most_freespace (MetaWindow *window,
|
||||
int max_area;
|
||||
int max_width, max_height, left, right, top, bottom;
|
||||
int left_space, right_space, top_space, bottom_space;
|
||||
int frame_size_left, frame_size_top;
|
||||
MetaRectangle work_area;
|
||||
MetaRectangle avoid;
|
||||
MetaRectangle outer;
|
||||
|
||||
frame_size_left = borders ? borders->visible.left : 0;
|
||||
frame_size_top = borders ? borders->visible.top : 0;
|
||||
MetaRectangle frame_rect;
|
||||
|
||||
meta_window_get_work_area_current_monitor (focus_window, &work_area);
|
||||
meta_window_get_outer_rect (focus_window, &avoid);
|
||||
meta_window_get_outer_rect (window, &outer);
|
||||
meta_window_get_frame_rect (focus_window, &avoid);
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
|
||||
/* Find the areas of choosing the various sides of the focus window */
|
||||
max_width = MIN (avoid.width, outer.width);
|
||||
max_height = MIN (avoid.height, outer.height);
|
||||
max_width = MIN (avoid.width, frame_rect.width);
|
||||
max_height = MIN (avoid.height, frame_rect.height);
|
||||
left_space = avoid.x - work_area.x;
|
||||
right_space = work_area.width - (avoid.x + avoid.width - work_area.x);
|
||||
top_space = avoid.y - work_area.y;
|
||||
bottom_space = work_area.height - (avoid.y + avoid.height - work_area.y);
|
||||
left = MIN (left_space, outer.width);
|
||||
right = MIN (right_space, outer.width);
|
||||
top = MIN (top_space, outer.height);
|
||||
bottom = MIN (bottom_space, outer.height);
|
||||
left = MIN (left_space, frame_rect.width);
|
||||
right = MIN (right_space, frame_rect.width);
|
||||
top = MIN (top_space, frame_rect.height);
|
||||
bottom = MIN (bottom_space, frame_rect.height);
|
||||
|
||||
/* Find out which side of the focus_window can show the most of the window */
|
||||
side = META_LEFT;
|
||||
@@ -304,39 +270,56 @@ find_most_freespace (MetaWindow *window,
|
||||
switch (side)
|
||||
{
|
||||
case META_LEFT:
|
||||
*new_y = avoid.y + frame_size_top;
|
||||
if (left_space > outer.width)
|
||||
*new_x = avoid.x - outer.width + frame_size_left;
|
||||
*new_y = avoid.y;
|
||||
if (left_space > frame_rect.width)
|
||||
*new_x = avoid.x - frame_rect.width;
|
||||
else
|
||||
*new_x = work_area.x + frame_size_left;
|
||||
*new_x = work_area.x;
|
||||
break;
|
||||
case META_RIGHT:
|
||||
*new_y = avoid.y + frame_size_top;
|
||||
if (right_space > outer.width)
|
||||
*new_x = avoid.x + avoid.width + frame_size_left;
|
||||
*new_y = avoid.y;
|
||||
if (right_space > frame_rect.width)
|
||||
*new_x = avoid.x + avoid.width;
|
||||
else
|
||||
*new_x = work_area.x + work_area.width - outer.width + frame_size_left;
|
||||
*new_x = work_area.x + work_area.width - frame_rect.width;
|
||||
break;
|
||||
case META_TOP:
|
||||
*new_x = avoid.x + frame_size_left;
|
||||
if (top_space > outer.height)
|
||||
*new_y = avoid.y - outer.height + frame_size_top;
|
||||
*new_x = avoid.x;
|
||||
if (top_space > frame_rect.height)
|
||||
*new_y = avoid.y - frame_rect.height;
|
||||
else
|
||||
*new_y = work_area.y + frame_size_top;
|
||||
*new_y = work_area.y;
|
||||
break;
|
||||
case META_BOTTOM:
|
||||
*new_x = avoid.x + frame_size_left;
|
||||
if (bottom_space > outer.height)
|
||||
*new_y = avoid.y + avoid.height + frame_size_top;
|
||||
*new_x = avoid.x;
|
||||
if (bottom_space > frame_rect.height)
|
||||
*new_y = avoid.y + avoid.height;
|
||||
else
|
||||
*new_y = work_area.y + work_area.height - outer.height + frame_size_top;
|
||||
*new_y = work_area.y + work_area.height - frame_rect.height;
|
||||
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
|
||||
avoid_being_obscured_as_second_modal_dialog (MetaWindow *window,
|
||||
MetaFrameBorders *borders,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
@@ -355,18 +338,17 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window,
|
||||
*/
|
||||
|
||||
MetaWindow *focus_window;
|
||||
MetaRectangle overlap;
|
||||
|
||||
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 &&
|
||||
window->wm_state_modal && /* FIXME: Maybe do this for all transients? */
|
||||
meta_window_same_application (window, focus_window) &&
|
||||
meta_rectangle_intersect (&window->rect,
|
||||
&focus_window->rect,
|
||||
&overlap))
|
||||
window_overlaps_focus_window (window))
|
||||
{
|
||||
find_most_freespace (window, borders, focus_window, *x, *y, x, y);
|
||||
find_most_freespace (window, focus_window, *x, *y, x, y);
|
||||
meta_topic (META_DEBUG_PLACEMENT,
|
||||
"Dialog window %s was denied focus but may be modal "
|
||||
"to the focus window; had to move it to avoid the "
|
||||
@@ -409,7 +391,7 @@ rectangle_overlaps_some_window (MetaRectangle *rect,
|
||||
case META_WINDOW_UTILITY:
|
||||
case META_WINDOW_TOOLBAR:
|
||||
case META_WINDOW_MENU:
|
||||
meta_window_get_outer_rect (other, &other_rect);
|
||||
meta_window_get_frame_rect (other, &other_rect);
|
||||
|
||||
if (meta_rectangle_intersect (rect, &other_rect, &dest))
|
||||
return TRUE;
|
||||
@@ -427,20 +409,14 @@ leftmost_cmp (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
MetaWindow *aw = (gpointer) a;
|
||||
MetaWindow *bw = (gpointer) b;
|
||||
MetaRectangle a_frame;
|
||||
MetaRectangle b_frame;
|
||||
int ax, bx;
|
||||
|
||||
/* we're interested in the frame position for cascading,
|
||||
* not meta_window_get_position()
|
||||
*/
|
||||
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;
|
||||
meta_window_get_frame_rect (aw, &a_frame);
|
||||
meta_window_get_frame_rect (bw, &b_frame);
|
||||
ax = a_frame.x;
|
||||
bx = b_frame.x;
|
||||
|
||||
if (ax < bx)
|
||||
return -1;
|
||||
@@ -455,20 +431,14 @@ topmost_cmp (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
MetaWindow *aw = (gpointer) a;
|
||||
MetaWindow *bw = (gpointer) b;
|
||||
MetaRectangle a_frame;
|
||||
MetaRectangle b_frame;
|
||||
int ay, by;
|
||||
|
||||
/* we're interested in the frame position for cascading,
|
||||
* not meta_window_get_position()
|
||||
*/
|
||||
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;
|
||||
meta_window_get_frame_rect (aw, &a_frame);
|
||||
meta_window_get_frame_rect (bw, &b_frame);
|
||||
ay = a_frame.y;
|
||||
by = b_frame.y;
|
||||
|
||||
if (ay < by)
|
||||
return -1;
|
||||
@@ -506,7 +476,6 @@ center_tile_rect_in_area (MetaRectangle *rect,
|
||||
*/
|
||||
static gboolean
|
||||
find_first_fit (MetaWindow *window,
|
||||
MetaFrameBorders *borders,
|
||||
/* visible windows on relevant workspaces */
|
||||
GList *windows,
|
||||
int monitor,
|
||||
@@ -540,15 +509,8 @@ find_first_fit (MetaWindow *window,
|
||||
right_sorted = g_list_copy (windows);
|
||||
right_sorted = g_list_sort (right_sorted, topmost_cmp);
|
||||
right_sorted = g_list_sort (right_sorted, leftmost_cmp);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
meta_window_get_frame_rect (window, &rect);
|
||||
|
||||
#ifdef WITH_VERBOSE_MODE
|
||||
{
|
||||
@@ -570,11 +532,6 @@ find_first_fit (MetaWindow *window,
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
if (borders)
|
||||
{
|
||||
*new_x += borders->visible.left;
|
||||
*new_y += borders->visible.top;
|
||||
}
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
@@ -586,23 +543,18 @@ find_first_fit (MetaWindow *window,
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle outer_rect;
|
||||
MetaRectangle frame_rect;
|
||||
|
||||
meta_window_get_outer_rect (w, &outer_rect);
|
||||
meta_window_get_frame_rect (w, &frame_rect);
|
||||
|
||||
rect.x = outer_rect.x;
|
||||
rect.y = outer_rect.y + outer_rect.height;
|
||||
rect.x = frame_rect.x;
|
||||
rect.y = frame_rect.y + frame_rect.height;
|
||||
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, below_sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
if (borders)
|
||||
{
|
||||
*new_x += borders->visible.left;
|
||||
*new_y += borders->visible.top;
|
||||
}
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
@@ -617,23 +569,18 @@ find_first_fit (MetaWindow *window,
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle outer_rect;
|
||||
MetaRectangle frame_rect;
|
||||
|
||||
meta_window_get_outer_rect (w, &outer_rect);
|
||||
meta_window_get_frame_rect (w, &frame_rect);
|
||||
|
||||
rect.x = outer_rect.x + outer_rect.width;
|
||||
rect.y = outer_rect.y;
|
||||
rect.x = frame_rect.x + frame_rect.width;
|
||||
rect.y = frame_rect.y;
|
||||
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, right_sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
if (borders)
|
||||
{
|
||||
*new_x += borders->visible.left;
|
||||
*new_y += borders->visible.top;
|
||||
}
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
@@ -652,7 +599,6 @@ find_first_fit (MetaWindow *window,
|
||||
|
||||
void
|
||||
meta_window_place (MetaWindow *window,
|
||||
MetaFrameBorders *borders,
|
||||
int x,
|
||||
int y,
|
||||
int *new_x,
|
||||
@@ -661,13 +607,6 @@ meta_window_place (MetaWindow *window,
|
||||
GList *windows;
|
||||
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);
|
||||
|
||||
windows = NULL;
|
||||
@@ -756,7 +695,7 @@ meta_window_place (MetaWindow *window,
|
||||
{
|
||||
meta_topic (META_DEBUG_PLACEMENT,
|
||||
"Not placing window with PPosition or USPosition set\n");
|
||||
avoid_being_obscured_as_second_modal_dialog (window, borders, &x, &y);
|
||||
avoid_being_obscured_as_second_modal_dialog (window, &x, &y);
|
||||
goto done_no_constraints;
|
||||
}
|
||||
}
|
||||
@@ -775,29 +714,27 @@ meta_window_place (MetaWindow *window,
|
||||
|
||||
if (parent)
|
||||
{
|
||||
int w;
|
||||
MetaRectangle frame_rect, parent_frame_rect;
|
||||
|
||||
meta_window_get_position (parent, &x, &y);
|
||||
w = parent->rect.width;
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
meta_window_get_frame_rect (parent, &parent_frame_rect);
|
||||
|
||||
y = parent_frame_rect.y;
|
||||
|
||||
/* center of parent */
|
||||
x = x + w / 2;
|
||||
x = parent_frame_rect.x + parent_frame_rect.width / 2;
|
||||
/* center of child over center of parent */
|
||||
x -= window->rect.width / 2;
|
||||
x -= frame_rect.width / 2;
|
||||
|
||||
/* "visually" center window over parent, leaving twice as
|
||||
* much space below as on top.
|
||||
*/
|
||||
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;
|
||||
y += (parent_frame_rect.height - frame_rect.height)/3;
|
||||
|
||||
meta_topic (META_DEBUG_PLACEMENT, "Centered window %s over transient parent\n",
|
||||
window->desc);
|
||||
|
||||
avoid_being_obscured_as_second_modal_dialog (window, borders, &x, &y);
|
||||
avoid_being_obscured_as_second_modal_dialog (window, &x, &y);
|
||||
|
||||
goto done;
|
||||
}
|
||||
@@ -813,6 +750,9 @@ meta_window_place (MetaWindow *window,
|
||||
{
|
||||
/* Center on current monitor */
|
||||
int w, h;
|
||||
MetaRectangle frame_rect;
|
||||
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
|
||||
/* Warning, this function is a round trip! */
|
||||
xi = meta_screen_get_current_monitor_info (window->screen);
|
||||
@@ -820,8 +760,8 @@ meta_window_place (MetaWindow *window,
|
||||
w = xi->rect.width;
|
||||
h = xi->rect.height;
|
||||
|
||||
x = (w - window->rect.width) / 2;
|
||||
y = (h - window->rect.height) / 2;
|
||||
x = (w - frame_rect.width) / 2;
|
||||
y = (h - frame_rect.height) / 2;
|
||||
|
||||
x += xi->rect.x;
|
||||
y += xi->rect.y;
|
||||
@@ -865,7 +805,7 @@ meta_window_place (MetaWindow *window,
|
||||
x = xi->rect.x;
|
||||
y = xi->rect.y;
|
||||
|
||||
if (find_first_fit (window, borders, windows,
|
||||
if (find_first_fit (window, windows,
|
||||
xi->number,
|
||||
x, y, &x, &y))
|
||||
goto done_check_denied_focus;
|
||||
@@ -878,17 +818,17 @@ meta_window_place (MetaWindow *window,
|
||||
!window->fullscreen)
|
||||
{
|
||||
MetaRectangle workarea;
|
||||
MetaRectangle outer;
|
||||
MetaRectangle frame_rect;
|
||||
|
||||
meta_window_get_work_area_for_monitor (window,
|
||||
xi->number,
|
||||
&workarea);
|
||||
meta_window_get_outer_rect (window, &outer);
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
|
||||
/* If the window is bigger than the screen, then automaximize. Do NOT
|
||||
* auto-maximize the directions independently. See #419810.
|
||||
*/
|
||||
if (outer.width >= workarea.width && outer.height >= workarea.height)
|
||||
if (frame_rect.width >= workarea.width && frame_rect.height >= workarea.height)
|
||||
{
|
||||
window->maximize_horizontally_after_placement = TRUE;
|
||||
window->maximize_vertically_after_placement = TRUE;
|
||||
@@ -899,7 +839,7 @@ meta_window_place (MetaWindow *window,
|
||||
* fully overlapping window (e.g. starting multiple terminals)
|
||||
* */
|
||||
if (x == xi->rect.x && y == xi->rect.y)
|
||||
find_next_cascade (window, borders, windows, x, y, &x, &y);
|
||||
find_next_cascade (window, windows, x, y, &x, &y);
|
||||
|
||||
done_check_denied_focus:
|
||||
/* If the window is being denied focus and isn't a transient of the
|
||||
@@ -909,17 +849,14 @@ meta_window_place (MetaWindow *window,
|
||||
*/
|
||||
if (window->denied_focus_and_not_transient)
|
||||
{
|
||||
gboolean found_fit;
|
||||
MetaWindow *focus_window;
|
||||
MetaRectangle overlap;
|
||||
gboolean found_fit;
|
||||
|
||||
focus_window = window->display->focus_window;
|
||||
g_assert (focus_window != NULL);
|
||||
|
||||
/* No need to do anything if the window doesn't overlap at all */
|
||||
found_fit = !meta_rectangle_intersect (&window->rect,
|
||||
&focus_window->rect,
|
||||
&overlap);
|
||||
found_fit = !window_overlaps_focus_window (window);
|
||||
|
||||
/* Try to do a first fit again, this time only taking into account the
|
||||
* focus window.
|
||||
@@ -933,7 +870,7 @@ meta_window_place (MetaWindow *window,
|
||||
x = xi->rect.x;
|
||||
y = xi->rect.y;
|
||||
|
||||
found_fit = find_first_fit (window, borders, focus_window_list,
|
||||
found_fit = find_first_fit (window, focus_window_list,
|
||||
xi->number,
|
||||
x, y, &x, &y);
|
||||
g_list_free (focus_window_list);
|
||||
@@ -943,7 +880,7 @@ meta_window_place (MetaWindow *window,
|
||||
* as possible.
|
||||
*/
|
||||
if (!found_fit)
|
||||
find_most_freespace (window, borders, focus_window, x, y, &x, &y);
|
||||
find_most_freespace (window, focus_window, x, y, &x, &y);
|
||||
}
|
||||
|
||||
done:
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_PLACE_H
|
||||
@@ -28,7 +26,6 @@
|
||||
#include "frame.h"
|
||||
|
||||
void meta_window_place (MetaWindow *window,
|
||||
MetaFrameBorders *borders,
|
||||
int x,
|
||||
int y,
|
||||
int *new_x,
|
||||
|
@@ -17,9 +17,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -25,9 +25,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_SCREEN_PRIVATE_H
|
||||
|
@@ -19,9 +19,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -859,9 +857,9 @@ meta_screen_free (MetaScreen *screen,
|
||||
screen->wm_sn_selection_window);
|
||||
|
||||
if (screen->work_area_later != 0)
|
||||
g_source_remove (screen->work_area_later);
|
||||
meta_later_remove (screen->work_area_later);
|
||||
if (screen->check_fullscreen_later != 0)
|
||||
g_source_remove (screen->check_fullscreen_later);
|
||||
meta_later_remove (screen->check_fullscreen_later);
|
||||
|
||||
if (screen->monitor_infos)
|
||||
g_free (screen->monitor_infos);
|
||||
@@ -880,83 +878,31 @@ meta_screen_free (MetaScreen *screen,
|
||||
meta_display_ungrab (display);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Window xwindow;
|
||||
XWindowAttributes attrs;
|
||||
} WindowInfo;
|
||||
|
||||
static GList *
|
||||
list_windows (MetaScreen *screen)
|
||||
{
|
||||
Window ignored1, ignored2;
|
||||
Window *children;
|
||||
guint n_children, i;
|
||||
GList *result;
|
||||
|
||||
XQueryTree (screen->display->xdisplay,
|
||||
screen->xroot,
|
||||
&ignored1, &ignored2, &children, &n_children);
|
||||
|
||||
result = NULL;
|
||||
for (i = 0; i < n_children; ++i)
|
||||
{
|
||||
WindowInfo *info = g_new0 (WindowInfo, 1);
|
||||
|
||||
meta_error_trap_push_with_return (screen->display);
|
||||
|
||||
XGetWindowAttributes (screen->display->xdisplay,
|
||||
children[i], &info->attrs);
|
||||
|
||||
if (meta_error_trap_pop_with_return (screen->display))
|
||||
{
|
||||
meta_verbose ("Failed to get attributes for window 0x%lx\n",
|
||||
children[i]);
|
||||
g_free (info);
|
||||
}
|
||||
else
|
||||
{
|
||||
info->xwindow = children[i];
|
||||
}
|
||||
|
||||
result = g_list_prepend (result, info);
|
||||
}
|
||||
|
||||
if (children)
|
||||
XFree (children);
|
||||
|
||||
return g_list_reverse (result);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_manage_all_windows (MetaScreen *screen)
|
||||
{
|
||||
GList *windows;
|
||||
GList *list;
|
||||
|
||||
meta_display_grab (screen->display);
|
||||
MetaStackWindow *_children;
|
||||
MetaStackWindow *children;
|
||||
int n_children, i;
|
||||
|
||||
if (screen->guard_window == None)
|
||||
screen->guard_window =
|
||||
meta_screen_create_guard_window (screen->display->xdisplay, screen);
|
||||
|
||||
windows = list_windows (screen);
|
||||
|
||||
meta_stack_freeze (screen->stack);
|
||||
for (list = windows; list != NULL; list = list->next)
|
||||
meta_stack_tracker_get_stack (screen->stack_tracker, &_children, &n_children);
|
||||
|
||||
/* Copy the stack as it will be modified as part of the loop */
|
||||
children = g_memdup (_children, sizeof (MetaStackWindow) * n_children);
|
||||
|
||||
for (i = 0; i < n_children; ++i)
|
||||
{
|
||||
WindowInfo *info = list->data;
|
||||
|
||||
meta_window_new_with_attrs (screen->display, info->xwindow, TRUE,
|
||||
META_COMP_EFFECT_NONE,
|
||||
&info->attrs);
|
||||
meta_window_new (screen->display, children[i].x11.xwindow, TRUE,
|
||||
META_COMP_EFFECT_NONE);
|
||||
}
|
||||
|
||||
g_free (children);
|
||||
meta_stack_thaw (screen->stack);
|
||||
|
||||
g_list_foreach (windows, (GFunc)g_free, NULL);
|
||||
g_list_free (windows);
|
||||
|
||||
meta_display_ungrab (screen->display);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1528,7 +1474,7 @@ meta_screen_tab_popup_create (MetaScreen *screen,
|
||||
if (show_type == META_TAB_SHOW_INSTANTLY ||
|
||||
!entries[i].hidden ||
|
||||
!meta_window_get_icon_geometry (window, &r))
|
||||
meta_window_get_outer_rect (window, &r);
|
||||
meta_window_get_frame_rect (window, &r);
|
||||
|
||||
entries[i].rect = r;
|
||||
|
||||
@@ -1914,7 +1860,7 @@ meta_screen_get_monitor_for_window (MetaScreen *screen,
|
||||
{
|
||||
MetaRectangle window_rect;
|
||||
|
||||
meta_window_get_outer_rect (window, &window_rect);
|
||||
meta_window_get_frame_rect (window, &window_rect);
|
||||
|
||||
return meta_screen_get_monitor_for_rect (screen, &window_rect);
|
||||
}
|
||||
|
@@ -18,9 +18,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
@@ -23,9 +23,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_SESSION_H
|
||||
|
@@ -29,9 +29,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
@@ -28,9 +28,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_STACK_TRACKER_H
|
||||
|
@@ -22,9 +22,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -92,16 +90,6 @@ meta_stack_new (MetaScreen *screen)
|
||||
static void
|
||||
free_last_all_root_children_stacked_cache (MetaStack *stack)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < stack->last_all_root_children_stacked->len; i++)
|
||||
{
|
||||
MetaStackWindow *window = &g_array_index (stack->last_all_root_children_stacked, MetaStackWindow, i);
|
||||
if (window->any.type == META_WINDOW_CLIENT_TYPE_WAYLAND)
|
||||
g_object_remove_weak_pointer (G_OBJECT (window->wayland.meta_window),
|
||||
(gpointer *)&window->wayland.meta_window);
|
||||
}
|
||||
|
||||
g_array_free (stack->last_all_root_children_stacked, TRUE);
|
||||
stack->last_all_root_children_stacked = NULL;
|
||||
}
|
||||
@@ -1337,17 +1325,6 @@ stack_sync_to_xserver (MetaStack *stack)
|
||||
/* build XRestackWindows() array from top to bottom */
|
||||
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||
g_array_append_val (x11_root_children_stacked, top_level_window);
|
||||
else
|
||||
{
|
||||
MetaStackWindow *new;
|
||||
|
||||
/* So we can determine later if a cached stack window is
|
||||
* stale because the corresponding window has been freed we
|
||||
* associate a weak pointer with the new window. */
|
||||
new = &g_array_index (all_root_children_stacked, MetaStackWindow, all_root_children_stacked->len - 1);
|
||||
g_object_add_weak_pointer (G_OBJECT (new->wayland.meta_window),
|
||||
(gpointer *)&new->wayland.meta_window);
|
||||
}
|
||||
}
|
||||
|
||||
meta_topic (META_DEBUG_STACK, "\n");
|
||||
@@ -1705,7 +1682,7 @@ window_contains_point (MetaWindow *window,
|
||||
{
|
||||
MetaRectangle rect;
|
||||
|
||||
meta_window_get_outer_rect (window, &rect);
|
||||
meta_window_get_frame_rect (window, &rect);
|
||||
|
||||
return POINT_IN_RECT (root_x, root_y, rect);
|
||||
}
|
||||
|
@@ -15,9 +15,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_STACK_H
|
||||
|
@@ -16,9 +16,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "boxes-private.h"
|
||||
|
@@ -15,9 +15,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -26,9 +26,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_WINDOW_PRIVATE_H
|
||||
@@ -44,6 +42,7 @@
|
||||
#include <X11/Xutil.h>
|
||||
#include <cairo.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include "meta-wayland-types.h"
|
||||
|
||||
typedef struct _MetaWindowQueue MetaWindowQueue;
|
||||
@@ -101,7 +100,7 @@ struct _MetaWindow
|
||||
|
||||
MetaWindowType type;
|
||||
Atom type_atom;
|
||||
|
||||
|
||||
/* NOTE these five are not in UTF-8, we just treat them as random
|
||||
* binary data
|
||||
*/
|
||||
@@ -350,6 +349,10 @@ struct _MetaWindow
|
||||
/* whether or not the window is from a program running on another machine */
|
||||
guint is_remote : 1;
|
||||
|
||||
/* Used for Wayland -- surfaces can behave as if they were unmapped if
|
||||
* they have a NULL buffer attached... */
|
||||
guint surface_mapped;
|
||||
|
||||
/* if non-NULL, the bounds of the window frame */
|
||||
cairo_region_t *frame_bounds;
|
||||
|
||||
@@ -362,6 +365,9 @@ struct _MetaWindow
|
||||
/* 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
|
||||
* also handles application frames */
|
||||
guint extended_sync_request_counter : 1;
|
||||
@@ -461,6 +467,8 @@ struct _MetaWindow
|
||||
|
||||
/* Bypass compositor hints */
|
||||
guint bypass_compositor;
|
||||
|
||||
GSList *pending_pings;
|
||||
};
|
||||
|
||||
struct _MetaWindowClass
|
||||
@@ -500,15 +508,9 @@ struct _MetaWindowClass
|
||||
|
||||
MetaWindow* meta_window_new (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
gboolean must_be_viewable);
|
||||
MetaWindow* meta_window_new_with_attrs (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
gboolean must_be_viewable,
|
||||
MetaCompEffect effect,
|
||||
XWindowAttributes *attrs);
|
||||
gboolean must_be_viewable,
|
||||
MetaCompEffect effect);
|
||||
MetaWindow *meta_window_new_for_wayland (MetaDisplay *display,
|
||||
int width,
|
||||
int height,
|
||||
MetaWaylandSurface *surface);
|
||||
void meta_window_unmanage (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
@@ -532,6 +534,7 @@ void meta_window_update_fullscreen_monitors (MetaWindow *window,
|
||||
unsigned long left,
|
||||
unsigned long right);
|
||||
|
||||
|
||||
/* args to move are window pos, not frame pos */
|
||||
void meta_window_move (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
@@ -642,8 +645,10 @@ void meta_window_update_sync_request_counter (MetaWindow *window,
|
||||
gint64 new_counter_value);
|
||||
#endif /* HAVE_XSYNC */
|
||||
|
||||
void meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
||||
XIDeviceEvent *xev);
|
||||
void meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
||||
const ClutterEvent *event);
|
||||
void meta_window_handle_mouse_grab_op_xevent (MetaWindow *window,
|
||||
XIDeviceEvent *xevent);
|
||||
|
||||
GList* meta_window_get_workspaces (MetaWindow *window);
|
||||
|
||||
@@ -682,6 +687,8 @@ void meta_window_recalc_features (MetaWindow *window);
|
||||
void meta_window_recalc_window_type (MetaWindow *window);
|
||||
void meta_window_type_changed (MetaWindow *window);
|
||||
|
||||
void meta_window_frame_size_changed (MetaWindow *window);
|
||||
|
||||
void meta_window_stack_just_below (MetaWindow *window,
|
||||
MetaWindow *below_this_one);
|
||||
|
||||
@@ -705,16 +712,8 @@ void meta_window_compute_tile_match (MetaWindow *window);
|
||||
|
||||
gboolean meta_window_updates_are_frozen (MetaWindow *window);
|
||||
|
||||
void meta_window_set_opaque_region (MetaWindow *window,
|
||||
cairo_region_t *region);
|
||||
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,
|
||||
cairo_region_t *region);
|
||||
void meta_window_update_shape_region_x11 (MetaWindow *window);
|
||||
|
||||
void meta_window_set_title (MetaWindow *window,
|
||||
@@ -733,4 +732,28 @@ void meta_window_set_gtk_dbus_properties (MetaWindow *window,
|
||||
void meta_window_set_transient_for (MetaWindow *window,
|
||||
MetaWindow *parent);
|
||||
|
||||
void meta_window_set_opacity (MetaWindow *window,
|
||||
guint opacity);
|
||||
|
||||
void meta_window_handle_enter (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
guint root_x,
|
||||
guint root_y);
|
||||
|
||||
void meta_window_set_surface_mapped (MetaWindow *window,
|
||||
gboolean surface_mapped);
|
||||
|
||||
typedef void (* MetaWindowPingFunc) (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
gpointer user_data);
|
||||
|
||||
void meta_window_ping (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
MetaWindowPingFunc ping_reply_func,
|
||||
MetaWindowPingFunc ping_timeout_func,
|
||||
void *user_data);
|
||||
void meta_window_pong (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
Window meta_window_get_toplevel_xwindow (MetaWindow *window);
|
||||
|
||||
#endif
|
||||
|
@@ -31,9 +31,7 @@
|
||||
* 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.
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
@@ -317,6 +315,9 @@ reload_gtk_frame_extents (MetaWindow *window,
|
||||
{
|
||||
window->has_custom_frame_extents = FALSE;
|
||||
}
|
||||
|
||||
if (!initial)
|
||||
meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1652,6 +1653,20 @@ reload_bypass_compositor (MetaWindow *window,
|
||||
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) \
|
||||
static void \
|
||||
reload_ ## var_name (MetaWindow *window, \
|
||||
@@ -1754,6 +1769,7 @@ 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_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_WINDOW_OPACITY, META_PROP_VALUE_CARDINAL, reload_window_opacity, TRUE, TRUE },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user