Compare commits
197 Commits
3.10.1-way
...
3.11.3-way
Author | SHA1 | Date | |
---|---|---|---|
![]() |
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
|
||||
|
@@ -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}
|
||||
|
45
NEWS
45
NEWS
@@ -1,3 +1,48 @@
|
||||
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]
|
||||
|
@@ -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], [3])
|
||||
|
||||
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
|
||||
$CLUTTER_PACKAGE >= 1.17.1
|
||||
cogl-1.0 >= 1.13.3
|
||||
upower-glib > 0.9.11
|
||||
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 \
|
||||
|
@@ -95,8 +95,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;
|
||||
}
|
||||
|
@@ -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 */
|
||||
|
@@ -41,20 +41,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 +119,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 +131,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 +160,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 *
|
||||
|
193
src/compositor/meta-cullable.c
Normal file
193
src/compositor/meta-cullable.c
Normal file
@@ -0,0 +1,193 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Owen Taylor <otaylor@redhat.com>
|
||||
* Ray Strode <rstrode@redhat.com>
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "meta-cullable.h"
|
||||
#include "clutter-utils.h"
|
||||
|
||||
G_DEFINE_INTERFACE (MetaCullable, meta_cullable, CLUTTER_TYPE_ACTOR);
|
||||
|
||||
/**
|
||||
* SECTION:meta-cullable
|
||||
* @title: MetaCullable
|
||||
* @short_description: CPU culling operations for efficient drawing
|
||||
*
|
||||
* When we are painting a stack of 5-10 large actors, the standard
|
||||
* bottom-to-top method of drawing every actor results in a tremendous
|
||||
* amount of overdraw. If these actors are painting textures like
|
||||
* windows, it can easily max out the available memory bandwidth on a
|
||||
* low-end graphics chipset. It's even worse if window textures are
|
||||
* being accessed over the AGP bus.
|
||||
*
|
||||
* #MetaCullable is our solution. The basic technique applied here is to
|
||||
* do a pre-pass before painting where we walk each actor from top to bottom
|
||||
* and ask each actor to "cull itself out". We pass in a region it can copy
|
||||
* to clip its drawing to, and the actor can subtract its fully opaque pixels
|
||||
* so that actors underneath know not to draw there as well.
|
||||
*/
|
||||
|
||||
/**
|
||||
* meta_cullable_cull_out_children:
|
||||
* @cullable: The #MetaCullable
|
||||
* @unobscured_region: The unobscured region, as passed into cull_out()
|
||||
* @clip_region: The clip region, as passed into cull_out()
|
||||
*
|
||||
* This is a helper method for actors that want to recurse over their
|
||||
* child actors, and cull them out.
|
||||
*
|
||||
* See #MetaCullable and meta_cullable_cull_out() for more details.
|
||||
*/
|
||||
void
|
||||
meta_cullable_cull_out_children (MetaCullable *cullable,
|
||||
cairo_region_t *unobscured_region,
|
||||
cairo_region_t *clip_region)
|
||||
{
|
||||
ClutterActor *actor = CLUTTER_ACTOR (cullable);
|
||||
ClutterActor *child;
|
||||
ClutterActorIter iter;
|
||||
|
||||
clutter_actor_iter_init (&iter, actor);
|
||||
while (clutter_actor_iter_prev (&iter, &child))
|
||||
{
|
||||
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);
|
||||
}
|
68
src/compositor/meta-cullable.h
Normal file
68
src/compositor/meta-cullable.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Owen Taylor <otaylor@redhat.com>
|
||||
* Ray Strode <rstrode@redhat.com>
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
*/
|
||||
|
||||
#ifndef __META_CULLABLE_H__
|
||||
#define __META_CULLABLE_H__
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define META_TYPE_CULLABLE (meta_cullable_get_type ())
|
||||
#define META_CULLABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CULLABLE, MetaCullable))
|
||||
#define META_IS_CULLABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CULLABLE))
|
||||
#define META_CULLABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), META_TYPE_CULLABLE, MetaCullableInterface))
|
||||
|
||||
typedef struct _MetaCullable MetaCullable;
|
||||
typedef struct _MetaCullableInterface MetaCullableInterface;
|
||||
|
||||
struct _MetaCullableInterface
|
||||
{
|
||||
GTypeInterface g_iface;
|
||||
|
||||
void (* cull_out) (MetaCullable *cullable,
|
||||
cairo_region_t *unobscured_region,
|
||||
cairo_region_t *clip_region);
|
||||
void (* reset_culling) (MetaCullable *cullable);
|
||||
};
|
||||
|
||||
GType meta_cullable_get_type (void);
|
||||
|
||||
void meta_cullable_cull_out (MetaCullable *cullable,
|
||||
cairo_region_t *unobscured_region,
|
||||
cairo_region_t *clip_region);
|
||||
void meta_cullable_reset_culling (MetaCullable *cullable);
|
||||
|
||||
/* Utility methods for implementations */
|
||||
void meta_cullable_cull_out_children (MetaCullable *cullable,
|
||||
cairo_region_t *unobscured_region,
|
||||
cairo_region_t *clip_region);
|
||||
void meta_cullable_reset_culling_children (MetaCullable *cullable);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __META_CULLABLE_H__ */
|
||||
|
@@ -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
|
||||
|
@@ -35,13 +35,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 +59,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 +72,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 +110,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 +140,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 +211,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 +227,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 +256,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 +317,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 +554,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 +596,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 +654,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 +677,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 +716,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 +777,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 +904,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 */
|
@@ -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;
|
||||
|
||||
@@ -2320,8 +2192,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 +2222,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 +2238,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 +2252,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 +2264,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 +2272,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 +2290,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 +2327,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 +2347,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 +2583,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 ())
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -118,8 +118,6 @@ typedef struct
|
||||
{
|
||||
MetaRectangle orig;
|
||||
MetaRectangle current;
|
||||
MetaFrameBorders *borders;
|
||||
gboolean must_free_borders;
|
||||
ActionType action_type;
|
||||
gboolean is_user_action;
|
||||
|
||||
@@ -195,7 +193,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 +201,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 +276,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 +298,6 @@ meta_window_constrain (MetaWindow *window,
|
||||
|
||||
setup_constraint_info (&info,
|
||||
window,
|
||||
orig_borders,
|
||||
flags,
|
||||
resize_gravity,
|
||||
orig,
|
||||
@@ -333,19 +327,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 +343,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 +493,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 +516,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 +562,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 +621,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 +654,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 +673,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 +707,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 +720,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 +806,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 +872,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 +920,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 +1029,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 +1221,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 +1242,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 +1266,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 +1379,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 +1457,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;
|
||||
|
@@ -40,7 +40,6 @@ typedef enum
|
||||
} MetaMoveResizeFlags;
|
||||
|
||||
void meta_window_constrain (MetaWindow *window,
|
||||
MetaFrameBorders *orig_borders,
|
||||
MetaMoveResizeFlags flags,
|
||||
int resize_gravity,
|
||||
const MetaRectangle *orig,
|
||||
|
@@ -172,6 +172,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 +283,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 +476,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,
|
||||
|
@@ -153,8 +153,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,
|
||||
|
@@ -43,14 +43,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 +65,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 +132,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
|
||||
|
@@ -39,6 +39,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 +57,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 +97,8 @@ struct _MetaDisplay
|
||||
char *name;
|
||||
Display *xdisplay;
|
||||
|
||||
int clutter_event_filter;
|
||||
|
||||
Window leader_window;
|
||||
Window timestamp_pinging_window;
|
||||
|
||||
@@ -147,6 +145,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 +185,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 +195,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 +451,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 +470,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,
|
||||
|
2843
src/core/display.c
2843
src/core/display.c
File diff suppressed because it is too large
Load Diff
@@ -985,7 +985,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 +1010,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 +1151,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 +1237,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,
|
||||
|
@@ -69,6 +69,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,
|
||||
@@ -334,9 +335,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
|
||||
|
@@ -41,6 +41,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 +52,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 +71,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,
|
||||
|
@@ -66,9 +66,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 +81,3 @@ gboolean meta_prefs_remove_keybinding (const char *name);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -31,18 +31,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
|
||||
|
@@ -68,11 +68,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 +121,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)
|
||||
@@ -352,7 +373,9 @@ meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
|
||||
|
||||
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);
|
||||
|
||||
@@ -518,8 +541,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);
|
||||
|
||||
@@ -644,6 +667,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 +695,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 +709,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);
|
||||
@@ -723,9 +757,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 +779,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 +802,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 +823,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 +882,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 +896,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 +942,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 +1003,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 +1013,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 +1086,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 +1171,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
|
||||
{
|
||||
|
@@ -949,6 +949,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",
|
||||
|
@@ -99,8 +99,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 +233,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 +817,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 +1352,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;
|
||||
|
@@ -119,6 +119,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 +410,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 */
|
||||
|
@@ -311,6 +311,29 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
XID output_id)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
XRRPropertyInfo *info;
|
||||
gboolean result = FALSE;
|
||||
|
||||
meta_error_trap_push (display);
|
||||
info = XRRQueryOutputProperty (manager_xrandr->xdisplay, output_id,
|
||||
display->atom_hotplug_mode_update);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
if (info)
|
||||
{
|
||||
result = TRUE;
|
||||
XFree (info);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
{
|
||||
@@ -430,8 +453,10 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
XRRFreeCrtcInfo (crtc);
|
||||
}
|
||||
|
||||
meta_error_trap_push (meta_get_display ());
|
||||
primary_output = XRRGetOutputPrimary (manager_xrandr->xdisplay,
|
||||
DefaultRootWindow (manager_xrandr->xdisplay));
|
||||
meta_error_trap_pop (meta_get_display ());
|
||||
|
||||
n_actual_outputs = 0;
|
||||
for (i = 0; i < (unsigned)resources->noutput; i++)
|
||||
@@ -484,6 +509,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
meta_output->width_mm = output->mm_width;
|
||||
meta_output->height_mm = output->mm_height;
|
||||
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||
meta_output->hotplug_mode_update =
|
||||
output_get_hotplug_mode_update (manager_xrandr, meta_output->output_id);
|
||||
|
||||
meta_output->n_modes = output->nmode;
|
||||
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
|
||||
@@ -666,10 +693,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 +791,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 +851,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 +860,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 +901,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 +931,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 +999,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 +1018,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 +1035,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);
|
||||
}
|
||||
|
||||
|
@@ -729,6 +729,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",
|
||||
|
299
src/core/place.c
299
src/core/place.c
@@ -47,34 +47,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 +74,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 +85,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 +104,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 +130,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 +205,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 +222,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 +272,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 +340,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 +393,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 +411,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 +433,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 +478,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 +511,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 +534,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 +545,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 +571,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 +601,6 @@ find_first_fit (MetaWindow *window,
|
||||
|
||||
void
|
||||
meta_window_place (MetaWindow *window,
|
||||
MetaFrameBorders *borders,
|
||||
int x,
|
||||
int y,
|
||||
int *new_x,
|
||||
@@ -661,13 +609,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 +697,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 +716,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 +752,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 +762,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 +807,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 +820,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 +841,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 +851,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 +872,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 +882,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:
|
||||
|
@@ -28,7 +28,6 @@
|
||||
#include "frame.h"
|
||||
|
||||
void meta_window_place (MetaWindow *window,
|
||||
MetaFrameBorders *borders,
|
||||
int x,
|
||||
int y,
|
||||
int *new_x,
|
||||
|
@@ -859,9 +859,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);
|
||||
@@ -1528,7 +1528,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 +1914,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);
|
||||
}
|
||||
|
@@ -92,16 +92,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 +1327,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 +1684,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);
|
||||
}
|
||||
|
@@ -44,6 +44,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 +102,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 +351,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 +367,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 +469,8 @@ struct _MetaWindow
|
||||
|
||||
/* Bypass compositor hints */
|
||||
guint bypass_compositor;
|
||||
|
||||
GSList *pending_pings;
|
||||
};
|
||||
|
||||
struct _MetaWindowClass
|
||||
@@ -507,8 +517,6 @@ MetaWindow* meta_window_new_with_attrs (MetaDisplay *display,
|
||||
MetaCompEffect effect,
|
||||
XWindowAttributes *attrs);
|
||||
MetaWindow *meta_window_new_for_wayland (MetaDisplay *display,
|
||||
int width,
|
||||
int height,
|
||||
MetaWaylandSurface *surface);
|
||||
void meta_window_unmanage (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
@@ -532,6 +540,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 +651,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 +693,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 +718,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 +738,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
|
||||
|
@@ -317,6 +317,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 +1655,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 +1771,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 },
|
||||
};
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -536,6 +536,81 @@ meta_prop_get_utf8_list (MetaDisplay *display,
|
||||
return utf8_list_from_results (&results, str_p, n_str_p);
|
||||
}
|
||||
|
||||
/* this one freakishly returns g_malloc memory */
|
||||
static gboolean
|
||||
latin1_list_from_results (GetPropertyResults *results,
|
||||
char ***str_p,
|
||||
int *n_str_p)
|
||||
{
|
||||
int i;
|
||||
int n_strings;
|
||||
char **retval;
|
||||
const char *p;
|
||||
|
||||
*str_p = NULL;
|
||||
*n_str_p = 0;
|
||||
|
||||
if (!validate_or_free_results (results, 8, XA_STRING, FALSE))
|
||||
return FALSE;
|
||||
|
||||
/* I'm not sure this is right, but I'm guessing the
|
||||
* property is nul-separated
|
||||
*/
|
||||
i = 0;
|
||||
n_strings = 0;
|
||||
while (i < (int) results->n_items)
|
||||
{
|
||||
if (results->prop[i] == '\0')
|
||||
++n_strings;
|
||||
++i;
|
||||
}
|
||||
|
||||
if (results->prop[results->n_items - 1] != '\0')
|
||||
++n_strings;
|
||||
|
||||
/* we're guaranteed that results->prop has a nul on the end
|
||||
* by XGetWindowProperty
|
||||
*/
|
||||
|
||||
retval = g_new0 (char*, n_strings + 1);
|
||||
|
||||
p = (char *)results->prop;
|
||||
i = 0;
|
||||
while (i < n_strings)
|
||||
{
|
||||
retval[i] = g_strdup (p);
|
||||
|
||||
p = p + strlen (p) + 1;
|
||||
++i;
|
||||
}
|
||||
|
||||
*str_p = retval;
|
||||
*n_str_p = i;
|
||||
|
||||
meta_XFree (results->prop);
|
||||
results->prop = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_prop_get_latin1_list (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
Atom xatom,
|
||||
char ***str_p,
|
||||
int *n_str_p)
|
||||
{
|
||||
GetPropertyResults results;
|
||||
|
||||
*str_p = NULL;
|
||||
|
||||
if (!get_property (display, xwindow, xatom,
|
||||
XA_STRING, &results))
|
||||
return FALSE;
|
||||
|
||||
return latin1_list_from_results (&results, str_p, n_str_p);
|
||||
}
|
||||
|
||||
void
|
||||
meta_prop_set_utf8_string_hint (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
|
@@ -102,6 +102,11 @@ gboolean meta_prop_get_utf8_list (MetaDisplay *display,
|
||||
Atom xatom,
|
||||
char ***str_p,
|
||||
int *n_str_p);
|
||||
gboolean meta_prop_get_latin1_list (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
Atom xatom,
|
||||
char ***str_p,
|
||||
int *n_str_p);
|
||||
void meta_prop_set_utf8_string_hint
|
||||
(MetaDisplay *display,
|
||||
Window xwindow,
|
||||
|
@@ -81,6 +81,8 @@ item(TIMESTAMP)
|
||||
item(VERSION)
|
||||
item(ATOM_PAIR)
|
||||
item(BACKLIGHT)
|
||||
item(_XKB_RULES_NAMES)
|
||||
item(hotplug_mode_update)
|
||||
|
||||
/* Oddities: These are used, and we need atoms for them,
|
||||
* but when we need all _NET_WM hints (i.e. when we're making
|
||||
@@ -178,6 +180,7 @@ item(_NET_WM_BYPASS_COMPOSITOR)
|
||||
item(_NET_WM_OPAQUE_REGION)
|
||||
item(_NET_WM_FRAME_DRAWN)
|
||||
item(_NET_WM_FRAME_TIMINGS)
|
||||
item(_NET_WM_WINDOW_OPACITY)
|
||||
|
||||
#if 0
|
||||
/* We apparently never use: */
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XInput.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
@@ -66,6 +66,8 @@ void meta_compositor_unmanage_screen (MetaCompositor *compositor,
|
||||
|
||||
void meta_compositor_window_shape_changed (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
void meta_compositor_window_opacity_changed (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
|
||||
gboolean meta_compositor_process_event (MetaCompositor *compositor,
|
||||
XEvent *event,
|
||||
|
@@ -35,13 +35,6 @@ gboolean meta_keybindings_set_custom_handler (const gchar *name,
|
||||
gpointer user_data,
|
||||
GDestroyNotify free_data);
|
||||
|
||||
void meta_keybindings_switch_window (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *event_window,
|
||||
XIDeviceEvent *event,
|
||||
MetaKeyBinding *binding);
|
||||
|
||||
|
||||
void meta_screen_ungrab_all_keys (MetaScreen *screen, guint32 timestamp);
|
||||
gboolean meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp);
|
||||
#endif
|
||||
|
@@ -81,9 +81,6 @@ void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
|
||||
void meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex,
|
||||
cairo_region_t *shape_region);
|
||||
|
||||
void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
|
||||
cairo_region_t *clip_region);
|
||||
|
||||
void meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex,
|
||||
cairo_region_t *opaque_region);
|
||||
|
||||
|
@@ -243,6 +243,10 @@ void meta_prefs_set_ignore_request_hide_titlebar (gboolean whether);
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_RIGHT: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_UP: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_DOWN: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_LEFT: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_RIGHT: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_UP: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_DOWN: FILLME
|
||||
* @META_KEYBINDING_ACTION_RAISE_OR_LOWER: FILLME
|
||||
* @META_KEYBINDING_ACTION_RAISE: FILLME
|
||||
* @META_KEYBINDING_ACTION_LOWER: FILLME
|
||||
@@ -258,6 +262,7 @@ void meta_prefs_set_ignore_request_hide_titlebar (gboolean whether);
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_W: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_CENTER: FILLME
|
||||
* @META_KEYBINDING_ACTION_OVERLAY_KEY: FILLME
|
||||
* @META_KEYBINDING_ACTION_ALWAYS_ON_TOP: FILLME
|
||||
* @META_KEYBINDING_ACTION_LAST: FILLME
|
||||
*/
|
||||
/* XXX FIXME This should be x-macroed, but isn't yet because it would be
|
||||
@@ -335,6 +340,10 @@ typedef enum _MetaKeyBindingAction
|
||||
META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_RIGHT,
|
||||
META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_UP,
|
||||
META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_DOWN,
|
||||
META_KEYBINDING_ACTION_MOVE_TO_MONITOR_LEFT,
|
||||
META_KEYBINDING_ACTION_MOVE_TO_MONITOR_RIGHT,
|
||||
META_KEYBINDING_ACTION_MOVE_TO_MONITOR_UP,
|
||||
META_KEYBINDING_ACTION_MOVE_TO_MONITOR_DOWN,
|
||||
META_KEYBINDING_ACTION_RAISE_OR_LOWER,
|
||||
META_KEYBINDING_ACTION_RAISE,
|
||||
META_KEYBINDING_ACTION_LOWER,
|
||||
@@ -351,6 +360,7 @@ typedef enum _MetaKeyBindingAction
|
||||
META_KEYBINDING_ACTION_MOVE_TO_CENTER,
|
||||
META_KEYBINDING_ACTION_OVERLAY_KEY,
|
||||
META_KEYBINDING_ACTION_ISO_NEXT_GROUP,
|
||||
META_KEYBINDING_ACTION_ALWAYS_ON_TOP,
|
||||
|
||||
META_KEYBINDING_ACTION_LAST
|
||||
} MetaKeyBindingAction;
|
||||
@@ -391,17 +401,17 @@ struct _MetaKeyCombo
|
||||
* @display: a #MetaDisplay
|
||||
* @screen: a #MetaScreen
|
||||
* @window: a #MetaWindow
|
||||
* @event: (type gpointer): a #XIDeviceEvent
|
||||
* @event: (type gpointer): a #ClutterKeyEvent
|
||||
* @binding: a #MetaKeyBinding
|
||||
* @user_data: data passed to the function
|
||||
*
|
||||
*/
|
||||
typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XIDeviceEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer user_data);
|
||||
typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
ClutterKeyEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer user_data);
|
||||
|
||||
typedef struct _MetaKeyHandler MetaKeyHandler;
|
||||
|
||||
|
@@ -110,7 +110,17 @@ gboolean meta_window_is_override_redirect (MetaWindow *window);
|
||||
gboolean meta_window_is_skip_taskbar (MetaWindow *window);
|
||||
MetaRectangle *meta_window_get_rect (MetaWindow *window);
|
||||
void meta_window_get_input_rect (const MetaWindow *window, MetaRectangle *rect);
|
||||
void meta_window_get_outer_rect (const MetaWindow *window, MetaRectangle *rect);
|
||||
|
||||
void meta_window_get_frame_rect (const MetaWindow *window, MetaRectangle *rect);
|
||||
void meta_window_get_outer_rect (const MetaWindow *window, MetaRectangle *rect) G_GNUC_DEPRECATED;
|
||||
|
||||
void meta_window_client_rect_to_frame_rect (MetaWindow *window,
|
||||
MetaRectangle *client_rect,
|
||||
MetaRectangle *frame_rect);
|
||||
void meta_window_frame_rect_to_client_rect (MetaWindow *window,
|
||||
MetaRectangle *frame_rect,
|
||||
MetaRectangle *client_rect);
|
||||
|
||||
MetaScreen *meta_window_get_screen (MetaWindow *window);
|
||||
MetaDisplay *meta_window_get_display (MetaWindow *window);
|
||||
Window meta_window_get_xwindow (MetaWindow *window);
|
||||
@@ -150,8 +160,7 @@ void meta_window_unset_demands_attention (MetaWindow *window);
|
||||
const char* meta_window_get_startup_id (MetaWindow *window);
|
||||
void meta_window_change_workspace_by_index (MetaWindow *window,
|
||||
gint space_index,
|
||||
gboolean append,
|
||||
guint32 timestamp);
|
||||
gboolean append);
|
||||
void meta_window_change_workspace (MetaWindow *window,
|
||||
MetaWorkspace *workspace);
|
||||
GObject *meta_window_get_compositor_private (MetaWindow *window);
|
||||
|
@@ -106,11 +106,49 @@ create_anonymous_file (off_t size,
|
||||
return -1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_wayland_xkb_info_new_keymap (MetaWaylandXkbInfo *xkb_info)
|
||||
static void
|
||||
inform_clients_of_new_keymap (MetaWaylandKeyboard *keyboard,
|
||||
int flags)
|
||||
{
|
||||
MetaWaylandCompositor *compositor;
|
||||
struct wl_client *xclient;
|
||||
struct wl_resource *keyboard_resource;
|
||||
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
xclient = compositor->xwayland_client;
|
||||
|
||||
wl_resource_for_each (keyboard_resource, &keyboard->resource_list)
|
||||
{
|
||||
if ((flags & META_WAYLAND_KEYBOARD_SKIP_XCLIENTS) &&
|
||||
wl_resource_get_client (keyboard_resource) == xclient)
|
||||
continue;
|
||||
|
||||
wl_keyboard_send_keymap (keyboard_resource,
|
||||
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
||||
keyboard->xkb_info.keymap_fd,
|
||||
keyboard->xkb_info.keymap_size);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard,
|
||||
struct xkb_keymap *keymap,
|
||||
int flags)
|
||||
{
|
||||
MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
|
||||
GError *error = NULL;
|
||||
char *keymap_str;
|
||||
size_t previous_size;
|
||||
|
||||
if (keymap == NULL)
|
||||
{
|
||||
g_warning ("Attempting to set null keymap (compilation probably failed)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (xkb_info->keymap)
|
||||
xkb_keymap_unref (xkb_info->keymap);
|
||||
xkb_info->keymap = keymap;
|
||||
|
||||
xkb_info->shift_mod =
|
||||
xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_SHIFT);
|
||||
@@ -129,21 +167,28 @@ meta_wayland_xkb_info_new_keymap (MetaWaylandXkbInfo *xkb_info)
|
||||
keymap_str = xkb_map_get_as_string (xkb_info->keymap);
|
||||
if (keymap_str == NULL)
|
||||
{
|
||||
g_warning ("failed to get string version of keymap\n");
|
||||
return FALSE;
|
||||
g_warning ("failed to get string version of keymap");
|
||||
return;
|
||||
}
|
||||
previous_size = xkb_info->keymap_size;
|
||||
xkb_info->keymap_size = strlen (keymap_str) + 1;
|
||||
|
||||
if (xkb_info->keymap_fd >= 0)
|
||||
close (xkb_info->keymap_fd);
|
||||
|
||||
xkb_info->keymap_fd = create_anonymous_file (xkb_info->keymap_size, &error);
|
||||
if (xkb_info->keymap_fd < 0)
|
||||
{
|
||||
g_warning ("creating a keymap file for %lu bytes failed: %s\n",
|
||||
g_warning ("creating a keymap file for %lu bytes failed: %s",
|
||||
(unsigned long) xkb_info->keymap_size,
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
goto err_keymap_str;
|
||||
}
|
||||
|
||||
if (xkb_info->keymap_area)
|
||||
munmap (xkb_info->keymap_area, previous_size);
|
||||
|
||||
xkb_info->keymap_area = mmap (NULL, xkb_info->keymap_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, xkb_info->keymap_fd, 0);
|
||||
@@ -156,41 +201,24 @@ meta_wayland_xkb_info_new_keymap (MetaWaylandXkbInfo *xkb_info)
|
||||
strcpy (xkb_info->keymap_area, keymap_str);
|
||||
free (keymap_str);
|
||||
|
||||
return TRUE;
|
||||
if (keyboard->is_evdev)
|
||||
{
|
||||
ClutterDeviceManager *manager;
|
||||
|
||||
manager = clutter_device_manager_get_default ();
|
||||
clutter_evdev_set_keyboard_map (manager, xkb_info->keymap);
|
||||
}
|
||||
|
||||
inform_clients_of_new_keymap (keyboard, flags);
|
||||
|
||||
return;
|
||||
|
||||
err_dev_zero:
|
||||
close (xkb_info->keymap_fd);
|
||||
xkb_info->keymap_fd = -1;
|
||||
err_keymap_str:
|
||||
free (keymap_str);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_wayland_keyboard_build_global_keymap (struct xkb_context *xkb_context,
|
||||
struct xkb_rule_names *xkb_names,
|
||||
MetaWaylandXkbInfo *xkb_info)
|
||||
{
|
||||
xkb_info->keymap = xkb_map_new_from_names (xkb_context,
|
||||
xkb_names,
|
||||
0 /* flags */);
|
||||
if (xkb_info->keymap == NULL)
|
||||
{
|
||||
g_warning ("failed to compile global XKB keymap\n"
|
||||
" tried rules %s, model %s, layout %s, variant %s, "
|
||||
"options %s\n",
|
||||
xkb_names->rules,
|
||||
xkb_names->model,
|
||||
xkb_names->layout,
|
||||
xkb_names->variant,
|
||||
xkb_names->options);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!meta_wayland_xkb_info_new_keymap (xkb_info))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -200,6 +228,7 @@ lose_keyboard_focus (struct wl_listener *listener, void *data)
|
||||
wl_container_of (listener, keyboard, focus_listener);
|
||||
|
||||
keyboard->focus_resource = NULL;
|
||||
keyboard->focus = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -306,9 +335,8 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
||||
struct wl_display *display,
|
||||
gboolean is_evdev)
|
||||
{
|
||||
ClutterDeviceManager *manager;
|
||||
|
||||
memset (keyboard, 0, sizeof *keyboard);
|
||||
keyboard->xkb_info.keymap_fd = -1;
|
||||
|
||||
wl_list_init (&keyboard->resource_list);
|
||||
wl_array_init (&keyboard->keys);
|
||||
@@ -320,18 +348,15 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
||||
keyboard->display = display;
|
||||
|
||||
keyboard->xkb_context = xkb_context_new (0 /* flags */);
|
||||
|
||||
meta_wayland_keyboard_build_global_keymap (keyboard->xkb_context,
|
||||
&keyboard->xkb_names,
|
||||
&keyboard->xkb_info);
|
||||
|
||||
keyboard->is_evdev = is_evdev;
|
||||
if (is_evdev)
|
||||
{
|
||||
manager = clutter_device_manager_get_default ();
|
||||
|
||||
clutter_evdev_set_keyboard_map (manager, keyboard->xkb_info.keymap);
|
||||
}
|
||||
/* Compute a default until gnome-settings-daemon starts and sets
|
||||
the appropriate values
|
||||
*/
|
||||
meta_wayland_keyboard_set_keymap_names (keyboard,
|
||||
"evdev",
|
||||
"pc105",
|
||||
"us", "", "", 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -487,27 +512,27 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard,
|
||||
struct wl_resource *resource;
|
||||
uint32_t serial;
|
||||
|
||||
if (keyboard->focus_resource && keyboard->focus != surface)
|
||||
{
|
||||
struct wl_display *display;
|
||||
struct wl_client *client;
|
||||
if (keyboard->focus == surface && keyboard->focus_resource != NULL)
|
||||
return;
|
||||
|
||||
resource = keyboard->focus_resource;
|
||||
client = wl_resource_get_client (resource);
|
||||
display = wl_client_get_display (client);
|
||||
resource = keyboard->focus_resource;
|
||||
if (keyboard->focus_resource && keyboard->focus->resource)
|
||||
{
|
||||
struct wl_client *client = wl_resource_get_client (resource);
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
serial = wl_display_next_serial (display);
|
||||
wl_keyboard_send_leave (resource, serial, keyboard->focus->resource);
|
||||
wl_list_remove (&keyboard->focus_listener.link);
|
||||
|
||||
meta_wayland_surface_focused_unset (keyboard->focus);
|
||||
}
|
||||
|
||||
resource = find_resource_for_surface (&keyboard->resource_list, surface);
|
||||
if (resource &&
|
||||
(keyboard->focus != surface || keyboard->focus_resource != resource))
|
||||
if (resource)
|
||||
{
|
||||
struct wl_client *client = wl_resource_get_client (resource);
|
||||
struct wl_display *display;
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
|
||||
display = wl_client_get_display (client);
|
||||
serial = wl_display_next_serial (display);
|
||||
|
||||
/* If we're in a modal grab, the client is focused but doesn't see
|
||||
@@ -534,6 +559,8 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard,
|
||||
}
|
||||
wl_resource_add_destroy_listener (resource, &keyboard->focus_listener);
|
||||
keyboard->focus_serial = serial;
|
||||
|
||||
meta_wayland_surface_focused_set (surface);
|
||||
}
|
||||
|
||||
keyboard->focus_resource = resource;
|
||||
@@ -559,12 +586,6 @@ meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard)
|
||||
void
|
||||
meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard)
|
||||
{
|
||||
g_free ((char *) keyboard->xkb_names.rules);
|
||||
g_free ((char *) keyboard->xkb_names.model);
|
||||
g_free ((char *) keyboard->xkb_names.layout);
|
||||
g_free ((char *) keyboard->xkb_names.variant);
|
||||
g_free ((char *) keyboard->xkb_names.options);
|
||||
|
||||
meta_wayland_xkb_info_destroy (&keyboard->xkb_info);
|
||||
xkb_context_unref (keyboard->xkb_context);
|
||||
|
||||
@@ -652,3 +673,28 @@ meta_wayland_keyboard_end_modal (MetaWaylandKeyboard *keyboard,
|
||||
|
||||
meta_verbose ("Released modal keyboard grab, timestamp %d\n", timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_keyboard_set_keymap_names (MetaWaylandKeyboard *keyboard,
|
||||
const char *rules,
|
||||
const char *model,
|
||||
const char *layout,
|
||||
const char *variant,
|
||||
const char *options,
|
||||
int flags)
|
||||
{
|
||||
struct xkb_rule_names xkb_names;
|
||||
|
||||
xkb_names.rules = rules;
|
||||
xkb_names.model = model;
|
||||
xkb_names.layout = layout;
|
||||
xkb_names.variant = variant;
|
||||
xkb_names.options = options;
|
||||
|
||||
meta_wayland_keyboard_take_keymap (keyboard,
|
||||
xkb_keymap_new_from_names (keyboard->xkb_context,
|
||||
&xkb_names,
|
||||
0 /* flags */),
|
||||
flags);
|
||||
}
|
||||
|
||||
|
@@ -112,7 +112,6 @@ struct _MetaWaylandKeyboard
|
||||
struct xkb_context *xkb_context;
|
||||
gboolean is_evdev;
|
||||
MetaWaylandXkbInfo xkb_info;
|
||||
struct xkb_rule_names xkb_names;
|
||||
|
||||
MetaWaylandKeyboardGrab input_method_grab;
|
||||
struct wl_resource *input_method_resource;
|
||||
@@ -123,6 +122,18 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
||||
struct wl_display *display,
|
||||
gboolean is_evdev);
|
||||
|
||||
typedef enum {
|
||||
META_WAYLAND_KEYBOARD_SKIP_XCLIENTS = 1,
|
||||
} MetaWaylandKeyboardSetKeymapFlags;
|
||||
|
||||
void
|
||||
meta_wayland_keyboard_set_keymap_names (MetaWaylandKeyboard *keyboard,
|
||||
const char *rules,
|
||||
const char *model,
|
||||
const char *layout,
|
||||
const char *variant,
|
||||
const char *options,
|
||||
int flags);
|
||||
gboolean
|
||||
meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
|
||||
const ClutterKeyEvent *event);
|
||||
|
@@ -49,6 +49,7 @@
|
||||
|
||||
#include "meta-wayland-pointer.h"
|
||||
#include "meta-wayland-private.h"
|
||||
#include "xdg-shell-server-protocol.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -317,8 +318,11 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
struct wl_resource *resource, *kr;
|
||||
uint32_t serial;
|
||||
|
||||
if (pointer->focus == surface && pointer->focus_resource != NULL)
|
||||
return;
|
||||
|
||||
resource = pointer->focus_resource;
|
||||
if (resource && pointer->focus != surface)
|
||||
if (resource && pointer->focus->resource)
|
||||
{
|
||||
struct wl_client *client = wl_resource_get_client (resource);
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
@@ -328,8 +332,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
}
|
||||
|
||||
resource = find_resource_for_surface (&pointer->resource_list, surface);
|
||||
if (resource &&
|
||||
(pointer->focus != surface || pointer->focus_resource != resource))
|
||||
if (resource)
|
||||
{
|
||||
struct wl_client *client = wl_resource_get_client (resource);
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
@@ -352,6 +355,11 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
}
|
||||
|
||||
meta_wayland_pointer_get_relative_coordinates (pointer, surface, &sx, &sy);
|
||||
meta_window_handle_enter (surface->window,
|
||||
/* XXX -- can we reliably get a timestamp for setting focus? */
|
||||
clutter_get_current_event_time (),
|
||||
wl_fixed_to_int (pointer->x),
|
||||
wl_fixed_to_int (pointer->y));
|
||||
wl_pointer_send_enter (resource, serial, surface->resource, sx, sy);
|
||||
wl_resource_add_destroy_listener (resource, &pointer->focus_listener);
|
||||
pointer->focus_serial = serial;
|
||||
@@ -385,32 +393,6 @@ meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer)
|
||||
interface->focus (pointer->grab, pointer->current, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
current_surface_destroy (struct wl_listener *listener, void *data)
|
||||
{
|
||||
MetaWaylandPointer *pointer =
|
||||
wl_container_of (listener, pointer, current_listener);
|
||||
|
||||
pointer->current = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_pointer_set_current (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
if (pointer->current)
|
||||
wl_list_remove (&pointer->current_listener.link);
|
||||
|
||||
pointer->current = surface;
|
||||
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
wl_resource_add_destroy_listener (surface->resource,
|
||||
&pointer->current_listener);
|
||||
pointer->current_listener.notify = current_surface_destroy;
|
||||
}
|
||||
|
||||
static void
|
||||
modal_focus (MetaWaylandPointerGrab *grab,
|
||||
MetaWaylandSurface *surface,
|
||||
@@ -466,24 +448,6 @@ meta_wayland_pointer_end_modal (MetaWaylandPointer *pointer)
|
||||
g_slice_free (MetaWaylandPointerGrab, grab);
|
||||
}
|
||||
|
||||
/* Called when the focused resource is destroyed */
|
||||
void
|
||||
meta_wayland_pointer_destroy_focus (MetaWaylandPointer *pointer)
|
||||
{
|
||||
if (pointer->grab == &pointer->default_grab)
|
||||
{
|
||||
/* The surface was destroyed, but had the implicit pointer grab.
|
||||
Bypass the grab interface. */
|
||||
g_assert (pointer->button_count > 0);
|
||||
|
||||
/* Note: we focus the NULL interface, not the current one, because
|
||||
we have button down, and the clients would be confused if the
|
||||
pointer enters the surface.
|
||||
*/
|
||||
meta_wayland_pointer_set_focus (pointer, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
MetaWaylandPointerGrab generic;
|
||||
|
||||
@@ -508,7 +472,7 @@ popup_grab_focus (MetaWaylandPointerGrab *grab,
|
||||
|
||||
/* Popup grabs are in owner-events mode (ie, events for the same client
|
||||
are reported as normal) */
|
||||
if (wl_resource_get_client (surface->resource) == popup_grab->grab_client)
|
||||
if (surface && wl_resource_get_client (surface->resource) == popup_grab->grab_client)
|
||||
default_grab_focus (grab, surface, event);
|
||||
else
|
||||
meta_wayland_pointer_set_focus (grab->pointer, NULL);
|
||||
@@ -558,9 +522,14 @@ meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer)
|
||||
|
||||
wl_list_for_each_safe (popup, tmp, &popup_grab->all_popups, link)
|
||||
{
|
||||
MetaWaylandSurfaceExtension *shell_surface = popup->surface->shell_surface;
|
||||
MetaWaylandSurfaceExtension *xdg_popup = &popup->surface->xdg_popup;
|
||||
struct wl_client *client = wl_resource_get_client (xdg_popup->resource);
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
uint32_t serial;
|
||||
|
||||
wl_shell_surface_send_popup_done (shell_surface->resource);
|
||||
serial = wl_display_next_serial (display);
|
||||
|
||||
xdg_popup_send_popup_done (xdg_popup->resource, serial);
|
||||
wl_list_remove (&popup->surface_destroy_listener.link);
|
||||
wl_list_remove (&popup->link);
|
||||
g_slice_free (MetaWaylandPopup, popup);
|
||||
@@ -622,7 +591,7 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
|
||||
popup->grab = grab;
|
||||
popup->surface = surface;
|
||||
popup->surface_destroy_listener.notify = on_popup_surface_destroy;
|
||||
wl_resource_add_destroy_listener (surface->resource, &popup->surface_destroy_listener);
|
||||
wl_resource_add_destroy_listener (surface->xdg_popup.resource, &popup->surface_destroy_listener);
|
||||
|
||||
wl_list_insert (&grab->all_popups, &popup->link);
|
||||
|
||||
|
@@ -62,8 +62,6 @@ struct _MetaWaylandPointer
|
||||
|
||||
wl_fixed_t x, y; /* TODO: remove, use ClutterInputDevice instead */
|
||||
MetaWaylandSurface *current;
|
||||
struct wl_listener current_listener;
|
||||
wl_fixed_t current_x, current_y;
|
||||
|
||||
guint32 button_count;
|
||||
};
|
||||
@@ -78,8 +76,6 @@ meta_wayland_pointer_release (MetaWaylandPointer *pointer);
|
||||
void
|
||||
meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface);
|
||||
void
|
||||
meta_wayland_pointer_destroy_focus (MetaWaylandPointer *pointer);
|
||||
|
||||
void
|
||||
meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer,
|
||||
@@ -97,10 +93,6 @@ gboolean
|
||||
meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *popup);
|
||||
|
||||
void
|
||||
meta_wayland_pointer_set_current (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
void
|
||||
meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface,
|
||||
|
@@ -83,14 +83,6 @@ struct _MetaWaylandCompositor
|
||||
int drm_fd;
|
||||
|
||||
MetaWaylandSeat *seat;
|
||||
|
||||
/* This surface is only used to keep drag of the implicit grab when
|
||||
synthesizing XEvents for Mutter */
|
||||
MetaWaylandSurface *implicit_grab_surface;
|
||||
/* Button that was pressed to initiate an implicit grab. The
|
||||
implicit grab will only be released when this button is
|
||||
released */
|
||||
guint32 implicit_grab_button;
|
||||
};
|
||||
|
||||
void meta_wayland_init (void);
|
||||
@@ -104,6 +96,8 @@ void meta_wayland_compositor_repick (MetaWaylandComp
|
||||
|
||||
void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
gboolean meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor,
|
||||
const ClutterEvent *event);
|
||||
|
||||
MetaLauncher *meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor);
|
||||
gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor);
|
||||
@@ -113,5 +107,8 @@ MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resou
|
||||
void meta_wayland_buffer_reference (MetaWaylandBufferReference *ref,
|
||||
MetaWaylandBuffer *buffer);
|
||||
|
||||
void meta_wayland_compositor_update (MetaWaylandCompositor *compositor,
|
||||
const ClutterEvent *event);
|
||||
void meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor);
|
||||
|
||||
#endif /* META_WAYLAND_PRIVATE_H */
|
||||
|
@@ -51,14 +51,7 @@ static void
|
||||
pointer_unmap_sprite (MetaWaylandSeat *seat)
|
||||
{
|
||||
if (seat->cursor_tracker)
|
||||
{
|
||||
meta_cursor_tracker_set_buffer (seat->cursor_tracker,
|
||||
NULL, 0, 0);
|
||||
|
||||
if (seat->current_stage)
|
||||
meta_cursor_tracker_queue_redraw (seat->cursor_tracker,
|
||||
CLUTTER_ACTOR (seat->current_stage));
|
||||
}
|
||||
meta_cursor_tracker_set_window_cursor (seat->cursor_tracker, NULL, 0, 0);
|
||||
|
||||
if (seat->sprite)
|
||||
{
|
||||
@@ -75,15 +68,15 @@ meta_wayland_seat_update_sprite (MetaWaylandSeat *seat)
|
||||
if (seat->cursor_tracker == NULL)
|
||||
return;
|
||||
|
||||
buffer = seat->sprite->buffer_ref.buffer->resource;
|
||||
meta_cursor_tracker_set_buffer (seat->cursor_tracker,
|
||||
buffer,
|
||||
seat->hotspot_x,
|
||||
seat->hotspot_y);
|
||||
if (seat->sprite->buffer_ref.buffer)
|
||||
buffer = seat->sprite->buffer_ref.buffer->resource;
|
||||
else
|
||||
buffer = NULL;
|
||||
|
||||
if (seat->current_stage)
|
||||
meta_cursor_tracker_queue_redraw (seat->cursor_tracker,
|
||||
CLUTTER_ACTOR (seat->current_stage));
|
||||
meta_cursor_tracker_set_window_cursor (seat->cursor_tracker,
|
||||
buffer,
|
||||
seat->hotspot_x,
|
||||
seat->hotspot_y);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -257,11 +250,6 @@ notify_motion (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaWaylandPointer *pointer = &seat->pointer;
|
||||
float x, y;
|
||||
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
pointer->x = wl_fixed_from_double (x);
|
||||
pointer->y = wl_fixed_from_double (y);
|
||||
|
||||
meta_wayland_seat_repick (seat, event);
|
||||
|
||||
@@ -280,34 +268,22 @@ handle_button_event (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaWaylandPointer *pointer = &seat->pointer;
|
||||
gboolean state = event->type == CLUTTER_BUTTON_PRESS;
|
||||
uint32_t button;
|
||||
MetaWaylandSurface *surface;
|
||||
gboolean implicit_grab;
|
||||
|
||||
notify_motion (seat, event);
|
||||
|
||||
if (state && pointer->button_count == 1)
|
||||
implicit_grab = (event->type == CLUTTER_BUTTON_PRESS) && (pointer->button_count == 1);
|
||||
if (implicit_grab)
|
||||
{
|
||||
button = clutter_event_get_button (event);
|
||||
pointer->grab_button = button;
|
||||
pointer->grab_button = clutter_event_get_button (event);
|
||||
pointer->grab_time = clutter_event_get_time (event);
|
||||
pointer->grab_x = pointer->x;
|
||||
pointer->grab_y = pointer->y;
|
||||
|
||||
/* FIXME: synth a XI2 event and handle in display.c */
|
||||
surface = pointer->current;
|
||||
if (button == CLUTTER_BUTTON_PRIMARY &&
|
||||
surface &&
|
||||
surface->window &&
|
||||
surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
|
||||
{
|
||||
meta_window_raise (surface->window);
|
||||
}
|
||||
}
|
||||
|
||||
pointer->grab->interface->button (pointer->grab, event);
|
||||
|
||||
if (pointer->button_count == 1)
|
||||
if (implicit_grab)
|
||||
pointer->grab_serial = wl_display_get_serial (seat->display);
|
||||
}
|
||||
|
||||
@@ -375,12 +351,33 @@ count_buttons (const ClutterEvent *event)
|
||||
return count;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_seat_update_pointer (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
float x, y;
|
||||
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
seat->pointer.x = wl_fixed_from_double (x);
|
||||
seat->pointer.y = wl_fixed_from_double (y);
|
||||
|
||||
seat->pointer.button_count = count_buttons (event);
|
||||
|
||||
if (seat->cursor_tracker)
|
||||
{
|
||||
meta_cursor_tracker_update_position (seat->cursor_tracker,
|
||||
wl_fixed_to_int (seat->pointer.x),
|
||||
wl_fixed_to_int (seat->pointer.y));
|
||||
|
||||
if (seat->pointer.current == NULL)
|
||||
meta_cursor_tracker_unset_window_cursor (seat->cursor_tracker);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
seat->pointer.button_count = count_buttons (event);
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_MOTION:
|
||||
@@ -408,20 +405,6 @@ meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_pointer_position_for_actor (MetaWaylandPointer *pointer,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
float ax, ay;
|
||||
|
||||
clutter_actor_transform_stage_point (actor,
|
||||
wl_fixed_to_double (pointer->x),
|
||||
wl_fixed_to_double (pointer->y),
|
||||
&ax, &ay);
|
||||
pointer->current_x = wl_fixed_from_double (ax);
|
||||
pointer->current_y = wl_fixed_from_double (ay);
|
||||
}
|
||||
|
||||
/* The actor argument can be NULL in which case a Clutter pick will be
|
||||
performed to determine the right actor. An actor should only be
|
||||
passed if the repick is being performed due to an event in which
|
||||
@@ -458,18 +441,8 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat,
|
||||
MetaWindow *window =
|
||||
meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor));
|
||||
|
||||
update_pointer_position_for_actor (pointer, actor);
|
||||
|
||||
surface = window->surface;
|
||||
}
|
||||
else if (META_IS_SHAPED_TEXTURE (actor))
|
||||
{
|
||||
MetaShapedTexture *shaped_texture = META_SHAPED_TEXTURE (actor);
|
||||
|
||||
update_pointer_position_for_actor (pointer, actor);
|
||||
|
||||
surface = meta_shaped_texture_get_wayland_surface (shaped_texture);
|
||||
}
|
||||
|
||||
pointer->current = surface;
|
||||
if (surface != pointer->focus)
|
||||
|
@@ -77,6 +77,10 @@ MetaWaylandSeat *
|
||||
meta_wayland_seat_new (struct wl_display *display,
|
||||
gboolean is_native);
|
||||
|
||||
void
|
||||
meta_wayland_seat_update_pointer (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event);
|
||||
|
||||
gboolean
|
||||
meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event);
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,7 @@
|
||||
|
||||
#include <meta/meta-cursor-tracker.h>
|
||||
#include "meta-wayland-types.h"
|
||||
#include "meta-surface-actor.h"
|
||||
|
||||
struct _MetaWaylandBuffer
|
||||
{
|
||||
@@ -66,33 +67,8 @@ typedef struct
|
||||
struct wl_list frame_callback_list;
|
||||
} MetaWaylandDoubleBufferedState;
|
||||
|
||||
typedef enum {
|
||||
META_WAYLAND_SURFACE_TOPLEVEL = 0,
|
||||
META_WAYLAND_SURFACE_MAXIMIZED,
|
||||
META_WAYLAND_SURFACE_FULLSCREEN,
|
||||
META_WAYLAND_SURFACE_POPUP,
|
||||
} MetaWaylandSurfaceType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaWaylandSurfaceType initial_type;
|
||||
struct wl_resource *transient_for;
|
||||
int x, y;
|
||||
|
||||
char *title;
|
||||
char *wm_class;
|
||||
|
||||
char *gtk_application_id;
|
||||
char *gtk_unique_bus_name;
|
||||
char *gtk_app_menu_path;
|
||||
char *gtk_menubar_path;
|
||||
char *gtk_application_object_path;
|
||||
char *gtk_window_object_path;
|
||||
} MetaWaylandSurfaceInitialState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaWaylandSurface *surface;
|
||||
struct wl_resource *resource;
|
||||
struct wl_listener surface_destroy_listener;
|
||||
} MetaWaylandSurfaceExtension;
|
||||
@@ -102,16 +78,15 @@ struct _MetaWaylandSurface
|
||||
struct wl_resource *resource;
|
||||
MetaWaylandCompositor *compositor;
|
||||
MetaWaylandBufferReference buffer_ref;
|
||||
MetaSurfaceActor *surface_actor;
|
||||
MetaWindow *window;
|
||||
MetaWaylandSurfaceExtension *shell_surface;
|
||||
MetaWaylandSurfaceExtension *gtk_surface;
|
||||
MetaWaylandSurfaceExtension xdg_surface;
|
||||
MetaWaylandSurfaceExtension xdg_popup;
|
||||
MetaWaylandSurfaceExtension gtk_surface;
|
||||
MetaWaylandSurfaceExtension subsurface;
|
||||
|
||||
/* All the pending state, that wl_surface.commit will apply. */
|
||||
MetaWaylandDoubleBufferedState pending;
|
||||
|
||||
/* All the initial state, that wl_shell_surface.set_* will apply
|
||||
(through meta_window_new_for_wayland) */
|
||||
MetaWaylandSurfaceInitialState *initial_state;
|
||||
};
|
||||
|
||||
void meta_wayland_init_shell (MetaWaylandCompositor *compositor);
|
||||
@@ -120,14 +95,15 @@ MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *composit
|
||||
struct wl_client *client,
|
||||
guint32 id,
|
||||
guint32 version);
|
||||
void meta_wayland_surface_free (MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_surface_set_initial_state (MetaWaylandSurface *surface,
|
||||
MetaWindow *window);
|
||||
|
||||
void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,
|
||||
int width,
|
||||
int height,
|
||||
int edges);
|
||||
|
||||
void meta_wayland_surface_focused_set (MetaWaylandSurface *surface);
|
||||
void meta_wayland_surface_focused_unset (MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_surface_ping (MetaWaylandSurface *surface,
|
||||
guint32 serial);
|
||||
|
||||
#endif
|
||||
|
@@ -37,23 +37,26 @@
|
||||
/* Global/master objects (version exported by wl_registry and negotiated through bind) */
|
||||
#define META_WL_COMPOSITOR_VERSION 3
|
||||
#define META_WL_DATA_DEVICE_MANAGER_VERSION 1
|
||||
#define META_WL_SHELL_VERSION 1
|
||||
#define META_WL_SEAT_VERSION 2 /* 3 not implemented yet */
|
||||
#define META_WL_OUTPUT_VERSION 2
|
||||
#define META_XSERVER_VERSION 1
|
||||
#define META_GTK_SHELL_VERSION 1
|
||||
#define META_XDG_SHELL_VERSION 1
|
||||
#define META_WL_SUBCOMPOSITOR_VERSION 1
|
||||
|
||||
/* Slave objects (version inherited from a master object) */
|
||||
#define META_WL_DATA_OFFER_VERSION 1 /* from wl_data_device */
|
||||
#define META_WL_DATA_SOURCE_VERSION 1 /* from wl_data_device */
|
||||
#define META_WL_DATA_DEVICE_VERSION 1 /* from wl_data_device_manager */
|
||||
#define META_WL_SHELL_SURFACE_VERSION 1 /* from wl_shell */
|
||||
#define META_WL_SURFACE_VERSION 3 /* from wl_compositor */
|
||||
#define META_WL_POINTER_VERSION 2 /* from wl_seat; 3 not implemented yet */
|
||||
#define META_WL_KEYBOARD_VERSION 2 /* from wl_seat; 3 not implemented yet */
|
||||
#define META_WL_TOUCH_VERSION 0 /* from wl_seat; wl_touch not supported */
|
||||
#define META_WL_REGION_VERSION 1 /* from wl_compositor */
|
||||
#define META_GTK_SURFACE_VERSION 1 /* from gtk_shell */
|
||||
#define META_XDG_SURFACE_VERSION 1 /* from xdg_shell */
|
||||
#define META_XDG_POPUP_VERSION 1 /* from xdg_shell */
|
||||
#define META_WL_SUBSURFACE_VERSION 1 /* from wl_subcompositor */
|
||||
|
||||
/* The first version to implement a specific event */
|
||||
#define META_WL_SEAT_HAS_NAME 2
|
||||
|
@@ -497,11 +497,9 @@ const static struct wl_compositor_interface meta_wayland_compositor_interface =
|
||||
meta_wayland_compositor_create_region
|
||||
};
|
||||
|
||||
static void
|
||||
paint_finished_cb (ClutterActor *self, void *user_data)
|
||||
void
|
||||
meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = user_data;
|
||||
|
||||
while (!wl_list_empty (&compositor->frame_callbacks))
|
||||
{
|
||||
MetaWaylandFrameCallback *callback =
|
||||
@@ -533,127 +531,18 @@ stage_destroy_cb (void)
|
||||
meta_quit (META_EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
#define N_BUTTONS 5
|
||||
|
||||
static void
|
||||
synthesize_motion_event (MetaWaylandCompositor *compositor,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
/* We want to synthesize X events for mouse motion events so that we
|
||||
don't have to rely on the X server's window position being
|
||||
synched with the surface position. See the comment in
|
||||
event_callback() in display.c */
|
||||
MetaWaylandSeat *seat = compositor->seat;
|
||||
MetaWaylandPointer *pointer = &seat->pointer;
|
||||
MetaWaylandSurface *surface;
|
||||
XGenericEventCookie generic_event;
|
||||
XIDeviceEvent device_event;
|
||||
unsigned char button_mask[(N_BUTTONS + 7) / 8] = { 0 };
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
ClutterModifierType button_state;
|
||||
int i;
|
||||
|
||||
generic_event.type = GenericEvent;
|
||||
generic_event.serial = 0;
|
||||
generic_event.send_event = False;
|
||||
generic_event.display = display->xdisplay;
|
||||
generic_event.extension = display->xinput_opcode;
|
||||
generic_event.evtype = XI_Motion;
|
||||
/* Mutter assumes the data for the event is already retrieved by GDK
|
||||
* so we don't need the cookie */
|
||||
generic_event.cookie = 0;
|
||||
generic_event.data = &device_event;
|
||||
|
||||
memcpy (&device_event, &generic_event, sizeof (XGenericEvent));
|
||||
|
||||
device_event.time = clutter_event_get_time (event);
|
||||
device_event.deviceid = clutter_event_get_device_id (event);
|
||||
device_event.sourceid = 0; /* not used, not sure what this should be */
|
||||
device_event.detail = 0;
|
||||
device_event.root = DefaultRootWindow (display->xdisplay);
|
||||
device_event.flags = 0 /* not used for motion events */;
|
||||
|
||||
if (compositor->implicit_grab_surface)
|
||||
surface = compositor->implicit_grab_surface;
|
||||
else
|
||||
surface = pointer->current;
|
||||
|
||||
if (surface == pointer->current)
|
||||
{
|
||||
device_event.event_x = wl_fixed_to_int (pointer->current_x);
|
||||
device_event.event_y = wl_fixed_to_int (pointer->current_y);
|
||||
}
|
||||
else if (surface && surface->window)
|
||||
{
|
||||
ClutterActor *window_actor =
|
||||
CLUTTER_ACTOR (meta_window_get_compositor_private (surface->window));
|
||||
|
||||
if (window_actor)
|
||||
{
|
||||
float ax, ay;
|
||||
|
||||
clutter_actor_transform_stage_point (window_actor,
|
||||
wl_fixed_to_double (pointer->x),
|
||||
wl_fixed_to_double (pointer->y),
|
||||
&ax, &ay);
|
||||
|
||||
device_event.event_x = ax;
|
||||
device_event.event_y = ay;
|
||||
}
|
||||
else
|
||||
{
|
||||
device_event.event_x = wl_fixed_to_double (pointer->x);
|
||||
device_event.event_y = wl_fixed_to_double (pointer->y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
device_event.event_x = wl_fixed_to_double (pointer->x);
|
||||
device_event.event_y = wl_fixed_to_double (pointer->y);
|
||||
}
|
||||
|
||||
if (surface && surface->window != NULL)
|
||||
device_event.event = surface->window->xwindow;
|
||||
else
|
||||
device_event.event = device_event.root;
|
||||
|
||||
/* Mutter doesn't really know about the sub-windows. This assumes it
|
||||
doesn't care either */
|
||||
device_event.child = device_event.event;
|
||||
device_event.root_x = wl_fixed_to_double (pointer->x);
|
||||
device_event.root_y = wl_fixed_to_double (pointer->y);
|
||||
|
||||
clutter_event_get_state_full (event,
|
||||
&button_state,
|
||||
(ClutterModifierType*)&device_event.mods.base,
|
||||
(ClutterModifierType*)&device_event.mods.latched,
|
||||
(ClutterModifierType*)&device_event.mods.locked,
|
||||
(ClutterModifierType*)&device_event.mods.effective);
|
||||
device_event.mods.effective &= ~button_state;
|
||||
memset (&device_event.group, 0, sizeof (device_event.group));
|
||||
device_event.group.effective = (device_event.mods.effective >> 13) & 0x3;
|
||||
|
||||
for (i = 0; i < N_BUTTONS; i++)
|
||||
if ((button_state & (CLUTTER_BUTTON1_MASK << i)))
|
||||
XISetMask (button_mask, i + 1);
|
||||
device_event.buttons.mask_len = N_BUTTONS + 1;
|
||||
device_event.buttons.mask = button_mask;
|
||||
|
||||
device_event.valuators.mask_len = 0;
|
||||
device_event.valuators.mask = NULL;
|
||||
device_event.valuators.values = NULL;
|
||||
|
||||
meta_display_handle_event (display, (XEvent *) &generic_event);
|
||||
}
|
||||
|
||||
static void
|
||||
reset_idletimes (const ClutterEvent *event)
|
||||
void
|
||||
meta_wayland_compositor_update (MetaWaylandCompositor *compositor,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
ClutterInputDevice *device, *source_device;
|
||||
MetaIdleMonitor *core_monitor, *device_monitor;
|
||||
int device_id;
|
||||
|
||||
device = clutter_event_get_device (event);
|
||||
if (device == NULL)
|
||||
return;
|
||||
|
||||
device_id = clutter_input_device_get_device_id (device);
|
||||
|
||||
core_monitor = meta_idle_monitor_get_core ();
|
||||
@@ -669,134 +558,24 @@ reset_idletimes (const ClutterEvent *event)
|
||||
device_monitor = meta_idle_monitor_get_for_device (device_id);
|
||||
meta_idle_monitor_reset_idletime (device_monitor);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
event_cb (ClutterActor *stage,
|
||||
const ClutterEvent *event,
|
||||
MetaWaylandCompositor *compositor)
|
||||
{
|
||||
MetaWaylandSeat *seat = compositor->seat;
|
||||
MetaWaylandPointer *pointer = &seat->pointer;
|
||||
MetaWaylandSurface *surface;
|
||||
MetaDisplay *display;
|
||||
|
||||
reset_idletimes (event);
|
||||
|
||||
if (meta_wayland_seat_handle_event (compositor->seat, event))
|
||||
return TRUE;
|
||||
|
||||
/* HACK: for now, the surfaces from Wayland clients aren't
|
||||
integrated into Mutter's event handling and Mutter won't give them
|
||||
focus on mouse clicks. As a hack to work around this we can just
|
||||
give them input focus on mouse clicks so we can at least test the
|
||||
keyboard support */
|
||||
if (event->type == CLUTTER_BUTTON_PRESS)
|
||||
{
|
||||
surface = pointer->current;
|
||||
|
||||
if (surface && surface->window &&
|
||||
surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
guint32 timestamp = meta_display_get_current_time_roundtrip (display);
|
||||
|
||||
meta_window_focus (surface->window, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
if (seat->cursor_tracker)
|
||||
{
|
||||
meta_cursor_tracker_update_position (seat->cursor_tracker,
|
||||
wl_fixed_to_int (pointer->x),
|
||||
wl_fixed_to_int (pointer->y));
|
||||
|
||||
if (pointer->current == NULL)
|
||||
meta_cursor_tracker_revert_root (seat->cursor_tracker);
|
||||
|
||||
meta_cursor_tracker_queue_redraw (seat->cursor_tracker, stage);
|
||||
}
|
||||
|
||||
display = meta_get_display ();
|
||||
if (!display)
|
||||
return FALSE;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
if (compositor->implicit_grab_surface == NULL)
|
||||
{
|
||||
compositor->implicit_grab_button = event->button.button;
|
||||
compositor->implicit_grab_surface = pointer->current;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
if (event->type == CLUTTER_BUTTON_RELEASE &&
|
||||
compositor->implicit_grab_surface &&
|
||||
event->button.button == compositor->implicit_grab_button)
|
||||
compositor->implicit_grab_surface = NULL;
|
||||
return FALSE;
|
||||
|
||||
case CLUTTER_MOTION:
|
||||
synthesize_motion_event (compositor, event);
|
||||
return FALSE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
event_emission_hook_cb (GSignalInvocationHint *ihint,
|
||||
guint n_param_values,
|
||||
const GValue *param_values,
|
||||
gpointer data)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = data;
|
||||
ClutterActor *actor;
|
||||
ClutterEvent *event;
|
||||
|
||||
g_return_val_if_fail (n_param_values == 2, FALSE);
|
||||
|
||||
actor = g_value_get_object (param_values + 0);
|
||||
event = g_value_get_boxed (param_values + 1);
|
||||
|
||||
if (actor == NULL)
|
||||
return TRUE /* stay connected */;
|
||||
|
||||
/* If this event belongs to the corresponding grab for this event
|
||||
* type then the captured-event signal won't be emitted so we have
|
||||
* to manually forward it on */
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
/* Pointer events */
|
||||
case CLUTTER_MOTION:
|
||||
case CLUTTER_ENTER:
|
||||
case CLUTTER_LEAVE:
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
case CLUTTER_SCROLL:
|
||||
if (actor == clutter_get_pointer_grab ())
|
||||
event_cb (clutter_actor_get_stage (actor),
|
||||
event,
|
||||
compositor);
|
||||
break;
|
||||
|
||||
/* Keyboard events */
|
||||
case CLUTTER_KEY_PRESS:
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
if (actor == clutter_get_keyboard_grab ())
|
||||
event_cb (clutter_actor_get_stage (actor),
|
||||
event,
|
||||
compositor);
|
||||
|
||||
meta_wayland_seat_update_pointer (compositor->seat, event);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE /* stay connected */;
|
||||
gboolean
|
||||
meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
return meta_wayland_seat_handle_event (compositor->seat, event);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -835,11 +614,19 @@ set_gnome_env (const char *name,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_log_func (const char *fmt,
|
||||
va_list arg)
|
||||
{
|
||||
char *str = g_strdup_vprintf (fmt, arg);
|
||||
g_warning ("WL: %s", str);
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_init (void)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = &_meta_wayland_compositor;
|
||||
guint event_signal;
|
||||
MetaMonitorManager *monitors;
|
||||
ClutterBackend *backend;
|
||||
CoglContext *cogl_context;
|
||||
@@ -853,6 +640,7 @@ meta_wayland_init (void)
|
||||
g_error ("failed to create wayland display");
|
||||
|
||||
wl_display_init_shm (compositor->wayland_display);
|
||||
wl_log_set_handler_server(meta_wayland_log_func);
|
||||
|
||||
wl_list_init (&compositor->frame_callbacks);
|
||||
|
||||
@@ -918,8 +706,6 @@ meta_wayland_init (void)
|
||||
compositor->outputs = meta_wayland_compositor_update_outputs (compositor, monitors);
|
||||
|
||||
compositor->stage = meta_wayland_stage_new ();
|
||||
g_signal_connect_after (compositor->stage, "paint",
|
||||
G_CALLBACK (paint_finished_cb), compositor);
|
||||
g_signal_connect (compositor->stage, "destroy",
|
||||
G_CALLBACK (stage_destroy_cb), NULL);
|
||||
|
||||
@@ -928,21 +714,6 @@ meta_wayland_init (void)
|
||||
compositor->seat = meta_wayland_seat_new (compositor->wayland_display,
|
||||
compositor->drm_fd >= 0);
|
||||
|
||||
g_signal_connect (compositor->stage,
|
||||
"captured-event",
|
||||
G_CALLBACK (event_cb),
|
||||
compositor);
|
||||
/* If something sets a grab on an actor then the captured event
|
||||
* signal won't get emitted but we still want to see these events so
|
||||
* we can update the cursor position. To make sure we see all events
|
||||
* we also install an emission hook on the event signal */
|
||||
event_signal = g_signal_lookup ("event", CLUTTER_TYPE_STAGE);
|
||||
g_signal_add_emission_hook (event_signal,
|
||||
0 /* detail */,
|
||||
event_emission_hook_cb,
|
||||
compositor, /* hook_data */
|
||||
NULL /* data_destroy */);
|
||||
|
||||
meta_wayland_init_shell (compositor);
|
||||
|
||||
clutter_actor_show (compositor->stage);
|
||||
|
@@ -39,30 +39,15 @@ xserver_set_window_id (struct wl_client *client,
|
||||
struct wl_resource *surface_resource,
|
||||
guint32 xid)
|
||||
{
|
||||
MetaWaylandCompositor *compositor =
|
||||
wl_resource_get_user_data (compositor_resource);
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
MetaWindow *window;
|
||||
|
||||
window = meta_display_lookup_x_window (display, xid);
|
||||
window = meta_display_lookup_x_window (display, xid);
|
||||
if (window)
|
||||
{
|
||||
MetaWindowActor *window_actor =
|
||||
META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
|
||||
meta_window_actor_set_wayland_surface (window_actor, surface);
|
||||
|
||||
surface->window = window;
|
||||
window->surface = surface;
|
||||
|
||||
/* If the window is already meant to have focus then the
|
||||
* original attempt to call this in response to the FocusIn
|
||||
* event will have been lost because there was no surface
|
||||
* yet. */
|
||||
if (window->has_focus)
|
||||
meta_wayland_compositor_set_input_focus (compositor, window);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +92,7 @@ bind_xserver (struct wl_client *client,
|
||||
* and unblock meta_wayland_init() to continue initializing mutter.
|
||||
* */
|
||||
g_main_loop_quit (compositor->init_loop);
|
||||
compositor->init_loop = NULL;
|
||||
g_clear_pointer (&compositor->init_loop, g_main_loop_unref);
|
||||
}
|
||||
|
||||
static char *
|
||||
@@ -311,6 +296,7 @@ meta_xwayland_start (MetaWaylandCompositor *compositor)
|
||||
char **env;
|
||||
char *fd_string;
|
||||
char *display_name;
|
||||
char *log_path;
|
||||
char *args[11];
|
||||
GError *error;
|
||||
|
||||
@@ -373,6 +359,7 @@ meta_xwayland_start (MetaWaylandCompositor *compositor)
|
||||
|
||||
display_name = g_strdup_printf (":%d",
|
||||
compositor->xwayland_display_index);
|
||||
log_path = g_build_filename (g_get_user_cache_dir (), "xwayland.log", NULL);
|
||||
|
||||
args[0] = XWAYLAND_PATH;
|
||||
args[1] = display_name;
|
||||
@@ -381,7 +368,7 @@ meta_xwayland_start (MetaWaylandCompositor *compositor)
|
||||
args[4] = "-retro";
|
||||
args[5] = "-noreset";
|
||||
args[6] = "-logfile";
|
||||
args[7] = g_build_filename (g_get_user_cache_dir (), "xwayland.log", NULL);
|
||||
args[7] = log_path;
|
||||
args[8] = "-nolisten";
|
||||
args[9] = "all";
|
||||
args[10] = NULL;
|
||||
@@ -415,6 +402,7 @@ meta_xwayland_start (MetaWaylandCompositor *compositor)
|
||||
|
||||
g_strfreev (env);
|
||||
g_free (display_name);
|
||||
g_free (log_path);
|
||||
|
||||
/* We need to run a mainloop until we know xwayland has a binding
|
||||
* for our xserver interface at which point we can assume it's
|
||||
|
@@ -738,9 +738,6 @@ main(int argc, char *argv[])
|
||||
|
||||
if (optind >= argc)
|
||||
error(1, 0, "Expected program argument");
|
||||
if (strcmp (argv[optind], "mutter-wayland") &&
|
||||
strcmp (argv[optind], "gnome-shell-wayland"))
|
||||
error(1, 0, "mutter-launch can only be used to launch mutter or gnome-shell");
|
||||
|
||||
wl.pw = getpwuid(getuid());
|
||||
if (wl.pw == NULL)
|
||||
|
Reference in New Issue
Block a user