Compare commits
225 Commits
3.13.4
...
wip/dnd-su
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7947bcb0b0 | ||
|
|
308cccc72c | ||
|
|
074946ac0b | ||
|
|
9688a0d7bc | ||
|
|
604d2155ba | ||
|
|
e7727d698f | ||
|
|
a3f75f401c | ||
|
|
d342f7c429 | ||
|
|
bb2b26ca44 | ||
|
|
2f9840a51c | ||
|
|
09aefdba43 | ||
|
|
4c8a408afc | ||
|
|
4c08d9a53b | ||
|
|
b091cbf361 | ||
|
|
a6fcda69ac | ||
|
|
9063e4568c | ||
|
|
3d37b5d696 | ||
|
|
3a8bad1e6f | ||
|
|
e822e51752 | ||
|
|
f9818f890b | ||
|
|
6526118d9f | ||
|
|
c15b3b4a09 | ||
|
|
e1acb69cf1 | ||
|
|
8f757c7b80 | ||
|
|
01a47c7d6d | ||
|
|
3ee09c6251 | ||
|
|
bb54f91dd1 | ||
|
|
41a79530e9 | ||
|
|
31f5a916f4 | ||
|
|
5657a671c1 | ||
|
|
ecc254c659 | ||
|
|
9cb1c95e49 | ||
|
|
e73c46ce03 | ||
|
|
952e9c52bc | ||
|
|
b879af46b3 | ||
|
|
9feb9d6bca | ||
|
|
dc0437a5b5 | ||
|
|
55331a0678 | ||
|
|
f5580f61f9 | ||
|
|
30953cf2d7 | ||
|
|
c7fa446ee7 | ||
|
|
9ecbac365b | ||
|
|
80f6fb6329 | ||
|
|
1b596a114d | ||
|
|
265c00235b | ||
|
|
fae37222a7 | ||
|
|
d41449b578 | ||
|
|
34979c3fe8 | ||
|
|
711f0c0c50 | ||
|
|
933d05a565 | ||
|
|
8a0da1cb07 | ||
|
|
1445903a34 | ||
|
|
5d9386df0c | ||
|
|
6fd1de226b | ||
|
|
ac099343da | ||
|
|
bce5f3f108 | ||
|
|
35e0982e35 | ||
|
|
767455e8d8 | ||
|
|
6b8dda0d00 | ||
|
|
277df44cfb | ||
|
|
2dded1e510 | ||
|
|
a7b1b1da80 | ||
|
|
de69678085 | ||
|
|
5f7b81eb95 | ||
|
|
f4f70afe31 | ||
|
|
116957b339 | ||
|
|
1af0033368 | ||
|
|
3645c63c08 | ||
|
|
04ddfe0a6f | ||
|
|
ec3dc4a607 | ||
|
|
0b98fbab0a | ||
|
|
5b8dc37c31 | ||
|
|
f42258327b | ||
|
|
7d1ef3f447 | ||
|
|
652fe57cdd | ||
|
|
20a6243c85 | ||
|
|
679edac9c3 | ||
|
|
bb59b8c249 | ||
|
|
c5c6b2257f | ||
|
|
6acf7b06f4 | ||
|
|
d0c004c93c | ||
|
|
53876d2b62 | ||
|
|
2b63b17327 | ||
|
|
226a09b38c | ||
|
|
527c53a2a0 | ||
|
|
19795c1681 | ||
|
|
1999fcaa8f | ||
|
|
6b5ff8fd74 | ||
|
|
821d946a72 | ||
|
|
5f7c901727 | ||
|
|
7b8ee4ee1e | ||
|
|
32cf4afb04 | ||
|
|
e0c92befd5 | ||
|
|
827e0341ab | ||
|
|
8627b65f8d | ||
|
|
9c62a907c5 | ||
|
|
a119ea96a3 | ||
|
|
06d55bf019 | ||
|
|
320f38de47 | ||
|
|
7adfaceccf | ||
|
|
67be4e2bf3 | ||
|
|
c3e87ee896 | ||
|
|
f2283ec634 | ||
|
|
d06e4beb7f | ||
|
|
e24863d175 | ||
|
|
2de2241690 | ||
|
|
977de8c5d4 | ||
|
|
fb6438cdd4 | ||
|
|
517e8f6fbd | ||
|
|
0e758a9e65 | ||
|
|
64a915a68d | ||
|
|
d233238c64 | ||
|
|
71a4fe746e | ||
|
|
f28c7835a1 | ||
|
|
cecf7f4bf0 | ||
|
|
c687cf9db6 | ||
|
|
54d2218ac2 | ||
|
|
471e6b9e13 | ||
|
|
f8dcea3975 | ||
|
|
d931af33c4 | ||
|
|
a0e3c05428 | ||
|
|
b8c13cc426 | ||
|
|
38253a9f73 | ||
|
|
cbc92b847f | ||
|
|
a5f993f269 | ||
|
|
31361e464a | ||
|
|
bb977c00ca | ||
|
|
39f65f9f86 | ||
|
|
bda2d6d1ac | ||
|
|
1e225ecdaf | ||
|
|
cfb85d9a9a | ||
|
|
f88c20f335 | ||
|
|
c98824bc9e | ||
|
|
69a35bb85f | ||
|
|
a3bb6c12e5 | ||
|
|
586f118279 | ||
|
|
31081e5dac | ||
|
|
ef363e9d2e | ||
|
|
9fa77acb8c | ||
|
|
1e30db64d1 | ||
|
|
e830b66604 | ||
|
|
5f0fab2156 | ||
|
|
467465c99c | ||
|
|
e935b52e51 | ||
|
|
879407c10c | ||
|
|
e76be14dbb | ||
|
|
7fa15c74b4 | ||
|
|
c3950699bf | ||
|
|
e6b950e31b | ||
|
|
9440bdb1aa | ||
|
|
e320b06aaa | ||
|
|
b284126d3b | ||
|
|
6858cb261f | ||
|
|
2d6954186e | ||
|
|
d72bf0cd5d | ||
|
|
584460deec | ||
|
|
e3d5969282 | ||
|
|
249468bbea | ||
|
|
f0f4c31d96 | ||
|
|
27f012ffad | ||
|
|
7d54631ebf | ||
|
|
513628e4ad | ||
|
|
101b215d6b | ||
|
|
6af48de0b8 | ||
|
|
e5c4fedd55 | ||
|
|
2ce23072d3 | ||
|
|
97f4eb6b75 | ||
|
|
75cbf3d730 | ||
|
|
bf9fdf448d | ||
|
|
63c627ec18 | ||
|
|
dadbd793be | ||
|
|
75b6e917ad | ||
|
|
ab53c0e943 | ||
|
|
c2fe6a18ad | ||
|
|
b7119c55a6 | ||
|
|
d0f2c6be6d | ||
|
|
3a535b6722 | ||
|
|
f9a77aec3f | ||
|
|
bee6d2b240 | ||
|
|
9a6a189e36 | ||
|
|
505eabb78c | ||
|
|
b0ba325f0e | ||
|
|
6fbd21001b | ||
|
|
626e4965b1 | ||
|
|
a15042b7e5 | ||
|
|
e56f963574 | ||
|
|
65a8f9100c | ||
|
|
6954d23444 | ||
|
|
6c624e1c26 | ||
|
|
cc839029b9 | ||
|
|
25f8eaf1ac | ||
|
|
8fdd226b8b | ||
|
|
6c5595fa9c | ||
|
|
e6558f838e | ||
|
|
57037a45b8 | ||
|
|
c844611052 | ||
|
|
b60e02956d | ||
|
|
4fe66ce0a9 | ||
|
|
4b5a503cee | ||
|
|
817995d97f | ||
|
|
0e7221c361 | ||
|
|
938fb8e6c8 | ||
|
|
fd8c49ff0a | ||
|
|
cd84317346 | ||
|
|
4f55e16fe9 | ||
|
|
c30ef668de | ||
|
|
62e0c42803 | ||
|
|
70aee2d95e | ||
|
|
63c7591698 | ||
|
|
930361b988 | ||
|
|
baadb75a5e | ||
|
|
f28f5dc0b6 | ||
|
|
41fdc4ac2e | ||
|
|
177ec27cca | ||
|
|
37652ca2cf | ||
|
|
6c22759d29 | ||
|
|
25b6a40ad4 | ||
|
|
fbea59b326 | ||
|
|
38e4906f72 | ||
|
|
029d69919b | ||
|
|
5e395fb676 | ||
|
|
ac448bd42b | ||
|
|
f55737ec06 | ||
|
|
80de15face | ||
|
|
32565e096d |
25
NEWS
25
NEWS
@@ -1,3 +1,28 @@
|
||||
3.13.90
|
||||
=======
|
||||
* Only call XSync() once per frame [Rui; #728464]
|
||||
* Update capabilities on device list changes [Carlos; #733563]
|
||||
* Make use of GLSL optional [Adel; #733623]
|
||||
* Handle gestures and touch events on wayland [Carlos; #733631]
|
||||
* Add support for unminimize compositor effects [Cosimo; #733789]
|
||||
* Always set the frame background to None [Giovanni; #734054]
|
||||
* Add backend methods to handle keymaps [Rui; #734301]
|
||||
* Actually mark revalidated MetaTextureTower levels as valid [Owen; #734400]
|
||||
* Rely on explicit -backward switcher keybindings instead of <shift>-magic
|
||||
[Christophe; #732295, #732385]
|
||||
* Misc. bug fixes and cleanups [Rui, Adel, Christophe; #727178, #734852,
|
||||
#734960]
|
||||
|
||||
Contributors:
|
||||
Emmanuele Bassi, Giovanni Campagna, Cosimo Cecchi, Piotr Drąg,
|
||||
Christophe Fergeau, Adel Gadllah, Carlos Garnacho, Rui Matos,
|
||||
Florian Müllner, Jasper St. Pierre, Rico Tzschichholz, Olav Vitters,
|
||||
Owen W. Taylor
|
||||
|
||||
Translations:
|
||||
Kjartan Maraas [nb], Inaki Larranaga Murgoitio [eu], Lasse Liehu [fi],
|
||||
ngoswami [as], Daniel Mustieles [es]
|
||||
|
||||
3.13.4
|
||||
======
|
||||
* Fix move/resize operations for wayland clients [Marek; #731237]
|
||||
|
||||
50
configure.ac
50
configure.ac
@@ -2,7 +2,7 @@ AC_PREREQ(2.62)
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [13])
|
||||
m4_define([mutter_micro_version], [4])
|
||||
m4_define([mutter_micro_version], [90])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
@@ -76,17 +76,24 @@ MUTTER_PC_MODULES="
|
||||
pango >= 1.2.0
|
||||
cairo >= 1.10.0
|
||||
gsettings-desktop-schemas >= 3.7.3
|
||||
xcomposite >= 0.2 xfixes xext xdamage xi >= 1.6.0
|
||||
xcursor
|
||||
$CLUTTER_PACKAGE >= 1.19.5
|
||||
clutter-wayland-1.0
|
||||
clutter-wayland-compositor-1.0
|
||||
clutter-egl-1.0
|
||||
cogl-1.0 >= 1.17.1
|
||||
libinput
|
||||
wayland-server >= 1.4.93
|
||||
gbm
|
||||
upower-glib >= 0.99.0
|
||||
gnome-desktop-3.0
|
||||
xcomposite >= 0.2
|
||||
xcursor
|
||||
xdamage
|
||||
xext
|
||||
xfixes
|
||||
xi >= 1.6.0
|
||||
xkbfile
|
||||
xkeyboard-config
|
||||
xkbcommon >= 0.4.3
|
||||
xkbcommon-x11
|
||||
x11-xcb
|
||||
xcb-randr
|
||||
"
|
||||
|
||||
GLIB_GSETTINGS
|
||||
@@ -185,20 +192,27 @@ if test x$found_introspection != xno; then
|
||||
AC_SUBST(META_GIR)
|
||||
fi
|
||||
|
||||
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
|
||||
AS_IF([test "x$WAYLAND_SCANNER" = "xno"],
|
||||
AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols]))
|
||||
AC_SUBST([WAYLAND_SCANNER])
|
||||
AC_SUBST(XWAYLAND_PATH)
|
||||
|
||||
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
|
||||
|
||||
PKG_CHECK_MODULES(MUTTER_NATIVE_BACKEND, [libdrm libsystemd], [have_native_backend=yes], [have_native_backend=no])
|
||||
PKG_CHECK_MODULES(MUTTER_NATIVE_BACKEND, [libdrm libsystemd libinput], [have_native_backend=yes], [have_native_backend=no])
|
||||
if test $have_native_backend = yes; then
|
||||
AC_DEFINE([HAVE_NATIVE_BACKEND],[1],[Define if you want to enable the native (KMS) backend based on systemd])
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_NATIVE_BACKEND],[test $have_native_backend = yes])
|
||||
|
||||
PKG_CHECK_MODULES(MUTTER_WAYLAND, [clutter-wayland-1.0 clutter-wayland-compositor-1.0 wayland-server >= 1.5.90], [have_wayland=yes], [have_wayland=no])
|
||||
if test $have_wayland = yes; then
|
||||
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
|
||||
AS_IF([test $WAYLAND_SCANNER = "no"],
|
||||
AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols]))
|
||||
AC_SUBST([WAYLAND_SCANNER])
|
||||
|
||||
AC_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support])
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_WAYLAND],[test $have_wayland = yes])
|
||||
|
||||
PKG_CHECK_EXISTS([xi >= 1.6.99.1],
|
||||
AC_DEFINE([HAVE_XI23],[1],[Define if you have support for XInput 2.3 or greater]))
|
||||
|
||||
@@ -235,16 +249,8 @@ if test x$have_xinerama = xno; then
|
||||
AC_MSG_ERROR([Xinerama extension was not found])
|
||||
fi
|
||||
|
||||
found_xkb=no
|
||||
AC_CHECK_LIB(X11, XkbQueryExtension,
|
||||
[AC_CHECK_HEADER(X11/XKBlib.h,
|
||||
found_xkb=yes)],
|
||||
, $ALL_X_LIBS)
|
||||
|
||||
if test "x$found_xkb" = "xyes"; then
|
||||
AC_DEFINE(HAVE_XKB, , [Have keyboard extension library])
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED([XKB_BASE], ["`$PKG_CONFIG --variable xkb_base xkeyboard-config`"],
|
||||
[XKB base dir])
|
||||
|
||||
RANDR_LIBS=
|
||||
found_randr=no
|
||||
|
||||
@@ -45,26 +45,68 @@
|
||||
_description="Move window one monitor down" />
|
||||
|
||||
<KeyListEntry name="switch-applications"
|
||||
reverse-entry="switch-applications-backward"
|
||||
_description="Switch applications"/>
|
||||
|
||||
<KeyListEntry name="switch-applications-backward"
|
||||
reverse-entry="switch-applications"
|
||||
hidden="true"
|
||||
_description="Switch to previous application"/>
|
||||
|
||||
<KeyListEntry name="switch-windows"
|
||||
reverse-entry="switch-windows-backward"
|
||||
_description="Switch windows"/>
|
||||
|
||||
<KeyListEntry name="switch-windows-backward"
|
||||
reverse-entry="switch-windows"
|
||||
hidden="true"
|
||||
_description="Switch to previous window"/>
|
||||
|
||||
<KeyListEntry name="switch-group"
|
||||
reverse-entry="switch-group-backward"
|
||||
_description="Switch windows of an application"/>
|
||||
|
||||
<KeyListEntry name="switch-group-backward"
|
||||
reverse-entry="switch-group"
|
||||
hidden="true"
|
||||
_description="Switch to previous window of an application"/>
|
||||
|
||||
<KeyListEntry name="switch-panels"
|
||||
reverse-entry="switch-panels-backward"
|
||||
_description="Switch system controls"/>
|
||||
|
||||
<KeyListEntry name="switch-panels-backward"
|
||||
reverse-entry="switch-panels"
|
||||
hidden="true"
|
||||
_description="Switch to previous system control"/>
|
||||
|
||||
<KeyListEntry name="cycle-windows"
|
||||
reverse-entry="cycle-windows-backward"
|
||||
_description="Switch windows directly"/>
|
||||
|
||||
<KeyListEntry name="cycle-windows-backward"
|
||||
reverse-entry="cycle-windows"
|
||||
hidden="true"
|
||||
_description="Switch directly to previous window"/>
|
||||
|
||||
<KeyListEntry name="cycle-group"
|
||||
reverse-entry="cycle-group-backward"
|
||||
_description="Switch windows of an app directly"/>
|
||||
|
||||
<KeyListEntry name="cycle-group-backward"
|
||||
reverse-entry="cycle-group"
|
||||
hidden="true"
|
||||
_description="Switch directly to previous window of an app"/>
|
||||
|
||||
<KeyListEntry name="cycle-panels"
|
||||
reverse-entry="cycle-panels-backward"
|
||||
_description="Switch system controls directly"/>
|
||||
|
||||
<KeyListEntry name="cycle-panels-backward"
|
||||
reverse-entry="cycle-panels"
|
||||
hidden="true"
|
||||
_description="Switch directly to previous system control"/>
|
||||
|
||||
<KeyListEntry name="show-desktop"
|
||||
_description="Hide all normal windows"/>
|
||||
|
||||
|
||||
@@ -300,6 +300,7 @@ MetaPluginVersion
|
||||
META_PLUGIN_DECLARE
|
||||
meta_plugin_switch_workspace_completed
|
||||
meta_plugin_minimize_completed
|
||||
meta_plugin_unminimize_completed
|
||||
meta_plugin_maximize_completed
|
||||
meta_plugin_unmaximize_completed
|
||||
meta_plugin_map_completed
|
||||
|
||||
@@ -23,7 +23,8 @@ environment.</description>
|
||||
<download-page rdf:resource="http://download.gnome.org/sources/mutter/" />
|
||||
<bug-database rdf:resource="http://bugzilla.gnome.org/browse.cgi?product=mutter" />
|
||||
|
||||
<category rdf:resource="http://api.gnome.org/doap-extensions#desktop" />
|
||||
<category rdf:resource="http://api.gnome.org/doap-extensions#core" />
|
||||
<programming-language>C</programming-language>
|
||||
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
|
||||
110
po/el.po
110
po/el.po
@@ -18,16 +18,16 @@ msgstr ""
|
||||
"Project-Id-Version: metacity.gnome-2-26\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
|
||||
"product=mutter&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2014-07-15 21:19+0000\n"
|
||||
"PO-Revision-Date: 2014-07-16 13:25+0200\n"
|
||||
"Last-Translator: Tom Tryfonidis <tomtryf@gmail.com>\n"
|
||||
"POT-Creation-Date: 2014-08-20 21:50+0000\n"
|
||||
"PO-Revision-Date: 2014-08-21 12:13+0200\n"
|
||||
"Last-Translator: Maria Mavridou <mavridou@gmail.com>\n"
|
||||
"Language-Team: www.gnome.gr\n"
|
||||
"Language: el\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 1.6.5\n"
|
||||
"X-Generator: Poedit 1.6.4\n"
|
||||
"X-Project-Style: gnome\n"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:1
|
||||
@@ -91,66 +91,100 @@ msgid "Switch applications"
|
||||
msgstr "Εναλλαγή εφαρμογών"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:16
|
||||
#| msgid "Switch applications"
|
||||
msgid "Switch to previous application"
|
||||
msgstr "Εναλλαγή στην προηγούμενη εφαρμογή"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:17
|
||||
msgid "Switch windows"
|
||||
msgstr "Εναλλαγή παραθύρων"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:17
|
||||
#: ../data/50-mutter-navigation.xml.in.h:18
|
||||
#| msgid "Switch windows"
|
||||
msgid "Switch to previous window"
|
||||
msgstr "Εναλλαγή στο προηγούμενο παράθυρο"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:19
|
||||
msgid "Switch windows of an application"
|
||||
msgstr "Εναλλαγή παραθύρων μιας εφαρμογής"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:18
|
||||
#: ../data/50-mutter-navigation.xml.in.h:20
|
||||
#| msgid "Switch windows of an application"
|
||||
msgid "Switch to previous window of an application"
|
||||
msgstr "Εναλλαγή στο προηγούμενο παράθυρο μιας εφαρμογής"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:21
|
||||
msgid "Switch system controls"
|
||||
msgstr "Εναλλαγή ελέγχων συστήματος"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:19
|
||||
#: ../data/50-mutter-navigation.xml.in.h:22
|
||||
#| msgid "Switch system controls"
|
||||
msgid "Switch to previous system control"
|
||||
msgstr "Εναλλαγή σε προηγούμενους ελέγχους συστήματος"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:23
|
||||
msgid "Switch windows directly"
|
||||
msgstr "Άμεση εναλλαγή παραθύρων"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:20
|
||||
#: ../data/50-mutter-navigation.xml.in.h:24
|
||||
msgid "Switch directly to previous window"
|
||||
msgstr "Άμεση εναλλαγή στο προηγούμενο παράθυρο"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:25
|
||||
msgid "Switch windows of an app directly"
|
||||
msgstr "Άμεση εναλλαγή παραθύρων μιας εφαρμογής"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:21
|
||||
#: ../data/50-mutter-navigation.xml.in.h:26
|
||||
#| msgid "Switch windows of an application"
|
||||
msgid "Switch directly to previous window of an app"
|
||||
msgstr "Άμεση εναλλαγή στο προηγούμενο παράθυρο μιας εφαρμογής"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:27
|
||||
msgid "Switch system controls directly"
|
||||
msgstr "Άμεση εναλλαγή ελέγχων συστήματος"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:22
|
||||
#: ../data/50-mutter-navigation.xml.in.h:28
|
||||
#| msgid "Switch system controls"
|
||||
msgid "Switch directly to previous system control"
|
||||
msgstr "Άμεση εναλλαγή σε προηγούμενους ελέγχους συστήματος"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:29
|
||||
msgid "Hide all normal windows"
|
||||
msgstr "Απόκρυψη όλων των κανονικών παραθύρων"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:23
|
||||
#: ../data/50-mutter-navigation.xml.in.h:30
|
||||
msgid "Switch to workspace 1"
|
||||
msgstr "Εναλλαγή στον χώρο εργασίας 1"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:24
|
||||
#: ../data/50-mutter-navigation.xml.in.h:31
|
||||
msgid "Switch to workspace 2"
|
||||
msgstr "Εναλλαγή στον χώρο εργασίας 2"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:25
|
||||
#: ../data/50-mutter-navigation.xml.in.h:32
|
||||
msgid "Switch to workspace 3"
|
||||
msgstr "Εναλλαγή στον χώρο εργασίας 3"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:26
|
||||
#: ../data/50-mutter-navigation.xml.in.h:33
|
||||
msgid "Switch to workspace 4"
|
||||
msgstr "Εναλλαγή στον χώρο εργασίας 4"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:27
|
||||
#: ../data/50-mutter-navigation.xml.in.h:34
|
||||
msgid "Switch to last workspace"
|
||||
msgstr "Εναλλαγή στον τελευταίο χώρο εργασίας"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:28
|
||||
#: ../data/50-mutter-navigation.xml.in.h:35
|
||||
msgid "Move to workspace left"
|
||||
msgstr "Μετακίνηση στον χώρο εργασίας αριστερά"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:29
|
||||
#: ../data/50-mutter-navigation.xml.in.h:36
|
||||
msgid "Move to workspace right"
|
||||
msgstr "Μετακίνηση στον χώρο εργασίας δεξιά"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:30
|
||||
#: ../data/50-mutter-navigation.xml.in.h:37
|
||||
msgid "Move to workspace above"
|
||||
msgstr "Μετακίνηση στον χώρο εργασίας επάνω"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:31
|
||||
#: ../data/50-mutter-navigation.xml.in.h:38
|
||||
msgid "Move to workspace below"
|
||||
msgstr "Μετακίνηση στον χώρο εργασίας κάτω"
|
||||
|
||||
@@ -444,7 +478,7 @@ msgstr "%s %s"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: ../src/compositor/compositor.c:445
|
||||
#: ../src/compositor/compositor.c:441
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
@@ -452,11 +486,11 @@ msgid ""
|
||||
msgstr ""
|
||||
"Εκτελείται ένας άλλος διαχειριστής παραθύρων στην οθόνη %i προβολή \"%s\"."
|
||||
|
||||
#: ../src/compositor/meta-background.c:990
|
||||
#: ../src/compositor/meta-background.c:1044
|
||||
msgid "background texture could not be created from file"
|
||||
msgstr "η υφή παρασκηνίου δεν μπόρεσε να δημιουργηθεί από αρχείο"
|
||||
|
||||
#: ../src/core/bell.c:215
|
||||
#: ../src/core/bell.c:185
|
||||
msgid "Bell event"
|
||||
msgstr "Ηχητικό συμβάν κουδουνιού"
|
||||
|
||||
@@ -486,49 +520,49 @@ msgid "_Force Quit"
|
||||
msgstr "_Εξαναγκασμός σε τερματισμό"
|
||||
|
||||
# gconf/gconf-internals.c:2416
|
||||
#: ../src/core/display.c:464
|
||||
#: ../src/core/display.c:547
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Αποτυχία ανοίγματος οθόνης του συστήματος παραθύρων Χ '%s'\n"
|
||||
|
||||
#: ../src/core/main.c:172
|
||||
#: ../src/core/main.c:176
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "Απενεργοποίηση σύνδεσης στο διαχειριστή συνεδρίας"
|
||||
|
||||
#: ../src/core/main.c:178
|
||||
#: ../src/core/main.c:182
|
||||
msgid "Replace the running window manager"
|
||||
msgstr "Αντικατάσταση του τρέχοντος διαχειριστή παραθύρων"
|
||||
|
||||
#: ../src/core/main.c:184
|
||||
#: ../src/core/main.c:188
|
||||
msgid "Specify session management ID"
|
||||
msgstr "Καθορισμός αναγνωριστικού διαχείρισης συνεδρίας"
|
||||
|
||||
#: ../src/core/main.c:189
|
||||
#: ../src/core/main.c:193
|
||||
msgid "X Display to use"
|
||||
msgstr "Εμφάνιση Χ για χρήση"
|
||||
|
||||
#: ../src/core/main.c:195
|
||||
#: ../src/core/main.c:199
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "Εκκίνηση συνεδρίας από savefile"
|
||||
|
||||
#: ../src/core/main.c:201
|
||||
#: ../src/core/main.c:205
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "Να καταστούν σύγχρονες οι κλήσεις του X"
|
||||
|
||||
#: ../src/core/main.c:207
|
||||
#: ../src/core/main.c:212
|
||||
msgid "Run as a wayland compositor"
|
||||
msgstr "Εκτέλεση ως συνθετητής wayland"
|
||||
|
||||
#: ../src/core/main.c:214
|
||||
#: ../src/core/main.c:220
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Εκτέλεση ως διακομιστής πλήρους οθόνης, αντί ενσωματωμένης"
|
||||
|
||||
#: ../src/core/main.c:448
|
||||
#: ../src/core/main.c:459
|
||||
#, c-format
|
||||
msgid "Failed to scan themes directory: %s\n"
|
||||
msgstr "Αποτυχία σάρωσης καταλόγου θεμάτων: %s\n"
|
||||
|
||||
#: ../src/core/main.c:464
|
||||
#: ../src/core/main.c:475
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
|
||||
@@ -560,17 +594,17 @@ msgstr "Εμφάνιση έκδοσης"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Πρόσθετα του Mutter για χρήση"
|
||||
|
||||
#: ../src/core/prefs.c:2086
|
||||
#: ../src/core/prefs.c:2101
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Χώρος εργασίας %d"
|
||||
|
||||
#: ../src/core/screen.c:553
|
||||
#: ../src/core/screen.c:548
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "Η οθόνη %d στην προβολή '%s' δεν είναι έγκυρη\n"
|
||||
|
||||
#: ../src/core/screen.c:569
|
||||
#: ../src/core/screen.c:564
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
@@ -580,7 +614,7 @@ msgstr ""
|
||||
"προσπαθήστε να χρησιμοποιήσετε την επιλογή --replace για να αντικαταστήσετε "
|
||||
"τον τρέχων διαχειριστή παραθύρων.\n"
|
||||
|
||||
#: ../src/core/screen.c:662
|
||||
#: ../src/core/screen.c:657
|
||||
#, c-format
|
||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||
msgstr "Η οθόνη %d στην προβολή \"%s\" έχει ήδη ένα διαχειριστή παραθύρων\n"
|
||||
@@ -1310,7 +1344,7 @@ msgstr ""
|
||||
"εγκατάστασης" και θα πρέπει να επανεκκινηθούν χειροκίνητα στην επόμενη "
|
||||
"είσοδο σας."
|
||||
|
||||
#: ../src/x11/window-props.c:513
|
||||
#: ../src/x11/window-props.c:515
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (σε %s)"
|
||||
|
||||
206
po/gl.po
206
po/gl.po
@@ -14,8 +14,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gl\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-07-01 21:56+0200\n"
|
||||
"PO-Revision-Date: 2014-07-01 21:58+0200\n"
|
||||
"POT-Creation-Date: 2014-08-25 22:40+0200\n"
|
||||
"PO-Revision-Date: 2014-08-25 22:42+0200\n"
|
||||
"Last-Translator: Fran Dieguez <frandieguez@gnome.org>\n"
|
||||
"Language-Team: gnome-l10n-gl@gnome.org\n"
|
||||
"Language: gl\n"
|
||||
@@ -86,66 +86,94 @@ msgid "Switch applications"
|
||||
msgstr "Cambiar entre aplicativos"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:16
|
||||
msgid "Switch to previous application"
|
||||
msgstr "Cambiar ao aplicativo aplicativos"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:17
|
||||
msgid "Switch windows"
|
||||
msgstr "Cambiar xanelas"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:17
|
||||
#: ../data/50-mutter-navigation.xml.in.h:18
|
||||
msgid "Switch to previous window"
|
||||
msgstr "Cambiar á xanela anterior"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:19
|
||||
msgid "Switch windows of an application"
|
||||
msgstr "Cambiar entre as xanelas dun aplicativo"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:18
|
||||
#: ../data/50-mutter-navigation.xml.in.h:20
|
||||
msgid "Switch to previous window of an application"
|
||||
msgstr "Cambia á xanela anterior dun aplicativo"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:21
|
||||
msgid "Switch system controls"
|
||||
msgstr "Cambiar entre os controles do sistema"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:19
|
||||
#: ../data/50-mutter-navigation.xml.in.h:22
|
||||
msgid "Switch to previous system control"
|
||||
msgstr "Cambia ao control do sistema anterior"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:23
|
||||
msgid "Switch windows directly"
|
||||
msgstr "Cambiar xanelas directamente"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:20
|
||||
#: ../data/50-mutter-navigation.xml.in.h:24
|
||||
msgid "Switch directly to previous window"
|
||||
msgstr "Cambia directamente á xanela anterior"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:25
|
||||
msgid "Switch windows of an app directly"
|
||||
msgstr "Cambiar entre as xanelas dun aplicativo directamente"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:21
|
||||
#: ../data/50-mutter-navigation.xml.in.h:26
|
||||
msgid "Switch directly to previous window of an app"
|
||||
msgstr "Cambia directamente á xanela anterior do aplicativo"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:27
|
||||
msgid "Switch system controls directly"
|
||||
msgstr "Cambiar entre os controles do sistema directamente"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:22
|
||||
#: ../data/50-mutter-navigation.xml.in.h:28
|
||||
msgid "Switch directly to previous system control"
|
||||
msgstr "Cambiar directamente ao control do sistema anterior"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:29
|
||||
msgid "Hide all normal windows"
|
||||
msgstr "Ocultar todas as xanelas normais"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:23
|
||||
#: ../data/50-mutter-navigation.xml.in.h:30
|
||||
msgid "Switch to workspace 1"
|
||||
msgstr "Cambiar ao espazo de traballo 1"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:24
|
||||
#: ../data/50-mutter-navigation.xml.in.h:31
|
||||
msgid "Switch to workspace 2"
|
||||
msgstr "Cambiar ao espazo de traballo 2"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:25
|
||||
#: ../data/50-mutter-navigation.xml.in.h:32
|
||||
msgid "Switch to workspace 3"
|
||||
msgstr "Cambiar ao espazo de traballo 3"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:26
|
||||
#: ../data/50-mutter-navigation.xml.in.h:33
|
||||
msgid "Switch to workspace 4"
|
||||
msgstr "Cambiar ao espazo de traballo 4"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:27
|
||||
#: ../data/50-mutter-navigation.xml.in.h:34
|
||||
msgid "Switch to last workspace"
|
||||
msgstr "Cambiar ao último espazo de traballo"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:28
|
||||
#: ../data/50-mutter-navigation.xml.in.h:35
|
||||
msgid "Move to workspace left"
|
||||
msgstr "Mover ao espazo da esquerda"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:29
|
||||
#: ../data/50-mutter-navigation.xml.in.h:36
|
||||
msgid "Move to workspace right"
|
||||
msgstr "Mover ao espazo da dereita"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:30
|
||||
#: ../data/50-mutter-navigation.xml.in.h:37
|
||||
msgid "Move to workspace above"
|
||||
msgstr "Mover ao espazo de arriba"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:31
|
||||
#: ../data/50-mutter-navigation.xml.in.h:38
|
||||
msgid "Move to workspace below"
|
||||
msgstr "Mover ao espazo de traballo de abaixo"
|
||||
|
||||
@@ -434,7 +462,7 @@ msgstr "%s %s"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: ../src/compositor/compositor.c:464
|
||||
#: ../src/compositor/compositor.c:441
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
@@ -443,24 +471,24 @@ msgstr ""
|
||||
"Xa se está a executar outro xestor de composición na pantalla %i na "
|
||||
"visualización «%s»"
|
||||
|
||||
#: ../src/compositor/meta-background.c:990
|
||||
#: ../src/compositor/meta-background.c:1044
|
||||
msgid "background texture could not be created from file"
|
||||
msgstr "a textura do fondo non puido crearse desde o ficheiro"
|
||||
|
||||
#: ../src/core/bell.c:215
|
||||
#: ../src/core/bell.c:185
|
||||
msgid "Bell event"
|
||||
msgstr "Evento de campá"
|
||||
|
||||
#: ../src/core/delete.c:129
|
||||
#: ../src/core/delete.c:127
|
||||
#, c-format
|
||||
msgid "“%s” is not responding."
|
||||
msgstr "«%s» non está respondendo."
|
||||
|
||||
#: ../src/core/delete.c:131
|
||||
#: ../src/core/delete.c:129
|
||||
msgid "Application is not responding."
|
||||
msgstr "O Aplicativo non está respondendo."
|
||||
|
||||
#: ../src/core/delete.c:136
|
||||
#: ../src/core/delete.c:134
|
||||
msgid ""
|
||||
"You may choose to wait a short while for it to continue or force the "
|
||||
"application to quit entirely."
|
||||
@@ -468,57 +496,57 @@ msgstr ""
|
||||
"Pode elixir esperar un momento para ver se continúa ou forzar ao aplicativo "
|
||||
"a pechar completamente."
|
||||
|
||||
#: ../src/core/delete.c:143
|
||||
#: ../src/core/delete.c:141
|
||||
msgid "_Wait"
|
||||
msgstr "Espe_rar"
|
||||
|
||||
#: ../src/core/delete.c:143
|
||||
#: ../src/core/delete.c:141
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Forzar a saída"
|
||||
|
||||
#: ../src/core/display.c:448
|
||||
#: ../src/core/display.c:547
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Produciuse un erro ao abrir a visualización do X Window System «%s»\n"
|
||||
|
||||
#: ../src/core/main.c:172
|
||||
#: ../src/core/main.c:176
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "Desactivar a conexión ao xestor de sesión"
|
||||
|
||||
#: ../src/core/main.c:178
|
||||
#: ../src/core/main.c:182
|
||||
msgid "Replace the running window manager"
|
||||
msgstr "Substituír o xestor de xanelas en execución"
|
||||
|
||||
#: ../src/core/main.c:184
|
||||
#: ../src/core/main.c:188
|
||||
msgid "Specify session management ID"
|
||||
msgstr "Especificar o ID de xestión de sesión"
|
||||
|
||||
#: ../src/core/main.c:189
|
||||
#: ../src/core/main.c:193
|
||||
msgid "X Display to use"
|
||||
msgstr "Pantalla X que se vai usar"
|
||||
|
||||
#: ../src/core/main.c:195
|
||||
#: ../src/core/main.c:199
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "Inicializar sesión desde o ficheiro de salvagarda"
|
||||
|
||||
#: ../src/core/main.c:201
|
||||
#: ../src/core/main.c:205
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "Facer que as chamadas a X sexan sincrónicas"
|
||||
|
||||
#: ../src/core/main.c:207
|
||||
#: ../src/core/main.c:212
|
||||
msgid "Run as a wayland compositor"
|
||||
msgstr "Executar como compositor de wayland"
|
||||
|
||||
#: ../src/core/main.c:214
|
||||
#: ../src/core/main.c:220
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Executar como un servidor de pantalla completo, fronte a un aniñado"
|
||||
|
||||
#: ../src/core/main.c:448
|
||||
#: ../src/core/main.c:459
|
||||
#, c-format
|
||||
msgid "Failed to scan themes directory: %s\n"
|
||||
msgstr "Produciuse un erro ao dixitalizar o directorio de temas: %s\n"
|
||||
|
||||
#: ../src/core/main.c:464
|
||||
#: ../src/core/main.c:475
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
|
||||
@@ -549,17 +577,17 @@ msgstr "Imprimir versión"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Engadido de mutter que usar"
|
||||
|
||||
#: ../src/core/prefs.c:2086
|
||||
#: ../src/core/prefs.c:2101
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Espazo de traballo %d"
|
||||
|
||||
#: ../src/core/screen.c:539
|
||||
#: ../src/core/screen.c:548
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "A pantalla %d na visualización «%s» non é válida\n"
|
||||
|
||||
#: ../src/core/screen.c:555
|
||||
#: ../src/core/screen.c:564
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
@@ -568,7 +596,7 @@ msgstr ""
|
||||
"A visualización %d na pantalla «%s» ten xa un xestor de xanelas, tente usar "
|
||||
"a opción --replace para substituír o xestor de xanelas.\n"
|
||||
|
||||
#: ../src/core/screen.c:660
|
||||
#: ../src/core/screen.c:657
|
||||
#, c-format
|
||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||
msgstr "A visualización %d na pantalla «%s» ten xa un xestor de xanelas\n"
|
||||
@@ -585,48 +613,48 @@ msgstr "Mutter foi compilado sen compatibilidade para o modo detallado\n"
|
||||
msgid "%d x %d"
|
||||
msgstr "%d x %d"
|
||||
|
||||
#: ../src/ui/theme.c:232
|
||||
#: ../src/ui/theme.c:233
|
||||
msgid "top"
|
||||
msgstr "superior"
|
||||
|
||||
#: ../src/ui/theme.c:234
|
||||
#: ../src/ui/theme.c:235
|
||||
msgid "bottom"
|
||||
msgstr "inferior"
|
||||
|
||||
#: ../src/ui/theme.c:236
|
||||
#: ../src/ui/theme.c:237
|
||||
msgid "left"
|
||||
msgstr "esquerda"
|
||||
|
||||
#: ../src/ui/theme.c:238
|
||||
#: ../src/ui/theme.c:239
|
||||
msgid "right"
|
||||
msgstr "dereita"
|
||||
|
||||
#: ../src/ui/theme.c:266
|
||||
#: ../src/ui/theme.c:267
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify \"%s\" dimension"
|
||||
msgstr "a xeometría do marco non especifica a dimensión «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:285
|
||||
#: ../src/ui/theme.c:286
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify dimension \"%s\" for border \"%s\""
|
||||
msgstr "a xeometría do marco non especifica a dimensión «%s» para o bordo «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:322
|
||||
#: ../src/ui/theme.c:323
|
||||
#, c-format
|
||||
msgid "Button aspect ratio %g is not reasonable"
|
||||
msgstr "A proporción de aspecto do botón %g non é razoábel"
|
||||
|
||||
#: ../src/ui/theme.c:334
|
||||
#: ../src/ui/theme.c:335
|
||||
#, c-format
|
||||
msgid "Frame geometry does not specify size of buttons"
|
||||
msgstr "A xeometría do marco non especifica o tamaño dos botóns"
|
||||
|
||||
#: ../src/ui/theme.c:1060
|
||||
#: ../src/ui/theme.c:1061
|
||||
#, c-format
|
||||
msgid "Gradients should have at least two colors"
|
||||
msgstr "As gradacións deben ter polo menos dúas cores"
|
||||
|
||||
#: ../src/ui/theme.c:1210
|
||||
#: ../src/ui/theme.c:1211
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK custom color specification must have color name and fallback in "
|
||||
@@ -636,7 +664,7 @@ msgstr ""
|
||||
"entre parénteses, por exemplo: gtk:custom(foo,bar); non foi posíbel analizar "
|
||||
"«%s»."
|
||||
|
||||
#: ../src/ui/theme.c:1226
|
||||
#: ../src/ui/theme.c:1227
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-"
|
||||
@@ -645,7 +673,7 @@ msgstr ""
|
||||
"O carácter «%c» non é válido no parámetro «color_name» de «gtk:custom», só "
|
||||
"«A-Za-z0-9» son válidos"
|
||||
|
||||
#: ../src/ui/theme.c:1240
|
||||
#: ../src/ui/theme.c:1241
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
|
||||
@@ -654,7 +682,7 @@ msgstr ""
|
||||
"O formato de «gtk:custom» é «gtk:custom(nome_de_cor,nome_alternativo», «%s» "
|
||||
"non respecta o formato"
|
||||
|
||||
#: ../src/ui/theme.c:1285
|
||||
#: ../src/ui/theme.c:1286
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] "
|
||||
@@ -663,7 +691,7 @@ msgstr ""
|
||||
"A especificación de cor do GTK debe ter o estado entre parénteses, exemplo. "
|
||||
"gtk:fg[NORMAL] onde NORMAL é o estado; non foi posíbel analizar «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:1299
|
||||
#: ../src/ui/theme.c:1300
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have a close bracket after the state, e.g. gtk:"
|
||||
@@ -673,17 +701,17 @@ msgstr ""
|
||||
"estado, exemplo. gtk:fg[NORMAL] onde NORMAL é o estado; non foi posíbel "
|
||||
"analizar «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:1310
|
||||
#: ../src/ui/theme.c:1311
|
||||
#, c-format
|
||||
msgid "Did not understand state \"%s\" in color specification"
|
||||
msgstr "Non se entende o estado «%s» na especificación da cor"
|
||||
|
||||
#: ../src/ui/theme.c:1323
|
||||
#: ../src/ui/theme.c:1324
|
||||
#, c-format
|
||||
msgid "Did not understand color component \"%s\" in color specification"
|
||||
msgstr "Non se entende o compoñente de cor «%s» na especificación da cor"
|
||||
|
||||
#: ../src/ui/theme.c:1351
|
||||
#: ../src/ui/theme.c:1352
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the "
|
||||
@@ -692,17 +720,17 @@ msgstr ""
|
||||
"O formato de blend é «blend/bg_color/fg_color/alpha», «%s»non coincide co "
|
||||
"formato"
|
||||
|
||||
#: ../src/ui/theme.c:1362
|
||||
#: ../src/ui/theme.c:1363
|
||||
#, c-format
|
||||
msgid "Could not parse alpha value \"%s\" in blended color"
|
||||
msgstr "Non foi posíbel analizar o valor alfa «%s» na cor mesturada"
|
||||
|
||||
#: ../src/ui/theme.c:1372
|
||||
#: ../src/ui/theme.c:1373
|
||||
#, c-format
|
||||
msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0"
|
||||
msgstr "O valor alfa «%s» na cor mesturada non está entre 0.0 e 1.0"
|
||||
|
||||
#: ../src/ui/theme.c:1418
|
||||
#: ../src/ui/theme.c:1419
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format"
|
||||
@@ -710,28 +738,28 @@ msgstr ""
|
||||
"O formato de sombreado é \"shade/base_color/factor\", «%s» non coincide co "
|
||||
"formato"
|
||||
|
||||
#: ../src/ui/theme.c:1429
|
||||
#: ../src/ui/theme.c:1430
|
||||
#, c-format
|
||||
msgid "Could not parse shade factor \"%s\" in shaded color"
|
||||
msgstr "Non foi posíbel analizar o factor de sombreado «%s» na cor sombreada"
|
||||
|
||||
#: ../src/ui/theme.c:1439
|
||||
#: ../src/ui/theme.c:1440
|
||||
#, c-format
|
||||
msgid "Shade factor \"%s\" in shaded color is negative"
|
||||
msgstr "O factor de sombreado «%s» na cor sombreada é negativo"
|
||||
|
||||
#: ../src/ui/theme.c:1468
|
||||
#: ../src/ui/theme.c:1469
|
||||
#, c-format
|
||||
msgid "Could not parse color \"%s\""
|
||||
msgstr "Non foi posíbel analizar a cor «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:1777
|
||||
#: ../src/ui/theme.c:1778
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains character '%s' which is not allowed"
|
||||
msgstr ""
|
||||
"A expresión de coordenadas contén un carácter «%s» que non está permitido"
|
||||
|
||||
#: ../src/ui/theme.c:1804
|
||||
#: ../src/ui/theme.c:1805
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contains floating point number '%s' which could not be "
|
||||
@@ -740,14 +768,14 @@ msgstr ""
|
||||
"A expresión de coordenadas contén un número de coma flotante «%s» que non "
|
||||
"foi posíbel analizar"
|
||||
|
||||
#: ../src/ui/theme.c:1818
|
||||
#: ../src/ui/theme.c:1819
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains integer '%s' which could not be parsed"
|
||||
msgstr ""
|
||||
"A expresión de coordenadas contén un enteiro «%s» que non foi posíbel "
|
||||
"analizar"
|
||||
|
||||
#: ../src/ui/theme.c:1939
|
||||
#: ../src/ui/theme.c:1940
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contained unknown operator at the start of this text: "
|
||||
@@ -756,17 +784,17 @@ msgstr ""
|
||||
"A expresión de coordenadas contén un operador non válido ao inicio do seu "
|
||||
"texto: «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:1996
|
||||
#: ../src/ui/theme.c:1997
|
||||
#, c-format
|
||||
msgid "Coordinate expression was empty or not understood"
|
||||
msgstr "A expresión de coordenadas está baleira ou non se entendeu"
|
||||
|
||||
#: ../src/ui/theme.c:2109 ../src/ui/theme.c:2119 ../src/ui/theme.c:2153
|
||||
#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154
|
||||
#, c-format
|
||||
msgid "Coordinate expression results in division by zero"
|
||||
msgstr "A expresión de coordenadas resultou nun erro de división por cero"
|
||||
|
||||
#: ../src/ui/theme.c:2161
|
||||
#: ../src/ui/theme.c:2162
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression tries to use mod operator on a floating-point number"
|
||||
@@ -774,25 +802,25 @@ msgstr ""
|
||||
"A expresión de coordenadas tentou usar un operador mod cun número de coma "
|
||||
"flotante"
|
||||
|
||||
#: ../src/ui/theme.c:2217
|
||||
#: ../src/ui/theme.c:2218
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has an operator \"%s\" where an operand was expected"
|
||||
msgstr ""
|
||||
"A expresión de coordenadas ten un operador «%s» onde se esperaba un operando"
|
||||
|
||||
#: ../src/ui/theme.c:2226
|
||||
#: ../src/ui/theme.c:2227
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an operand where an operator was expected"
|
||||
msgstr ""
|
||||
"A expresión de coordenadas ten un operando onde se esperaba un operador"
|
||||
|
||||
#: ../src/ui/theme.c:2234
|
||||
#: ../src/ui/theme.c:2235
|
||||
#, c-format
|
||||
msgid "Coordinate expression ended with an operator instead of an operand"
|
||||
msgstr "A expresión de coordenadas remata cun operador en vez dun operando"
|
||||
|
||||
#: ../src/ui/theme.c:2244
|
||||
#: ../src/ui/theme.c:2245
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
|
||||
@@ -801,42 +829,42 @@ msgstr ""
|
||||
"A expresión de coordenadas ten un operador \"%c\" seguido do operador \"%c\" "
|
||||
"sen un operando entre eles"
|
||||
|
||||
#: ../src/ui/theme.c:2395 ../src/ui/theme.c:2440
|
||||
#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441
|
||||
#, c-format
|
||||
msgid "Coordinate expression had unknown variable or constant \"%s\""
|
||||
msgstr ""
|
||||
"A expresión de coordenadas ten unha variábel ou constante descoñecida «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:2494
|
||||
#: ../src/ui/theme.c:2495
|
||||
#, c-format
|
||||
msgid "Coordinate expression parser overflowed its buffer."
|
||||
msgstr "O analizador da expresión de coordenadas desbordou o seu búfer."
|
||||
|
||||
#: ../src/ui/theme.c:2523
|
||||
#: ../src/ui/theme.c:2524
|
||||
#, c-format
|
||||
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
|
||||
msgstr ""
|
||||
"A expresión de coordenadas ten unha paréntese pechada sen unha paréntese "
|
||||
"aberta"
|
||||
|
||||
#: ../src/ui/theme.c:2587
|
||||
#: ../src/ui/theme.c:2588
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
|
||||
msgstr ""
|
||||
"A expresión de coordenadas ten unha paréntese aberta sen unha paréntese "
|
||||
"pechada"
|
||||
|
||||
#: ../src/ui/theme.c:2598
|
||||
#: ../src/ui/theme.c:2599
|
||||
#, c-format
|
||||
msgid "Coordinate expression doesn't seem to have any operators or operands"
|
||||
msgstr "A expresión de coordenadas non parece ter nin operadores nin operandos"
|
||||
|
||||
#: ../src/ui/theme.c:2811 ../src/ui/theme.c:2831 ../src/ui/theme.c:2851
|
||||
#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852
|
||||
#, c-format
|
||||
msgid "Theme contained an expression that resulted in an error: %s\n"
|
||||
msgstr "O tema contiña unha expresión que resultou ser un erro: %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:4466
|
||||
#: ../src/ui/theme.c:4455
|
||||
#, c-format
|
||||
msgid ""
|
||||
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
|
||||
@@ -845,24 +873,24 @@ msgstr ""
|
||||
"<button function=«%s» state=«%s» draw_ops=\"whatever\"/> débese especificar "
|
||||
"para este estilo de marco"
|
||||
|
||||
#: ../src/ui/theme.c:4981 ../src/ui/theme.c:5006
|
||||
#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
|
||||
msgstr "Falta <frame state=«%s» resize=«%s» focus=«%s» style=\"whatever\"/>"
|
||||
|
||||
#: ../src/ui/theme.c:5052
|
||||
#: ../src/ui/theme.c:5041
|
||||
#, c-format
|
||||
msgid "Failed to load theme \"%s\": %s\n"
|
||||
msgstr "Produciuse un erro ao cargar o tema «%s»: %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:5188 ../src/ui/theme.c:5195 ../src/ui/theme.c:5202
|
||||
#: ../src/ui/theme.c:5209 ../src/ui/theme.c:5216
|
||||
#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191
|
||||
#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205
|
||||
#, c-format
|
||||
msgid "No <%s> set for theme \"%s\""
|
||||
msgstr "Non se configurou <%s> para o tema «%s»"
|
||||
|
||||
#: ../src/ui/theme.c:5224
|
||||
#: ../src/ui/theme.c:5213
|
||||
#, c-format
|
||||
msgid ""
|
||||
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
|
||||
@@ -871,7 +899,7 @@ msgstr ""
|
||||
"Non hai un estilo de marco para o tipo de xanela «%s» no tema «%s», engada "
|
||||
"un elemento <window type=«%s» style_set=\"whatever\"/>"
|
||||
|
||||
#: ../src/ui/theme.c:5631 ../src/ui/theme.c:5693 ../src/ui/theme.c:5756
|
||||
#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745
|
||||
#, c-format
|
||||
msgid ""
|
||||
"User-defined constants must begin with a capital letter; \"%s\" does not"
|
||||
@@ -879,7 +907,7 @@ msgstr ""
|
||||
"As constantes definidas polo usuario deben comezar cunha letra maiúscula; "
|
||||
"«%s» non o fai"
|
||||
|
||||
#: ../src/ui/theme.c:5639 ../src/ui/theme.c:5701 ../src/ui/theme.c:5764
|
||||
#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753
|
||||
#, c-format
|
||||
msgid "Constant \"%s\" has already been defined"
|
||||
msgstr "A constante «%s» xa foi definida"
|
||||
@@ -1279,7 +1307,7 @@ msgstr ""
|
||||
"Estas xanelas non soportan "save current setup" e terán que "
|
||||
"reiniciarse manualmente a próxima vez que inicie a sesión."
|
||||
|
||||
#: ../src/x11/window-props.c:465
|
||||
#: ../src/x11/window-props.c:515
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (en %s)"
|
||||
|
||||
115
po/pt_BR.po
115
po/pt_BR.po
@@ -21,8 +21,8 @@ msgstr ""
|
||||
"Project-Id-Version: mutter\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
|
||||
"product=mutter&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2014-07-18 09:51+0000\n"
|
||||
"PO-Revision-Date: 2014-07-18 14:53-0300\n"
|
||||
"POT-Creation-Date: 2014-08-22 09:52+0000\n"
|
||||
"PO-Revision-Date: 2014-08-22 16:18-0300\n"
|
||||
"Last-Translator: Enrico Nicoletto <liverig@gmail.com>\n"
|
||||
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
@@ -53,7 +53,6 @@ msgid "Move window to workspace 4"
|
||||
msgstr "Mover a janela para o espaço de trabalho 4"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:6
|
||||
#| msgid "Move window to workspace 1"
|
||||
msgid "Move window to last workspace"
|
||||
msgstr "Mover a janela para o último espaço de trabalho"
|
||||
|
||||
@@ -98,67 +97,100 @@ msgid "Switch applications"
|
||||
msgstr "Alternar aplicativos"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:16
|
||||
#| msgid "Switch applications"
|
||||
msgid "Switch to previous application"
|
||||
msgstr "Alternar para o aplicativo anterior"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:17
|
||||
msgid "Switch windows"
|
||||
msgstr "Alternar janelas"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:17
|
||||
#: ../data/50-mutter-navigation.xml.in.h:18
|
||||
#| msgid "Switch windows"
|
||||
msgid "Switch to previous window"
|
||||
msgstr "Alternar para a janela anterior"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:19
|
||||
msgid "Switch windows of an application"
|
||||
msgstr "Alternar as janelas de um aplicativo"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:18
|
||||
#: ../data/50-mutter-navigation.xml.in.h:20
|
||||
#| msgid "Switch windows of an application"
|
||||
msgid "Switch to previous window of an application"
|
||||
msgstr "Alternar para a janela anterior de um aplicativo"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:21
|
||||
msgid "Switch system controls"
|
||||
msgstr "Alternar os controles de sistema"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:19
|
||||
#: ../data/50-mutter-navigation.xml.in.h:22
|
||||
#| msgid "Switch system controls"
|
||||
msgid "Switch to previous system control"
|
||||
msgstr "Alternar para o controle de sistema anterior"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:23
|
||||
msgid "Switch windows directly"
|
||||
msgstr "Alternar as janelas diretamente"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:20
|
||||
#: ../data/50-mutter-navigation.xml.in.h:24
|
||||
msgid "Switch directly to previous window"
|
||||
msgstr "Alternar diretamente para a janela anterior"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:25
|
||||
msgid "Switch windows of an app directly"
|
||||
msgstr "Alternar as janelas de um aplicativo diretamente"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:21
|
||||
#: ../data/50-mutter-navigation.xml.in.h:26
|
||||
#| msgid "Switch windows of an application"
|
||||
msgid "Switch directly to previous window of an app"
|
||||
msgstr "Alternar diretamente para a janela anterior de um aplicativo"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:27
|
||||
msgid "Switch system controls directly"
|
||||
msgstr "Alternar os controles de sistema diretamente"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:22
|
||||
#: ../data/50-mutter-navigation.xml.in.h:28
|
||||
#| msgid "Switch system controls"
|
||||
msgid "Switch directly to previous system control"
|
||||
msgstr "Alternar diretamente para o controle de sistema anterior"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:29
|
||||
msgid "Hide all normal windows"
|
||||
msgstr "Ocultar todas as janelas normais"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:23
|
||||
#: ../data/50-mutter-navigation.xml.in.h:30
|
||||
msgid "Switch to workspace 1"
|
||||
msgstr "Trocar para o espaço de trabalho 1"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:24
|
||||
#: ../data/50-mutter-navigation.xml.in.h:31
|
||||
msgid "Switch to workspace 2"
|
||||
msgstr "Trocar para o espaço de trabalho 2"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:25
|
||||
#: ../data/50-mutter-navigation.xml.in.h:32
|
||||
msgid "Switch to workspace 3"
|
||||
msgstr "Trocar para o espaço de trabalho 3"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:26
|
||||
#: ../data/50-mutter-navigation.xml.in.h:33
|
||||
msgid "Switch to workspace 4"
|
||||
msgstr "Trocar para o espaço de trabalho 4"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:27
|
||||
#| msgid "Switch to workspace 1"
|
||||
#: ../data/50-mutter-navigation.xml.in.h:34
|
||||
msgid "Switch to last workspace"
|
||||
msgstr "Trocar para o último espaço de trabalho"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:28
|
||||
#: ../data/50-mutter-navigation.xml.in.h:35
|
||||
msgid "Move to workspace left"
|
||||
msgstr "Move para o espaço de trabalho à esquerda"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:29
|
||||
#: ../data/50-mutter-navigation.xml.in.h:36
|
||||
msgid "Move to workspace right"
|
||||
msgstr "Move para o espaço de trabalho à direita"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:30
|
||||
#: ../data/50-mutter-navigation.xml.in.h:37
|
||||
msgid "Move to workspace above"
|
||||
msgstr "Mover para o espaço de trabalho acima"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:31
|
||||
#: ../data/50-mutter-navigation.xml.in.h:38
|
||||
msgid "Move to workspace below"
|
||||
msgstr "Mover para o espaço de trabalho abaixo"
|
||||
|
||||
@@ -399,37 +431,30 @@ msgid "Cancel tab popup"
|
||||
msgstr "Cancelar aba instantânea"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1
|
||||
#| msgid "Switch to workspace 1"
|
||||
msgid "Switch to VT 1"
|
||||
msgstr "Trocar para o VT 1"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2
|
||||
#| msgid "Switch to workspace 2"
|
||||
msgid "Switch to VT 2"
|
||||
msgstr "Trocar para o VT 2"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3
|
||||
#| msgid "Switch to workspace 3"
|
||||
msgid "Switch to VT 3"
|
||||
msgstr "Trocar para o VT 3"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4
|
||||
#| msgid "Switch to workspace 4"
|
||||
msgid "Switch to VT 4"
|
||||
msgstr "Trocar para o VT 4"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5
|
||||
#| msgid "Switch to workspace 5"
|
||||
msgid "Switch to VT 5"
|
||||
msgstr "Trocar para o VT 5"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6
|
||||
#| msgid "Switch to workspace 6"
|
||||
msgid "Switch to VT 6"
|
||||
msgstr "Trocar para o VT 6"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7
|
||||
#| msgid "Switch to workspace 7"
|
||||
msgid "Switch to VT 7"
|
||||
msgstr "Trocar para o VT 7"
|
||||
|
||||
@@ -455,7 +480,7 @@ msgstr "%s de %s"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: ../src/compositor/compositor.c:445
|
||||
#: ../src/compositor/compositor.c:441
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
@@ -463,11 +488,11 @@ msgid ""
|
||||
msgstr ""
|
||||
"Outro compositor de janelas está em execução na tela %i na área \"%s\"."
|
||||
|
||||
#: ../src/compositor/meta-background.c:990
|
||||
#: ../src/compositor/meta-background.c:1044
|
||||
msgid "background texture could not be created from file"
|
||||
msgstr "textura de plano de fundo não pôde ser criado de arquivo"
|
||||
|
||||
#: ../src/core/bell.c:215
|
||||
#: ../src/core/bell.c:185
|
||||
msgid "Bell event"
|
||||
msgstr "Evento de som"
|
||||
|
||||
@@ -496,49 +521,49 @@ msgstr "_Esperar"
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Forçar sair"
|
||||
|
||||
#: ../src/core/display.c:519
|
||||
#: ../src/core/display.c:547
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Falha ao abrir a exibição \"%s\" do sistema de janelas X\n"
|
||||
|
||||
#: ../src/core/main.c:172
|
||||
#: ../src/core/main.c:176
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "Desabilitar a conexão com o gerenciador de sessões"
|
||||
|
||||
#: ../src/core/main.c:178
|
||||
#: ../src/core/main.c:182
|
||||
msgid "Replace the running window manager"
|
||||
msgstr "Substituir o gerenciador de janelas em execução"
|
||||
|
||||
#: ../src/core/main.c:184
|
||||
#: ../src/core/main.c:188
|
||||
msgid "Specify session management ID"
|
||||
msgstr "Especificar o ID do gerenciador de sessões"
|
||||
|
||||
#: ../src/core/main.c:189
|
||||
#: ../src/core/main.c:193
|
||||
msgid "X Display to use"
|
||||
msgstr "Exibição do X a ser utilizada"
|
||||
|
||||
#: ../src/core/main.c:195
|
||||
#: ../src/core/main.c:199
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "Inicializar a sessão a partir do arquivo salvo"
|
||||
|
||||
#: ../src/core/main.c:201
|
||||
#: ../src/core/main.c:205
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "Fazer X chamadas síncronas"
|
||||
|
||||
#: ../src/core/main.c:207
|
||||
#: ../src/core/main.c:212
|
||||
msgid "Run as a wayland compositor"
|
||||
msgstr "Executar como um compositor wayland"
|
||||
|
||||
#: ../src/core/main.c:214
|
||||
#: ../src/core/main.c:220
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Executar como um servidor de tela cheia, ao invés de aninhado"
|
||||
|
||||
#: ../src/core/main.c:450
|
||||
#: ../src/core/main.c:459
|
||||
#, c-format
|
||||
msgid "Failed to scan themes directory: %s\n"
|
||||
msgstr "Falha ao varrer a pasta de temas: %s\n"
|
||||
|
||||
#: ../src/core/main.c:466
|
||||
#: ../src/core/main.c:475
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
|
||||
@@ -570,17 +595,17 @@ msgstr "Versão impressa"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Plug-in do Mutter para usar"
|
||||
|
||||
#: ../src/core/prefs.c:2086
|
||||
#: ../src/core/prefs.c:2101
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Espaço de trabalho %d"
|
||||
|
||||
#: ../src/core/screen.c:553
|
||||
#: ../src/core/screen.c:548
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "A tela %d na exibição \"%s\" é inválida\n"
|
||||
|
||||
#: ../src/core/screen.c:569
|
||||
#: ../src/core/screen.c:564
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
@@ -589,7 +614,7 @@ msgstr ""
|
||||
"A tela %d na exibição \"%s\" já possui um gerenciador de janelas; tente usar "
|
||||
"a opção --replace para substituir o gerenciador de janelas atual.\n"
|
||||
|
||||
#: ../src/core/screen.c:662
|
||||
#: ../src/core/screen.c:657
|
||||
#, c-format
|
||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||
msgstr "A tela %d na exibição \"%s\" já possui um gerenciador de janelas\n"
|
||||
@@ -1304,7 +1329,7 @@ msgstr ""
|
||||
"atual" e precisarão ser reiniciadas manualmente quando você reiniciar a "
|
||||
"sessão."
|
||||
|
||||
#: ../src/x11/window-props.c:513
|
||||
#: ../src/x11/window-props.c:515
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (em %s)"
|
||||
|
||||
1267
po/zh_HK.po
1267
po/zh_HK.po
File diff suppressed because it is too large
Load Diff
1295
po/zh_TW.po
1295
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -35,13 +35,16 @@ mutter_built_sources = \
|
||||
$(dbus_idle_built_sources) \
|
||||
$(dbus_display_config_built_sources) \
|
||||
$(dbus_login1_built_sources) \
|
||||
meta/meta-version.h \
|
||||
mutter-enum-types.h \
|
||||
mutter-enum-types.c \
|
||||
mutter-enum-types.c
|
||||
|
||||
if HAVE_WAYLAND
|
||||
mutter_built_sources += \
|
||||
gtk-shell-protocol.c \
|
||||
gtk-shell-server-protocol.h \
|
||||
xdg-shell-protocol.c \
|
||||
xdg-shell-server-protocol.h
|
||||
endif
|
||||
|
||||
wayland_protocols = \
|
||||
wayland/protocol/gtk-shell.xml \
|
||||
@@ -49,7 +52,7 @@ wayland_protocols = \
|
||||
|
||||
libmutter_la_SOURCES = \
|
||||
backends/meta-backend.c \
|
||||
backends/meta-backend.h \
|
||||
meta/meta-backend.h \
|
||||
backends/meta-backend-private.h \
|
||||
backends/meta-cursor.c \
|
||||
backends/meta-cursor.h \
|
||||
@@ -69,6 +72,8 @@ libmutter_la_SOURCES = \
|
||||
backends/meta-monitor-manager.h \
|
||||
backends/meta-monitor-manager-dummy.c \
|
||||
backends/meta-monitor-manager-dummy.h \
|
||||
backends/meta-stage.h \
|
||||
backends/meta-stage.c \
|
||||
backends/edid-parse.c \
|
||||
backends/edid.h \
|
||||
backends/x11/meta-backend-x11.c \
|
||||
@@ -113,10 +118,6 @@ libmutter_la_SOURCES = \
|
||||
compositor/meta-surface-actor.h \
|
||||
compositor/meta-surface-actor-x11.c \
|
||||
compositor/meta-surface-actor-x11.h \
|
||||
compositor/meta-surface-actor-wayland.c \
|
||||
compositor/meta-surface-actor-wayland.h \
|
||||
compositor/meta-stage.h \
|
||||
compositor/meta-stage.c \
|
||||
compositor/meta-texture-rectangle.c \
|
||||
compositor/meta-texture-rectangle.h \
|
||||
compositor/meta-texture-tower.c \
|
||||
@@ -212,7 +213,12 @@ libmutter_la_SOURCES = \
|
||||
x11/window-x11-private.h \
|
||||
x11/xprops.c \
|
||||
x11/xprops.h \
|
||||
x11/mutter-Xatomtype.h \
|
||||
x11/mutter-Xatomtype.h
|
||||
|
||||
if HAVE_WAYLAND
|
||||
libmutter_la_SOURCES += \
|
||||
compositor/meta-surface-actor-wayland.c \
|
||||
compositor/meta-surface-actor-wayland.h \
|
||||
wayland/meta-wayland.c \
|
||||
wayland/meta-wayland.h \
|
||||
wayland/meta-wayland-private.h \
|
||||
@@ -237,6 +243,7 @@ libmutter_la_SOURCES = \
|
||||
wayland/meta-wayland-outputs.h \
|
||||
wayland/window-wayland.c \
|
||||
wayland/window-wayland.h
|
||||
endif
|
||||
|
||||
if HAVE_NATIVE_BACKEND
|
||||
libmutter_la_SOURCES += \
|
||||
@@ -274,6 +281,7 @@ libmutterinclude_headers = \
|
||||
meta/group.h \
|
||||
meta/keybindings.h \
|
||||
meta/main.h \
|
||||
meta/meta-backend.h \
|
||||
meta/meta-background-actor.h \
|
||||
meta/meta-background-group.h \
|
||||
meta/meta-background.h \
|
||||
@@ -368,10 +376,12 @@ dbus_idle_built_sources = meta-dbus-idle-monitor.c meta-dbus-idle-monitor.h
|
||||
|
||||
CLEANFILES = \
|
||||
$(mutter_built_sources) \
|
||||
$(libmutterinclude_built_headers) \
|
||||
$(typelib_DATA) \
|
||||
$(gir_DATA)
|
||||
|
||||
DISTCLEANFILES = \
|
||||
$(libmutterinclude_built_headers)
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libmutter.pc
|
||||
|
||||
@@ -384,7 +394,10 @@ EXTRA_DIST = \
|
||||
org.gnome.Mutter.DisplayConfig.xml \
|
||||
org.gnome.Mutter.IdleMonitor.xml
|
||||
|
||||
BUILT_SOURCES = $(mutter_built_sources)
|
||||
BUILT_SOURCES = \
|
||||
$(mutter_built_sources) \
|
||||
$(libmutterinclude_built_headers)
|
||||
|
||||
MUTTER_STAMP_FILES = stamp-mutter-enum-types.h
|
||||
CLEANFILES += $(MUTTER_STAMP_FILES)
|
||||
|
||||
|
||||
@@ -28,7 +28,15 @@
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "meta-backend.h"
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/meta-idle-monitor.h>
|
||||
#include "meta-cursor-renderer.h"
|
||||
#include "meta-monitor-manager.h"
|
||||
|
||||
#define DEFAULT_XKB_RULES_FILE "evdev"
|
||||
#define DEFAULT_XKB_MODEL "pc105+inet"
|
||||
|
||||
#define META_TYPE_BACKEND (meta_backend_get_type ())
|
||||
#define META_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BACKEND, MetaBackend))
|
||||
@@ -66,6 +74,37 @@ struct _MetaBackendClass
|
||||
void (* warp_pointer) (MetaBackend *backend,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
void (* set_keymap) (MetaBackend *backend,
|
||||
const char *layouts,
|
||||
const char *variants,
|
||||
const char *options);
|
||||
|
||||
struct xkb_keymap * (* get_keymap) (MetaBackend *backend);
|
||||
|
||||
void (* lock_layout_group) (MetaBackend *backend,
|
||||
guint idx);
|
||||
|
||||
void (* update_screen_size) (MetaBackend *backend, int width, int height);
|
||||
void (* select_stage_events) (MetaBackend *backend);
|
||||
};
|
||||
|
||||
MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend,
|
||||
int device_id);
|
||||
MetaMonitorManager * meta_backend_get_monitor_manager (MetaBackend *backend);
|
||||
MetaCursorRenderer * meta_backend_get_cursor_renderer (MetaBackend *backend);
|
||||
|
||||
gboolean meta_backend_grab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
uint32_t timestamp);
|
||||
gboolean meta_backend_ungrab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
uint32_t timestamp);
|
||||
|
||||
void meta_backend_warp_pointer (MetaBackend *backend,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
struct xkb_keymap * meta_backend_get_keymap (MetaBackend *backend);
|
||||
|
||||
#endif /* META_BACKEND_PRIVATE_H */
|
||||
|
||||
@@ -24,12 +24,11 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-backend.h"
|
||||
#include <meta/meta-backend.h>
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "meta-stage.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
@@ -37,6 +36,13 @@
|
||||
|
||||
static MetaBackend *_backend;
|
||||
|
||||
/**
|
||||
* meta_get_backend:
|
||||
*
|
||||
* Accessor for the singleton MetaBackend.
|
||||
*
|
||||
* Returns: (transfer none): The only #MetaBackend there is.
|
||||
*/
|
||||
MetaBackend *
|
||||
meta_get_backend (void)
|
||||
{
|
||||
@@ -47,6 +53,8 @@ struct _MetaBackendPrivate
|
||||
{
|
||||
MetaMonitorManager *monitor_manager;
|
||||
MetaCursorRenderer *cursor_renderer;
|
||||
|
||||
ClutterActor *stage;
|
||||
};
|
||||
typedef struct _MetaBackendPrivate MetaBackendPrivate;
|
||||
|
||||
@@ -70,12 +78,40 @@ meta_backend_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_sync_screen_size (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
int width, height;
|
||||
|
||||
meta_monitor_manager_get_screen_size (priv->monitor_manager, &width, &height);
|
||||
|
||||
META_BACKEND_GET_CLASS (backend)->update_screen_size (backend, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
on_monitors_changed (MetaMonitorManager *monitors,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaBackend *backend = META_BACKEND (user_data);
|
||||
meta_backend_sync_screen_size (backend);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_real_post_init (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
|
||||
priv->stage = meta_stage_new ();
|
||||
clutter_actor_realize (priv->stage);
|
||||
META_BACKEND_GET_CLASS (backend)->select_stage_events (backend);
|
||||
|
||||
priv->monitor_manager = META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend);
|
||||
|
||||
g_signal_connect (priv->monitor_manager, "monitors-changed",
|
||||
G_CALLBACK (on_monitors_changed), backend);
|
||||
meta_backend_sync_screen_size (backend);
|
||||
|
||||
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
|
||||
}
|
||||
|
||||
@@ -103,6 +139,21 @@ meta_backend_real_ungrab_device (MetaBackend *backend,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_real_update_screen_size (MetaBackend *backend,
|
||||
int width, int height)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
|
||||
clutter_actor_set_size (priv->stage, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_real_select_stage_events (MetaBackend *backend)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_class_init (MetaBackendClass *klass)
|
||||
{
|
||||
@@ -114,6 +165,15 @@ meta_backend_class_init (MetaBackendClass *klass)
|
||||
klass->create_cursor_renderer = meta_backend_real_create_cursor_renderer;
|
||||
klass->grab_device = meta_backend_real_grab_device;
|
||||
klass->ungrab_device = meta_backend_real_ungrab_device;
|
||||
klass->update_screen_size = meta_backend_real_update_screen_size;
|
||||
klass->select_stage_events = meta_backend_real_select_stage_events;
|
||||
|
||||
g_signal_new ("keymap-changed",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -145,6 +205,9 @@ meta_backend_post_init (MetaBackend *backend)
|
||||
META_BACKEND_GET_CLASS (backend)->post_init (backend);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_get_idle_monitor: (skip)
|
||||
*/
|
||||
MetaIdleMonitor *
|
||||
meta_backend_get_idle_monitor (MetaBackend *backend,
|
||||
int device_id)
|
||||
@@ -160,6 +223,9 @@ meta_backend_get_idle_monitor (MetaBackend *backend,
|
||||
return backend->device_monitors[device_id];
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_get_monitor_manager: (skip)
|
||||
*/
|
||||
MetaMonitorManager *
|
||||
meta_backend_get_monitor_manager (MetaBackend *backend)
|
||||
{
|
||||
@@ -168,6 +234,9 @@ meta_backend_get_monitor_manager (MetaBackend *backend)
|
||||
return priv->monitor_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_get_cursor_renderer: (skip)
|
||||
*/
|
||||
MetaCursorRenderer *
|
||||
meta_backend_get_cursor_renderer (MetaBackend *backend)
|
||||
{
|
||||
@@ -176,6 +245,9 @@ meta_backend_get_cursor_renderer (MetaBackend *backend)
|
||||
return priv->cursor_renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_grab_device: (skip)
|
||||
*/
|
||||
gboolean
|
||||
meta_backend_grab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
@@ -184,6 +256,9 @@ meta_backend_grab_device (MetaBackend *backend,
|
||||
return META_BACKEND_GET_CLASS (backend)->grab_device (backend, device_id, timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_ungrab_device: (skip)
|
||||
*/
|
||||
gboolean
|
||||
meta_backend_ungrab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
@@ -192,6 +267,9 @@ meta_backend_ungrab_device (MetaBackend *backend,
|
||||
return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_warp_pointer: (skip)
|
||||
*/
|
||||
void
|
||||
meta_backend_warp_pointer (MetaBackend *backend,
|
||||
int x,
|
||||
@@ -200,6 +278,47 @@ meta_backend_warp_pointer (MetaBackend *backend,
|
||||
META_BACKEND_GET_CLASS (backend)->warp_pointer (backend, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_backend_set_keymap (MetaBackend *backend,
|
||||
const char *layouts,
|
||||
const char *variants,
|
||||
const char *options)
|
||||
{
|
||||
META_BACKEND_GET_CLASS (backend)->set_keymap (backend, layouts, variants, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_get_keymap: (skip)
|
||||
*/
|
||||
struct xkb_keymap *
|
||||
meta_backend_get_keymap (MetaBackend *backend)
|
||||
|
||||
{
|
||||
return META_BACKEND_GET_CLASS (backend)->get_keymap (backend);
|
||||
}
|
||||
|
||||
void
|
||||
meta_backend_lock_layout_group (MetaBackend *backend,
|
||||
guint idx)
|
||||
{
|
||||
META_BACKEND_GET_CLASS (backend)->lock_layout_group (backend, idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_get_stage:
|
||||
* @backend: A #MetaBackend
|
||||
*
|
||||
* Gets the global #ClutterStage that's managed by this backend.
|
||||
*
|
||||
* Returns: (transfer none): the #ClutterStage
|
||||
*/
|
||||
ClutterActor *
|
||||
meta_backend_get_stage (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
return priv->stage;
|
||||
}
|
||||
|
||||
static GType
|
||||
get_backend_type (void)
|
||||
{
|
||||
@@ -272,6 +391,9 @@ static GSourceFuncs event_funcs = {
|
||||
event_dispatch
|
||||
};
|
||||
|
||||
/**
|
||||
* meta_clutter_init: (skip)
|
||||
*/
|
||||
void
|
||||
meta_clutter_init (void)
|
||||
{
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
typedef struct {
|
||||
CoglTexture2D *texture;
|
||||
struct gbm_bo *bo;
|
||||
int hot_x, hot_y;
|
||||
int offset_x, offset_y;
|
||||
} MetaCursorImage;
|
||||
|
||||
struct _MetaCursorReference {
|
||||
@@ -41,11 +41,11 @@ struct _MetaCursorReference {
|
||||
};
|
||||
|
||||
CoglTexture *meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y);
|
||||
int *offset_x,
|
||||
int *offset_y);
|
||||
|
||||
struct gbm_bo *meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y);
|
||||
int *offset_x,
|
||||
int *offset_y);
|
||||
|
||||
#endif /* META_CURSOR_PRIVATE_H */
|
||||
|
||||
@@ -27,21 +27,29 @@
|
||||
#include "meta-cursor-renderer.h"
|
||||
#include "meta-cursor-private.h"
|
||||
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/util.h>
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "meta-stage.h"
|
||||
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
typedef struct
|
||||
{
|
||||
CoglTexture *texture;
|
||||
MetaRectangle current_rect;
|
||||
gboolean handled_by_backend;
|
||||
} MetaCursorLayer;
|
||||
|
||||
struct _MetaCursorRendererPrivate
|
||||
{
|
||||
int current_x, current_y;
|
||||
MetaRectangle current_rect;
|
||||
|
||||
MetaCursorLayer core_layer;
|
||||
MetaCursorLayer dnd_layer;
|
||||
|
||||
MetaCursorReference *displayed_cursor;
|
||||
gboolean handled_by_backend;
|
||||
};
|
||||
typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
|
||||
|
||||
@@ -51,17 +59,16 @@ static void
|
||||
queue_redraw (MetaCursorRenderer *renderer)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
ClutterActor *stage = compositor->stage;
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
|
||||
/* During early initialization, we can have no stage */
|
||||
if (!stage)
|
||||
return;
|
||||
|
||||
if (priv->handled_by_backend)
|
||||
meta_stage_set_cursor (META_STAGE (stage), NULL, &priv->current_rect);
|
||||
else
|
||||
meta_stage_set_cursor (META_STAGE (stage), priv->displayed_cursor, &priv->current_rect);
|
||||
if (priv->core_layer.texture && !priv->core_layer.handled_by_backend)
|
||||
meta_stage_set_cursor (META_STAGE (stage), layer->texture, &priv->current_rect);
|
||||
meta_stage_set_dnd_surface (META_STAGE (stage),
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -81,33 +88,68 @@ meta_cursor_renderer_init (MetaCursorRenderer *renderer)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
update_layer (MetaCursorRenderer *renderer,
|
||||
MetaCursorLayer *layer,
|
||||
CoglTexture *texture,
|
||||
int offset_x,
|
||||
int offset_y)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
|
||||
layer->texture = texture;
|
||||
|
||||
if (layer->texture)
|
||||
{
|
||||
layer->current_rect.x = priv->current_x + offset_x;
|
||||
layer->current_rect.y = priv->current_y + offset_y;
|
||||
layer->current_rect.width = cogl_texture_get_width (layer->texture);
|
||||
layer->current_rect.height = cogl_texture_get_height (layer->texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
layer->current_rect.x = 0;
|
||||
layer->current_rect.y = 0;
|
||||
layer->current_rect.width = 0;
|
||||
layer->current_rect.height = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_cursor (MetaCursorRenderer *renderer)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
gboolean handled_by_backend;
|
||||
gboolean should_redraw = FALSE;
|
||||
CoglTexture *texture;
|
||||
int hot_x, hot_y;
|
||||
|
||||
if (priv->displayed_cursor)
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
CoglTexture *texture;
|
||||
int hot_x, hot_y;
|
||||
int offset_x, offset_y;
|
||||
|
||||
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, &hot_x, &hot_y);
|
||||
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, &offset_x, &offset_y);
|
||||
|
||||
priv->current_rect.x = priv->current_x - hot_x;
|
||||
priv->current_rect.y = priv->current_y - hot_y;
|
||||
priv->current_rect.x = priv->current_x + offset_x;
|
||||
priv->current_rect.y = priv->current_y + offset_y;
|
||||
priv->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (texture));
|
||||
priv->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (texture));
|
||||
=======
|
||||
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, &hot_x, &hot_y);
|
||||
>>>>>>> 75e7834... dnd 2
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->current_rect.x = 0;
|
||||
priv->current_rect.y = 0;
|
||||
priv->current_rect.width = 0;
|
||||
priv->current_rect.height = 0;
|
||||
texture = NULL;
|
||||
hot_x = 0;
|
||||
hot_y = 0;
|
||||
}
|
||||
|
||||
update_layer (renderer, &priv->core_layer, texture, hot_x, hot_y);
|
||||
update_layer (renderer, &priv->
|
||||
|
||||
handled_by_backend = META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer);
|
||||
if (handled_by_backend != priv->handled_by_backend)
|
||||
{
|
||||
@@ -141,6 +183,17 @@ meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
||||
update_cursor (renderer);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_renderer_set_dnd_surface (MetaCursorRenderer *renderer,
|
||||
CoglTexture *texture,
|
||||
int offset_x,
|
||||
int offset_y)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
|
||||
update_layer (renderer, &priv->dnd_layer,
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
|
||||
int x, int y)
|
||||
@@ -168,5 +221,5 @@ meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
|
||||
return &priv->current_rect;
|
||||
return &priv->core_layer.current_rect;
|
||||
}
|
||||
|
||||
@@ -34,13 +34,12 @@
|
||||
#include <meta/errors.h>
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include "meta-backend.h"
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
@@ -48,8 +47,8 @@
|
||||
G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
|
||||
|
||||
enum {
|
||||
CURSOR_CHANGED,
|
||||
LAST_SIGNAL
|
||||
CURSOR_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
@@ -62,7 +61,7 @@ get_displayed_cursor (MetaCursorTracker *tracker)
|
||||
if (!tracker->is_showing)
|
||||
return NULL;
|
||||
|
||||
if (display->grab_op == META_GRAB_OP_NONE)
|
||||
if (meta_display_windows_are_interactable (display))
|
||||
{
|
||||
if (tracker->has_window_cursor)
|
||||
return tracker->window_cursor;
|
||||
@@ -311,6 +310,7 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
|
||||
int *y)
|
||||
{
|
||||
MetaCursorReference *cursor;
|
||||
int offset_x, offset_y;
|
||||
|
||||
g_return_if_fail (META_IS_CURSOR_TRACKER (tracker));
|
||||
|
||||
@@ -325,14 +325,19 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
|
||||
}
|
||||
|
||||
if (cursor)
|
||||
meta_cursor_reference_get_cogl_texture (cursor, x, y);
|
||||
{
|
||||
meta_cursor_reference_get_cogl_texture (cursor, &offset_x, &offset_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x)
|
||||
*x = 0;
|
||||
if (y)
|
||||
*y = 0;
|
||||
offset_x = 0;
|
||||
offset_y = 0;
|
||||
}
|
||||
|
||||
if (x)
|
||||
*x = -offset_x;
|
||||
if (y)
|
||||
*y = -offset_y;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "display-private.h"
|
||||
#include "screen-private.h"
|
||||
#include "meta-backend.h"
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-cursor-renderer-native.h"
|
||||
@@ -39,7 +39,9 @@
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
#endif
|
||||
|
||||
MetaCursorReference *
|
||||
meta_cursor_reference_ref (MetaCursorReference *self)
|
||||
@@ -247,6 +249,7 @@ meta_cursor_reference_from_theme (MetaCursor cursor)
|
||||
return self;
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
static void
|
||||
meta_cursor_image_load_from_buffer (MetaCursorImage *image,
|
||||
struct wl_resource *buffer,
|
||||
@@ -345,28 +348,29 @@ meta_cursor_reference_from_buffer (struct wl_resource *buffer,
|
||||
|
||||
return self;
|
||||
}
|
||||
#endif
|
||||
|
||||
CoglTexture *
|
||||
meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y)
|
||||
int *offset_x,
|
||||
int *offset_y)
|
||||
{
|
||||
if (hot_x)
|
||||
*hot_x = cursor->image.hot_x;
|
||||
if (hot_y)
|
||||
*hot_y = cursor->image.hot_y;
|
||||
if (offset_x)
|
||||
*offset_x = cursor->image.offset_x;
|
||||
if (offset_y)
|
||||
*offset_y = cursor->image.offset_y;
|
||||
return COGL_TEXTURE (cursor->image.texture);
|
||||
}
|
||||
|
||||
struct gbm_bo *
|
||||
meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y)
|
||||
int *offset_x,
|
||||
int *offset_y)
|
||||
{
|
||||
if (hot_x)
|
||||
*hot_x = cursor->image.hot_x;
|
||||
if (hot_y)
|
||||
*hot_y = cursor->image.hot_y;
|
||||
if (offset_x)
|
||||
*offset_x = cursor->image.offset_x;
|
||||
if (offset_y)
|
||||
*offset_y = cursor->image.offset_y;
|
||||
return cursor->image.bo;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,13 +28,14 @@ MetaCursorReference * meta_cursor_reference_ref (MetaCursorReference *cursor);
|
||||
void meta_cursor_reference_unref (MetaCursorReference *cursor);
|
||||
|
||||
#include <meta/common.h>
|
||||
#include <wayland-server.h>
|
||||
|
||||
MetaCursorReference * meta_cursor_reference_from_theme (MetaCursor cursor);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include <wayland-server.h>
|
||||
MetaCursorReference * meta_cursor_reference_from_buffer (struct wl_resource *buffer,
|
||||
int hot_x,
|
||||
int hot_y);
|
||||
int offset_x, int offset_y);
|
||||
#endif
|
||||
|
||||
MetaCursor meta_cursor_reference_get_meta_cursor (MetaCursorReference *cursor);
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include <meta/meta-idle-monitor.h>
|
||||
#include "meta-idle-monitor-private.h"
|
||||
#include "meta-idle-monitor-dbus.h"
|
||||
#include "meta-backend.h"
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer));
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <meta/errors.h>
|
||||
#include "meta-monitor-config.h"
|
||||
#include "backends/x11/meta-monitor-manager-xrandr.h"
|
||||
#include "meta-backend.h"
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
enum {
|
||||
CONFIRM_DISPLAY_CHANGE,
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include "display-private.h"
|
||||
#include <meta/screen.h>
|
||||
#include "stack-tracker.h"
|
||||
#include "ui.h"
|
||||
|
||||
#include "meta-display-config-shared.h"
|
||||
#include "meta-dbus-display-config.h"
|
||||
|
||||
214
src/backends/meta-stage.c
Normal file
214
src/backends/meta-stage.c
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "meta-stage.h"
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/util.h>
|
||||
|
||||
typedef struct {
|
||||
gboolean enabled;
|
||||
|
||||
CoglPipeline *pipeline;
|
||||
CoglTexture *texture;
|
||||
|
||||
MetaRectangle current_rect;
|
||||
MetaRectangle previous_rect;
|
||||
gboolean previous_is_valid;
|
||||
} MetaOverlay;
|
||||
|
||||
struct _MetaStagePrivate {
|
||||
MetaOverlay dnd_overlay;
|
||||
MetaOverlay cursor_overlay;
|
||||
};
|
||||
typedef struct _MetaStagePrivate MetaStagePrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaStage, meta_stage, CLUTTER_TYPE_STAGE);
|
||||
|
||||
static void
|
||||
meta_overlay_init (MetaOverlay *overlay)
|
||||
{
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
|
||||
overlay->pipeline = cogl_pipeline_new (ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_overlay_free (MetaOverlay *overlay)
|
||||
{
|
||||
if (overlay->pipeline)
|
||||
cogl_object_unref (overlay->pipeline);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_overlay_set (MetaOverlay *overlay,
|
||||
CoglTexture *texture,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
if (overlay->texture != texture)
|
||||
{
|
||||
overlay->texture = texture;
|
||||
|
||||
if (texture)
|
||||
{
|
||||
cogl_pipeline_set_layer_texture (overlay->pipeline, 0, texture);
|
||||
overlay->enabled = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
cogl_pipeline_set_layer_texture (overlay->pipeline, 0, NULL);
|
||||
overlay->enabled = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
overlay->current_rect = *rect;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_overlay_paint (MetaOverlay *overlay)
|
||||
{
|
||||
if (!overlay->enabled)
|
||||
return;
|
||||
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
|
||||
cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
|
||||
overlay->pipeline,
|
||||
overlay->current_rect.x,
|
||||
overlay->current_rect.y,
|
||||
overlay->current_rect.x +
|
||||
overlay->current_rect.width,
|
||||
overlay->current_rect.y +
|
||||
overlay->current_rect.height);
|
||||
|
||||
overlay->previous_rect = overlay->current_rect;
|
||||
overlay->previous_is_valid = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stage_finalize (GObject *object)
|
||||
{
|
||||
MetaStage *stage = META_STAGE (object);
|
||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||
|
||||
meta_overlay_free (&priv->dnd_overlay);
|
||||
meta_overlay_free (&priv->cursor_overlay);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stage_paint (ClutterActor *actor)
|
||||
{
|
||||
MetaStage *stage = META_STAGE (actor);
|
||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor);
|
||||
|
||||
meta_overlay_paint (&priv->dnd_overlay);
|
||||
meta_overlay_paint (&priv->cursor_overlay);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stage_class_init (MetaStageClass *klass)
|
||||
{
|
||||
ClutterActorClass *actor_class = (ClutterActorClass *) klass;
|
||||
GObjectClass *object_class = (GObjectClass *) klass;
|
||||
|
||||
object_class->finalize = meta_stage_finalize;
|
||||
|
||||
actor_class->paint = meta_stage_paint;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stage_init (MetaStage *stage)
|
||||
{
|
||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||
|
||||
meta_overlay_init (&priv->dnd_overlay);
|
||||
meta_overlay_init (&priv->cursor_overlay);
|
||||
|
||||
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), FALSE);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
meta_stage_new (void)
|
||||
{
|
||||
return g_object_new (META_TYPE_STAGE,
|
||||
"cursor-visible", FALSE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
queue_redraw_for_overlay (MetaStage *stage,
|
||||
MetaOverlay *overlay)
|
||||
{
|
||||
cairo_rectangle_int_t clip;
|
||||
|
||||
/* Clear the location the overlay was at before, if we need to. */
|
||||
if (overlay->previous_is_valid)
|
||||
{
|
||||
clip.x = overlay->previous_rect.x;
|
||||
clip.y = overlay->previous_rect.y;
|
||||
clip.width = overlay->previous_rect.width;
|
||||
clip.height = overlay->previous_rect.height;
|
||||
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
|
||||
overlay->previous_is_valid = FALSE;
|
||||
}
|
||||
|
||||
/* Draw the overlay at the new position */
|
||||
if (overlay->enabled)
|
||||
{
|
||||
clip.x = overlay->current_rect.x;
|
||||
clip.y = overlay->current_rect.y;
|
||||
clip.width = overlay->current_rect.width;
|
||||
clip.height = overlay->current_rect.height;
|
||||
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_stage_set_dnd_surface (MetaStage *stage,
|
||||
CoglTexture *texture,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
|
||||
meta_overlay_set (&priv->dnd_overlay, texture, rect);
|
||||
queue_redraw_for_overlay (stage, &priv->dnd_overlay);
|
||||
}
|
||||
|
||||
void
|
||||
meta_stage_set_cursor (MetaStage *stage,
|
||||
CoglTexture *texture,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||
|
||||
g_assert (meta_is_wayland_compositor () || texture == NULL);
|
||||
|
||||
meta_overlay_set (&priv->cursor_overlay, texture, rect);
|
||||
queue_redraw_for_overlay (stage, &priv->cursor_overlay);
|
||||
}
|
||||
@@ -51,9 +51,14 @@ GType meta_stage_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterActor *meta_stage_new (void);
|
||||
|
||||
void meta_stage_set_cursor (MetaStage *stage,
|
||||
MetaCursorReference *cursor,
|
||||
MetaRectangle *rect);
|
||||
void meta_stage_set_dnd_surface (MetaStage *stage,
|
||||
CoglTexture *texture,
|
||||
MetaRectangle *rect);
|
||||
|
||||
void meta_stage_set_cursor (MetaStage *stage,
|
||||
CoglTexture *texture,
|
||||
MetaRectangle *rect);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* META_STAGE_H */
|
||||
@@ -188,6 +188,49 @@ meta_backend_native_warp_pointer (MetaBackend *backend,
|
||||
clutter_evdev_warp_pointer (device, time_, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_native_set_keymap (MetaBackend *backend,
|
||||
const char *layouts,
|
||||
const char *variants,
|
||||
const char *options)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
struct xkb_rule_names names;
|
||||
struct xkb_keymap *keymap;
|
||||
struct xkb_context *context;
|
||||
|
||||
names.rules = DEFAULT_XKB_RULES_FILE;
|
||||
names.model = DEFAULT_XKB_MODEL;
|
||||
names.layout = layouts;
|
||||
names.variant = variants;
|
||||
names.options = options;
|
||||
|
||||
context = xkb_context_new (XKB_CONTEXT_NO_FLAGS);
|
||||
keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
xkb_context_unref (context);
|
||||
|
||||
clutter_evdev_set_keyboard_map (manager, keymap);
|
||||
|
||||
g_signal_emit_by_name (backend, "keymap-changed", 0);
|
||||
|
||||
xkb_keymap_unref (keymap);
|
||||
}
|
||||
|
||||
static struct xkb_keymap *
|
||||
meta_backend_native_get_keymap (MetaBackend *backend)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
return clutter_evdev_get_keyboard_map (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_native_lock_layout_group (MetaBackend *backend,
|
||||
guint idx)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
clutter_evdev_set_keyboard_layout_index (manager, idx);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_native_class_init (MetaBackendNativeClass *klass)
|
||||
{
|
||||
@@ -199,6 +242,9 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
|
||||
backend_class->create_cursor_renderer = meta_backend_native_create_cursor_renderer;
|
||||
|
||||
backend_class->warp_pointer = meta_backend_native_warp_pointer;
|
||||
backend_class->set_keymap = meta_backend_native_set_keymap;
|
||||
backend_class->get_keymap = meta_backend_native_get_keymap;
|
||||
backend_class->lock_layout_group = meta_backend_native_lock_layout_group;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -72,16 +72,16 @@ set_crtc_cursor (MetaCursorRendererNative *native,
|
||||
struct gbm_bo *bo;
|
||||
union gbm_bo_handle handle;
|
||||
int width, height;
|
||||
int hot_x, hot_y;
|
||||
int offset_x, offset_y;
|
||||
|
||||
bo = meta_cursor_reference_get_gbm_bo (cursor, &hot_x, &hot_y);
|
||||
bo = meta_cursor_reference_get_gbm_bo (cursor, &offset_x, &offset_y);
|
||||
|
||||
handle = gbm_bo_get_handle (bo);
|
||||
width = gbm_bo_get_width (bo);
|
||||
height = gbm_bo_get_height (bo);
|
||||
|
||||
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, handle.u32,
|
||||
width, height, hot_x, hot_y);
|
||||
width, height, -offset_x, -offset_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -41,8 +41,7 @@
|
||||
#include "dbus-utils.h"
|
||||
#include "meta-dbus-login1.h"
|
||||
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#include "backends/meta-backend.h"
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "meta-cursor-renderer-native.h"
|
||||
|
||||
struct _MetaLauncher
|
||||
@@ -101,15 +100,15 @@ session_unpause (void)
|
||||
clutter_egl_thaw_master_clock ();
|
||||
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (backend);
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
|
||||
/* When we mode-switch back, we need to immediately queue a redraw
|
||||
* in case nothing else queued one for us, and force the cursor to
|
||||
* update. */
|
||||
|
||||
clutter_actor_queue_redraw (compositor->stage);
|
||||
clutter_actor_queue_redraw (stage);
|
||||
meta_cursor_renderer_native_force_update (META_CURSOR_RENDERER_NATIVE (renderer));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,11 +24,18 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "meta-backend-x11.h"
|
||||
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
|
||||
#include <X11/extensions/sync.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include <X11/extensions/XKBrules.h>
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include <xkbcommon/xkbcommon-x11.h>
|
||||
|
||||
#include "meta-idle-monitor-xsync.h"
|
||||
#include "meta-monitor-manager-xrandr.h"
|
||||
@@ -43,6 +50,7 @@ struct _MetaBackendX11Private
|
||||
{
|
||||
/* The host X11 display */
|
||||
Display *xdisplay;
|
||||
xcb_connection_t *xcb;
|
||||
GSource *source;
|
||||
|
||||
int xsync_event_base;
|
||||
@@ -52,6 +60,11 @@ struct _MetaBackendX11Private
|
||||
int xinput_event_base;
|
||||
int xinput_error_base;
|
||||
Time latest_evtime;
|
||||
|
||||
uint8_t xkb_event_base;
|
||||
uint8_t xkb_error_base;
|
||||
|
||||
struct xkb_keymap *keymap;
|
||||
};
|
||||
typedef struct _MetaBackendX11Private MetaBackendX11Private;
|
||||
|
||||
@@ -145,24 +158,62 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
keymap_changed (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
|
||||
if (priv->keymap)
|
||||
{
|
||||
xkb_keymap_unref (priv->keymap);
|
||||
priv->keymap = NULL;
|
||||
}
|
||||
|
||||
g_signal_emit_by_name (backend, "keymap-changed", 0);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_host_xevent (MetaBackend *backend,
|
||||
XEvent *event)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
MetaCompositor *compositor = display->compositor;
|
||||
gboolean bypass_clutter = FALSE;
|
||||
|
||||
XGetEventData (priv->xdisplay, &event->xcookie);
|
||||
|
||||
if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
|
||||
bypass_clutter = TRUE;
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
if (display)
|
||||
{
|
||||
MetaCompositor *compositor = display->compositor;
|
||||
if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
|
||||
bypass_clutter = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (event->type == (priv->xsync_event_base + XSyncAlarmNotify))
|
||||
handle_alarm_notify (backend, event);
|
||||
|
||||
if (event->type == priv->xkb_event_base)
|
||||
{
|
||||
XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event;
|
||||
|
||||
if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID)
|
||||
{
|
||||
switch (xkb_ev->xkb_type)
|
||||
{
|
||||
case XkbNewKeyboardNotify:
|
||||
case XkbMapNotify:
|
||||
keymap_changed (backend);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend);
|
||||
if (META_IS_MONITOR_MANAGER_XRANDR (manager) &&
|
||||
@@ -314,6 +365,17 @@ meta_backend_x11_post_init (MetaBackend *backend)
|
||||
|
||||
take_touch_grab (backend);
|
||||
|
||||
priv->xcb = XGetXCBConnection (priv->xdisplay);
|
||||
if (!xkb_x11_setup_xkb_extension (priv->xcb,
|
||||
XKB_X11_MIN_MAJOR_XKB_VERSION,
|
||||
XKB_X11_MIN_MINOR_XKB_VERSION,
|
||||
XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS,
|
||||
NULL, NULL,
|
||||
&priv->xkb_event_base,
|
||||
&priv->xkb_error_base))
|
||||
meta_fatal ("X server doesn't have the XKB extension, version %d.%d or newer\n",
|
||||
XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION);
|
||||
|
||||
META_BACKEND_CLASS (meta_backend_x11_parent_class)->post_init (backend);
|
||||
}
|
||||
|
||||
@@ -407,6 +469,198 @@ meta_backend_x11_warp_pointer (MetaBackend *backend,
|
||||
x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
get_xkbrf_var_defs (Display *xdisplay,
|
||||
const char *layouts,
|
||||
const char *variants,
|
||||
const char *options,
|
||||
char **rules_p,
|
||||
XkbRF_VarDefsRec *var_defs)
|
||||
{
|
||||
char *rules = NULL;
|
||||
|
||||
/* Get it from the X property or fallback on defaults */
|
||||
if (!XkbRF_GetNamesProp (xdisplay, &rules, var_defs) || !rules)
|
||||
{
|
||||
rules = strdup (DEFAULT_XKB_RULES_FILE);
|
||||
var_defs->model = strdup (DEFAULT_XKB_MODEL);
|
||||
var_defs->layout = NULL;
|
||||
var_defs->variant = NULL;
|
||||
var_defs->options = NULL;
|
||||
}
|
||||
|
||||
/* Swap in our new options... */
|
||||
free (var_defs->layout);
|
||||
var_defs->layout = strdup (layouts);
|
||||
free (var_defs->variant);
|
||||
var_defs->variant = strdup (variants);
|
||||
free (var_defs->options);
|
||||
var_defs->options = strdup (options);
|
||||
|
||||
/* Sometimes, the property is a file path, and sometimes it's
|
||||
not. Normalize it so it's always a file path. */
|
||||
if (rules[0] == '/')
|
||||
*rules_p = g_strdup (rules);
|
||||
else
|
||||
*rules_p = g_build_filename (XKB_BASE, "rules", rules, NULL);
|
||||
|
||||
free (rules);
|
||||
}
|
||||
|
||||
static void
|
||||
free_xkbrf_var_defs (XkbRF_VarDefsRec *var_defs)
|
||||
{
|
||||
free (var_defs->model);
|
||||
free (var_defs->layout);
|
||||
free (var_defs->variant);
|
||||
free (var_defs->options);
|
||||
}
|
||||
|
||||
static void
|
||||
free_xkb_component_names (XkbComponentNamesRec *p)
|
||||
{
|
||||
free (p->keymap);
|
||||
free (p->keycodes);
|
||||
free (p->types);
|
||||
free (p->compat);
|
||||
free (p->symbols);
|
||||
free (p->geometry);
|
||||
}
|
||||
|
||||
static void
|
||||
upload_xkb_description (Display *xdisplay,
|
||||
const gchar *rules_file_path,
|
||||
XkbRF_VarDefsRec *var_defs,
|
||||
XkbComponentNamesRec *comp_names)
|
||||
{
|
||||
XkbDescRec *xkb_desc;
|
||||
gchar *rules_file;
|
||||
|
||||
/* Upload it to the X server using the same method as setxkbmap */
|
||||
xkb_desc = XkbGetKeyboardByName (xdisplay,
|
||||
XkbUseCoreKbd,
|
||||
comp_names,
|
||||
XkbGBN_AllComponentsMask,
|
||||
XkbGBN_AllComponentsMask &
|
||||
(~XkbGBN_GeometryMask), True);
|
||||
if (!xkb_desc)
|
||||
{
|
||||
g_warning ("Couldn't upload new XKB keyboard description");
|
||||
return;
|
||||
}
|
||||
|
||||
XkbFreeKeyboard (xkb_desc, 0, True);
|
||||
|
||||
rules_file = g_path_get_basename (rules_file_path);
|
||||
|
||||
if (!XkbRF_SetNamesProp (xdisplay, rules_file, var_defs))
|
||||
g_warning ("Couldn't update the XKB root window property");
|
||||
|
||||
g_free (rules_file);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_set_keymap (MetaBackend *backend,
|
||||
const char *layouts,
|
||||
const char *variants,
|
||||
const char *options)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
XkbRF_RulesRec *xkb_rules;
|
||||
XkbRF_VarDefsRec xkb_var_defs = { 0 };
|
||||
gchar *rules_file_path;
|
||||
|
||||
get_xkbrf_var_defs (priv->xdisplay,
|
||||
layouts,
|
||||
variants,
|
||||
options,
|
||||
&rules_file_path,
|
||||
&xkb_var_defs);
|
||||
|
||||
xkb_rules = XkbRF_Load (rules_file_path, NULL, True, True);
|
||||
if (xkb_rules)
|
||||
{
|
||||
XkbComponentNamesRec xkb_comp_names = { 0 };
|
||||
|
||||
XkbRF_GetComponents (xkb_rules, &xkb_var_defs, &xkb_comp_names);
|
||||
upload_xkb_description (priv->xdisplay, rules_file_path, &xkb_var_defs, &xkb_comp_names);
|
||||
|
||||
free_xkb_component_names (&xkb_comp_names);
|
||||
XkbRF_Free (xkb_rules, True);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Couldn't load XKB rules");
|
||||
}
|
||||
|
||||
free_xkbrf_var_defs (&xkb_var_defs);
|
||||
g_free (rules_file_path);
|
||||
}
|
||||
|
||||
static struct xkb_keymap *
|
||||
meta_backend_x11_get_keymap (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
|
||||
if (priv->keymap == NULL)
|
||||
{
|
||||
struct xkb_context *context = xkb_context_new (XKB_CONTEXT_NO_FLAGS);
|
||||
priv->keymap = xkb_x11_keymap_new_from_device (context,
|
||||
priv->xcb,
|
||||
xkb_x11_get_core_keyboard_device_id (priv->xcb),
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
xkb_context_unref (context);
|
||||
}
|
||||
|
||||
return priv->keymap;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_lock_layout_group (MetaBackend *backend,
|
||||
guint idx)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
|
||||
XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, idx);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_update_screen_size (MetaBackend *backend,
|
||||
int width, int height)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
Window xwin = meta_backend_x11_get_xwindow (x11);
|
||||
XResizeWindow (priv->xdisplay, xwin, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_select_stage_events (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
Window xwin = meta_backend_x11_get_xwindow (x11);
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
|
||||
XISetMask (mask.mask, XI_KeyPress);
|
||||
XISetMask (mask.mask, XI_KeyRelease);
|
||||
XISetMask (mask.mask, XI_ButtonPress);
|
||||
XISetMask (mask.mask, XI_ButtonRelease);
|
||||
XISetMask (mask.mask, XI_Enter);
|
||||
XISetMask (mask.mask, XI_Leave);
|
||||
XISetMask (mask.mask, XI_FocusIn);
|
||||
XISetMask (mask.mask, XI_FocusOut);
|
||||
XISetMask (mask.mask, XI_Motion);
|
||||
XIClearMask (mask.mask, XI_TouchBegin);
|
||||
XIClearMask (mask.mask, XI_TouchEnd);
|
||||
XIClearMask (mask.mask, XI_TouchUpdate);
|
||||
XISelectEvents (priv->xdisplay, xwin, &mask, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_class_init (MetaBackendX11Class *klass)
|
||||
{
|
||||
@@ -416,10 +670,14 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
|
||||
backend_class->create_idle_monitor = meta_backend_x11_create_idle_monitor;
|
||||
backend_class->create_monitor_manager = meta_backend_x11_create_monitor_manager;
|
||||
backend_class->create_cursor_renderer = meta_backend_x11_create_cursor_renderer;
|
||||
|
||||
backend_class->grab_device = meta_backend_x11_grab_device;
|
||||
backend_class->ungrab_device = meta_backend_x11_ungrab_device;
|
||||
backend_class->warp_pointer = meta_backend_x11_warp_pointer;
|
||||
backend_class->set_keymap = meta_backend_x11_set_keymap;
|
||||
backend_class->get_keymap = meta_backend_x11_get_keymap;
|
||||
backend_class->lock_layout_group = meta_backend_x11_lock_layout_group;
|
||||
backend_class->update_screen_size = meta_backend_x11_update_screen_size;
|
||||
backend_class->select_stage_events = meta_backend_x11_select_stage_events;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -440,12 +698,6 @@ meta_backend_x11_get_xdisplay (MetaBackendX11 *x11)
|
||||
Window
|
||||
meta_backend_x11_get_xwindow (MetaBackendX11 *x11)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
MetaCompositor *compositor = display->compositor;
|
||||
|
||||
if (compositor == NULL)
|
||||
return None;
|
||||
|
||||
ClutterStage *stage = CLUTTER_STAGE (compositor->stage);
|
||||
return clutter_x11_get_stage_window (stage);
|
||||
ClutterActor *stage = meta_backend_get_stage (META_BACKEND (x11));
|
||||
return clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <X11/extensions/dpms.h>
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include <xcb/randr.h>
|
||||
|
||||
#include "meta-backend-x11.h"
|
||||
#include <meta/main.h>
|
||||
@@ -139,8 +141,8 @@ meta_monitor_transform_from_xrandr_all (Rotation rotation)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
output_get_boolean_property (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output, const char *propname)
|
||||
{
|
||||
gboolean value;
|
||||
Atom atom, actual_type;
|
||||
@@ -148,7 +150,7 @@ output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
unsigned long nitems, bytes_after;
|
||||
unsigned char *buffer;
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "_MUTTER_PRESENTATION_OUTPUT", False);
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, propname, False);
|
||||
XRRGetOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
atom,
|
||||
@@ -166,6 +168,13 @@ output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
return value;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
return output_get_boolean_property (manager_xrandr, output, "_MUTTER_PRESENTATION_OUTPUT");
|
||||
}
|
||||
|
||||
static int
|
||||
normalize_backlight (MetaOutput *output,
|
||||
int hw_value)
|
||||
@@ -207,30 +216,34 @@ output_get_backlight_limits_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
Atom atom;
|
||||
XRRPropertyInfo *info;
|
||||
xcb_connection_t *xcb_conn;
|
||||
xcb_randr_query_output_property_reply_t *reply;
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
|
||||
info = XRRQueryOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
atom);
|
||||
|
||||
if (info == NULL)
|
||||
{
|
||||
meta_verbose ("could not get output property for %s\n", output->name);
|
||||
return;
|
||||
}
|
||||
xcb_conn = XGetXCBConnection (manager_xrandr->xdisplay);
|
||||
reply = xcb_randr_query_output_property_reply (xcb_conn,
|
||||
xcb_randr_query_output_property (xcb_conn,
|
||||
(xcb_randr_output_t) output->winsys_id,
|
||||
(xcb_atom_t) atom),
|
||||
NULL);
|
||||
|
||||
if (!info->range || info->num_values != 2)
|
||||
/* This can happen on systems without backlights. */
|
||||
if (reply == NULL)
|
||||
return;
|
||||
|
||||
if (!reply->range || reply->length != 2)
|
||||
{
|
||||
meta_verbose ("backlight %s was not range\n", output->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
output->backlight_min = info->values[0];
|
||||
output->backlight_max = info->values[1];
|
||||
int32_t *values = xcb_randr_query_output_property_valid_values (reply);
|
||||
output->backlight_min = values[0];
|
||||
output->backlight_max = values[1];
|
||||
|
||||
out:
|
||||
XFree (info);
|
||||
free (reply);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -312,25 +325,25 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
|
||||
static gboolean
|
||||
output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
XID winsys_id)
|
||||
MetaOutput *output)
|
||||
{
|
||||
Atom atom;
|
||||
XRRPropertyInfo *info;
|
||||
gboolean result = FALSE;
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "hotplug_mode_update", False);
|
||||
info = XRRQueryOutputProperty (manager_xrandr->xdisplay, winsys_id,
|
||||
atom);
|
||||
|
||||
if (info)
|
||||
{
|
||||
result = TRUE;
|
||||
XFree (info);
|
||||
}
|
||||
|
||||
return result;
|
||||
return output_get_boolean_property (manager_xrandr, output, "hotplug_mode_update");
|
||||
}
|
||||
|
||||
static char *
|
||||
get_xmode_name (XRRModeInfo *xmode)
|
||||
{
|
||||
int width = xmode->width;
|
||||
int height = xmode->height;
|
||||
|
||||
if (xmode->hSkew != 0)
|
||||
{
|
||||
width += 2 * (xmode->hSkew >> 8);
|
||||
height += 2 * (xmode->hSkew & 0xff);
|
||||
}
|
||||
|
||||
return g_strdup_printf ("%dx%d", width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
@@ -417,6 +430,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
mode->height = xmode->height;
|
||||
mode->refresh_rate = (xmode->dotClock /
|
||||
((float)xmode->hTotal * xmode->vTotal));
|
||||
mode->name = get_xmode_name (xmode);
|
||||
}
|
||||
|
||||
for (i = 0; i < (unsigned)resources->ncrtc; i++)
|
||||
@@ -503,8 +517,7 @@ 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->winsys_id);
|
||||
meta_output->hotplug_mode_update = output_get_hotplug_mode_update (manager_xrandr, meta_output);
|
||||
|
||||
meta_output->n_modes = output->nmode;
|
||||
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
|
||||
|
||||
@@ -22,48 +22,6 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include "cogl-utils.h"
|
||||
|
||||
/**
|
||||
* meta_create_color_texture_4ub:
|
||||
* @red: red component
|
||||
* @green: green component
|
||||
* @blue: blue component
|
||||
* @alpha: alpha component
|
||||
* @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE;
|
||||
* %COGL_TEXTURE_NO_SLICING is useful if the texture will be
|
||||
* repeated to create a constant color fill, since hardware
|
||||
* repeat can't be used for a sliced texture.
|
||||
*
|
||||
* Creates a texture that is a single pixel with the specified
|
||||
* unpremultiplied color components.
|
||||
*
|
||||
* Return value: (transfer full): a newly created Cogl texture
|
||||
*/
|
||||
CoglTexture *
|
||||
meta_create_color_texture_4ub (guint8 red,
|
||||
guint8 green,
|
||||
guint8 blue,
|
||||
guint8 alpha,
|
||||
CoglTextureFlags flags)
|
||||
{
|
||||
CoglColor color;
|
||||
guint8 pixel[4];
|
||||
|
||||
cogl_color_init_from_4ub (&color, red, green, blue, alpha);
|
||||
cogl_color_premultiply (&color);
|
||||
|
||||
pixel[0] = cogl_color_get_red_byte (&color);
|
||||
pixel[1] = cogl_color_get_green_byte (&color);
|
||||
pixel[2] = cogl_color_get_blue_byte (&color);
|
||||
pixel[3] = cogl_color_get_alpha_byte (&color);
|
||||
|
||||
return cogl_texture_new_from_data (1, 1,
|
||||
flags,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
4, pixel);
|
||||
}
|
||||
|
||||
|
||||
/* Based on gnome-shell/src/st/st-private.c:_st_create_texture_material.c */
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,11 +23,6 @@
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
CoglTexture * meta_create_color_texture_4ub (guint8 red,
|
||||
guint8 green,
|
||||
guint8 blue,
|
||||
guint8 alpha,
|
||||
CoglTextureFlags flags);
|
||||
CoglPipeline * meta_create_texture_pipeline (CoglTexture *texture);
|
||||
|
||||
#endif /* __META_COGL_UTILS_H__ */
|
||||
|
||||
@@ -38,6 +38,8 @@ struct _MetaCompositor
|
||||
gint switch_workspace_in_progress;
|
||||
|
||||
MetaPluginManager *plugin_mgr;
|
||||
|
||||
gboolean frame_has_updated_xsurfaces;
|
||||
};
|
||||
|
||||
/* Wait 2ms after vblank before starting to draw next frame */
|
||||
|
||||
@@ -67,40 +67,29 @@
|
||||
#include <meta/compositor-mutter.h>
|
||||
#include <meta/prefs.h>
|
||||
#include <meta/main.h>
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/meta-background-actor.h>
|
||||
#include <meta/meta-background-group.h>
|
||||
#include <meta/meta-shadow-factory.h>
|
||||
#include "meta-window-actor-private.h"
|
||||
#include "meta-window-group.h"
|
||||
#include "meta-stage.h"
|
||||
#include "window-private.h" /* to check window->hidden */
|
||||
#include "display-private.h" /* for meta_display_lookup_x_window() */
|
||||
#include "display-private.h" /* for meta_display_lookup_x_window() and meta_display_cancel_touch() */
|
||||
#include "util-private.h"
|
||||
#include "frame.h"
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
|
||||
#include "backends/meta-backend.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
is_modal (MetaDisplay *display)
|
||||
{
|
||||
return display->grab_op == META_GRAB_OP_COMPOSITOR;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
composite_at_least_version (MetaDisplay *display, int maj, int min)
|
||||
{
|
||||
static int major = -1;
|
||||
static int minor = -1;
|
||||
|
||||
if (major == -1)
|
||||
meta_display_get_compositor_version (display, &major, &minor);
|
||||
|
||||
return (major > maj || (major == maj && minor >= min));
|
||||
return display->event_route == META_EVENT_ROUTE_COMPOSITOR_GRAB;
|
||||
}
|
||||
|
||||
static void sync_actor_stacking (MetaCompositor *compositor);
|
||||
@@ -146,6 +135,8 @@ process_damage (MetaCompositor *compositor,
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
meta_window_actor_process_x11_damage (window_actor, event);
|
||||
|
||||
compositor->frame_has_updated_xsurfaces = TRUE;
|
||||
}
|
||||
|
||||
/* compat helper */
|
||||
@@ -354,6 +345,7 @@ meta_begin_modal_for_plugin (MetaCompositor *compositor,
|
||||
return FALSE;
|
||||
|
||||
display->grab_op = META_GRAB_OP_COMPOSITOR;
|
||||
display->event_route = META_EVENT_ROUTE_COMPOSITOR_GRAB;
|
||||
display->grab_window = NULL;
|
||||
display->grab_have_pointer = TRUE;
|
||||
display->grab_have_keyboard = TRUE;
|
||||
@@ -363,7 +355,10 @@ meta_begin_modal_for_plugin (MetaCompositor *compositor,
|
||||
display->grab_window, display->grab_op);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
{
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
meta_display_cancel_touch (display);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -383,6 +378,7 @@ meta_end_modal_for_plugin (MetaCompositor *compositor,
|
||||
display->grab_window, display->grab_op);
|
||||
|
||||
display->grab_op = META_GRAB_OP_NONE;
|
||||
display->event_route = META_EVENT_ROUTE_NORMAL;
|
||||
display->grab_window = NULL;
|
||||
display->grab_have_pointer = FALSE;
|
||||
display->grab_have_keyboard = FALSE;
|
||||
@@ -404,8 +400,10 @@ after_stage_paint (ClutterStage *stage,
|
||||
for (l = compositor->windows; l; l = l->next)
|
||||
meta_window_actor_post_paint (l->data);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_wayland_compositor_paint_finished (meta_wayland_compositor_get_default ());
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -457,55 +455,13 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
MetaDisplay *display = compositor->display;
|
||||
Display *xdisplay = display->xdisplay;
|
||||
MetaScreen *screen = display->screen;
|
||||
Window xwin = 0;
|
||||
gint width, height;
|
||||
|
||||
meta_screen_set_cm_selection (display->screen);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaWaylandCompositor *wayland_compositor = meta_wayland_compositor_get_default ();
|
||||
|
||||
compositor->stage = meta_stage_new ();
|
||||
|
||||
wayland_compositor->stage = compositor->stage;
|
||||
|
||||
meta_screen_get_size (screen, &width, &height);
|
||||
clutter_actor_set_size (compositor->stage, width, height);
|
||||
clutter_actor_show (compositor->stage);
|
||||
}
|
||||
else
|
||||
{
|
||||
compositor->stage = clutter_stage_new ();
|
||||
|
||||
meta_screen_get_size (screen, &width, &height);
|
||||
clutter_actor_realize (compositor->stage);
|
||||
|
||||
xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage));
|
||||
|
||||
XResizeWindow (xdisplay, xwin, width, height);
|
||||
|
||||
{
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
Display *backend_xdisplay = meta_backend_x11_get_xdisplay (backend);
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
|
||||
XISetMask (mask.mask, XI_KeyPress);
|
||||
XISetMask (mask.mask, XI_KeyRelease);
|
||||
XISetMask (mask.mask, XI_ButtonPress);
|
||||
XISetMask (mask.mask, XI_ButtonRelease);
|
||||
XISetMask (mask.mask, XI_Enter);
|
||||
XISetMask (mask.mask, XI_Leave);
|
||||
XISetMask (mask.mask, XI_FocusIn);
|
||||
XISetMask (mask.mask, XI_FocusOut);
|
||||
XISetMask (mask.mask, XI_Motion);
|
||||
XIClearMask (mask.mask, XI_TouchBegin);
|
||||
XIClearMask (mask.mask, XI_TouchEnd);
|
||||
XIClearMask (mask.mask, XI_TouchUpdate);
|
||||
XISelectEvents (backend_xdisplay, xwin, &mask, 1);
|
||||
}
|
||||
}
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
compositor->stage = meta_backend_get_stage (backend);
|
||||
}
|
||||
|
||||
/* We use connect_after() here to accomodate code in GNOME Shell that,
|
||||
* when benchmarking drawing performance, connects to ::after-paint
|
||||
@@ -535,8 +491,12 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
}
|
||||
else
|
||||
{
|
||||
Window xwin;
|
||||
|
||||
compositor->output = screen->composite_overlay_window;
|
||||
|
||||
xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (meta_get_backend ()));
|
||||
|
||||
XReparentWindow (xdisplay, xwin, compositor->output, 0, 0);
|
||||
|
||||
meta_empty_stage_input_region (screen);
|
||||
@@ -1028,43 +988,6 @@ meta_compositor_sync_window_geometry (MetaCompositor *compositor,
|
||||
meta_window_actor_sync_actor_geometry (window_actor, did_placement);
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_sync_screen_size (MetaCompositor *compositor,
|
||||
guint width,
|
||||
guint height)
|
||||
{
|
||||
MetaDisplay *display = compositor->display;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
/* FIXME: when we support a sliced stage, this is the place to do it
|
||||
But! This is not the place to apply KMS config, here we only
|
||||
notify Clutter/Cogl/GL that the framebuffer sizes changed.
|
||||
|
||||
And because for now clutter does not do sliced, we use one
|
||||
framebuffer the size of the whole screen, and when running on
|
||||
bare metal MetaMonitorManager will do the necessary tricks to
|
||||
show the right portions on the right screens.
|
||||
*/
|
||||
|
||||
clutter_actor_set_size (compositor->stage, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
Display *xdisplay;
|
||||
Window xwin;
|
||||
|
||||
xdisplay = meta_display_get_xdisplay (display);
|
||||
xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage));
|
||||
|
||||
XResizeWindow (xdisplay, xwin, width, height);
|
||||
}
|
||||
|
||||
meta_verbose ("Changed size for stage on screen %d to %dx%d\n",
|
||||
meta_screen_get_screen_number (display->screen),
|
||||
width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
frame_callback (CoglOnscreen *onscreen,
|
||||
CoglFrameEvent event,
|
||||
@@ -1135,6 +1058,33 @@ pre_paint_windows (MetaCompositor *compositor)
|
||||
|
||||
for (l = compositor->windows; l; l = l->next)
|
||||
meta_window_actor_pre_paint (l->data);
|
||||
|
||||
if (compositor->frame_has_updated_xsurfaces)
|
||||
{
|
||||
/* We need to make sure that any X drawing that happens before
|
||||
* the XDamageSubtract() for each window above is visible to
|
||||
* subsequent GL rendering; the only standardized way to do this
|
||||
* is EXT_x11_sync_object, which isn't yet widely available. For
|
||||
* now, we count on details of Xorg and the open source drivers,
|
||||
* and hope for the best otherwise.
|
||||
*
|
||||
* Xorg and open source driver specifics:
|
||||
*
|
||||
* The X server makes sure to flush drawing to the kernel before
|
||||
* sending out damage events, but since we use
|
||||
* DamageReportBoundingBox there may be drawing between the last
|
||||
* damage event and the XDamageSubtract() that needs to be
|
||||
* flushed as well.
|
||||
*
|
||||
* Xorg always makes sure that drawing is flushed to the kernel
|
||||
* before writing events or responses to the client, so any
|
||||
* round trip request at this point is sufficient to flush the
|
||||
* GLX buffers.
|
||||
*/
|
||||
XSync (compositor->display->xdisplay, False);
|
||||
|
||||
compositor->frame_has_updated_xsurfaces = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1165,11 +1115,7 @@ meta_compositor_new (MetaDisplay *display)
|
||||
{
|
||||
MetaCompositor *compositor;
|
||||
|
||||
if (!composite_at_least_version (display, 0, 3))
|
||||
return NULL;
|
||||
|
||||
compositor = g_new0 (MetaCompositor, 1);
|
||||
|
||||
compositor->display = display;
|
||||
|
||||
if (g_getenv("META_DISABLE_MIPMAPS"))
|
||||
|
||||
@@ -185,7 +185,7 @@ cullable_iface_init (MetaCullableInterface *iface)
|
||||
* meta_background_actor_get_clip_region:
|
||||
* @self: a #MetaBackgroundActor
|
||||
*
|
||||
* Return value (transfer full): a #cairo_region_t that represents the part of
|
||||
* Return value (transfer none): a #cairo_region_t that represents the part of
|
||||
* the background not obscured by other #MetaBackgroundActor or
|
||||
* #MetaWindowActor objects.
|
||||
*/
|
||||
@@ -193,24 +193,5 @@ cairo_region_t *
|
||||
meta_background_actor_get_clip_region (MetaBackgroundActor *self)
|
||||
{
|
||||
MetaBackgroundActorPrivate *priv = self->priv;
|
||||
ClutterActorBox content_box;
|
||||
cairo_rectangle_int_t content_area = { 0 };
|
||||
cairo_region_t *clip_region;
|
||||
|
||||
g_return_val_if_fail (META_IS_BACKGROUND_ACTOR (self), NULL);
|
||||
|
||||
if (!priv->clip_region)
|
||||
return NULL;
|
||||
|
||||
clutter_actor_get_content_box (CLUTTER_ACTOR (self), &content_box);
|
||||
|
||||
content_area.x = content_box.x1;
|
||||
content_area.y = content_box.y1;
|
||||
content_area.width = content_box.x2 - content_box.x1;
|
||||
content_area.height = content_box.y2 - content_box.y1;
|
||||
|
||||
clip_region = cairo_region_create_rectangle (&content_area);
|
||||
cairo_region_intersect (clip_region, priv->clip_region);
|
||||
|
||||
return clip_region;
|
||||
return priv->clip_region;
|
||||
}
|
||||
|
||||
@@ -288,6 +288,26 @@ get_wrap_mode (MetaBackground *self)
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
texture_has_alpha (CoglTexture *texture)
|
||||
{
|
||||
if (!texture)
|
||||
return FALSE;
|
||||
|
||||
switch (cogl_texture_get_components (texture))
|
||||
{
|
||||
case COGL_TEXTURE_COMPONENTS_A:
|
||||
case COGL_TEXTURE_COMPONENTS_RGBA:
|
||||
return TRUE;
|
||||
case COGL_TEXTURE_COMPONENTS_RG:
|
||||
case COGL_TEXTURE_COMPONENTS_RGB:
|
||||
case COGL_TEXTURE_COMPONENTS_DEPTH:
|
||||
return FALSE;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static ClutterPaintNode *
|
||||
meta_background_paint_node_new (MetaBackground *self,
|
||||
ClutterActor *actor)
|
||||
@@ -296,6 +316,7 @@ meta_background_paint_node_new (MetaBackground *self,
|
||||
ClutterPaintNode *node;
|
||||
guint8 opacity;
|
||||
guint8 color_component;
|
||||
gboolean needs_blending;
|
||||
|
||||
opacity = clutter_actor_get_paint_opacity (actor);
|
||||
color_component = (guint8) (0.5 + opacity * priv->brightness);
|
||||
@@ -308,6 +329,13 @@ meta_background_paint_node_new (MetaBackground *self,
|
||||
|
||||
node = clutter_pipeline_node_new (priv->pipeline);
|
||||
|
||||
needs_blending = (opacity < 255) || (texture_has_alpha (priv->texture));
|
||||
|
||||
if (needs_blending)
|
||||
cogl_pipeline_set_blend (priv->pipeline, "RGBA = ADD (SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))", NULL);
|
||||
else
|
||||
cogl_pipeline_set_blend (priv->pipeline, "RGBA = ADD (SRC_COLOR, 0)", NULL);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -382,8 +410,6 @@ meta_background_paint_content (ClutterContent *content,
|
||||
if (priv->texture == NULL)
|
||||
return;
|
||||
|
||||
node = meta_background_paint_node_new (self, actor);
|
||||
|
||||
clutter_actor_get_content_box (actor, &actor_box);
|
||||
|
||||
/* First figure out where on the monitor the texture is supposed to be painted.
|
||||
@@ -413,12 +439,14 @@ meta_background_paint_content (ClutterContent *content,
|
||||
clip_region = meta_background_actor_get_clip_region (META_BACKGROUND_ACTOR (actor));
|
||||
|
||||
if (clip_region != NULL)
|
||||
{
|
||||
cairo_region_intersect (paintable_region, clip_region);
|
||||
cairo_region_destroy (clip_region);
|
||||
}
|
||||
cairo_region_intersect (paintable_region, clip_region);
|
||||
}
|
||||
|
||||
if (cairo_region_is_empty (paintable_region))
|
||||
goto out;
|
||||
|
||||
node = meta_background_paint_node_new (self, actor);
|
||||
|
||||
/* Finally, split the paintable region up into distinct areas
|
||||
* and paint each area one by one
|
||||
*/
|
||||
@@ -441,10 +469,11 @@ meta_background_paint_content (ClutterContent *content,
|
||||
|
||||
clutter_paint_node_add_texture_rectangle (node, &texture_rectangle, tx1, ty1, tx2, ty2);
|
||||
}
|
||||
cairo_region_destroy (paintable_region);
|
||||
|
||||
clutter_paint_node_add_child (root, node);
|
||||
clutter_paint_node_unref (node);
|
||||
|
||||
out:
|
||||
cairo_region_destroy (paintable_region);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -498,7 +527,8 @@ set_brightness (MetaBackground *self,
|
||||
|
||||
priv->brightness = brightness;
|
||||
|
||||
if (priv->effects & META_BACKGROUND_EFFECTS_VIGNETTE)
|
||||
if (clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL) &&
|
||||
priv->effects & META_BACKGROUND_EFFECTS_VIGNETTE)
|
||||
{
|
||||
ensure_pipeline (self);
|
||||
cogl_pipeline_set_uniform_1f (priv->pipeline,
|
||||
@@ -506,6 +536,14 @@ set_brightness (MetaBackground *self,
|
||||
"brightness"),
|
||||
priv->brightness);
|
||||
}
|
||||
else
|
||||
{
|
||||
ensure_pipeline (self);
|
||||
CoglColor blend_color;
|
||||
cogl_color_init_from_4f (&blend_color, brightness, brightness, brightness, 1.0);
|
||||
cogl_pipeline_set_layer_combine (priv->pipeline, 1, "RGB=MODULATE(PREVIOUS, CONSTANT) A=REPLACE(PREVIOUS)", NULL);
|
||||
cogl_pipeline_set_layer_combine_constant (priv->pipeline, 1, &blend_color);
|
||||
}
|
||||
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (self));
|
||||
|
||||
@@ -523,6 +561,9 @@ set_vignette_sharpness (MetaBackground *self,
|
||||
|
||||
priv->vignette_sharpness = sharpness;
|
||||
|
||||
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
||||
return;
|
||||
|
||||
if (priv->effects & META_BACKGROUND_EFFECTS_VIGNETTE)
|
||||
{
|
||||
ensure_pipeline (self);
|
||||
@@ -543,6 +584,9 @@ add_vignette (MetaBackground *self)
|
||||
MetaBackgroundPrivate *priv = self->priv;
|
||||
static CoglSnippet *snippet = NULL;
|
||||
|
||||
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
||||
return;
|
||||
|
||||
ensure_pipeline (self);
|
||||
|
||||
/* Cogl automatically caches pipelines with no eviction policy,
|
||||
@@ -770,6 +814,8 @@ meta_background_load_gradient (MetaBackground *self,
|
||||
ClutterColor *color,
|
||||
ClutterColor *second_color)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
|
||||
MetaBackgroundPrivate *priv = self->priv;
|
||||
CoglTexture *texture;
|
||||
guint width, height;
|
||||
@@ -799,18 +845,17 @@ meta_background_load_gradient (MetaBackground *self,
|
||||
pixels[0] = color->red;
|
||||
pixels[1] = color->green;
|
||||
pixels[2] = color->blue;
|
||||
pixels[3] = color->alpha;
|
||||
pixels[3] = 0xFF;
|
||||
pixels[4] = second_color->red;
|
||||
pixels[5] = second_color->green;
|
||||
pixels[6] = second_color->blue;
|
||||
pixels[7] = second_color->alpha;
|
||||
pixels[7] = 0xFF;
|
||||
|
||||
texture = cogl_texture_new_from_data (width, height,
|
||||
COGL_TEXTURE_NO_SLICING,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
4,
|
||||
pixels);
|
||||
texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, width, height,
|
||||
COGL_PIXEL_FORMAT_RGB_888,
|
||||
4,
|
||||
pixels,
|
||||
NULL));
|
||||
set_texture (self, COGL_TEXTURE (texture));
|
||||
}
|
||||
|
||||
@@ -828,10 +873,13 @@ void
|
||||
meta_background_load_color (MetaBackground *self,
|
||||
ClutterColor *color)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
|
||||
MetaBackgroundPrivate *priv = self->priv;
|
||||
CoglTexture *texture;
|
||||
ClutterActor *stage = meta_get_stage_for_screen (priv->screen);
|
||||
ClutterColor stage_color;
|
||||
uint8_t pixels[4];
|
||||
|
||||
ensure_pipeline (self);
|
||||
|
||||
@@ -844,11 +892,16 @@ meta_background_load_color (MetaBackground *self,
|
||||
color = &stage_color;
|
||||
}
|
||||
|
||||
texture = meta_create_color_texture_4ub (color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
0xff,
|
||||
COGL_TEXTURE_NO_SLICING);
|
||||
pixels[0] = color->red;
|
||||
pixels[1] = color->green;
|
||||
pixels[2] = color->blue;
|
||||
pixels[3] = 0xFF;
|
||||
|
||||
texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, 1, 1,
|
||||
COGL_PIXEL_FORMAT_RGB_888,
|
||||
4,
|
||||
pixels,
|
||||
NULL));
|
||||
set_texture (self, COGL_TEXTURE (texture));
|
||||
}
|
||||
|
||||
@@ -946,6 +999,8 @@ meta_background_load_file_finish (MetaBackground *self,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
|
||||
GTask *task;
|
||||
LoadFileTaskData *task_data;
|
||||
CoglTexture *texture;
|
||||
@@ -954,6 +1009,7 @@ meta_background_load_file_finish (MetaBackground *self,
|
||||
guchar *pixels;
|
||||
gboolean has_alpha;
|
||||
gboolean loaded = FALSE;
|
||||
CoglPixelFormat pixel_format;
|
||||
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), FALSE);
|
||||
|
||||
@@ -972,15 +1028,13 @@ meta_background_load_file_finish (MetaBackground *self,
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
|
||||
|
||||
texture = cogl_texture_new_from_data (width,
|
||||
height,
|
||||
COGL_TEXTURE_NO_ATLAS,
|
||||
has_alpha ?
|
||||
COGL_PIXEL_FORMAT_RGBA_8888 :
|
||||
COGL_PIXEL_FORMAT_RGB_888,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
row_stride,
|
||||
pixels);
|
||||
pixel_format = has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888;
|
||||
|
||||
texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, width, height,
|
||||
pixel_format,
|
||||
row_stride,
|
||||
pixels,
|
||||
NULL));
|
||||
|
||||
if (texture == NULL)
|
||||
{
|
||||
|
||||
@@ -170,6 +170,15 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
|
||||
klass->minimize (plugin, actor);
|
||||
}
|
||||
break;
|
||||
case META_PLUGIN_UNMINIMIZE:
|
||||
if (klass->unminimize)
|
||||
{
|
||||
retval = TRUE;
|
||||
meta_plugin_manager_kill_window_effects (plugin_mgr,
|
||||
actor);
|
||||
klass->unminimize (plugin, actor);
|
||||
}
|
||||
break;
|
||||
case META_PLUGIN_MAP:
|
||||
if (klass->map)
|
||||
{
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#define META_PLUGIN_MAP (1<<3)
|
||||
#define META_PLUGIN_DESTROY (1<<4)
|
||||
#define META_PLUGIN_SWITCH_WORKSPACE (1<<5)
|
||||
#define META_PLUGIN_UNMINIMIZE (1<<6)
|
||||
|
||||
#define META_PLUGIN_ALL_EFFECTS (~0)
|
||||
|
||||
|
||||
@@ -110,6 +110,13 @@ meta_plugin_minimize_completed (MetaPlugin *plugin,
|
||||
meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_MINIMIZE);
|
||||
}
|
||||
|
||||
void
|
||||
meta_plugin_unminimize_completed (MetaPlugin *plugin,
|
||||
MetaWindowActor *actor)
|
||||
{
|
||||
meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_UNMINIMIZE);
|
||||
}
|
||||
|
||||
void
|
||||
meta_plugin_maximize_completed (MetaPlugin *plugin,
|
||||
MetaWindowActor *actor)
|
||||
|
||||
@@ -541,7 +541,7 @@ blur_xspan (guchar *row,
|
||||
* be well predicted and there are enough different possibilities
|
||||
* that trying to write this as a series of unconditional loops
|
||||
* is hard and not an obvious win. The main slow down here seems
|
||||
* to be the integer division for pixel; one possible optimization
|
||||
* to be the integer division per pixel; one possible optimization
|
||||
* would be to accumulate into two 16-bit integer buffers and
|
||||
* only divide down after all three passes. (SSE parallel implementation
|
||||
* of the divide step is possible.)
|
||||
@@ -549,27 +549,27 @@ blur_xspan (guchar *row,
|
||||
for (i = x0 - d + offset; i < x1 + offset; i++)
|
||||
{
|
||||
if (i >= 0 && i < row_width)
|
||||
sum += row[i];
|
||||
sum += row[i];
|
||||
|
||||
if (i >= x0 + offset)
|
||||
{
|
||||
if (i >= d)
|
||||
sum -= row[i - d];
|
||||
{
|
||||
if (i >= d)
|
||||
sum -= row[i - d];
|
||||
|
||||
tmp_buffer[i - offset] = (sum + d / 2) / d;
|
||||
}
|
||||
tmp_buffer[i - offset] = (sum + d / 2) / d;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(row + x0, tmp_buffer + x0, x1 - x0);
|
||||
memcpy (row + x0, tmp_buffer + x0, x1 - x0);
|
||||
}
|
||||
|
||||
static void
|
||||
blur_rows (cairo_region_t *convolve_region,
|
||||
int x_offset,
|
||||
int y_offset,
|
||||
guchar *buffer,
|
||||
int buffer_width,
|
||||
int buffer_height,
|
||||
guchar *buffer,
|
||||
int buffer_width,
|
||||
int buffer_height,
|
||||
int d)
|
||||
{
|
||||
int i, j;
|
||||
@@ -586,30 +586,30 @@ blur_rows (cairo_region_t *convolve_region,
|
||||
cairo_region_get_rectangle (convolve_region, i, &rect);
|
||||
|
||||
for (j = y_offset + rect.y; j < y_offset + rect.y + rect.height; j++)
|
||||
{
|
||||
guchar *row = buffer + j * buffer_width;
|
||||
int x0 = x_offset + rect.x;
|
||||
int x1 = x0 + rect.width;
|
||||
{
|
||||
guchar *row = buffer + j * buffer_width;
|
||||
int x0 = x_offset + rect.x;
|
||||
int x1 = x0 + rect.width;
|
||||
|
||||
/* We want to produce a symmetric blur that spreads a pixel
|
||||
* equally far to the left and right. If d is odd that happens
|
||||
* naturally, but for d even, we approximate by using a blur
|
||||
* on either side and then a centered blur of size d + 1.
|
||||
* (techique also from the SVG specification)
|
||||
* (technique also from the SVG specification)
|
||||
*/
|
||||
if (d % 2 == 1)
|
||||
{
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 1);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, -1);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d + 1, 0);
|
||||
}
|
||||
}
|
||||
if (d % 2 == 1)
|
||||
{
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 1);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, -1);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d + 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_free (tmp_buffer);
|
||||
@@ -634,7 +634,7 @@ fade_bytes (guchar *bytes,
|
||||
*/
|
||||
static guchar *
|
||||
flip_buffer (guchar *buffer,
|
||||
int width,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
/* Working in blocks increases cache efficiency, compared to reading
|
||||
@@ -646,33 +646,33 @@ flip_buffer (guchar *buffer,
|
||||
int i0, j0;
|
||||
|
||||
for (j0 = 0; j0 < height; j0 += BLOCK_SIZE)
|
||||
for (i0 = 0; i0 <= j0; i0 += BLOCK_SIZE)
|
||||
{
|
||||
int max_j = MIN(j0 + BLOCK_SIZE, height);
|
||||
int max_i = MIN(i0 + BLOCK_SIZE, width);
|
||||
int i, j;
|
||||
for (i0 = 0; i0 <= j0; i0 += BLOCK_SIZE)
|
||||
{
|
||||
int max_j = MIN(j0 + BLOCK_SIZE, height);
|
||||
int max_i = MIN(i0 + BLOCK_SIZE, width);
|
||||
int i, j;
|
||||
|
||||
if (i0 == j0)
|
||||
{
|
||||
for (j = j0; j < max_j; j++)
|
||||
for (i = i0; i < j; i++)
|
||||
{
|
||||
guchar tmp = buffer[j * width + i];
|
||||
buffer[j * width + i] = buffer[i * width + j];
|
||||
buffer[i * width + j] = tmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = j0; j < max_j; j++)
|
||||
for (i = i0; i < max_i; i++)
|
||||
{
|
||||
guchar tmp = buffer[j * width + i];
|
||||
buffer[j * width + i] = buffer[i * width + j];
|
||||
buffer[i * width + j] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i0 == j0)
|
||||
{
|
||||
for (j = j0; j < max_j; j++)
|
||||
for (i = i0; i < j; i++)
|
||||
{
|
||||
guchar tmp = buffer[j * width + i];
|
||||
buffer[j * width + i] = buffer[i * width + j];
|
||||
buffer[i * width + j] = tmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = j0; j < max_j; j++)
|
||||
for (i = i0; i < max_i; i++)
|
||||
{
|
||||
guchar tmp = buffer[j * width + i];
|
||||
buffer[j * width + i] = buffer[i * width + j];
|
||||
buffer[i * width + j] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
@@ -683,15 +683,15 @@ flip_buffer (guchar *buffer,
|
||||
|
||||
for (i0 = 0; i0 < width; i0 += BLOCK_SIZE)
|
||||
for (j0 = 0; j0 < height; j0 += BLOCK_SIZE)
|
||||
{
|
||||
int max_j = MIN(j0 + BLOCK_SIZE, height);
|
||||
int max_i = MIN(i0 + BLOCK_SIZE, width);
|
||||
int i, j;
|
||||
{
|
||||
int max_j = MIN(j0 + BLOCK_SIZE, height);
|
||||
int max_i = MIN(i0 + BLOCK_SIZE, width);
|
||||
int i, j;
|
||||
|
||||
for (i = i0; i < max_i; i++)
|
||||
for (j = j0; j < max_j; j++)
|
||||
new_buffer[i * height + j] = buffer[j * width + i];
|
||||
}
|
||||
new_buffer[i * height + j] = buffer[j * width + i];
|
||||
}
|
||||
|
||||
g_free (buffer);
|
||||
|
||||
@@ -704,6 +704,8 @@ static void
|
||||
make_shadow (MetaShadow *shadow,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
|
||||
int d = get_box_filter_size (shadow->key.radius);
|
||||
int spread = get_shadow_spread (shadow->key.radius);
|
||||
cairo_rectangle_int_t extents;
|
||||
@@ -763,7 +765,7 @@ make_shadow (MetaShadow *shadow,
|
||||
|
||||
cairo_region_get_rectangle (region, k, &rect);
|
||||
for (j = y_offset + rect.y; j < y_offset + rect.y + rect.height; j++)
|
||||
memset (buffer + buffer_width * j + x_offset + rect.x, 255, rect.width);
|
||||
memset (buffer + buffer_width * j + x_offset + rect.x, 255, rect.width);
|
||||
}
|
||||
|
||||
/* Step 2: swap rows and columns */
|
||||
@@ -793,15 +795,15 @@ make_shadow (MetaShadow *shadow,
|
||||
* in the case of top_fade >= 0. We also account for padding at the left for symmetry
|
||||
* though that doesn't currently occur.
|
||||
*/
|
||||
shadow->texture = cogl_texture_new_from_data (shadow->outer_border_left + extents.width + shadow->outer_border_right,
|
||||
shadow->outer_border_top + extents.height + shadow->outer_border_bottom,
|
||||
COGL_TEXTURE_NONE,
|
||||
COGL_PIXEL_FORMAT_A_8,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
buffer_width,
|
||||
(buffer +
|
||||
(y_offset - shadow->outer_border_top) * buffer_width +
|
||||
(x_offset - shadow->outer_border_left)));
|
||||
shadow->texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx,
|
||||
shadow->outer_border_left + extents.width + shadow->outer_border_right,
|
||||
shadow->outer_border_top + extents.height + shadow->outer_border_bottom,
|
||||
COGL_PIXEL_FORMAT_A_8,
|
||||
buffer_width,
|
||||
(buffer +
|
||||
(y_offset - shadow->outer_border_top) * buffer_width +
|
||||
(x_offset - shadow->outer_border_left)),
|
||||
NULL));
|
||||
|
||||
cairo_region_destroy (row_convolve_region);
|
||||
cairo_region_destroy (column_convolve_region);
|
||||
|
||||
@@ -32,8 +32,6 @@
|
||||
ClutterActor *meta_shaped_texture_new (void);
|
||||
void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
|
||||
CoglTexture *texture);
|
||||
gboolean meta_shaped_texture_get_unobscured_bounds (MetaShapedTexture *stex,
|
||||
cairo_rectangle_int_t *unobscured_bounds);
|
||||
gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,16 +28,14 @@
|
||||
#include <config.h>
|
||||
|
||||
#include <meta/meta-shaped-texture.h>
|
||||
#include <meta/util.h>
|
||||
#include "meta-shaped-texture-private.h"
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
#include <gdk/gdk.h> /* for gdk_rectangle_intersect() */
|
||||
|
||||
#include "clutter-utils.h"
|
||||
#include "meta-texture-tower.h"
|
||||
|
||||
#include "meta-shaped-texture-private.h"
|
||||
#include "meta-window-actor-private.h"
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <gdk/gdk.h> /* for gdk_rectangle_intersect() */
|
||||
#include "meta-cullable.h"
|
||||
|
||||
static void meta_shaped_texture_dispose (GObject *object);
|
||||
@@ -65,6 +63,14 @@ G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_AC
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_SHAPED_TEXTURE, \
|
||||
MetaShapedTexturePrivate))
|
||||
|
||||
enum {
|
||||
SIZE_CHANGED,
|
||||
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
struct _MetaShapedTexturePrivate
|
||||
{
|
||||
MetaTextureTower *paint_tower;
|
||||
@@ -97,6 +103,13 @@ meta_shaped_texture_class_init (MetaShapedTextureClass *klass)
|
||||
actor_class->paint = meta_shaped_texture_paint;
|
||||
actor_class->get_paint_volume = meta_shaped_texture_get_paint_volume;
|
||||
|
||||
signals[SIZE_CHANGED] = g_signal_new ("size-changed",
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (MetaShapedTexturePrivate));
|
||||
}
|
||||
|
||||
@@ -249,22 +262,20 @@ set_cogl_texture (MetaShapedTexture *stex,
|
||||
cogl_object_ref (cogl_tex);
|
||||
width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex));
|
||||
height = cogl_texture_get_height (COGL_TEXTURE (cogl_tex));
|
||||
|
||||
if (width != priv->tex_width ||
|
||||
height != priv->tex_height)
|
||||
{
|
||||
priv->tex_width = width;
|
||||
priv->tex_height = height;
|
||||
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* size changed to 0 going to an invalid handle */
|
||||
priv->tex_width = 0;
|
||||
priv->tex_height = 0;
|
||||
width = 0;
|
||||
height = 0;
|
||||
}
|
||||
|
||||
if (priv->tex_width != width ||
|
||||
priv->tex_height != height)
|
||||
{
|
||||
priv->tex_width = width;
|
||||
priv->tex_height = height;
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
|
||||
g_signal_emit (stex, signals[SIZE_CHANGED], 0);
|
||||
}
|
||||
|
||||
/* NB: We don't queue a redraw of the actor here because we don't
|
||||
@@ -285,10 +296,8 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
guchar opacity;
|
||||
CoglContext *ctx;
|
||||
CoglFramebuffer *fb;
|
||||
CoglPipeline *pipeline = NULL;
|
||||
CoglTexture *paint_tex;
|
||||
ClutterActorBox alloc;
|
||||
cairo_region_t *blended_region = NULL;
|
||||
CoglPipelineFilter filter;
|
||||
|
||||
if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
|
||||
@@ -326,6 +335,8 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
if (tex_width == 0 || tex_height == 0) /* no contents yet */
|
||||
return;
|
||||
|
||||
cairo_rectangle_int_t tex_rect = { 0, 0, tex_width, tex_height };
|
||||
|
||||
/* Use nearest-pixel interpolation if the texture is unscaled. This
|
||||
* improves performance, especially with software rendering.
|
||||
*/
|
||||
@@ -341,7 +352,45 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
opacity = clutter_actor_get_paint_opacity (actor);
|
||||
clutter_actor_get_allocation_box (actor, &alloc);
|
||||
|
||||
if (priv->opaque_region != NULL && opacity == 255)
|
||||
cairo_region_t *blended_region;
|
||||
gboolean use_opaque_region = (priv->opaque_region != NULL && opacity == 255);
|
||||
|
||||
if (use_opaque_region)
|
||||
{
|
||||
if (priv->clip_region != NULL)
|
||||
blended_region = cairo_region_copy (priv->clip_region);
|
||||
else
|
||||
blended_region = cairo_region_create_rectangle (&tex_rect);
|
||||
|
||||
cairo_region_subtract (blended_region, priv->opaque_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (priv->clip_region != NULL)
|
||||
blended_region = cairo_region_reference (priv->clip_region);
|
||||
else
|
||||
blended_region = NULL;
|
||||
}
|
||||
|
||||
/* Limit to how many separate rectangles we'll draw; beyond this just
|
||||
* fall back and draw the whole thing */
|
||||
#define MAX_RECTS 16
|
||||
|
||||
if (blended_region != NULL)
|
||||
{
|
||||
int n_rects = cairo_region_num_rectangles (blended_region);
|
||||
if (n_rects > MAX_RECTS)
|
||||
{
|
||||
/* Fall back to taking the fully blended path. */
|
||||
use_opaque_region = FALSE;
|
||||
|
||||
cairo_region_destroy (blended_region);
|
||||
blended_region = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* First, paint the unblended parts, which are part of the opaque region. */
|
||||
if (use_opaque_region)
|
||||
{
|
||||
CoglPipeline *opaque_pipeline;
|
||||
cairo_region_t *region;
|
||||
@@ -358,103 +407,87 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
region = cairo_region_reference (priv->opaque_region);
|
||||
}
|
||||
|
||||
if (cairo_region_is_empty (region))
|
||||
goto paint_blended;
|
||||
|
||||
opaque_pipeline = get_unblended_pipeline (ctx);
|
||||
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
|
||||
cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
|
||||
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
for (i = 0; i < n_rects; i++)
|
||||
if (!cairo_region_is_empty (region))
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
paint_clipped_rectangle (fb, opaque_pipeline, &rect, &alloc);
|
||||
opaque_pipeline = get_unblended_pipeline (ctx);
|
||||
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
|
||||
cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
|
||||
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
paint_clipped_rectangle (fb, opaque_pipeline, &rect, &alloc);
|
||||
}
|
||||
|
||||
cogl_object_unref (opaque_pipeline);
|
||||
}
|
||||
|
||||
cogl_object_unref (opaque_pipeline);
|
||||
|
||||
if (priv->clip_region != NULL)
|
||||
{
|
||||
blended_region = cairo_region_copy (priv->clip_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_rectangle_int_t rect = { 0, 0, tex_width, tex_height };
|
||||
blended_region = cairo_region_create_rectangle (&rect);
|
||||
}
|
||||
|
||||
cairo_region_subtract (blended_region, priv->opaque_region);
|
||||
|
||||
paint_blended:
|
||||
cairo_region_destroy (region);
|
||||
}
|
||||
|
||||
if (blended_region == NULL && priv->clip_region != NULL)
|
||||
blended_region = cairo_region_reference (priv->clip_region);
|
||||
/* Now, go ahead and paint the blended parts. */
|
||||
|
||||
if (blended_region != NULL && cairo_region_is_empty (blended_region))
|
||||
goto out;
|
||||
|
||||
if (priv->mask_texture == NULL)
|
||||
/* We have three cases:
|
||||
* 1) blended_region has rectangles - paint the rectangles.
|
||||
* 2) blended_region is empty - don't paint anything
|
||||
* 3) blended_region is NULL - paint fully-blended.
|
||||
*
|
||||
* 1) and 3) are the times where we have to paint stuff. This tests
|
||||
* for 1) and 3).
|
||||
*/
|
||||
if (blended_region == NULL || !cairo_region_is_empty (blended_region))
|
||||
{
|
||||
pipeline = get_unmasked_pipeline (ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
pipeline = get_masked_pipeline (ctx);
|
||||
cogl_pipeline_set_layer_texture (pipeline, 1, priv->mask_texture);
|
||||
cogl_pipeline_set_layer_filters (pipeline, 1, filter, filter);
|
||||
}
|
||||
CoglPipeline *blended_pipeline;
|
||||
|
||||
cogl_pipeline_set_layer_texture (pipeline, 0, paint_tex);
|
||||
cogl_pipeline_set_layer_filters (pipeline, 0, filter, filter);
|
||||
if (priv->mask_texture == NULL)
|
||||
{
|
||||
blended_pipeline = get_unmasked_pipeline (ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
blended_pipeline = get_masked_pipeline (ctx);
|
||||
cogl_pipeline_set_layer_texture (blended_pipeline, 1, priv->mask_texture);
|
||||
cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
|
||||
}
|
||||
|
||||
{
|
||||
CoglColor color;
|
||||
cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
|
||||
cogl_pipeline_set_color (pipeline, &color);
|
||||
}
|
||||
cogl_pipeline_set_layer_texture (blended_pipeline, 0, paint_tex);
|
||||
cogl_pipeline_set_layer_filters (blended_pipeline, 0, filter, filter);
|
||||
|
||||
if (blended_region != NULL)
|
||||
{
|
||||
int n_rects;
|
||||
CoglColor color;
|
||||
cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
|
||||
cogl_pipeline_set_color (blended_pipeline, &color);
|
||||
|
||||
/* Limit to how many separate rectangles we'll draw; beyond this just
|
||||
* fall back and draw the whole thing */
|
||||
# define MAX_RECTS 16
|
||||
|
||||
n_rects = cairo_region_num_rectangles (blended_region);
|
||||
if (n_rects <= MAX_RECTS)
|
||||
{
|
||||
if (blended_region != NULL)
|
||||
{
|
||||
/* 1) blended_region is not empty. Paint the rectangles. */
|
||||
int i;
|
||||
cairo_rectangle_int_t tex_rect = { 0, 0, tex_width, tex_height };
|
||||
int n_rects = cairo_region_num_rectangles (blended_region);
|
||||
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_region_get_rectangle (blended_region, i, &rect);
|
||||
|
||||
cairo_region_get_rectangle (blended_region, i, &rect);
|
||||
if (!gdk_rectangle_intersect (&tex_rect, &rect, &rect))
|
||||
continue;
|
||||
|
||||
if (!gdk_rectangle_intersect (&tex_rect, &rect, &rect))
|
||||
continue;
|
||||
|
||||
paint_clipped_rectangle (fb, pipeline, &rect, &alloc);
|
||||
paint_clipped_rectangle (fb, blended_pipeline, &rect, &alloc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 3) blended_region is NULL. Do a full paint. */
|
||||
cogl_framebuffer_draw_rectangle (fb, blended_pipeline,
|
||||
0, 0,
|
||||
alloc.x2 - alloc.x1,
|
||||
alloc.y2 - alloc.y1);
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
cogl_object_unref (blended_pipeline);
|
||||
}
|
||||
|
||||
cogl_framebuffer_draw_rectangle (fb, pipeline,
|
||||
0, 0,
|
||||
alloc.x2 - alloc.x1,
|
||||
alloc.y2 - alloc.y1);
|
||||
|
||||
out:
|
||||
if (pipeline != NULL)
|
||||
cogl_object_unref (pipeline);
|
||||
if (blended_region != NULL)
|
||||
cairo_region_destroy (blended_region);
|
||||
}
|
||||
@@ -472,7 +505,7 @@ meta_shaped_texture_get_preferred_width (ClutterActor *self,
|
||||
priv = META_SHAPED_TEXTURE (self)->priv;
|
||||
|
||||
if (min_width_p)
|
||||
*min_width_p = 0;
|
||||
*min_width_p = priv->tex_width;
|
||||
|
||||
if (natural_width_p)
|
||||
*natural_width_p = priv->tex_width;
|
||||
@@ -491,43 +524,70 @@ meta_shaped_texture_get_preferred_height (ClutterActor *self,
|
||||
priv = META_SHAPED_TEXTURE (self)->priv;
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p = 0;
|
||||
*min_height_p = priv->tex_height;
|
||||
|
||||
if (natural_height_p)
|
||||
*natural_height_p = priv->tex_height;
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
effective_unobscured_region (MetaShapedTexture *self)
|
||||
{
|
||||
MetaShapedTexturePrivate *priv = self->priv;
|
||||
ClutterActor *actor;
|
||||
|
||||
/* Fail if we have any mapped clones. */
|
||||
actor = CLUTTER_ACTOR (self);
|
||||
do
|
||||
{
|
||||
if (clutter_actor_has_mapped_clones (actor))
|
||||
return NULL;
|
||||
actor = clutter_actor_get_parent (actor);
|
||||
}
|
||||
while (actor != NULL);
|
||||
|
||||
return priv->unobscured_region;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_unobscured_bounds (MetaShapedTexture *self,
|
||||
cairo_rectangle_int_t *unobscured_bounds)
|
||||
{
|
||||
cairo_region_t *unobscured_region = effective_unobscured_region (self);
|
||||
|
||||
if (unobscured_region)
|
||||
{
|
||||
cairo_region_get_extents (unobscured_region, unobscured_bounds);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_shaped_texture_get_paint_volume (ClutterActor *actor,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
MetaShapedTexture *self = META_SHAPED_TEXTURE (actor);
|
||||
ClutterActorBox box;
|
||||
cairo_rectangle_int_t unobscured_bounds;
|
||||
|
||||
if (!clutter_paint_volume_set_from_allocation (volume, actor))
|
||||
if (!clutter_actor_has_allocation (actor))
|
||||
return FALSE;
|
||||
|
||||
if (meta_shaped_texture_get_unobscured_bounds (self, &unobscured_bounds))
|
||||
clutter_actor_get_allocation_box (actor, &box);
|
||||
|
||||
if (get_unobscured_bounds (self, &unobscured_bounds))
|
||||
{
|
||||
ClutterVertex origin;
|
||||
cairo_rectangle_int_t bounds;
|
||||
|
||||
/* I hate ClutterPaintVolume so much... */
|
||||
clutter_paint_volume_get_origin (volume, &origin);
|
||||
bounds.x = origin.x;
|
||||
bounds.y = origin.y;
|
||||
bounds.width = clutter_paint_volume_get_width (volume);
|
||||
bounds.height = clutter_paint_volume_get_height (volume);
|
||||
|
||||
gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds);
|
||||
|
||||
origin.x = bounds.x;
|
||||
origin.y = bounds.y;
|
||||
clutter_paint_volume_set_origin (volume, &origin);
|
||||
clutter_paint_volume_set_width (volume, bounds.width);
|
||||
clutter_paint_volume_set_height (volume, bounds.height);
|
||||
box.x1 = MAX (unobscured_bounds.x, box.x1);
|
||||
box.x2 = MIN (unobscured_bounds.x + unobscured_bounds.width, box.x2);
|
||||
box.y1 = MAX (unobscured_bounds.y, box.y1);
|
||||
box.y2 = MIN (unobscured_bounds.y + unobscured_bounds.height, box.y2);
|
||||
}
|
||||
box.x2 = MAX (box.x2, box.x1);
|
||||
box.y2 = MAX (box.y2, box.y1);
|
||||
|
||||
clutter_paint_volume_union_box (volume, &box);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -573,39 +633,6 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
effective_unobscured_region (MetaShapedTexture *self)
|
||||
{
|
||||
MetaShapedTexturePrivate *priv = self->priv;
|
||||
ClutterActor *parent = clutter_actor_get_parent (CLUTTER_ACTOR (self));
|
||||
|
||||
if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (self)))
|
||||
return NULL;
|
||||
|
||||
while (parent && !META_IS_WINDOW_ACTOR (parent))
|
||||
parent = clutter_actor_get_parent (parent);
|
||||
|
||||
if (parent && clutter_actor_has_mapped_clones (parent))
|
||||
return NULL;
|
||||
|
||||
return priv->unobscured_region;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_shaped_texture_get_unobscured_bounds (MetaShapedTexture *self,
|
||||
cairo_rectangle_int_t *unobscured_bounds)
|
||||
{
|
||||
cairo_region_t *unobscured_region = effective_unobscured_region (self);
|
||||
|
||||
if (unobscured_region)
|
||||
{
|
||||
cairo_region_get_extents (unobscured_region, unobscured_bounds);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_shaped_texture_is_obscured (MetaShapedTexture *self)
|
||||
{
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "meta-stage.h"
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include "meta-backend.h"
|
||||
#include <meta/util.h>
|
||||
|
||||
struct _MetaStagePrivate {
|
||||
CoglPipeline *pipeline;
|
||||
gboolean should_paint_cursor;
|
||||
|
||||
MetaCursorReference *cursor;
|
||||
|
||||
MetaRectangle current_rect;
|
||||
MetaRectangle previous_rect;
|
||||
gboolean previous_is_valid;
|
||||
};
|
||||
typedef struct _MetaStagePrivate MetaStagePrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaStage, meta_stage, CLUTTER_TYPE_STAGE);
|
||||
|
||||
static void
|
||||
update_pipeline (MetaStage *stage)
|
||||
{
|
||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||
|
||||
if (priv->cursor)
|
||||
{
|
||||
CoglTexture *texture = meta_cursor_reference_get_cogl_texture (priv->cursor, NULL, NULL);
|
||||
cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture);
|
||||
}
|
||||
else
|
||||
cogl_pipeline_set_layer_texture (priv->pipeline, 0, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stage_finalize (GObject *object)
|
||||
{
|
||||
MetaStage *stage = META_STAGE (object);
|
||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||
|
||||
if (priv->pipeline)
|
||||
cogl_object_unref (priv->pipeline);
|
||||
}
|
||||
|
||||
static void
|
||||
paint_cursor (MetaStage *stage)
|
||||
{
|
||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
|
||||
if (!priv->cursor)
|
||||
return;
|
||||
|
||||
cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
|
||||
priv->pipeline,
|
||||
priv->current_rect.x,
|
||||
priv->current_rect.y,
|
||||
priv->current_rect.x +
|
||||
priv->current_rect.width,
|
||||
priv->current_rect.y +
|
||||
priv->current_rect.height);
|
||||
|
||||
priv->previous_rect = priv->current_rect;
|
||||
priv->previous_is_valid = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stage_paint (ClutterActor *actor)
|
||||
{
|
||||
MetaStage *stage = META_STAGE (actor);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
paint_cursor (stage);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stage_class_init (MetaStageClass *klass)
|
||||
{
|
||||
ClutterActorClass *actor_class = (ClutterActorClass *) klass;
|
||||
GObjectClass *object_class = (GObjectClass *) klass;
|
||||
|
||||
object_class->finalize = meta_stage_finalize;
|
||||
|
||||
actor_class->paint = meta_stage_paint;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stage_init (MetaStage *stage)
|
||||
{
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||
|
||||
priv->pipeline = cogl_pipeline_new (ctx);
|
||||
|
||||
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), FALSE);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
meta_stage_new (void)
|
||||
{
|
||||
return g_object_new (META_TYPE_STAGE,
|
||||
"cursor-visible", FALSE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
queue_redraw (MetaStage *stage)
|
||||
{
|
||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||
cairo_rectangle_int_t clip;
|
||||
|
||||
/* Clear the location the cursor was at before, if we need to. */
|
||||
if (priv->previous_is_valid)
|
||||
{
|
||||
clip.x = priv->previous_rect.x;
|
||||
clip.y = priv->previous_rect.y;
|
||||
clip.width = priv->previous_rect.width;
|
||||
clip.height = priv->previous_rect.height;
|
||||
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
|
||||
priv->previous_is_valid = FALSE;
|
||||
}
|
||||
|
||||
/* And queue a redraw for the current cursor location. */
|
||||
if (priv->cursor)
|
||||
{
|
||||
clip.x = priv->current_rect.x;
|
||||
clip.y = priv->current_rect.y;
|
||||
clip.width = priv->current_rect.width;
|
||||
clip.height = priv->current_rect.height;
|
||||
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_stage_set_cursor (MetaStage *stage,
|
||||
MetaCursorReference *cursor,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||
|
||||
if (priv->cursor != cursor)
|
||||
{
|
||||
priv->cursor = cursor;
|
||||
update_pipeline (stage);
|
||||
}
|
||||
|
||||
priv->current_rect = *rect;
|
||||
queue_redraw (stage);
|
||||
}
|
||||
@@ -34,45 +34,15 @@
|
||||
struct _MetaSurfaceActorWaylandPrivate
|
||||
{
|
||||
MetaWaylandSurface *surface;
|
||||
MetaWaylandBuffer *buffer;
|
||||
struct wl_listener buffer_destroy_listener;
|
||||
};
|
||||
typedef struct _MetaSurfaceActorWaylandPrivate MetaSurfaceActorWaylandPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaSurfaceActorWayland, meta_surface_actor_wayland, META_TYPE_SURFACE_ACTOR)
|
||||
|
||||
static void
|
||||
meta_surface_actor_handle_buffer_destroy (struct wl_listener *listener, void *data)
|
||||
{
|
||||
MetaSurfaceActorWaylandPrivate *priv = wl_container_of (listener, priv, buffer_destroy_listener);
|
||||
|
||||
/* If the buffer is destroyed while we're attached to it,
|
||||
* we want to unset priv->buffer so we don't access freed
|
||||
* memory. Keep the texture set however so the user doesn't
|
||||
* see the window disappear. */
|
||||
priv->buffer = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_process_damage (MetaSurfaceActor *actor,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
|
||||
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
|
||||
|
||||
if (priv->buffer)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
meta_surface_actor_update_area (META_SURFACE_ACTOR (self), x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -213,7 +183,7 @@ meta_surface_actor_wayland_dispose (GObject *object)
|
||||
{
|
||||
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (object);
|
||||
|
||||
meta_surface_actor_wayland_set_buffer (self, NULL);
|
||||
meta_surface_actor_wayland_set_texture (self, NULL);
|
||||
|
||||
G_OBJECT_CLASS (meta_surface_actor_wayland_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -244,9 +214,6 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
|
||||
static void
|
||||
meta_surface_actor_wayland_init (MetaSurfaceActorWayland *self)
|
||||
{
|
||||
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
|
||||
|
||||
priv->buffer_destroy_listener.notify = meta_surface_actor_handle_buffer_destroy;
|
||||
}
|
||||
|
||||
MetaSurfaceActor *
|
||||
@@ -263,24 +230,11 @@ meta_surface_actor_wayland_new (MetaWaylandSurface *surface)
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self,
|
||||
MetaWaylandBuffer *buffer)
|
||||
meta_surface_actor_wayland_set_texture (MetaSurfaceActorWayland *self,
|
||||
CoglTexture *texture)
|
||||
{
|
||||
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
|
||||
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||
|
||||
if (priv->buffer)
|
||||
wl_list_remove (&priv->buffer_destroy_listener.link);
|
||||
|
||||
priv->buffer = buffer;
|
||||
|
||||
if (priv->buffer)
|
||||
{
|
||||
wl_signal_add (&priv->buffer->destroy_signal, &priv->buffer_destroy_listener);
|
||||
meta_shaped_texture_set_texture (stex, priv->buffer->texture);
|
||||
}
|
||||
else
|
||||
meta_shaped_texture_set_texture (stex, NULL);
|
||||
meta_shaped_texture_set_texture (stex, texture);
|
||||
}
|
||||
|
||||
MetaWaylandSurface *
|
||||
|
||||
@@ -58,8 +58,8 @@ GType meta_surface_actor_wayland_get_type (void);
|
||||
MetaSurfaceActor * meta_surface_actor_wayland_new (MetaWaylandSurface *surface);
|
||||
MetaWaylandSurface * meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self);
|
||||
|
||||
void meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self,
|
||||
MetaWaylandBuffer *buffer);
|
||||
void meta_surface_actor_wayland_set_texture (MetaSurfaceActorWayland *self,
|
||||
CoglTexture *texture);
|
||||
|
||||
double meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor);
|
||||
|
||||
|
||||
@@ -179,19 +179,6 @@ is_visible (MetaSurfaceActorX11 *self)
|
||||
return (priv->pixmap != None) && !priv->unredirected;
|
||||
}
|
||||
|
||||
static void
|
||||
damage_area (MetaSurfaceActorX11 *self,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
|
||||
|
||||
if (!is_visible (self))
|
||||
return;
|
||||
|
||||
cogl_texture_pixmap_x11_update_area (priv->texture, x, y, width, height);
|
||||
meta_surface_actor_update_area (META_SURFACE_ACTOR (self), x, y, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
|
||||
int x, int y, int width, int height)
|
||||
@@ -218,11 +205,10 @@ meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
|
||||
priv->does_full_damage = TRUE;
|
||||
}
|
||||
|
||||
/* Drop damage event for unredirected windows */
|
||||
if (priv->unredirected)
|
||||
if (!is_visible (self))
|
||||
return;
|
||||
|
||||
damage_area (self, x, y, width, height);
|
||||
cogl_texture_pixmap_x11_update_area (priv->texture, x, y, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -239,26 +225,6 @@ meta_surface_actor_x11_pre_paint (MetaSurfaceActor *actor)
|
||||
XDamageSubtract (xdisplay, priv->damage, None, None);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
/* We need to make sure that any X drawing that happens before the
|
||||
* XDamageSubtract() above is visible to subsequent GL rendering;
|
||||
* the only standardized way to do this is EXT_x11_sync_object,
|
||||
* which isn't yet widely available. For now, we count on details
|
||||
* of Xorg and the open source drivers, and hope for the best
|
||||
* otherwise.
|
||||
*
|
||||
* Xorg and open source driver specifics:
|
||||
*
|
||||
* The X server makes sure to flush drawing to the kernel before
|
||||
* sending out damage events, but since we use DamageReportBoundingBox
|
||||
* there may be drawing between the last damage event and the
|
||||
* XDamageSubtract() that needs to be flushed as well.
|
||||
*
|
||||
* Xorg always makes sure that drawing is flushed to the kernel
|
||||
* before writing events or responses to the client, so any round trip
|
||||
* request at this point is sufficient to flush the GLX buffers.
|
||||
*/
|
||||
XSync (xdisplay, False);
|
||||
|
||||
priv->received_damage = FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,20 +36,13 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_
|
||||
|
||||
enum {
|
||||
REPAINT_SCHEDULED,
|
||||
SIZE_CHANGED,
|
||||
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
gboolean
|
||||
meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self,
|
||||
cairo_rectangle_int_t *unobscured_bounds)
|
||||
{
|
||||
MetaSurfaceActorPrivate *priv = self->priv;
|
||||
return meta_shaped_texture_get_unobscured_bounds (priv->texture, unobscured_bounds);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_pick (ClutterActor *actor,
|
||||
const ClutterColor *color)
|
||||
@@ -128,6 +121,13 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
signals[SIZE_CHANGED] = g_signal_new ("size-changed",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate));
|
||||
}
|
||||
|
||||
@@ -152,6 +152,14 @@ cullable_iface_init (MetaCullableInterface *iface)
|
||||
iface->reset_culling = meta_surface_actor_reset_culling;
|
||||
}
|
||||
|
||||
static void
|
||||
texture_size_changed (MetaShapedTexture *texture,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaSurfaceActor *actor = META_SURFACE_ACTOR (user_data);
|
||||
g_signal_emit (actor, signals[SIZE_CHANGED], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_init (MetaSurfaceActor *self)
|
||||
{
|
||||
@@ -162,6 +170,8 @@ meta_surface_actor_init (MetaSurfaceActor *self)
|
||||
MetaSurfaceActorPrivate);
|
||||
|
||||
priv->texture = META_SHAPED_TEXTURE (meta_shaped_texture_new ());
|
||||
g_signal_connect_object (priv->texture, "size-changed",
|
||||
G_CALLBACK (texture_size_changed), self, 0);
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->texture));
|
||||
}
|
||||
|
||||
@@ -178,7 +188,7 @@ meta_surface_actor_get_texture (MetaSurfaceActor *self)
|
||||
return self->priv->texture;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
meta_surface_actor_update_area (MetaSurfaceActor *self,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
@@ -252,6 +262,9 @@ meta_surface_actor_process_damage (MetaSurfaceActor *self,
|
||||
}
|
||||
|
||||
META_SURFACE_ACTOR_GET_CLASS (self)->process_damage (self, x, y, width, height);
|
||||
|
||||
if (meta_surface_actor_is_visible (self))
|
||||
meta_surface_actor_update_area (self, x, y, width, height);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -267,9 +280,15 @@ meta_surface_actor_is_argb32 (MetaSurfaceActor *self)
|
||||
CoglTexture *texture = meta_shaped_texture_get_texture (stex);
|
||||
|
||||
/* If we don't have a texture, like during initialization, assume
|
||||
* that we're ARGB32. */
|
||||
* that we're ARGB32.
|
||||
*
|
||||
* If we are unredirected and we have no texture assume that we are
|
||||
* not ARGB32 otherwise we wouldn't be unredirected in the first
|
||||
* place. This prevents us from continually redirecting and
|
||||
* unredirecting on every paint.
|
||||
*/
|
||||
if (!texture)
|
||||
return TRUE;
|
||||
return !meta_surface_actor_is_unredirected (self);
|
||||
|
||||
switch (cogl_texture_get_components (texture))
|
||||
{
|
||||
|
||||
@@ -55,17 +55,12 @@ MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self);
|
||||
MetaWindow *meta_surface_actor_get_window (MetaSurfaceActor *self);
|
||||
|
||||
gboolean meta_surface_actor_is_obscured (MetaSurfaceActor *self);
|
||||
gboolean meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self,
|
||||
cairo_rectangle_int_t *unobscured_bounds);
|
||||
|
||||
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);
|
||||
|
||||
void meta_surface_actor_update_area (MetaSurfaceActor *actor,
|
||||
int x, int y, int width, int height);
|
||||
|
||||
void meta_surface_actor_process_damage (MetaSurfaceActor *actor,
|
||||
int x, int y, int width, int height);
|
||||
void meta_surface_actor_pre_paint (MetaSurfaceActor *actor);
|
||||
|
||||
@@ -378,8 +378,8 @@ texture_tower_create_texture (MetaTextureTower *tower,
|
||||
}
|
||||
|
||||
static void
|
||||
texture_tower_revalidate_fbo (MetaTextureTower *tower,
|
||||
int level)
|
||||
texture_tower_revalidate (MetaTextureTower *tower,
|
||||
int level)
|
||||
{
|
||||
CoglTexture *source_texture = tower->textures[level - 1];
|
||||
int source_texture_width = cogl_texture_get_width (source_texture);
|
||||
@@ -425,13 +425,9 @@ texture_tower_revalidate_fbo (MetaTextureTower *tower,
|
||||
(2. * invalid->y2) / source_texture_height);
|
||||
|
||||
cogl_object_unref (pipeline);
|
||||
}
|
||||
|
||||
static void
|
||||
texture_tower_revalidate (MetaTextureTower *tower,
|
||||
int level)
|
||||
{
|
||||
texture_tower_revalidate_fbo (tower, level);
|
||||
tower->invalid[level].x1 = tower->invalid[level].x2 = 0;
|
||||
tower->invalid[level].y1 = tower->invalid[level].y2 = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,9 +32,11 @@
|
||||
|
||||
#include "meta-surface-actor.h"
|
||||
#include "meta-surface-actor-x11.h"
|
||||
#include "meta-surface-actor-wayland.h"
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "meta-surface-actor-wayland.h"
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
INITIALLY_FROZEN,
|
||||
@@ -76,7 +78,7 @@ struct _MetaWindowActorPrivate
|
||||
gint64 frame_drawn_time;
|
||||
|
||||
guint repaint_scheduled_id;
|
||||
guint allocation_changed_id;
|
||||
guint size_changed_id;
|
||||
|
||||
/*
|
||||
* These need to be counters rather than flags, since more plugins
|
||||
@@ -84,6 +86,7 @@ struct _MetaWindowActorPrivate
|
||||
* might be dubious, but we have to at least handle it correctly.
|
||||
*/
|
||||
gint minimize_in_progress;
|
||||
gint unminimize_in_progress;
|
||||
gint maximize_in_progress;
|
||||
gint unmaximize_in_progress;
|
||||
gint map_in_progress;
|
||||
@@ -272,12 +275,11 @@ window_appears_focused_notify (MetaWindow *mw,
|
||||
}
|
||||
|
||||
static void
|
||||
surface_allocation_changed_notify (ClutterActor *actor,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags,
|
||||
MetaWindowActor *self)
|
||||
surface_size_changed (MetaSurfaceActor *actor,
|
||||
gpointer user_data)
|
||||
{
|
||||
meta_window_actor_sync_actor_geometry (self, FALSE);
|
||||
MetaWindowActor *self = META_WINDOW_ACTOR (user_data);
|
||||
|
||||
meta_window_actor_update_shape (self);
|
||||
}
|
||||
|
||||
@@ -369,9 +371,8 @@ set_surface (MetaWindowActor *self,
|
||||
if (priv->surface)
|
||||
{
|
||||
g_signal_handler_disconnect (priv->surface, priv->repaint_scheduled_id);
|
||||
g_signal_handler_disconnect (priv->surface, priv->size_changed_id);
|
||||
priv->repaint_scheduled_id = 0;
|
||||
g_signal_handler_disconnect (priv->surface, priv->allocation_changed_id);
|
||||
priv->allocation_changed_id = 0;
|
||||
clutter_actor_remove_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
|
||||
g_object_unref (priv->surface);
|
||||
}
|
||||
@@ -383,8 +384,8 @@ set_surface (MetaWindowActor *self,
|
||||
g_object_ref_sink (priv->surface);
|
||||
priv->repaint_scheduled_id = g_signal_connect (priv->surface, "repaint-scheduled",
|
||||
G_CALLBACK (surface_repaint_scheduled), self);
|
||||
priv->allocation_changed_id = g_signal_connect (priv->surface, "allocation-changed",
|
||||
G_CALLBACK (surface_allocation_changed_notify), self);
|
||||
priv->size_changed_id = g_signal_connect (priv->surface, "size-changed",
|
||||
G_CALLBACK (surface_size_changed), self);
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
|
||||
|
||||
/* If the previous surface actor was frozen, start out
|
||||
@@ -405,9 +406,12 @@ meta_window_actor_update_surface (MetaWindowActor *self)
|
||||
MetaWindow *window = priv->window;
|
||||
MetaSurfaceActor *surface_actor;
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (window->surface)
|
||||
surface_actor = window->surface->surface_actor;
|
||||
else if (!meta_is_wayland_compositor ())
|
||||
else
|
||||
#endif
|
||||
if (!meta_is_wayland_compositor ())
|
||||
surface_actor = meta_surface_actor_x11_new (window);
|
||||
else
|
||||
surface_actor = NULL;
|
||||
@@ -597,6 +601,7 @@ meta_window_actor_get_shape_bounds (MetaWindowActor *self,
|
||||
|
||||
cairo_region_get_extents (priv->shape_region, bounds);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (META_IS_SURFACE_ACTOR_WAYLAND (priv->surface))
|
||||
{
|
||||
double scale = priv->surface ?
|
||||
@@ -606,6 +611,7 @@ meta_window_actor_get_shape_bounds (MetaWindowActor *self,
|
||||
bounds->width *= scale;
|
||||
bounds->height *= scale;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -713,25 +719,16 @@ meta_window_actor_get_paint_volume (ClutterActor *actor,
|
||||
{
|
||||
MetaWindowActor *self = META_WINDOW_ACTOR (actor);
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
cairo_rectangle_int_t unobscured_bounds, bounds;
|
||||
gboolean appears_focused = meta_window_appears_focused (priv->window);
|
||||
ClutterVertex origin;
|
||||
|
||||
/* The paint volume is computed before paint functions are called
|
||||
* so our bounds might not be updated yet. Force an update. */
|
||||
meta_window_actor_handle_updates (self);
|
||||
|
||||
meta_window_actor_get_shape_bounds (self, &bounds);
|
||||
|
||||
if (priv->surface)
|
||||
{
|
||||
if (meta_surface_actor_get_unobscured_bounds (priv->surface, &unobscured_bounds))
|
||||
gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds);
|
||||
}
|
||||
|
||||
if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow)
|
||||
{
|
||||
cairo_rectangle_int_t shadow_bounds;
|
||||
ClutterActorBox shadow_box;
|
||||
|
||||
/* We could compute an full clip region as we do for the window
|
||||
* texture, but the shadow is relatively cheap to draw, and
|
||||
@@ -741,16 +738,24 @@ meta_window_actor_get_paint_volume (ClutterActor *actor,
|
||||
*/
|
||||
|
||||
meta_window_actor_get_shadow_bounds (self, appears_focused, &shadow_bounds);
|
||||
gdk_rectangle_union (&bounds, &shadow_bounds, &bounds);
|
||||
shadow_box.x1 = shadow_bounds.x;
|
||||
shadow_box.x2 = shadow_bounds.x + shadow_bounds.width;
|
||||
shadow_box.y1 = shadow_bounds.y;
|
||||
shadow_box.y2 = shadow_bounds.y + shadow_bounds.height;
|
||||
|
||||
clutter_paint_volume_union_box (volume, &shadow_box);
|
||||
}
|
||||
|
||||
origin.x = bounds.x;
|
||||
origin.y = bounds.y;
|
||||
origin.z = 0.0f;
|
||||
clutter_paint_volume_set_origin (volume, &origin);
|
||||
if (priv->surface)
|
||||
{
|
||||
const ClutterPaintVolume *child_volume;
|
||||
|
||||
clutter_paint_volume_set_width (volume, bounds.width);
|
||||
clutter_paint_volume_set_height (volume, bounds.height);
|
||||
child_volume = clutter_actor_get_transformed_paint_volume (CLUTTER_ACTOR (priv->surface), actor);
|
||||
if (!child_volume)
|
||||
return FALSE;
|
||||
|
||||
clutter_paint_volume_union (volume, child_volume);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1008,6 +1013,9 @@ start_simple_effect (MetaWindowActor *self,
|
||||
case META_PLUGIN_MINIMIZE:
|
||||
counter = &priv->minimize_in_progress;
|
||||
break;
|
||||
case META_PLUGIN_UNMINIMIZE:
|
||||
counter = &priv->unminimize_in_progress;
|
||||
break;
|
||||
case META_PLUGIN_MAP:
|
||||
counter = &priv->map_in_progress;
|
||||
break;
|
||||
@@ -1078,6 +1086,16 @@ meta_window_actor_effect_completed (MetaWindowActor *self,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case META_PLUGIN_UNMINIMIZE:
|
||||
{
|
||||
priv->unminimize_in_progress--;
|
||||
if (priv->unminimize_in_progress < 0)
|
||||
{
|
||||
g_warning ("Error in unminimize accounting.");
|
||||
priv->unminimize_in_progress = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case META_PLUGIN_MAP:
|
||||
/*
|
||||
* Make sure that the actor is at the correct place in case
|
||||
@@ -1243,8 +1261,7 @@ meta_window_actor_show (MetaWindowActor *self,
|
||||
event = META_PLUGIN_MAP;
|
||||
break;
|
||||
case META_COMP_EFFECT_UNMINIMIZE:
|
||||
/* FIXME: should have META_PLUGIN_UNMINIMIZE */
|
||||
event = META_PLUGIN_MAP;
|
||||
event = META_PLUGIN_UNMINIMIZE;
|
||||
break;
|
||||
case META_COMP_EFFECT_NONE:
|
||||
break;
|
||||
@@ -1647,6 +1664,8 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
||||
cairo_rectangle_int_t *client_area,
|
||||
cairo_region_t *shape_region)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
guchar *mask_data;
|
||||
guint tex_width, tex_height;
|
||||
@@ -1709,10 +1728,7 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
||||
|
||||
if (meta_texture_rectangle_check (paint_tex))
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *context = clutter_backend_get_cogl_context (backend);
|
||||
|
||||
mask_texture = COGL_TEXTURE (cogl_texture_rectangle_new_with_size (context, tex_width, tex_height));
|
||||
mask_texture = COGL_TEXTURE (cogl_texture_rectangle_new_with_size (ctx, tex_width, tex_height));
|
||||
cogl_texture_set_components (mask_texture, COGL_TEXTURE_COMPONENTS_A);
|
||||
cogl_texture_set_region (mask_texture,
|
||||
0, 0, /* src_x/y */
|
||||
@@ -1724,15 +1740,9 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Note: we don't allow slicing for this texture because we
|
||||
* need to use it with multi-texturing which doesn't support
|
||||
* sliced textures */
|
||||
mask_texture = cogl_texture_new_from_data (tex_width, tex_height,
|
||||
COGL_TEXTURE_NO_SLICING,
|
||||
COGL_PIXEL_FORMAT_A_8,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
stride,
|
||||
mask_data);
|
||||
mask_texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, tex_width, tex_height,
|
||||
COGL_PIXEL_FORMAT_A_8,
|
||||
stride, mask_data, NULL));
|
||||
}
|
||||
|
||||
meta_shaped_texture_set_mask_texture (stex, mask_texture);
|
||||
|
||||
120
src/core/bell.c
120
src/core/bell.c
@@ -69,12 +69,9 @@
|
||||
*
|
||||
* If the configure script found we had no XKB, this does not exist.
|
||||
*/
|
||||
#ifdef HAVE_XKB
|
||||
static void
|
||||
bell_flash_fullscreen (MetaDisplay *display,
|
||||
XkbAnyEvent *xkb_ev)
|
||||
bell_flash_fullscreen (MetaDisplay *display)
|
||||
{
|
||||
g_assert (xkb_ev->xkb_type == XkbBellNotify);
|
||||
meta_compositor_flash_screen (display->compositor, display->screen);
|
||||
}
|
||||
|
||||
@@ -139,30 +136,17 @@ bell_flash_window_frame (MetaWindow *window)
|
||||
* @display: The display the bell event came in on
|
||||
* @xkb_ev: The bell event we just received
|
||||
*
|
||||
* Flashes the frame of the focussed window. If there is no focussed window,
|
||||
* Flashes the frame of the focused window. If there is no focused window,
|
||||
* flashes the screen.
|
||||
*/
|
||||
static void
|
||||
bell_flash_frame (MetaDisplay *display,
|
||||
XkbAnyEvent *xkb_ev)
|
||||
MetaWindow *window)
|
||||
{
|
||||
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent *) xkb_ev;
|
||||
MetaWindow *window;
|
||||
|
||||
g_assert (xkb_ev->xkb_type == XkbBellNotify);
|
||||
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
|
||||
if (!window && (display->focus_window))
|
||||
{
|
||||
window = display->focus_window;
|
||||
}
|
||||
if (window && window->frame)
|
||||
{
|
||||
bell_flash_window_frame (window);
|
||||
}
|
||||
else /* revert to fullscreen flash if there's no focussed window */
|
||||
{
|
||||
bell_flash_fullscreen (display, xkb_ev);
|
||||
}
|
||||
bell_flash_window_frame (window);
|
||||
else
|
||||
bell_flash_fullscreen (display);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,69 +156,73 @@ bell_flash_frame (MetaDisplay *display,
|
||||
*
|
||||
* Gives the user some kind of visual bell substitute, in response to a
|
||||
* bell event. What this is depends on the "visual bell type" pref.
|
||||
*
|
||||
* If the configure script found we had no XKB, this does not exist.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Bug: This should be merged with meta_bell_notify().
|
||||
*/
|
||||
static void
|
||||
bell_visual_notify (MetaDisplay *display,
|
||||
XkbAnyEvent *xkb_ev)
|
||||
MetaWindow *window)
|
||||
{
|
||||
switch (meta_prefs_get_visual_bell_type ())
|
||||
{
|
||||
case G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH:
|
||||
bell_flash_fullscreen (display, xkb_ev);
|
||||
bell_flash_fullscreen (display);
|
||||
break;
|
||||
case G_DESKTOP_VISUAL_BELL_FRAME_FLASH:
|
||||
bell_flash_frame (display, xkb_ev); /* does nothing yet */
|
||||
bell_flash_frame (display, window);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
bell_audible_notify (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
#ifdef HAVE_LIBCANBERRA
|
||||
ca_proplist *p;
|
||||
int res;
|
||||
|
||||
ca_proplist_create (&p);
|
||||
ca_proplist_sets (p, CA_PROP_EVENT_ID, "bell-window-system");
|
||||
ca_proplist_sets (p, CA_PROP_EVENT_DESCRIPTION, _("Bell event"));
|
||||
ca_proplist_sets (p, CA_PROP_CANBERRA_CACHE_CONTROL, "permanent");
|
||||
|
||||
if (window)
|
||||
{
|
||||
ca_proplist_sets (p, CA_PROP_WINDOW_NAME, window->title);
|
||||
ca_proplist_setf (p, CA_PROP_WINDOW_X11_XID, "%lu", (unsigned long)window->xwindow);
|
||||
ca_proplist_sets (p, CA_PROP_APPLICATION_NAME, window->res_name);
|
||||
ca_proplist_setf (p, CA_PROP_APPLICATION_PROCESS_ID, "%d", window->net_wm_pid);
|
||||
}
|
||||
|
||||
res = ca_context_play_full (ca_gtk_context_get (), 1, p, NULL, NULL);
|
||||
|
||||
ca_proplist_destroy (p);
|
||||
|
||||
return res == CA_SUCCESS || res == CA_ERROR_DISABLED;
|
||||
#endif /* HAVE_LIBCANBERRA */
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_bell_notify (MetaDisplay *display,
|
||||
XkbAnyEvent *xkb_ev)
|
||||
{
|
||||
MetaWindow *window;
|
||||
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent*) xkb_ev;
|
||||
|
||||
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
|
||||
if (!window && display->focus_window && display->focus_window->frame)
|
||||
window = display->focus_window;
|
||||
|
||||
/* flash something */
|
||||
if (meta_prefs_get_visual_bell ())
|
||||
bell_visual_notify (display, xkb_ev);
|
||||
bell_visual_notify (display, window);
|
||||
|
||||
#ifdef HAVE_LIBCANBERRA
|
||||
if (meta_prefs_bell_is_audible ())
|
||||
{
|
||||
ca_proplist *p;
|
||||
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent*) xkb_ev;
|
||||
MetaWindow *window;
|
||||
int res;
|
||||
|
||||
ca_proplist_create (&p);
|
||||
ca_proplist_sets (p, CA_PROP_EVENT_ID, "bell-window-system");
|
||||
ca_proplist_sets (p, CA_PROP_EVENT_DESCRIPTION, _("Bell event"));
|
||||
ca_proplist_sets (p, CA_PROP_CANBERRA_CACHE_CONTROL, "permanent");
|
||||
|
||||
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
|
||||
if (!window && (display->focus_window) && (display->focus_window->frame))
|
||||
window = display->focus_window;
|
||||
|
||||
if (window)
|
||||
if (!bell_audible_notify (display, window))
|
||||
{
|
||||
ca_proplist_sets (p, CA_PROP_WINDOW_NAME, window->title);
|
||||
ca_proplist_setf (p, CA_PROP_WINDOW_X11_XID, "%lu", (unsigned long)window->xwindow);
|
||||
ca_proplist_sets (p, CA_PROP_APPLICATION_NAME, window->res_name);
|
||||
ca_proplist_setf (p, CA_PROP_APPLICATION_PROCESS_ID, "%d", window->net_wm_pid);
|
||||
}
|
||||
|
||||
/* First, we try to play a real sound ... */
|
||||
res = ca_context_play_full (ca_gtk_context_get (), 1, p, NULL, NULL);
|
||||
|
||||
ca_proplist_destroy (p);
|
||||
|
||||
if (res != CA_SUCCESS && res != CA_ERROR_DISABLED)
|
||||
{
|
||||
/* ...and in case that failed we use the classic X11 bell. */
|
||||
/* Force a classic bell if the libcanberra bell failed. */
|
||||
XkbForceDeviceBell (display->xdisplay,
|
||||
xkb_bell_event->device,
|
||||
xkb_bell_event->bell_class,
|
||||
@@ -242,14 +230,11 @@ meta_bell_notify (MetaDisplay *display,
|
||||
xkb_bell_event->percent);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_LIBCANBERRA */
|
||||
}
|
||||
#endif /* HAVE_XKB */
|
||||
|
||||
void
|
||||
meta_bell_set_audible (MetaDisplay *display, gboolean audible)
|
||||
{
|
||||
#ifdef HAVE_XKB
|
||||
#ifdef HAVE_LIBCANBERRA
|
||||
/* When we are playing sounds using libcanberra support, we handle the
|
||||
* bell whether its an audible bell or a visible bell */
|
||||
@@ -262,13 +247,11 @@ meta_bell_set_audible (MetaDisplay *display, gboolean audible)
|
||||
XkbUseCoreKbd,
|
||||
XkbAudibleBellMask,
|
||||
enable_system_bell ? XkbAudibleBellMask : 0);
|
||||
#endif /* HAVE_XKB */
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_bell_init (MetaDisplay *display)
|
||||
{
|
||||
#ifdef HAVE_XKB
|
||||
int xkb_base_error_type, xkb_opcode;
|
||||
|
||||
if (!XkbQueryExtension (display->xdisplay, &xkb_opcode,
|
||||
@@ -298,20 +281,17 @@ meta_bell_init (MetaDisplay *display)
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_bell_shutdown (MetaDisplay *display)
|
||||
{
|
||||
#ifdef HAVE_XKB
|
||||
/* TODO: persist initial bell state in display, reset here */
|
||||
XkbChangeEnabledControls (display->xdisplay,
|
||||
XkbUseCoreKbd,
|
||||
XkbAudibleBellMask,
|
||||
XkbAudibleBellMask);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,13 +18,10 @@
|
||||
*/
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#ifdef HAVE_XKB
|
||||
#include <X11/XKBlib.h>
|
||||
#endif
|
||||
#include "display-private.h"
|
||||
#include "frame.h"
|
||||
|
||||
#ifdef HAVE_XKB
|
||||
/**
|
||||
* meta_bell_notify:
|
||||
* @display: The display the bell event came in on
|
||||
@@ -37,7 +34,6 @@
|
||||
* If the configure script found we had no XKB, this does not exist.
|
||||
*/
|
||||
void meta_bell_notify (MetaDisplay *display, XkbAnyEvent *xkb_ev);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* meta_bell_set_audible:
|
||||
@@ -61,12 +57,6 @@ void meta_bell_set_audible (MetaDisplay *display, gboolean audible);
|
||||
* to send us bell notifications, and then also switching
|
||||
* off the audible bell if we're using a visual one ourselves.
|
||||
*
|
||||
* Unlike most X extensions we use, we only initialise XKB here
|
||||
* (rather than in main()). It's possible that XKB is not
|
||||
* installed at all, but if that was known at build time
|
||||
* we will have HAVE_XKB undefined, which will cause this
|
||||
* function to be a no-op.
|
||||
*
|
||||
* \bug There is a line of code that's never run that tells
|
||||
* XKB to reset the bell status after we quit. Bill H said
|
||||
* (<http://bugzilla.gnome.org/show_bug.cgi?id=99886#c12>)
|
||||
|
||||
@@ -79,6 +79,24 @@ typedef enum {
|
||||
META_TILE_MAXIMIZED
|
||||
} MetaTileMode;
|
||||
|
||||
typedef enum {
|
||||
/* Normal interaction where you're interacting with windows.
|
||||
* Events go to windows normally. */
|
||||
META_EVENT_ROUTE_NORMAL,
|
||||
|
||||
/* In a compositor grab operation. All events go to the
|
||||
* compositor plugin. */
|
||||
META_EVENT_ROUTE_COMPOSITOR_GRAB,
|
||||
|
||||
/* A Wayland application has a popup open. All events go to
|
||||
* the Wayland application. */
|
||||
META_EVENT_ROUTE_WAYLAND_POPUP,
|
||||
|
||||
/* In a window operation like moving or resizing. All events
|
||||
* goes to MetaWindow, but not to the actual client window. */
|
||||
META_EVENT_ROUTE_WINDOW_OP,
|
||||
} MetaEventRoute;
|
||||
|
||||
struct _MetaDisplay
|
||||
{
|
||||
GObject parent_instance;
|
||||
@@ -174,8 +192,8 @@ struct _MetaDisplay
|
||||
guint autoraise_timeout_id;
|
||||
MetaWindow* autoraise_window;
|
||||
|
||||
/* Alt+click button grabs */
|
||||
ClutterModifierType window_grab_modifiers;
|
||||
/* Event routing */
|
||||
MetaEventRoute event_route;
|
||||
|
||||
/* current window operation */
|
||||
MetaGrabOp grab_op;
|
||||
@@ -200,34 +218,17 @@ struct _MetaDisplay
|
||||
GTimeVal grab_last_moveresize_time;
|
||||
MetaEdgeResistanceData *grab_edge_resistance_data;
|
||||
unsigned int grab_last_user_action_was_snap;
|
||||
guint32 grab_timestamp;
|
||||
|
||||
/* we use property updates as sentinels for certain window focus events
|
||||
* to avoid some race conditions on EnterNotify events
|
||||
*/
|
||||
int sentinel_counter;
|
||||
|
||||
#ifdef HAVE_XKB
|
||||
int xkb_base_event_type;
|
||||
guint32 last_bell_time;
|
||||
#endif
|
||||
int grab_resize_timeout_id;
|
||||
|
||||
/* Keybindings stuff */
|
||||
GHashTable *key_bindings;
|
||||
GHashTable *key_bindings_index;
|
||||
int min_keycode;
|
||||
int max_keycode;
|
||||
KeySym *keymap;
|
||||
int keysyms_per_keycode;
|
||||
unsigned int ignored_modifier_mask;
|
||||
unsigned int hyper_mask;
|
||||
unsigned int super_mask;
|
||||
unsigned int meta_mask;
|
||||
MetaKeyCombo overlay_key_combo;
|
||||
gboolean overlay_key_only_pressed;
|
||||
MetaKeyCombo *iso_next_group_combos;
|
||||
int n_iso_next_group_combos;
|
||||
MetaKeyBindingManager key_binding_manager;
|
||||
|
||||
/* Monitor cache */
|
||||
unsigned int monitor_cache_invalidated : 1;
|
||||
@@ -253,6 +254,7 @@ struct _MetaDisplay
|
||||
MetaCompositor *compositor;
|
||||
|
||||
MetaGestureTracker *gesture_tracker;
|
||||
ClutterEventSequence *pointer_emulating_sequence;
|
||||
|
||||
int composite_event_base;
|
||||
int composite_error_base;
|
||||
@@ -396,14 +398,8 @@ int meta_resize_gravity_from_grab_op (MetaGrabOp op);
|
||||
|
||||
gboolean meta_grab_op_is_moving (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_resizing (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_moving_or_resizing (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_mouse (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_keyboard (MetaGrabOp op);
|
||||
gboolean meta_grab_op_should_block_wayland (MetaGrabOp op);
|
||||
|
||||
void meta_display_devirtualize_modifiers (MetaDisplay *display,
|
||||
MetaVirtualModifier modifiers,
|
||||
unsigned int *mask);
|
||||
|
||||
void meta_display_increment_focus_sentinel (MetaDisplay *display);
|
||||
void meta_display_decrement_focus_sentinel (MetaDisplay *display);
|
||||
@@ -453,4 +449,8 @@ gboolean meta_display_request_restart (MetaDisplay *display);
|
||||
void meta_restart_init (void);
|
||||
void meta_restart_finish (void);
|
||||
|
||||
void meta_display_cancel_touch (MetaDisplay *display);
|
||||
|
||||
gboolean meta_display_windows_are_interactable (MetaDisplay *display);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#include "mutter-enum-types.h"
|
||||
#include "meta-idle-monitor-dbus.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include "meta-backend.h"
|
||||
#include <meta/meta-backend.h>
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
|
||||
@@ -65,12 +65,15 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "x11/events.h"
|
||||
#include "x11/window-x11.h"
|
||||
#include "x11/window-props.h"
|
||||
#include "x11/group-props.h"
|
||||
#include "x11/xprops.h"
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "wayland/meta-xwayland-private.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SECTION:pings
|
||||
@@ -143,7 +146,6 @@ static const char *gnome_wm_keybindings = "Mutter";
|
||||
static const char *net_wm_name = "Mutter";
|
||||
|
||||
static void update_cursor_theme (void);
|
||||
static void update_window_grab_modifiers (MetaDisplay *display);
|
||||
|
||||
static void prefs_changed_callback (MetaPreference pref,
|
||||
void *data);
|
||||
@@ -415,11 +417,15 @@ enable_compositor (MetaDisplay *display)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!display->compositor)
|
||||
display->compositor = meta_compositor_new (display);
|
||||
int version = (display->composite_major_version * 10) + display->composite_minor_version;
|
||||
if (version < 3)
|
||||
{
|
||||
meta_warning ("Your version of COMPOSITE is too old.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!display->compositor)
|
||||
return;
|
||||
display->compositor = meta_compositor_new (display);
|
||||
|
||||
meta_compositor_manage (display->compositor);
|
||||
}
|
||||
@@ -461,26 +467,48 @@ meta_set_gnome_wm_keybindings (const char *wm_keybindings)
|
||||
gnome_wm_keybindings = wm_keybindings;
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_cancel_touch (MetaDisplay *display)
|
||||
{
|
||||
#ifdef HAVE_WAYLAND
|
||||
MetaWaylandCompositor *compositor;
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
return;
|
||||
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
meta_wayland_touch_cancel (&compositor->seat->touch);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_tracker_state_changed (MetaGestureTracker *tracker,
|
||||
ClutterEventSequence *sequence,
|
||||
MetaSequenceState state,
|
||||
MetaDisplay *display)
|
||||
{
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
int event_mode;
|
||||
|
||||
if (state == META_SEQUENCE_ACCEPTED)
|
||||
event_mode = XIAcceptTouch;
|
||||
else if (state == META_SEQUENCE_REJECTED)
|
||||
event_mode = XIRejectTouch;
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
if (state == META_SEQUENCE_ACCEPTED)
|
||||
meta_display_cancel_touch (display);
|
||||
}
|
||||
else
|
||||
return;
|
||||
{
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
int event_mode;
|
||||
|
||||
XIAllowTouchEvents (meta_backend_x11_get_xdisplay (backend),
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
clutter_x11_event_sequence_get_touch_detail (sequence),
|
||||
DefaultRootWindow (display->xdisplay), event_mode);
|
||||
if (state == META_SEQUENCE_ACCEPTED)
|
||||
event_mode = XIAcceptTouch;
|
||||
else if (state == META_SEQUENCE_REJECTED)
|
||||
event_mode = XIRejectTouch;
|
||||
else
|
||||
return;
|
||||
|
||||
XIAllowTouchEvents (meta_backend_x11_get_xdisplay (backend),
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
clutter_x11_event_sequence_get_touch_detail (sequence),
|
||||
DefaultRootWindow (display->xdisplay), event_mode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -521,8 +549,10 @@ meta_display_open (void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_xwayland_complete_init ();
|
||||
#endif
|
||||
|
||||
if (meta_is_syncing ())
|
||||
XSynchronize (xdisplay, True);
|
||||
@@ -556,8 +586,6 @@ meta_display_open (void)
|
||||
|
||||
meta_display_init_keys (display);
|
||||
|
||||
update_window_grab_modifiers (display);
|
||||
|
||||
meta_prefs_add_listener (prefs_changed_callback, display);
|
||||
|
||||
meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names));
|
||||
@@ -595,6 +623,7 @@ meta_display_open (void)
|
||||
|
||||
/* Get events */
|
||||
meta_display_init_events (display);
|
||||
meta_display_init_events_x11 (display);
|
||||
|
||||
display->xids = g_hash_table_new (meta_unsigned_long_hash,
|
||||
meta_unsigned_long_equal);
|
||||
@@ -614,9 +643,7 @@ meta_display_open (void)
|
||||
display->grab_resize_timeout_id = 0;
|
||||
display->grab_have_keyboard = FALSE;
|
||||
|
||||
#ifdef HAVE_XKB
|
||||
display->last_bell_time = 0;
|
||||
#endif
|
||||
|
||||
display->grab_op = META_GRAB_OP_NONE;
|
||||
display->grab_window = NULL;
|
||||
@@ -1061,6 +1088,7 @@ meta_display_close (MetaDisplay *display,
|
||||
display->focus_timeout_id = 0;
|
||||
|
||||
/* Stop caring about events */
|
||||
meta_display_free_events_x11 (display);
|
||||
meta_display_free_events (display);
|
||||
|
||||
meta_screen_free (display->screen, timestamp);
|
||||
@@ -1139,117 +1167,64 @@ meta_get_display (void)
|
||||
return the_display;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
grab_op_is_window (MetaGrabOp op)
|
||||
{
|
||||
return GRAB_OP_GET_BASE_TYPE (op) == META_GRAB_OP_WINDOW_BASE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_grab_op_is_mouse (MetaGrabOp op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case META_GRAB_OP_MOVING:
|
||||
case META_GRAB_OP_RESIZING_SE:
|
||||
case META_GRAB_OP_RESIZING_S:
|
||||
case META_GRAB_OP_RESIZING_SW:
|
||||
case META_GRAB_OP_RESIZING_N:
|
||||
case META_GRAB_OP_RESIZING_NE:
|
||||
case META_GRAB_OP_RESIZING_NW:
|
||||
case META_GRAB_OP_RESIZING_W:
|
||||
case META_GRAB_OP_RESIZING_E:
|
||||
return TRUE;
|
||||
if (!grab_op_is_window (op))
|
||||
return FALSE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return (op & META_GRAB_OP_WINDOW_FLAG_KEYBOARD) == 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_grab_op_is_keyboard (MetaGrabOp op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case META_GRAB_OP_KEYBOARD_MOVING:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_S:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_N:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_W:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_E:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_SE:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
|
||||
return TRUE;
|
||||
if (!grab_op_is_window (op))
|
||||
return FALSE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return (op & META_GRAB_OP_WINDOW_FLAG_KEYBOARD) != 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_grab_op_is_resizing (MetaGrabOp op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case META_GRAB_OP_RESIZING_SE:
|
||||
case META_GRAB_OP_RESIZING_S:
|
||||
case META_GRAB_OP_RESIZING_SW:
|
||||
case META_GRAB_OP_RESIZING_N:
|
||||
case META_GRAB_OP_RESIZING_NE:
|
||||
case META_GRAB_OP_RESIZING_NW:
|
||||
case META_GRAB_OP_RESIZING_W:
|
||||
case META_GRAB_OP_RESIZING_E:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_S:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_N:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_W:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_E:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_SE:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
|
||||
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
|
||||
return TRUE;
|
||||
if (!grab_op_is_window (op))
|
||||
return FALSE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return (op & META_GRAB_OP_WINDOW_DIR_MASK) != 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_grab_op_is_moving (MetaGrabOp op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case META_GRAB_OP_MOVING:
|
||||
case META_GRAB_OP_KEYBOARD_MOVING:
|
||||
return TRUE;
|
||||
if (!grab_op_is_window (op))
|
||||
return FALSE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_grab_op_is_moving_or_resizing (MetaGrabOp op)
|
||||
{
|
||||
return (meta_grab_op_is_moving (op) ||
|
||||
meta_grab_op_is_resizing (op));
|
||||
return (op & META_GRAB_OP_WINDOW_DIR_MASK) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_grab_op_should_block_wayland:
|
||||
* meta_grab_op_windows_are_interactable:
|
||||
* @op: A #MetaGrabOp
|
||||
*
|
||||
* Starting a grab with one of these grab operations means
|
||||
* that we will remove key / pointer focus from the current
|
||||
* Wayland focus.
|
||||
* Whether windows can be interacted with.
|
||||
*/
|
||||
gboolean
|
||||
meta_grab_op_should_block_wayland (MetaGrabOp op)
|
||||
meta_display_windows_are_interactable (MetaDisplay *display)
|
||||
{
|
||||
switch (op)
|
||||
switch (display->event_route)
|
||||
{
|
||||
case META_GRAB_OP_WAYLAND_POPUP:
|
||||
case META_GRAB_OP_NONE:
|
||||
return FALSE;
|
||||
default:
|
||||
case META_EVENT_ROUTE_NORMAL:
|
||||
case META_EVENT_ROUTE_WAYLAND_POPUP:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1414,10 +1389,11 @@ meta_display_queue_autoraise_callback (MetaDisplay *display,
|
||||
void
|
||||
meta_display_sync_wayland_input_focus (MetaDisplay *display)
|
||||
{
|
||||
#ifdef HAVE_WAYLAND
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaWindow *focus_window = NULL;
|
||||
|
||||
if (meta_grab_op_should_block_wayland (display->grab_op))
|
||||
if (!meta_display_windows_are_interactable (display))
|
||||
focus_window = NULL;
|
||||
else if (meta_display_xwindow_is_a_no_focus_window (display, display->focus_xwindow))
|
||||
focus_window = NULL;
|
||||
@@ -1429,6 +1405,7 @@ meta_display_sync_wayland_input_focus (MetaDisplay *display)
|
||||
meta_wayland_compositor_set_input_focus (compositor, focus_window);
|
||||
|
||||
meta_wayland_seat_repick (compositor->seat);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1725,6 +1702,30 @@ get_first_freefloating_window (MetaWindow *window)
|
||||
return window;
|
||||
}
|
||||
|
||||
static MetaEventRoute
|
||||
get_event_route_from_grab_op (MetaGrabOp op)
|
||||
{
|
||||
switch (GRAB_OP_GET_BASE_TYPE (op))
|
||||
{
|
||||
case META_GRAB_OP_NONE:
|
||||
/* begin_grab_op shouldn't be called with META_GRAB_OP_NONE. */
|
||||
g_assert_not_reached ();
|
||||
|
||||
case META_GRAB_OP_WINDOW_BASE:
|
||||
return META_EVENT_ROUTE_WINDOW_OP;
|
||||
|
||||
case META_GRAB_OP_COMPOSITOR:
|
||||
/* begin_grab_op shouldn't be called with META_GRAB_OP_COMPOSITOR. */
|
||||
g_assert_not_reached ();
|
||||
|
||||
case META_GRAB_OP_WAYLAND_POPUP:
|
||||
return META_EVENT_ROUTE_WAYLAND_POPUP;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_display_begin_grab_op (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
@@ -1740,6 +1741,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaWindow *grab_window = NULL;
|
||||
MetaEventRoute event_route;
|
||||
|
||||
g_assert (window != NULL);
|
||||
|
||||
@@ -1756,7 +1758,9 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (meta_grab_op_is_moving (op) || meta_grab_op_is_resizing (op))
|
||||
event_route = get_event_route_from_grab_op (op);
|
||||
|
||||
if (event_route == META_EVENT_ROUTE_WINDOW_OP)
|
||||
{
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
meta_window_raise (window);
|
||||
@@ -1802,8 +1806,8 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Grab keys for keyboard ops and mouse move/resizes; see #126497 */
|
||||
if (meta_grab_op_is_moving_or_resizing (op))
|
||||
/* Grab keys when beginning window ops; see #126497 */
|
||||
if (event_route == META_EVENT_ROUTE_WINDOW_OP)
|
||||
{
|
||||
display->grab_have_keyboard = meta_window_grab_all_keys (grab_window, timestamp);
|
||||
|
||||
@@ -1816,6 +1820,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
}
|
||||
}
|
||||
|
||||
display->event_route = event_route;
|
||||
display->grab_op = op;
|
||||
display->grab_window = grab_window;
|
||||
display->grab_button = button;
|
||||
@@ -1830,7 +1835,6 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
display->grab_last_user_action_was_snap = FALSE;
|
||||
display->grab_frame_action = frame_action;
|
||||
display->grab_resize_unmaximize = 0;
|
||||
display->grab_timestamp = timestamp;
|
||||
|
||||
meta_display_update_cursor (display);
|
||||
|
||||
@@ -1849,12 +1853,16 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
display->grab_anchor_window_pos = display->grab_initial_window_pos;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
{
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
meta_display_cancel_touch (display);
|
||||
}
|
||||
|
||||
g_signal_emit (display, display_signals[GRAB_OP_BEGIN], 0,
|
||||
screen, display->grab_window, display->grab_op);
|
||||
|
||||
meta_window_grab_op_began (display->grab_window, display->grab_op);
|
||||
if (display->event_route == META_EVENT_ROUTE_WINDOW_OP)
|
||||
meta_window_grab_op_began (display->grab_window, display->grab_op);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1869,13 +1877,13 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Ending grab op %u at time %u\n", grab_op, timestamp);
|
||||
|
||||
if (display->grab_op == META_GRAB_OP_NONE)
|
||||
if (display->event_route == META_EVENT_ROUTE_NORMAL)
|
||||
return;
|
||||
|
||||
g_signal_emit (display, display_signals[GRAB_OP_END], 0,
|
||||
display->screen, grab_window, grab_op);
|
||||
|
||||
if (meta_grab_op_is_moving_or_resizing (grab_op))
|
||||
if (display->event_route == META_EVENT_ROUTE_WINDOW_OP)
|
||||
{
|
||||
/* Clear out the edge cache */
|
||||
meta_display_cleanup_edges (display);
|
||||
@@ -1889,6 +1897,8 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
if (!meta_prefs_get_raise_on_click () &&
|
||||
display->grab_threshold_movement_reached)
|
||||
meta_window_raise (display->grab_window);
|
||||
|
||||
meta_window_grab_op_ended (grab_window, grab_op);
|
||||
}
|
||||
|
||||
if (display->grab_have_pointer)
|
||||
@@ -1904,11 +1914,11 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
meta_window_ungrab_all_keys (grab_window, timestamp);
|
||||
}
|
||||
|
||||
display->grab_timestamp = 0;
|
||||
display->event_route = META_EVENT_ROUTE_NORMAL;
|
||||
display->grab_op = META_GRAB_OP_NONE;
|
||||
display->grab_window = NULL;
|
||||
display->grab_tile_mode = META_TILE_NONE;
|
||||
display->grab_tile_monitor_number = -1;
|
||||
display->grab_op = META_GRAB_OP_NONE;
|
||||
|
||||
meta_display_update_cursor (display);
|
||||
|
||||
@@ -1918,8 +1928,6 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
display->grab_resize_timeout_id = 0;
|
||||
}
|
||||
|
||||
meta_window_grab_op_ended (grab_window, grab_op);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
}
|
||||
@@ -1956,221 +1964,6 @@ meta_display_check_threshold_reached (MetaDisplay *display,
|
||||
display->grab_threshold_movement_reached = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_change_button_grab (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
gboolean grab,
|
||||
gboolean sync,
|
||||
int button,
|
||||
int modmask)
|
||||
{
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
|
||||
|
||||
unsigned int ignored_mask;
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
|
||||
XISetMask (mask.mask, XI_ButtonPress);
|
||||
XISetMask (mask.mask, XI_ButtonRelease);
|
||||
XISetMask (mask.mask, XI_Motion);
|
||||
|
||||
ignored_mask = 0;
|
||||
while (ignored_mask <= display->ignored_modifier_mask)
|
||||
{
|
||||
XIGrabModifiers mods;
|
||||
|
||||
if (ignored_mask & ~(display->ignored_modifier_mask))
|
||||
{
|
||||
/* Not a combination of ignored modifiers
|
||||
* (it contains some non-ignored modifiers)
|
||||
*/
|
||||
++ignored_mask;
|
||||
continue;
|
||||
}
|
||||
|
||||
mods = (XIGrabModifiers) { modmask | ignored_mask, 0 };
|
||||
|
||||
/* GrabModeSync means freeze until XAllowEvents */
|
||||
|
||||
if (grab)
|
||||
XIGrabButton (xdisplay,
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
button, xwindow, None,
|
||||
sync ? XIGrabModeSync : XIGrabModeAsync,
|
||||
XIGrabModeAsync, False,
|
||||
&mask, 1, &mods);
|
||||
else
|
||||
XIUngrabButton (xdisplay,
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
button, xwindow, 1, &mods);
|
||||
|
||||
++ignored_mask;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_grab_window_buttons (MetaDisplay *display,
|
||||
Window xwindow)
|
||||
{
|
||||
if (meta_is_wayland_compositor ())
|
||||
return;
|
||||
|
||||
/* Grab Alt + button1 for moving window.
|
||||
* Grab Alt + button2 for resizing window.
|
||||
* Grab Alt + button3 for popping up window menu.
|
||||
* Grab Alt + Shift + button1 for snap-moving window.
|
||||
*/
|
||||
meta_verbose ("Grabbing window buttons for 0x%lx\n", xwindow);
|
||||
|
||||
/* FIXME If we ignored errors here instead of spewing, we could
|
||||
* put one big error trap around the loop and avoid a bunch of
|
||||
* XSync()
|
||||
*/
|
||||
|
||||
if (display->window_grab_modifiers != 0)
|
||||
{
|
||||
gboolean debug = g_getenv ("MUTTER_DEBUG_BUTTON_GRABS") != NULL;
|
||||
int i;
|
||||
for (i = 1; i < 4; i++)
|
||||
{
|
||||
meta_change_button_grab (display, xwindow,
|
||||
TRUE,
|
||||
FALSE,
|
||||
i, display->window_grab_modifiers);
|
||||
|
||||
/* This is for debugging, since I end up moving the Xnest
|
||||
* otherwise ;-)
|
||||
*/
|
||||
if (debug)
|
||||
meta_change_button_grab (display, xwindow,
|
||||
TRUE,
|
||||
FALSE,
|
||||
i, ControlMask);
|
||||
}
|
||||
|
||||
/* In addition to grabbing Alt+Button1 for moving the window,
|
||||
* grab Alt+Shift+Button1 for snap-moving the window. See bug
|
||||
* 112478. Unfortunately, this doesn't work with
|
||||
* Shift+Alt+Button1 for some reason; so at least part of the
|
||||
* order still matters, which sucks (please FIXME).
|
||||
*/
|
||||
meta_change_button_grab (display, xwindow,
|
||||
TRUE,
|
||||
FALSE,
|
||||
1, display->window_grab_modifiers | ShiftMask);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_ungrab_window_buttons (MetaDisplay *display,
|
||||
Window xwindow)
|
||||
{
|
||||
gboolean debug;
|
||||
int i;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
return;
|
||||
|
||||
if (display->window_grab_modifiers == 0)
|
||||
return;
|
||||
|
||||
debug = g_getenv ("MUTTER_DEBUG_BUTTON_GRABS") != NULL;
|
||||
i = 1;
|
||||
while (i < 4)
|
||||
{
|
||||
meta_change_button_grab (display, xwindow,
|
||||
FALSE, FALSE, i,
|
||||
display->window_grab_modifiers);
|
||||
|
||||
if (debug)
|
||||
meta_change_button_grab (display, xwindow,
|
||||
FALSE, FALSE, i, ControlMask);
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Grab buttons we only grab while unfocused in click-to-focus mode */
|
||||
#define MAX_FOCUS_BUTTON 4
|
||||
void
|
||||
meta_display_grab_focus_window_button (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
if (meta_is_wayland_compositor ())
|
||||
return;
|
||||
|
||||
/* Grab button 1 for activating unfocused windows */
|
||||
meta_verbose ("Grabbing unfocused window buttons for %s\n", window->desc);
|
||||
|
||||
#if 0
|
||||
/* FIXME:115072 */
|
||||
/* Don't grab at all unless in click to focus mode. In click to
|
||||
* focus, we may sometimes be clever about intercepting and eating
|
||||
* the focus click. But in mouse focus, we never do that since the
|
||||
* focus window may not be raised, and who wants to think about
|
||||
* mouse focus anyway.
|
||||
*/
|
||||
if (meta_prefs_get_focus_mode () != G_DESKTOP_FOCUS_MODE_CLICK)
|
||||
{
|
||||
meta_verbose (" (well, not grabbing since not in click to focus mode)\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (window->have_focus_click_grab)
|
||||
{
|
||||
meta_verbose (" (well, not grabbing since we already have the grab)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME If we ignored errors here instead of spewing, we could
|
||||
* put one big error trap around the loop and avoid a bunch of
|
||||
* XSync()
|
||||
*/
|
||||
|
||||
{
|
||||
int i = 1;
|
||||
while (i < MAX_FOCUS_BUTTON)
|
||||
{
|
||||
meta_change_button_grab (display,
|
||||
window->xwindow,
|
||||
TRUE, TRUE,
|
||||
i, 0);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
window->have_focus_click_grab = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_ungrab_focus_window_button (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
if (meta_is_wayland_compositor ())
|
||||
return;
|
||||
|
||||
meta_verbose ("Ungrabbing unfocused window buttons for %s\n", window->desc);
|
||||
|
||||
if (!window->have_focus_click_grab)
|
||||
return;
|
||||
|
||||
{
|
||||
int i = 1;
|
||||
while (i < MAX_FOCUS_BUTTON)
|
||||
{
|
||||
meta_change_button_grab (display, window->xwindow,
|
||||
FALSE, FALSE, i, 0);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
window->have_focus_click_grab = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_increment_event_serial (MetaDisplay *display)
|
||||
{
|
||||
@@ -2820,92 +2613,23 @@ meta_display_sort_windows_by_stacking (MetaDisplay *display,
|
||||
return copy;
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_devirtualize_modifiers (MetaDisplay *display,
|
||||
MetaVirtualModifier modifiers,
|
||||
unsigned int *mask)
|
||||
{
|
||||
*mask = 0;
|
||||
|
||||
if (modifiers & META_VIRTUAL_SHIFT_MASK)
|
||||
*mask |= ShiftMask;
|
||||
if (modifiers & META_VIRTUAL_CONTROL_MASK)
|
||||
*mask |= ControlMask;
|
||||
if (modifiers & META_VIRTUAL_ALT_MASK)
|
||||
*mask |= Mod1Mask;
|
||||
if (modifiers & META_VIRTUAL_META_MASK)
|
||||
*mask |= display->meta_mask;
|
||||
if (modifiers & META_VIRTUAL_HYPER_MASK)
|
||||
*mask |= display->hyper_mask;
|
||||
if (modifiers & META_VIRTUAL_SUPER_MASK)
|
||||
*mask |= display->super_mask;
|
||||
if (modifiers & META_VIRTUAL_MOD2_MASK)
|
||||
*mask |= Mod2Mask;
|
||||
if (modifiers & META_VIRTUAL_MOD3_MASK)
|
||||
*mask |= Mod3Mask;
|
||||
if (modifiers & META_VIRTUAL_MOD4_MASK)
|
||||
*mask |= Mod4Mask;
|
||||
if (modifiers & META_VIRTUAL_MOD5_MASK)
|
||||
*mask |= Mod5Mask;
|
||||
}
|
||||
|
||||
static void
|
||||
update_window_grab_modifiers (MetaDisplay *display)
|
||||
{
|
||||
MetaVirtualModifier virtual_mods;
|
||||
unsigned int mods;
|
||||
|
||||
virtual_mods = meta_prefs_get_mouse_button_mods ();
|
||||
meta_display_devirtualize_modifiers (display, virtual_mods,
|
||||
&mods);
|
||||
|
||||
display->window_grab_modifiers = mods;
|
||||
}
|
||||
|
||||
static void
|
||||
prefs_changed_callback (MetaPreference pref,
|
||||
void *data)
|
||||
{
|
||||
MetaDisplay *display = data;
|
||||
|
||||
/* It may not be obvious why we regrab on focus mode
|
||||
* change; it's because we handle focus clicks a
|
||||
* bit differently for the different focus modes.
|
||||
*/
|
||||
if (pref == META_PREF_MOUSE_BUTTON_MODS ||
|
||||
pref == META_PREF_FOCUS_MODE)
|
||||
if (pref == META_PREF_FOCUS_MODE)
|
||||
{
|
||||
MetaDisplay *display = data;
|
||||
GSList *windows;
|
||||
GSList *tmp;
|
||||
|
||||
GSList *windows, *l;
|
||||
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
|
||||
|
||||
/* Ungrab all */
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
for (l = windows; l; l = l->next)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
meta_display_ungrab_window_buttons (display, w->xwindow);
|
||||
MetaWindow *w = l->data;
|
||||
meta_display_ungrab_focus_window_button (display, w);
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
/* change our modifier */
|
||||
if (pref == META_PREF_MOUSE_BUTTON_MODS)
|
||||
update_window_grab_modifiers (display);
|
||||
|
||||
/* Grab all */
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
if (w->type != META_WINDOW_DOCK)
|
||||
{
|
||||
meta_display_grab_focus_window_button (display, w);
|
||||
meta_display_grab_window_buttons (display, w->xwindow);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
meta_display_grab_focus_window_button (display, w);
|
||||
}
|
||||
|
||||
g_slist_free (windows);
|
||||
@@ -3074,15 +2798,6 @@ meta_display_modifiers_accelerator_activate (MetaDisplay *display)
|
||||
return freeze;
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_get_compositor_version (MetaDisplay *display,
|
||||
int *major,
|
||||
int *minor)
|
||||
{
|
||||
*major = display->composite_major_version;
|
||||
*minor = display->composite_minor_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_get_xinput_opcode: (skip)
|
||||
* @display: a #MetaDisplay
|
||||
@@ -3219,3 +2934,23 @@ meta_display_request_restart (MetaDisplay *display)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_is_pointer_emulating_sequence:
|
||||
* @display: the display
|
||||
* @sequence: (nullable): a #ClutterEventSequence
|
||||
*
|
||||
* Tells whether the event sequence is the used for pointer emulation
|
||||
* and single-touch interaction.
|
||||
*
|
||||
* Returns: #TRUE if the sequence emulates pointer behavior
|
||||
**/
|
||||
gboolean
|
||||
meta_display_is_pointer_emulating_sequence (MetaDisplay *display,
|
||||
ClutterEventSequence *sequence)
|
||||
{
|
||||
if (!sequence)
|
||||
return FALSE;
|
||||
|
||||
return display->pointer_emulating_sequence == sequence;
|
||||
}
|
||||
|
||||
@@ -23,9 +23,10 @@
|
||||
#include "config.h"
|
||||
#include "events.h"
|
||||
|
||||
#include <meta/meta-backend.h>
|
||||
|
||||
#include "display-private.h"
|
||||
#include "window-private.h"
|
||||
#include "backends/meta-backend.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
@@ -33,34 +34,45 @@
|
||||
#include "backends/native/meta-idle-monitor-native.h"
|
||||
#endif
|
||||
|
||||
#include "x11/events.h"
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "backends/meta-cursor-tracker-private.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#endif
|
||||
#include "meta-surface-actor.h"
|
||||
|
||||
static MetaWindow *
|
||||
get_window_for_event (MetaDisplay *display,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
ClutterActor *source;
|
||||
|
||||
if (display->grab_op != META_GRAB_OP_NONE)
|
||||
return display->grab_window;
|
||||
|
||||
/* Always use the key focused window for key events. */
|
||||
switch (event->type)
|
||||
switch (display->event_route)
|
||||
{
|
||||
case CLUTTER_KEY_PRESS:
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
return display->focus_window;
|
||||
case META_EVENT_ROUTE_NORMAL:
|
||||
{
|
||||
ClutterActor *source;
|
||||
|
||||
/* Always use the key focused window for key events. */
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_KEY_PRESS:
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
return display->focus_window;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
source = clutter_event_get_source (event);
|
||||
if (META_IS_SURFACE_ACTOR (source))
|
||||
return meta_surface_actor_get_window (META_SURFACE_ACTOR (source));
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
case META_EVENT_ROUTE_WAYLAND_POPUP:
|
||||
case META_EVENT_ROUTE_WINDOW_OP:
|
||||
case META_EVENT_ROUTE_COMPOSITOR_GRAB:
|
||||
return display->grab_window;
|
||||
default:
|
||||
break;
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
source = clutter_event_get_source (event);
|
||||
if (META_IS_SURFACE_ACTOR (source))
|
||||
return meta_surface_actor_get_window (META_SURFACE_ACTOR (source));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -99,20 +111,90 @@ handle_idletime_for_event (const ClutterEvent *event)
|
||||
#endif /* HAVE_NATIVE_BACKEND */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sequence_is_pointer_emulated (MetaDisplay *display,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
ClutterEventSequence *sequence;
|
||||
|
||||
sequence = clutter_event_get_event_sequence (event);
|
||||
|
||||
if (!sequence)
|
||||
return FALSE;
|
||||
|
||||
if (clutter_event_is_pointer_emulated (event))
|
||||
return TRUE;
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
/* When using Clutter's native input backend there is no concept of
|
||||
* pointer emulating sequence, we still must make up our own to be
|
||||
* able to implement single-touch (hence pointer alike) behavior.
|
||||
*
|
||||
* This is implemented similarly to X11, where only the first touch
|
||||
* on screen gets the "pointer emulated" flag, and it won't get assigned
|
||||
* to another sequence until the next first touch on an idle touchscreen.
|
||||
*/
|
||||
if (META_IS_BACKEND_NATIVE (backend))
|
||||
{
|
||||
MetaGestureTracker *tracker;
|
||||
|
||||
tracker = meta_display_get_gesture_tracker (display);
|
||||
|
||||
if (event->type == CLUTTER_TOUCH_BEGIN &&
|
||||
meta_gesture_tracker_get_n_current_touches (tracker) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* HAVE_NATIVE_BACKEND */
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_display_update_pointer_emulating_sequence (MetaDisplay *display,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
ClutterEventSequence *sequence;
|
||||
|
||||
sequence = clutter_event_get_event_sequence (event);
|
||||
|
||||
if (event->type == CLUTTER_TOUCH_BEGIN &&
|
||||
!display->pointer_emulating_sequence &&
|
||||
sequence_is_pointer_emulated (display, event))
|
||||
display->pointer_emulating_sequence = sequence;
|
||||
else if (event->type == CLUTTER_TOUCH_END &&
|
||||
display->pointer_emulating_sequence == sequence)
|
||||
display->pointer_emulating_sequence = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_display_handle_event (MetaDisplay *display,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaWindow *window;
|
||||
gboolean bypass_clutter = FALSE, bypass_wayland = FALSE;
|
||||
MetaWaylandCompositor *compositor = NULL;
|
||||
gboolean bypass_clutter = FALSE;
|
||||
G_GNUC_UNUSED gboolean bypass_wayland = FALSE;
|
||||
MetaGestureTracker *tracker;
|
||||
|
||||
meta_display_update_pointer_emulating_sequence (display, event);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
MetaWaylandCompositor *compositor = NULL;
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
meta_wayland_compositor_update (compositor, event);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (meta_is_wayland_compositor () && event->type == CLUTTER_MOTION)
|
||||
{
|
||||
MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
meta_cursor_tracker_update_position (tracker, event->motion.x, event->motion.y);
|
||||
}
|
||||
#endif
|
||||
|
||||
handle_idletime_for_event (event);
|
||||
|
||||
@@ -146,13 +228,11 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
|
||||
if (meta_gesture_tracker_handle_event (tracker, event))
|
||||
{
|
||||
bypass_wayland = TRUE;
|
||||
bypass_clutter = meta_gesture_tracker_consumes_event (tracker, event);
|
||||
bypass_wayland = bypass_clutter = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (display->grab_window == window &&
|
||||
meta_grab_op_is_moving_or_resizing (display->grab_op))
|
||||
if (display->event_route == META_EVENT_ROUTE_WINDOW_OP)
|
||||
{
|
||||
if (meta_window_handle_mouse_grab_op_event (window, event))
|
||||
{
|
||||
@@ -177,29 +257,42 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
|
||||
if (window)
|
||||
{
|
||||
/* Swallow all events on windows that come our way. */
|
||||
bypass_clutter = TRUE;
|
||||
|
||||
/* Under X11, we have a Sync grab and in order to send it back to
|
||||
* clients, we have to explicitly replay it.
|
||||
*
|
||||
* Under Wayland, we retrieve all events and we have to make sure
|
||||
* to filter them out from Wayland clients.
|
||||
*/
|
||||
if (meta_window_handle_ungrabbed_event (window, event))
|
||||
if (!clutter_event_get_event_sequence (event))
|
||||
{
|
||||
/* Swallow all non-touch events on windows that come our way.
|
||||
* Touch events that reach here aren't yet in an accepted state,
|
||||
* so Clutter must see them to maybe trigger gestures into
|
||||
* recognition.
|
||||
*/
|
||||
bypass_clutter = TRUE;
|
||||
}
|
||||
|
||||
meta_window_handle_ungrabbed_event (window, event);
|
||||
|
||||
/* This might start a grab op. If it does, then filter out the
|
||||
* event, and if it doesn't, replay the event to release our
|
||||
* own sync grab. */
|
||||
|
||||
if (display->event_route == META_EVENT_ROUTE_WINDOW_OP)
|
||||
{
|
||||
bypass_clutter = TRUE;
|
||||
bypass_wayland = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
if (META_IS_BACKEND_X11 (backend))
|
||||
/* Only replay button press events, since that's where we
|
||||
* have the synchronous grab. */
|
||||
if (event->type == CLUTTER_BUTTON_PRESS)
|
||||
{
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
||||
meta_verbose ("Allowing events time %u\n",
|
||||
(unsigned int)event->button.time);
|
||||
XIAllowEvents (xdisplay, clutter_event_get_device_id (event),
|
||||
XIReplayDevice, event->button.time);
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
if (META_IS_BACKEND_X11 (backend))
|
||||
{
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
||||
meta_verbose ("Allowing events time %u\n",
|
||||
(unsigned int)event->button.time);
|
||||
XIAllowEvents (xdisplay, clutter_event_get_device_id (event),
|
||||
XIReplayDevice, event->button.time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,18 +301,20 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
|
||||
out:
|
||||
/* If the compositor has a grab, don't pass that through to Wayland */
|
||||
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
|
||||
if (display->event_route == META_EVENT_ROUTE_COMPOSITOR_GRAB)
|
||||
bypass_wayland = TRUE;
|
||||
|
||||
/* If a Wayland client has a grab, don't pass that through to Clutter */
|
||||
if (display->grab_op == META_GRAB_OP_WAYLAND_POPUP)
|
||||
if (display->event_route == META_EVENT_ROUTE_WAYLAND_POPUP)
|
||||
bypass_clutter = TRUE;
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (compositor && !bypass_wayland)
|
||||
{
|
||||
if (meta_wayland_compositor_handle_event (compositor, event))
|
||||
bypass_clutter = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
display->current_time = CurrentTime;
|
||||
return bypass_clutter;
|
||||
@@ -237,7 +332,6 @@ event_callback (const ClutterEvent *event,
|
||||
void
|
||||
meta_display_init_events (MetaDisplay *display)
|
||||
{
|
||||
meta_display_init_events_x11 (display);
|
||||
display->clutter_event_filter = clutter_event_add_filter (NULL,
|
||||
event_callback,
|
||||
NULL,
|
||||
@@ -247,7 +341,6 @@ meta_display_init_events (MetaDisplay *display)
|
||||
void
|
||||
meta_display_free_events (MetaDisplay *display)
|
||||
{
|
||||
meta_display_free_events_x11 (display);
|
||||
clutter_event_remove_filter (display->clutter_event_filter);
|
||||
display->clutter_event_filter = 0;
|
||||
}
|
||||
|
||||
@@ -151,7 +151,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
* style and background.
|
||||
*/
|
||||
meta_ui_update_frame_style (window->screen->ui, frame->xwindow);
|
||||
meta_ui_reset_frame_bg (window->screen->ui, frame->xwindow);
|
||||
|
||||
if (window->title)
|
||||
meta_ui_set_frame_title (window->screen->ui,
|
||||
@@ -372,15 +371,6 @@ meta_frame_sync_to_window (MetaFrame *frame,
|
||||
frame->rect.x + frame->rect.width,
|
||||
frame->rect.y + frame->rect.height);
|
||||
|
||||
/* set bg to none to avoid flicker */
|
||||
if (need_resize)
|
||||
{
|
||||
meta_ui_unflicker_frame_bg (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
frame->rect.width,
|
||||
frame->rect.height);
|
||||
}
|
||||
|
||||
meta_ui_move_resize_frame (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
frame->rect.x,
|
||||
@@ -390,9 +380,6 @@ meta_frame_sync_to_window (MetaFrame *frame,
|
||||
|
||||
if (need_resize)
|
||||
{
|
||||
meta_ui_reset_frame_bg (frame->window->screen->ui,
|
||||
frame->xwindow);
|
||||
|
||||
/* If we're interactively resizing the frame, repaint
|
||||
* it immediately so we don't start to lag.
|
||||
*/
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <meta/keybindings.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
typedef struct _MetaKeyHandler MetaKeyHandler;
|
||||
struct _MetaKeyHandler
|
||||
@@ -80,9 +81,6 @@ typedef struct
|
||||
*/
|
||||
GSList *combos;
|
||||
|
||||
/* for keybindings that can have shift or not like Alt+Tab */
|
||||
gboolean add_shift:1;
|
||||
|
||||
/* for keybindings that apply only to a window */
|
||||
gboolean per_window:1;
|
||||
|
||||
@@ -90,6 +88,23 @@ typedef struct
|
||||
gboolean builtin:1;
|
||||
} MetaKeyPref;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GHashTable *key_bindings;
|
||||
GHashTable *key_bindings_index;
|
||||
xkb_mod_mask_t ignored_modifier_mask;
|
||||
xkb_mod_mask_t hyper_mask;
|
||||
xkb_mod_mask_t super_mask;
|
||||
xkb_mod_mask_t meta_mask;
|
||||
MetaKeyCombo overlay_key_combo;
|
||||
gboolean overlay_key_only_pressed;
|
||||
MetaKeyCombo *iso_next_group_combos;
|
||||
int n_iso_next_group_combos;
|
||||
|
||||
/* Alt+click button grabs */
|
||||
ClutterModifierType window_grab_modifiers;
|
||||
} MetaKeyBindingManager;
|
||||
|
||||
void meta_display_init_keys (MetaDisplay *display);
|
||||
void meta_display_shutdown_keys (MetaDisplay *display);
|
||||
void meta_screen_grab_keys (MetaScreen *screen);
|
||||
@@ -103,8 +118,8 @@ void meta_window_ungrab_all_keys (MetaWindow *window,
|
||||
gboolean meta_keybindings_process_event (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
const ClutterEvent *event);
|
||||
void meta_display_process_mapping_event (MetaDisplay *display,
|
||||
XEvent *event);
|
||||
|
||||
ClutterModifierType meta_display_get_window_grab_modifiers (MetaDisplay *display);
|
||||
|
||||
gboolean meta_prefs_add_keybinding (const char *name,
|
||||
GSettings *settings,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,6 +52,7 @@
|
||||
#include "ui.h"
|
||||
#include <meta/prefs.h>
|
||||
#include <meta/compositor.h>
|
||||
#include <meta/meta-backend.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <glib-unix.h>
|
||||
@@ -77,8 +78,9 @@
|
||||
|
||||
#include "x11/session.h"
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "wayland/meta-wayland.h"
|
||||
#include "backends/meta-backend.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The exit code we'll return to our parent process when we eventually die.
|
||||
@@ -160,7 +162,9 @@ static gchar *opt_client_id;
|
||||
static gboolean opt_replace_wm;
|
||||
static gboolean opt_disable_sm;
|
||||
static gboolean opt_sync;
|
||||
#ifdef HAVE_WAYLAND
|
||||
static gboolean opt_wayland;
|
||||
#endif
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static gboolean opt_display_server;
|
||||
#endif
|
||||
@@ -201,12 +205,14 @@ static GOptionEntry meta_options[] = {
|
||||
N_("Make X calls synchronous"),
|
||||
NULL
|
||||
},
|
||||
#ifdef HAVE_WAYLAND
|
||||
{
|
||||
"wayland", 0, 0, G_OPTION_ARG_NONE,
|
||||
&opt_wayland,
|
||||
N_("Run as a wayland compositor"),
|
||||
NULL
|
||||
},
|
||||
#endif
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
{
|
||||
"display-server", 0, 0, G_OPTION_ARG_NONE,
|
||||
@@ -271,8 +277,10 @@ meta_finalize (void)
|
||||
meta_display_close (display,
|
||||
CurrentTime); /* I doubt correct timestamps matter here */
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_wayland_finalize ();
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -319,9 +327,13 @@ meta_init (void)
|
||||
#if defined(CLUTTER_WINDOWING_EGL) && defined(HAVE_NATIVE_BACKEND)
|
||||
if (opt_display_server)
|
||||
clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL);
|
||||
else
|
||||
#endif
|
||||
clutter_set_windowing_backend (CLUTTER_WINDOWING_X11);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
meta_set_is_wayland_compositor (opt_wayland);
|
||||
#endif
|
||||
|
||||
if (g_get_home_dir ())
|
||||
if (chdir (g_get_home_dir ()) < 0)
|
||||
@@ -334,15 +346,24 @@ meta_init (void)
|
||||
g_irepository_prepend_search_path (MUTTER_PKGLIBDIR);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
/* NB: When running as a hybrid wayland compositor we run our own headless X
|
||||
* server so the user can't control the X display to connect too. */
|
||||
meta_wayland_init ();
|
||||
}
|
||||
else
|
||||
meta_wayland_pre_clutter_init ();
|
||||
#endif
|
||||
|
||||
/* NB: When running as a hybrid wayland compositor we run our own headless X
|
||||
* server so the user can't control the X display to connect too. */
|
||||
if (!meta_is_wayland_compositor ())
|
||||
meta_select_display (opt_display_name);
|
||||
|
||||
meta_clutter_init ();
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
/* Bring up Wayland. This also launches Xwayland and sets DISPLAY as well... */
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_wayland_init ();
|
||||
#endif
|
||||
|
||||
meta_set_syncing (opt_sync || (g_getenv ("MUTTER_SYNC") != NULL));
|
||||
|
||||
if (opt_replace_wm)
|
||||
@@ -355,18 +376,6 @@ meta_init (void)
|
||||
|
||||
meta_ui_init ();
|
||||
|
||||
/* If we are running with wayland then we don't wait until we have
|
||||
* an X connection before initializing clutter we instead initialize
|
||||
* it earlier since we need to initialize the GL driver so the driver
|
||||
* can register any needed wayland extensions. */
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
/*
|
||||
* Clutter can only be initialized after the UI.
|
||||
*/
|
||||
meta_clutter_init ();
|
||||
}
|
||||
|
||||
meta_restart_init ();
|
||||
|
||||
/*
|
||||
|
||||
@@ -70,7 +70,6 @@ gboolean meta_gesture_tracker_set_sequence_state (MetaGestureTracker
|
||||
MetaSequenceState state);
|
||||
MetaSequenceState meta_gesture_tracker_get_sequence_state (MetaGestureTracker *tracker,
|
||||
ClutterEventSequence *sequence);
|
||||
gboolean meta_gesture_tracker_consumes_event (MetaGestureTracker *tracker,
|
||||
const ClutterEvent *event);
|
||||
gint meta_gesture_tracker_get_n_current_touches (MetaGestureTracker *tracker);
|
||||
|
||||
#endif /* META_GESTURE_TRACKER_PRIVATE_H */
|
||||
|
||||
@@ -413,6 +413,7 @@ meta_gesture_tracker_handle_event (MetaGestureTracker *tracker,
|
||||
{
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
ClutterEventSequence *sequence;
|
||||
MetaSequenceState state;
|
||||
MetaSequenceInfo *info;
|
||||
ClutterActor *stage;
|
||||
gfloat x, y;
|
||||
@@ -446,6 +447,7 @@ meta_gesture_tracker_handle_event (MetaGestureTracker *tracker,
|
||||
meta_gesture_tracker_set_sequence_state (tracker, sequence,
|
||||
priv->stage_state);
|
||||
}
|
||||
state = info->state;
|
||||
break;
|
||||
case CLUTTER_TOUCH_END:
|
||||
info = g_hash_table_lookup (priv->sequences, sequence);
|
||||
@@ -460,6 +462,7 @@ meta_gesture_tracker_handle_event (MetaGestureTracker *tracker,
|
||||
meta_gesture_tracker_set_sequence_state (tracker, sequence,
|
||||
META_SEQUENCE_REJECTED);
|
||||
|
||||
state = info->state;
|
||||
g_hash_table_remove (priv->sequences, sequence);
|
||||
|
||||
if (g_hash_table_size (priv->sequences) == 0)
|
||||
@@ -478,13 +481,34 @@ meta_gesture_tracker_handle_event (MetaGestureTracker *tracker,
|
||||
ABS (info->start_y - y) > DISTANCE_THRESHOLD))
|
||||
meta_gesture_tracker_set_sequence_state (tracker, sequence,
|
||||
META_SEQUENCE_REJECTED);
|
||||
state = info->state;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
/* As soon as a sequence is accepted, we replay it to
|
||||
* the stage as a captured event, and make sure it's never
|
||||
* propagated anywhere else. Since ClutterGestureAction does
|
||||
* all its event handling from a captured-event handler on
|
||||
* the stage, this effectively acts as a "sequence grab" on
|
||||
* gesture actions.
|
||||
*
|
||||
* Sequences that aren't (yet or never) in an accepted state
|
||||
* will go through, these events will get processed through
|
||||
* the compositor, and eventually through clutter, still
|
||||
* triggering the gestures capturing events on the stage, and
|
||||
* possibly resulting in MetaSequenceState changes.
|
||||
*/
|
||||
if (state == META_SEQUENCE_ACCEPTED)
|
||||
{
|
||||
clutter_actor_event (CLUTTER_ACTOR (clutter_event_get_stage (event)),
|
||||
event, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -546,22 +570,13 @@ meta_gesture_tracker_get_sequence_state (MetaGestureTracker *tracker,
|
||||
return info->state;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_gesture_tracker_consumes_event (MetaGestureTracker *tracker,
|
||||
const ClutterEvent *event)
|
||||
gint
|
||||
meta_gesture_tracker_get_n_current_touches (MetaGestureTracker *tracker)
|
||||
{
|
||||
ClutterEventSequence *sequence;
|
||||
MetaSequenceState state;
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (META_IS_GESTURE_TRACKER (tracker), FALSE);
|
||||
g_return_val_if_fail (META_IS_GESTURE_TRACKER (tracker), 0);
|
||||
|
||||
sequence = clutter_event_get_event_sequence (event);
|
||||
|
||||
if (!sequence)
|
||||
return FALSE;
|
||||
|
||||
state = meta_gesture_tracker_get_sequence_state (tracker, sequence);
|
||||
|
||||
return (event->type != CLUTTER_TOUCH_END &&
|
||||
(state == META_SEQUENCE_REJECTED || state == META_SEQUENCE_PENDING_END));
|
||||
priv = meta_gesture_tracker_get_instance_private (tracker);
|
||||
return g_hash_table_size (priv->sequences);
|
||||
}
|
||||
|
||||
132
src/core/prefs.c
132
src/core/prefs.c
@@ -28,7 +28,6 @@
|
||||
|
||||
#include <config.h>
|
||||
#include <meta/prefs.h>
|
||||
#include "ui.h"
|
||||
#include "util-private.h"
|
||||
#include "meta-plugin-manager.h"
|
||||
#include <glib.h>
|
||||
@@ -67,6 +66,7 @@
|
||||
#define SCHEMA_INTERFACE "org.gnome.desktop.interface"
|
||||
#define SCHEMA_INPUT_SOURCES "org.gnome.desktop.input-sources"
|
||||
#define SCHEMA_XSETTINGS "org.gnome.settings-daemon.plugins.xsettings"
|
||||
#define SCHEMA_MOUSE "org.gnome.settings-daemon.peripherals.mouse"
|
||||
|
||||
#define SETTINGS(s) g_hash_table_lookup (settings_schemas, (s))
|
||||
|
||||
@@ -101,6 +101,7 @@ static gboolean gnome_animations = TRUE;
|
||||
static char *cursor_theme = NULL;
|
||||
static int cursor_size = 24;
|
||||
static int draggable_border_width = 10;
|
||||
static int drag_threshold;
|
||||
static gboolean resize_with_right_button = FALSE;
|
||||
static gboolean edge_tiling = FALSE;
|
||||
static gboolean force_fullscreen = TRUE;
|
||||
@@ -492,6 +493,13 @@ static MetaIntPreference preferences_int[] =
|
||||
},
|
||||
&draggable_border_width
|
||||
},
|
||||
{
|
||||
{ "drag-threshold",
|
||||
SCHEMA_MOUSE,
|
||||
META_PREF_DRAG_THRESHOLD,
|
||||
},
|
||||
&drag_threshold
|
||||
},
|
||||
{ { NULL, 0, 0 }, NULL },
|
||||
};
|
||||
|
||||
@@ -978,6 +986,10 @@ meta_prefs_init (void)
|
||||
g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL);
|
||||
g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_MUTTER), settings);
|
||||
|
||||
settings = g_settings_new (SCHEMA_MOUSE);
|
||||
g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL);
|
||||
g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_MOUSE), settings);
|
||||
|
||||
/* Individual keys we watch outside of our schemas */
|
||||
settings = g_settings_new (SCHEMA_INTERFACE);
|
||||
g_signal_connect (settings, "changed::" KEY_GNOME_ACCESSIBILITY,
|
||||
@@ -1198,8 +1210,9 @@ settings_changed (GSettings *settings,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Someone added a preference of an unhandled type */
|
||||
g_assert_not_reached ();
|
||||
/* Unknown preference type. This quite likely simply isn't
|
||||
* a preference we track changes to. */
|
||||
return;
|
||||
}
|
||||
|
||||
g_variant_unref (value);
|
||||
@@ -1334,10 +1347,26 @@ meta_prefs_get_cursor_theme (void)
|
||||
return cursor_theme;
|
||||
}
|
||||
|
||||
static int
|
||||
get_scale_factor (void)
|
||||
{
|
||||
GdkScreen *screen;
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
g_value_init (&value, G_TYPE_INT);
|
||||
|
||||
/* XXX: Should this be in ui/ ? Or MetaMonitorManager? */
|
||||
screen = gdk_screen_get_default ();
|
||||
if (gdk_screen_get_setting (screen, "gdk-window-scaling-factor", &value))
|
||||
return g_value_get_int (&value);
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
meta_prefs_get_cursor_size (void)
|
||||
{
|
||||
return cursor_size;
|
||||
return cursor_size * get_scale_factor ();
|
||||
}
|
||||
|
||||
|
||||
@@ -1668,43 +1697,43 @@ button_layout_handler (GVariant *value,
|
||||
g_strfreev (sides);
|
||||
|
||||
/* Invert the button layout for RTL languages */
|
||||
if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
|
||||
{
|
||||
MetaButtonLayout rtl_layout;
|
||||
int j;
|
||||
if (meta_get_locale_direction() == META_LOCALE_DIRECTION_RTL)
|
||||
{
|
||||
MetaButtonLayout rtl_layout;
|
||||
int j;
|
||||
|
||||
for (i = 0; new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1];
|
||||
if (j == 0)
|
||||
rtl_layout.right_buttons_has_spacer[i - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
|
||||
else
|
||||
rtl_layout.right_buttons_has_spacer[j - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
|
||||
}
|
||||
for (; j < MAX_BUTTONS_PER_CORNER; j++)
|
||||
{
|
||||
rtl_layout.right_buttons[j] = META_BUTTON_FUNCTION_LAST;
|
||||
rtl_layout.right_buttons_has_spacer[j] = FALSE;
|
||||
}
|
||||
for (i = 0; new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1];
|
||||
if (j == 0)
|
||||
rtl_layout.right_buttons_has_spacer[i - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
|
||||
else
|
||||
rtl_layout.right_buttons_has_spacer[j - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
|
||||
}
|
||||
for (; j < MAX_BUTTONS_PER_CORNER; j++)
|
||||
{
|
||||
rtl_layout.right_buttons[j] = META_BUTTON_FUNCTION_LAST;
|
||||
rtl_layout.right_buttons_has_spacer[j] = FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1];
|
||||
if (j == 0)
|
||||
rtl_layout.left_buttons_has_spacer[i - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
|
||||
else
|
||||
rtl_layout.left_buttons_has_spacer[j - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
|
||||
}
|
||||
for (; j < MAX_BUTTONS_PER_CORNER; j++)
|
||||
{
|
||||
rtl_layout.left_buttons[j] = META_BUTTON_FUNCTION_LAST;
|
||||
rtl_layout.left_buttons_has_spacer[j] = FALSE;
|
||||
}
|
||||
for (i = 0; new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1];
|
||||
if (j == 0)
|
||||
rtl_layout.left_buttons_has_spacer[i - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
|
||||
else
|
||||
rtl_layout.left_buttons_has_spacer[j - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
|
||||
}
|
||||
for (; j < MAX_BUTTONS_PER_CORNER; j++)
|
||||
{
|
||||
rtl_layout.left_buttons[j] = META_BUTTON_FUNCTION_LAST;
|
||||
rtl_layout.left_buttons_has_spacer[j] = FALSE;
|
||||
}
|
||||
|
||||
new_layout = rtl_layout;
|
||||
}
|
||||
new_layout = rtl_layout;
|
||||
}
|
||||
|
||||
if (!button_layout_equal (&button_layout, &new_layout))
|
||||
{
|
||||
@@ -1908,6 +1937,9 @@ meta_preference_to_string (MetaPreference pref)
|
||||
case META_PREF_DRAGGABLE_BORDER_WIDTH:
|
||||
return "DRAGGABLE_BORDER_WIDTH";
|
||||
|
||||
case META_PREF_DRAG_THRESHOLD:
|
||||
return "DRAG_TRHESHOLD";
|
||||
|
||||
case META_PREF_DYNAMIC_WORKSPACES:
|
||||
return "DYNAMIC_WORKSPACES";
|
||||
|
||||
@@ -2001,23 +2033,6 @@ update_binding (MetaKeyPref *binding,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Bug 329676: Bindings which can be shifted must not have no modifiers,
|
||||
* nor only SHIFT as a modifier.
|
||||
*/
|
||||
|
||||
if (binding->add_shift &&
|
||||
0 != keysym &&
|
||||
(META_VIRTUAL_SHIFT_MASK == mods || 0 == mods))
|
||||
{
|
||||
meta_warning ("Cannot bind \"%s\" to %s: it needs a modifier "
|
||||
"such as Ctrl or Alt.\n",
|
||||
binding->name, strokes[i]);
|
||||
|
||||
/* Value is kept and will thus be removed next time we save the key.
|
||||
* Changing the key in response to a modification could lead to cyclic calls. */
|
||||
continue;
|
||||
}
|
||||
|
||||
combo = g_malloc0 (sizeof (MetaKeyCombo));
|
||||
combo->keysym = keysym;
|
||||
combo->keycode = keycode;
|
||||
@@ -2193,7 +2208,6 @@ meta_prefs_add_keybinding (const char *name,
|
||||
pref->settings = g_object_ref (settings);
|
||||
pref->action = action;
|
||||
pref->combos = NULL;
|
||||
pref->add_shift = (flags & META_KEY_BINDING_REVERSES) != 0;
|
||||
pref->per_window = (flags & META_KEY_BINDING_PER_WINDOW) != 0;
|
||||
pref->builtin = (flags & META_KEY_BINDING_BUILTIN) != 0;
|
||||
|
||||
@@ -2373,6 +2387,12 @@ meta_prefs_get_draggable_border_width (void)
|
||||
return draggable_border_width;
|
||||
}
|
||||
|
||||
int
|
||||
meta_prefs_get_drag_threshold (void)
|
||||
{
|
||||
return drag_threshold;
|
||||
}
|
||||
|
||||
void
|
||||
meta_prefs_set_force_fullscreen (gboolean whether)
|
||||
{
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
#include "ui.h"
|
||||
#include "meta-monitor-manager.h"
|
||||
|
||||
typedef void (* MetaScreenWindowFunc) (MetaScreen *screen, MetaWindow *window,
|
||||
gpointer user_data);
|
||||
typedef void (* MetaScreenWindowFunc) (MetaWindow *window,
|
||||
gpointer user_data);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -140,6 +140,7 @@ void meta_screen_free (MetaScreen *scree
|
||||
void meta_screen_init_workspaces (MetaScreen *screen);
|
||||
void meta_screen_manage_all_windows (MetaScreen *screen);
|
||||
void meta_screen_foreach_window (MetaScreen *screen,
|
||||
MetaListWindowsFlags flags,
|
||||
MetaScreenWindowFunc func,
|
||||
gpointer data);
|
||||
|
||||
|
||||
@@ -63,7 +63,6 @@ static char* get_screen_name (MetaDisplay *display,
|
||||
|
||||
static void update_num_workspaces (MetaScreen *screen,
|
||||
guint32 timestamp);
|
||||
static void update_focus_mode (MetaScreen *screen);
|
||||
static void set_workspace_names (MetaScreen *screen);
|
||||
static void prefs_changed_callback (MetaPreference pref,
|
||||
gpointer data);
|
||||
@@ -407,17 +406,13 @@ meta_screen_xinerama_index_to_monitor_index (MetaScreen *screen,
|
||||
static void
|
||||
reload_monitor_infos (MetaScreen *screen)
|
||||
{
|
||||
GList *tmp;
|
||||
GList *l;
|
||||
MetaMonitorManager *manager;
|
||||
|
||||
tmp = screen->workspaces;
|
||||
while (tmp != NULL)
|
||||
for (l = screen->workspaces; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWorkspace *space = tmp->data;
|
||||
|
||||
MetaWorkspace *space = l->data;
|
||||
meta_workspace_invalidate_work_area (space);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
/* Any previous screen->monitor_infos or screen->outputs is freed by the caller */
|
||||
@@ -926,10 +921,6 @@ prefs_changed_callback (MetaPreference pref,
|
||||
meta_display_get_current_time_roundtrip (screen->display);
|
||||
update_num_workspaces (screen, timestamp);
|
||||
}
|
||||
else if (pref == META_PREF_FOCUS_MODE)
|
||||
{
|
||||
update_focus_mode (screen);
|
||||
}
|
||||
else if (pref == META_PREF_WORKSPACE_NAMES)
|
||||
{
|
||||
set_workspace_names (screen);
|
||||
@@ -967,75 +958,23 @@ get_screen_name (MetaDisplay *display,
|
||||
return scr;
|
||||
}
|
||||
|
||||
static gint
|
||||
ptrcmp (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
if (a < b)
|
||||
return -1;
|
||||
else if (a > b)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
listify_func (gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
GSList **listp;
|
||||
|
||||
listp = data;
|
||||
|
||||
*listp = g_slist_prepend (*listp, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_screen_foreach_window:
|
||||
* @screen: a #MetaScreen
|
||||
* @func: function to call for each window
|
||||
* @data: user data to pass to @func
|
||||
*
|
||||
* Calls the specified function for each window on the screen,
|
||||
* ignoring override-redirect windows.
|
||||
*/
|
||||
void
|
||||
meta_screen_foreach_window (MetaScreen *screen,
|
||||
MetaScreenWindowFunc func,
|
||||
gpointer data)
|
||||
meta_screen_foreach_window (MetaScreen *screen,
|
||||
MetaListWindowsFlags flags,
|
||||
MetaScreenWindowFunc func,
|
||||
gpointer data)
|
||||
{
|
||||
GSList *winlist;
|
||||
GSList *tmp;
|
||||
GSList *windows;
|
||||
|
||||
/* If we end up doing this often, just keeping a list
|
||||
* of windows might be sensible.
|
||||
*/
|
||||
|
||||
winlist = NULL;
|
||||
g_hash_table_foreach (screen->display->xids,
|
||||
listify_func,
|
||||
&winlist);
|
||||
windows = meta_display_list_windows (screen->display, flags);
|
||||
|
||||
winlist = g_slist_sort (winlist, ptrcmp);
|
||||
g_slist_foreach (windows, (GFunc) func, data);
|
||||
|
||||
tmp = winlist;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
/* If the next node doesn't contain this window
|
||||
* a second time, delete the window.
|
||||
*/
|
||||
if (tmp->next == NULL ||
|
||||
(tmp->next && tmp->next->data != tmp->data))
|
||||
{
|
||||
MetaWindow *window = tmp->data;
|
||||
|
||||
if (META_IS_WINDOW (window) &&
|
||||
window->screen == screen &&
|
||||
!window->override_redirect)
|
||||
(* func) (screen, window, data);
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
g_slist_free (winlist);
|
||||
g_slist_free (windows);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1060,27 +999,7 @@ MetaWorkspace*
|
||||
meta_screen_get_workspace_by_index (MetaScreen *screen,
|
||||
int idx)
|
||||
{
|
||||
GList *tmp;
|
||||
int i;
|
||||
|
||||
/* should be robust, idx is maybe from an app */
|
||||
if (idx < 0)
|
||||
return NULL;
|
||||
|
||||
i = 0;
|
||||
tmp = screen->workspaces;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWorkspace *w = tmp->data;
|
||||
|
||||
if (i == idx)
|
||||
return w;
|
||||
|
||||
++i;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return g_list_nth_data (screen->workspaces, idx);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1154,41 +1073,28 @@ meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace,
|
||||
guint32 timestamp)
|
||||
{
|
||||
GList *l;
|
||||
GList *next;
|
||||
MetaWorkspace *neighbour = NULL;
|
||||
GList *next = NULL;
|
||||
int index;
|
||||
gboolean active_index_changed;
|
||||
int new_num;
|
||||
|
||||
l = screen->workspaces;
|
||||
while (l)
|
||||
{
|
||||
MetaWorkspace *w = l->data;
|
||||
|
||||
if (w == workspace)
|
||||
{
|
||||
if (l->next)
|
||||
next = l->next;
|
||||
|
||||
if (l->prev)
|
||||
neighbour = l->prev->data;
|
||||
else if (l->next)
|
||||
neighbour = l->next->data;
|
||||
else
|
||||
{
|
||||
/* Cannot remove the only workspace! */
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
if (!neighbour)
|
||||
l = g_list_find (screen->workspaces, workspace);
|
||||
if (!l)
|
||||
return;
|
||||
|
||||
next = l->next;
|
||||
|
||||
if (l->prev)
|
||||
neighbour = l->prev->data;
|
||||
else if (l->next)
|
||||
neighbour = l->next->data;
|
||||
else
|
||||
{
|
||||
/* Cannot remove the only workspace! */
|
||||
return;
|
||||
}
|
||||
|
||||
meta_workspace_relocate_windows (workspace, neighbour);
|
||||
|
||||
if (workspace == screen->active_workspace)
|
||||
@@ -1213,14 +1119,10 @@ meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace,
|
||||
if (active_index_changed)
|
||||
meta_screen_set_active_workspace_hint (screen);
|
||||
|
||||
l = next;
|
||||
while (l)
|
||||
for (l = next; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWorkspace *w = l->data;
|
||||
|
||||
meta_workspace_update_window_hints (w);
|
||||
|
||||
l = l->next;
|
||||
meta_workspace_index_changed (w);
|
||||
}
|
||||
|
||||
meta_screen_queue_workarea_recalc (screen);
|
||||
@@ -1280,7 +1182,7 @@ update_num_workspaces (MetaScreen *screen,
|
||||
guint32 timestamp)
|
||||
{
|
||||
int new_num, old_num;
|
||||
GList *tmp;
|
||||
GList *l;
|
||||
int i;
|
||||
GList *extras;
|
||||
MetaWorkspace *last_remaining;
|
||||
@@ -1319,10 +1221,9 @@ update_num_workspaces (MetaScreen *screen,
|
||||
last_remaining = NULL;
|
||||
extras = NULL;
|
||||
i = 0;
|
||||
tmp = screen->workspaces;
|
||||
while (tmp != NULL)
|
||||
for (l = screen->workspaces; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWorkspace *w = tmp->data;
|
||||
MetaWorkspace *w = l->data;
|
||||
|
||||
if (i >= new_num)
|
||||
extras = g_list_prepend (extras, w);
|
||||
@@ -1330,7 +1231,6 @@ update_num_workspaces (MetaScreen *screen,
|
||||
last_remaining = w;
|
||||
|
||||
++i;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
old_num = i;
|
||||
|
||||
@@ -1343,32 +1243,26 @@ update_num_workspaces (MetaScreen *screen,
|
||||
* is on a removed workspace ;-)
|
||||
*/
|
||||
need_change_space = FALSE;
|
||||
tmp = extras;
|
||||
while (tmp != NULL)
|
||||
for (l = extras; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWorkspace *w = tmp->data;
|
||||
MetaWorkspace *w = l->data;
|
||||
|
||||
meta_workspace_relocate_windows (w, last_remaining);
|
||||
|
||||
if (w == screen->active_workspace)
|
||||
need_change_space = TRUE;
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
if (need_change_space)
|
||||
meta_workspace_activate (last_remaining, timestamp);
|
||||
|
||||
/* Should now be safe to free the workspaces */
|
||||
tmp = extras;
|
||||
while (tmp != NULL)
|
||||
for (l = extras; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWorkspace *w = tmp->data;
|
||||
MetaWorkspace *w = l->data;
|
||||
|
||||
g_assert (w->windows == NULL);
|
||||
meta_workspace_remove (w);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
g_list_free (extras);
|
||||
@@ -1386,12 +1280,6 @@ update_num_workspaces (MetaScreen *screen,
|
||||
g_object_notify (G_OBJECT (screen), "n-workspaces");
|
||||
}
|
||||
|
||||
static void
|
||||
update_focus_mode (MetaScreen *screen)
|
||||
{
|
||||
/* nothing to do anymore */ ;
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_update_cursor (MetaScreen *screen)
|
||||
{
|
||||
@@ -2116,31 +2004,25 @@ static void
|
||||
set_work_area_hint (MetaScreen *screen)
|
||||
{
|
||||
int num_workspaces;
|
||||
GList *tmp_list;
|
||||
GList *l;
|
||||
unsigned long *data, *tmp;
|
||||
MetaRectangle area;
|
||||
|
||||
num_workspaces = meta_screen_get_n_workspaces (screen);
|
||||
data = g_new (unsigned long, num_workspaces * 4);
|
||||
tmp_list = screen->workspaces;
|
||||
tmp = data;
|
||||
|
||||
while (tmp_list != NULL)
|
||||
for (l = screen->workspaces; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWorkspace *workspace = tmp_list->data;
|
||||
MetaWorkspace *workspace = l->data;
|
||||
|
||||
if (workspace->screen == screen)
|
||||
{
|
||||
meta_workspace_get_work_area_all_monitors (workspace, &area);
|
||||
tmp[0] = area.x;
|
||||
tmp[1] = area.y;
|
||||
tmp[2] = area.width;
|
||||
tmp[3] = area.height;
|
||||
meta_workspace_get_work_area_all_monitors (workspace, &area);
|
||||
tmp[0] = area.x;
|
||||
tmp[1] = area.y;
|
||||
tmp[2] = area.width;
|
||||
tmp[3] = area.height;
|
||||
|
||||
tmp += 4;
|
||||
}
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
tmp += 4;
|
||||
}
|
||||
|
||||
meta_error_trap_push (screen->display);
|
||||
@@ -2480,9 +2362,8 @@ meta_screen_free_workspace_layout (MetaWorkspaceLayout *layout)
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_resize_func (MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
void *user_data)
|
||||
meta_screen_resize_func (MetaWindow *window,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (window->struts)
|
||||
{
|
||||
@@ -2497,8 +2378,6 @@ static void
|
||||
on_monitors_changed (MetaMonitorManager *manager,
|
||||
MetaScreen *screen)
|
||||
{
|
||||
GSList *tmp, *windows;
|
||||
|
||||
meta_monitor_manager_get_screen_size (manager,
|
||||
&screen->rect.width,
|
||||
&screen->rect.height);
|
||||
@@ -2522,24 +2401,11 @@ on_monitors_changed (MetaMonitorManager *manager,
|
||||
&changes);
|
||||
}
|
||||
|
||||
meta_compositor_sync_screen_size (screen->display->compositor,
|
||||
screen->rect.width, screen->rect.height);
|
||||
|
||||
/* Queue a resize on all the windows */
|
||||
meta_screen_foreach_window (screen, meta_screen_resize_func, 0);
|
||||
meta_screen_foreach_window (screen, META_LIST_DEFAULT, meta_screen_resize_func, 0);
|
||||
|
||||
/* Fix up monitor for all windows on this screen */
|
||||
windows = meta_display_list_windows (screen->display,
|
||||
META_LIST_INCLUDE_OVERRIDE_REDIRECT);
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
MetaWindow *window = tmp->data;
|
||||
|
||||
if (window->screen == screen)
|
||||
meta_window_update_for_monitors_changed (window);
|
||||
}
|
||||
|
||||
g_slist_free (windows);
|
||||
meta_screen_foreach_window (screen, META_LIST_INCLUDE_OVERRIDE_REDIRECT, (MetaScreenWindowFunc) meta_window_update_for_monitors_changed, 0);
|
||||
|
||||
meta_screen_queue_check_fullscreen (screen);
|
||||
|
||||
@@ -2564,8 +2430,7 @@ meta_screen_update_showing_desktop_hint (MetaScreen *screen)
|
||||
static void
|
||||
queue_windows_showing (MetaScreen *screen)
|
||||
{
|
||||
GSList *windows;
|
||||
GSList *tmp;
|
||||
GSList *windows, *l;
|
||||
|
||||
/* Must operate on all windows on display instead of just on the
|
||||
* active_workspace's window list, because the active_workspace's
|
||||
@@ -2573,15 +2438,10 @@ queue_windows_showing (MetaScreen *screen)
|
||||
*/
|
||||
windows = meta_display_list_windows (screen->display, META_LIST_DEFAULT);
|
||||
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
for (l = windows; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
|
||||
if (w->screen == screen)
|
||||
meta_window_queue (w, META_QUEUE_CALC_SHOWING);
|
||||
|
||||
tmp = tmp->next;
|
||||
MetaWindow *w = l->data;
|
||||
meta_window_queue (w, META_QUEUE_CALC_SHOWING);
|
||||
}
|
||||
|
||||
g_slist_free (windows);
|
||||
@@ -2591,22 +2451,14 @@ void
|
||||
meta_screen_minimize_all_on_active_workspace_except (MetaScreen *screen,
|
||||
MetaWindow *keep)
|
||||
{
|
||||
GList *windows;
|
||||
GList *tmp;
|
||||
GList *l;
|
||||
|
||||
windows = screen->active_workspace->windows;
|
||||
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
for (l = screen->active_workspace->windows; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaWindow *w = l->data;
|
||||
|
||||
if (w->screen == screen &&
|
||||
w->has_minimize_func &&
|
||||
w != keep)
|
||||
if (w->has_minimize_func && w != keep)
|
||||
meta_window_minimize (w);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2614,7 +2466,7 @@ void
|
||||
meta_screen_show_desktop (MetaScreen *screen,
|
||||
guint32 timestamp)
|
||||
{
|
||||
GList *windows;
|
||||
GList *l;
|
||||
|
||||
if (screen->active_workspace->showing_desktop)
|
||||
return;
|
||||
@@ -2626,22 +2478,17 @@ meta_screen_show_desktop (MetaScreen *screen,
|
||||
/* Focus the most recently used META_WINDOW_DESKTOP window, if there is one;
|
||||
* see bug 159257.
|
||||
*/
|
||||
windows = screen->active_workspace->mru_list;
|
||||
while (windows != NULL)
|
||||
for (l = screen->active_workspace->mru_list; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWindow *w = windows->data;
|
||||
MetaWindow *w = l->data;
|
||||
|
||||
if (w->screen == screen &&
|
||||
w->type == META_WINDOW_DESKTOP)
|
||||
if (w->type == META_WINDOW_DESKTOP)
|
||||
{
|
||||
meta_window_focus (w, timestamp);
|
||||
break;
|
||||
}
|
||||
|
||||
windows = windows->next;
|
||||
}
|
||||
|
||||
|
||||
meta_screen_update_showing_desktop_hint (screen);
|
||||
}
|
||||
|
||||
@@ -2770,7 +2617,7 @@ startup_sequence_timeout (void *data)
|
||||
{
|
||||
MetaScreen *screen = data;
|
||||
CollectTimedOutData ctod;
|
||||
GSList *tmp;
|
||||
GSList *l;
|
||||
|
||||
ctod.list = NULL;
|
||||
g_get_current_time (&ctod.now);
|
||||
@@ -2778,18 +2625,15 @@ startup_sequence_timeout (void *data)
|
||||
collect_timed_out_foreach,
|
||||
&ctod);
|
||||
|
||||
tmp = ctod.list;
|
||||
while (tmp != NULL)
|
||||
for (l = ctod.list; l != NULL; l = l->next)
|
||||
{
|
||||
SnStartupSequence *sequence = tmp->data;
|
||||
SnStartupSequence *sequence = l->data;
|
||||
|
||||
meta_topic (META_DEBUG_STARTUP,
|
||||
"Timed out sequence %s\n",
|
||||
sn_startup_sequence_get_id (sequence));
|
||||
|
||||
sn_startup_sequence_complete (sequence);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
g_slist_free (ctod.list);
|
||||
@@ -2890,7 +2734,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
{
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
const char *startup_id;
|
||||
GSList *tmp;
|
||||
GSList *l;
|
||||
SnStartupSequence *sequence;
|
||||
|
||||
/* Does the window have a startup ID stored? */
|
||||
@@ -2908,12 +2752,12 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
* startup-notification library whether there's anything
|
||||
* stored for the resource name or resource class hints.
|
||||
*/
|
||||
tmp = screen->startup_sequences;
|
||||
while (tmp != NULL)
|
||||
for (l = screen->startup_sequences; l != NULL; l = l->next)
|
||||
{
|
||||
const char *wmclass;
|
||||
SnStartupSequence *seq = l->data;
|
||||
|
||||
wmclass = sn_startup_sequence_get_wmclass (tmp->data);
|
||||
wmclass = sn_startup_sequence_get_wmclass (seq);
|
||||
|
||||
if (wmclass != NULL &&
|
||||
((window->res_class &&
|
||||
@@ -2921,7 +2765,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
(window->res_name &&
|
||||
strcmp (wmclass, window->res_name) == 0)))
|
||||
{
|
||||
sequence = tmp->data;
|
||||
sequence = seq;
|
||||
|
||||
g_assert (window->startup_id == NULL);
|
||||
window->startup_id = g_strdup (sn_startup_sequence_get_id (sequence));
|
||||
@@ -2935,8 +2779,6 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
sn_startup_sequence_complete (sequence);
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2950,20 +2792,18 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
*/
|
||||
if (sequence == NULL)
|
||||
{
|
||||
tmp = screen->startup_sequences;
|
||||
while (tmp != NULL)
|
||||
for (l = screen->startup_sequences; l != NULL; l = l->next)
|
||||
{
|
||||
SnStartupSequence *seq = l->data;
|
||||
const char *id;
|
||||
|
||||
id = sn_startup_sequence_get_id (tmp->data);
|
||||
id = sn_startup_sequence_get_id (seq);
|
||||
|
||||
if (strcmp (id, startup_id) == 0)
|
||||
{
|
||||
sequence = tmp->data;
|
||||
sequence = seq;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,10 +45,8 @@
|
||||
w->type == META_WINDOW_MENU || \
|
||||
w->type == META_WINDOW_UTILITY)
|
||||
|
||||
#define WINDOW_TRANSIENT_FOR_WHOLE_GROUP(w) \
|
||||
((w->xtransient_for == None || \
|
||||
w->transient_parent_is_root_window) && \
|
||||
WINDOW_HAS_TRANSIENT_TYPE (w))
|
||||
#define WINDOW_TRANSIENT_FOR_WHOLE_GROUP(w) \
|
||||
(WINDOW_HAS_TRANSIENT_TYPE (w) && w->transient_for == NULL)
|
||||
|
||||
#define WINDOW_IN_STACK(w) (w->stack_position >= 0)
|
||||
|
||||
@@ -414,8 +412,7 @@ compute_layer (MetaWindow *window)
|
||||
*/
|
||||
if (window->layer != META_LAYER_DESKTOP &&
|
||||
WINDOW_HAS_TRANSIENT_TYPE(window) &&
|
||||
(window->xtransient_for == None ||
|
||||
window->transient_parent_is_root_window))
|
||||
window->transient_for == NULL)
|
||||
{
|
||||
/* We only do the group thing if the dialog is NOT transient for
|
||||
* a particular window. Imagine a group with a normal window, a dock,
|
||||
@@ -636,16 +633,13 @@ create_constraints (Constraint **constraints,
|
||||
|
||||
g_slist_free (group_windows);
|
||||
}
|
||||
else if (w->xtransient_for != None &&
|
||||
!w->transient_parent_is_root_window)
|
||||
else if (w->transient_for != NULL)
|
||||
{
|
||||
MetaWindow *parent;
|
||||
|
||||
parent =
|
||||
meta_display_lookup_x_window (w->display, w->xtransient_for);
|
||||
parent = w->transient_for;
|
||||
|
||||
if (parent && WINDOW_IN_STACK (parent) &&
|
||||
parent->screen == w->screen)
|
||||
if (parent && WINDOW_IN_STACK (parent))
|
||||
{
|
||||
meta_topic (META_DEBUG_STACK, "Constraining %s above %s due to transiency\n",
|
||||
w->desc, parent->desc);
|
||||
@@ -925,7 +919,7 @@ stack_do_relayer (MetaStack *stack)
|
||||
GList *tmp;
|
||||
|
||||
if (!stack->need_relayer)
|
||||
return;
|
||||
return;
|
||||
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"Recomputing layers\n");
|
||||
@@ -1175,16 +1169,16 @@ raise_window_relative_to_managed_windows (MetaScreen *screen,
|
||||
|
||||
/* No sibling to use, just lower ourselves to the bottom
|
||||
* to be sure we're below any override redirect windows.
|
||||
*/
|
||||
*/
|
||||
meta_stack_tracker_record_lower (screen->stack_tracker,
|
||||
window,
|
||||
serial);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* window is the topmost managed child */
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"Moving 0x%lx above topmost managed child window 0x%lx\n",
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"Moving 0x%lx above topmost managed child window 0x%lx\n",
|
||||
window->any.type == META_WINDOW_CLIENT_TYPE_X11 ? window->x11.xwindow: 0,
|
||||
sibling->any.type == META_WINDOW_CLIENT_TYPE_X11 ? sibling->x11.xwindow: 0);
|
||||
|
||||
@@ -1197,26 +1191,26 @@ raise_window_relative_to_managed_windows (MetaScreen *screen,
|
||||
if (x11_sibling)
|
||||
{
|
||||
changes.sibling = x11_sibling->x11.xwindow;
|
||||
changes.stack_mode = Above;
|
||||
changes.stack_mode = Above;
|
||||
|
||||
meta_error_trap_push (screen->display);
|
||||
XConfigureWindow (screen->display->xdisplay,
|
||||
meta_error_trap_push (screen->display);
|
||||
XConfigureWindow (screen->display->xdisplay,
|
||||
window->x11.xwindow,
|
||||
CWSibling | CWStackMode,
|
||||
&changes);
|
||||
meta_error_trap_pop (screen->display);
|
||||
CWSibling | CWStackMode,
|
||||
&changes);
|
||||
meta_error_trap_pop (screen->display);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No sibling to use, just lower ourselves to the bottom
|
||||
* to be sure we're below any override redirect windows.
|
||||
*/
|
||||
meta_error_trap_push (screen->display);
|
||||
XLowerWindow (screen->display->xdisplay,
|
||||
{
|
||||
/* No sibling to use, just lower ourselves to the bottom
|
||||
* to be sure we're below any override redirect windows.
|
||||
*/
|
||||
meta_error_trap_push (screen->display);
|
||||
XLowerWindow (screen->display->xdisplay,
|
||||
window->x11.xwindow);
|
||||
meta_error_trap_pop (screen->display);
|
||||
meta_error_trap_pop (screen->display);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
meta_stack_tracker_record_raise_above (screen->stack_tracker,
|
||||
window,
|
||||
@@ -1357,7 +1351,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
||||
if (x11_root_children_stacked->len > 1)
|
||||
{
|
||||
serial = XNextRequest (stack->screen->display->xdisplay);
|
||||
XRestackWindows (stack->screen->display->xdisplay,
|
||||
XRestackWindows (stack->screen->display->xdisplay,
|
||||
(Window *) x11_root_children_stacked->data,
|
||||
x11_root_children_stacked->len);
|
||||
}
|
||||
@@ -1490,7 +1484,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
||||
|
||||
/* Restack remaining windows */
|
||||
meta_topic (META_DEBUG_STACK, "Restacking remaining %d windows\n",
|
||||
(int) (new_end - newp));
|
||||
(int) (new_end - newp));
|
||||
|
||||
/* rewind until we find the last stacked X window that we can use
|
||||
* as a reference point for re-stacking remaining X windows */
|
||||
|
||||
@@ -946,5 +946,19 @@ meta_later_remove (guint later_id)
|
||||
}
|
||||
}
|
||||
|
||||
MetaLocaleDirection
|
||||
meta_get_locale_direction (void)
|
||||
{
|
||||
switch (gtk_get_locale_direction ())
|
||||
{
|
||||
case GTK_TEXT_DIR_LTR:
|
||||
return META_LOCALE_DIRECTION_LTR;
|
||||
case GTK_TEXT_DIR_RTL:
|
||||
return META_LOCALE_DIRECTION_RTL;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
/* eof util.c */
|
||||
|
||||
|
||||
@@ -329,9 +329,6 @@ struct _MetaWindow
|
||||
*/
|
||||
guint calc_placement : 1;
|
||||
|
||||
/* Transient parent is a root window */
|
||||
guint transient_parent_is_root_window : 1;
|
||||
|
||||
/* if TRUE, window was maximized at start of current grab op */
|
||||
guint shaken_loose : 1;
|
||||
|
||||
@@ -521,7 +518,6 @@ MetaWindow * _meta_window_shared_new (MetaDisplay *display,
|
||||
|
||||
void meta_window_unmanage (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
void meta_window_calc_showing (MetaWindow *window);
|
||||
void meta_window_queue (MetaWindow *window,
|
||||
guint queuebits);
|
||||
void meta_window_tile (MetaWindow *window);
|
||||
@@ -628,7 +624,7 @@ void meta_window_set_user_time (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
|
||||
void meta_window_update_for_monitors_changed (MetaWindow *window);
|
||||
void meta_window_update_on_all_workspaces (MetaWindow *window);
|
||||
void meta_window_on_all_workspaces_changed (MetaWindow *window);
|
||||
|
||||
gboolean meta_window_should_attach_to_parent (MetaWindow *window);
|
||||
gboolean meta_window_can_tile_side_by_side (MetaWindow *window);
|
||||
@@ -665,8 +661,8 @@ void meta_window_handle_enter (MetaWindow *window,
|
||||
guint root_y);
|
||||
void meta_window_handle_leave (MetaWindow *window);
|
||||
|
||||
gboolean meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
const ClutterEvent *event);
|
||||
void meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
const ClutterEvent *event);
|
||||
|
||||
void meta_window_get_client_area_rect (const MetaWindow *window,
|
||||
cairo_rectangle_int_t *rect);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -94,4 +94,6 @@ void meta_workspace_focus_default_window (MetaWorkspace *workspace,
|
||||
|
||||
const char* meta_workspace_get_name (MetaWorkspace *workspace);
|
||||
|
||||
void meta_workspace_index_changed (MetaWorkspace *workspace);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -47,12 +47,6 @@
|
||||
#include <canberra-gtk.h>
|
||||
#endif
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
||||
PROP_N_WINDOWS,
|
||||
};
|
||||
|
||||
void meta_workspace_queue_calc_showing (MetaWorkspace *workspace);
|
||||
static void focus_ancestor_or_top_window (MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one,
|
||||
@@ -62,6 +56,17 @@ static void free_this (gpointer candidate,
|
||||
|
||||
G_DEFINE_TYPE (MetaWorkspace, meta_workspace, G_TYPE_OBJECT);
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
||||
PROP_N_WINDOWS,
|
||||
PROP_WORKSPACE_INDEX,
|
||||
|
||||
LAST_PROP,
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[LAST_PROP];
|
||||
|
||||
enum
|
||||
{
|
||||
WINDOW_ADDED,
|
||||
@@ -70,7 +75,7 @@ enum
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals [LAST_SIGNAL] = { 0 };
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void
|
||||
meta_workspace_finalize (GObject *object)
|
||||
@@ -110,6 +115,9 @@ meta_workspace_get_property (GObject *object,
|
||||
*/
|
||||
g_value_set_uint (value, g_list_length (ws->windows));
|
||||
break;
|
||||
case PROP_WORKSPACE_INDEX:
|
||||
g_value_set_uint (value, meta_workspace_index (ws));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -120,8 +128,6 @@ static void
|
||||
meta_workspace_class_init (MetaWorkspaceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
object_class->finalize = meta_workspace_finalize;
|
||||
object_class->get_property = meta_workspace_get_property;
|
||||
object_class->set_property = meta_workspace_set_property;
|
||||
@@ -141,15 +147,18 @@ meta_workspace_class_init (MetaWorkspaceClass *klass)
|
||||
G_TYPE_NONE, 1,
|
||||
META_TYPE_WINDOW);
|
||||
|
||||
pspec = g_param_spec_uint ("n-windows",
|
||||
"N Windows",
|
||||
"Number of windows",
|
||||
0, G_MAXUINT, 0,
|
||||
G_PARAM_READABLE);
|
||||
obj_props[PROP_N_WINDOWS] = g_param_spec_uint ("n-windows",
|
||||
"N Windows",
|
||||
"Number of windows",
|
||||
0, G_MAXUINT, 0,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_WORKSPACE_INDEX] = g_param_spec_uint ("workspace-index",
|
||||
"Workspace index",
|
||||
"The workspace's index",
|
||||
0, G_MAXUINT, 0,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_N_WINDOWS,
|
||||
pspec);
|
||||
g_object_class_install_properties (object_class, LAST_PROP, obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -157,15 +166,6 @@ meta_workspace_init (MetaWorkspace *workspace)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_add_to_list (MetaScreen *screen, MetaWindow *window, gpointer data)
|
||||
{
|
||||
GList **mru_list = data;
|
||||
|
||||
if (window->on_all_workspaces)
|
||||
*mru_list = g_list_prepend (*mru_list, window);
|
||||
}
|
||||
|
||||
MetaWorkspace*
|
||||
meta_workspace_new (MetaScreen *screen)
|
||||
{
|
||||
@@ -178,7 +178,6 @@ meta_workspace_new (MetaScreen *screen)
|
||||
g_list_append (workspace->screen->workspaces, workspace);
|
||||
workspace->windows = NULL;
|
||||
workspace->mru_list = NULL;
|
||||
meta_screen_foreach_window (screen, maybe_add_to_list, &workspace->mru_list);
|
||||
|
||||
workspace->work_areas_invalid = TRUE;
|
||||
workspace->work_area_monitor = NULL;
|
||||
@@ -242,34 +241,28 @@ workspace_free_builtin_struts (MetaWorkspace *workspace)
|
||||
workspace->builtin_struts = NULL;
|
||||
}
|
||||
|
||||
/* Ensure that the workspace is empty by making sure that
|
||||
* all of our windows are on-all-workspaces. */
|
||||
static void
|
||||
assert_workspace_empty (MetaWorkspace *workspace)
|
||||
{
|
||||
GList *l;
|
||||
for (l = workspace->windows; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWindow *window = l->data;
|
||||
g_assert (window->on_all_workspaces);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_workspace_remove (MetaWorkspace *workspace)
|
||||
{
|
||||
GList *tmp;
|
||||
MetaScreen *screen;
|
||||
int i;
|
||||
|
||||
g_return_if_fail (workspace != workspace->screen->active_workspace);
|
||||
|
||||
/* Here we assume all the windows are already on another workspace
|
||||
* as well, so they won't be "orphaned"
|
||||
*/
|
||||
|
||||
tmp = workspace->windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
GList *next;
|
||||
MetaWindow *window = tmp->data;
|
||||
next = tmp->next;
|
||||
|
||||
/* pop front of list we're iterating over */
|
||||
meta_workspace_remove_window (workspace, window);
|
||||
g_assert (window->workspace != NULL);
|
||||
|
||||
tmp = next;
|
||||
}
|
||||
|
||||
g_assert (workspace->windows == NULL);
|
||||
assert_workspace_empty (workspace);
|
||||
|
||||
screen = workspace->screen;
|
||||
|
||||
@@ -312,38 +305,11 @@ void
|
||||
meta_workspace_add_window (MetaWorkspace *workspace,
|
||||
MetaWindow *window)
|
||||
{
|
||||
g_return_if_fail (window->workspace == NULL);
|
||||
|
||||
/* If the window is on all workspaces, we want to add it to all mru
|
||||
* lists, otherwise just add it to this workspaces mru list
|
||||
*/
|
||||
if (window->on_all_workspaces)
|
||||
{
|
||||
if (window->workspace == NULL)
|
||||
{
|
||||
GList* tmp = window->screen->workspaces;
|
||||
while (tmp)
|
||||
{
|
||||
MetaWorkspace* work = (MetaWorkspace*) tmp->data;
|
||||
if (!g_list_find (work->mru_list, window))
|
||||
work->mru_list = g_list_prepend (work->mru_list, window);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (g_list_find (workspace->mru_list, window) == NULL);
|
||||
workspace->mru_list = g_list_prepend (workspace->mru_list, window);
|
||||
}
|
||||
g_assert (g_list_find (workspace->mru_list, window) == NULL);
|
||||
workspace->mru_list = g_list_prepend (workspace->mru_list, window);
|
||||
|
||||
workspace->windows = g_list_prepend (workspace->windows, window);
|
||||
|
||||
window->workspace = workspace;
|
||||
|
||||
meta_window_current_workspace_changed (window);
|
||||
|
||||
if (window->struts)
|
||||
{
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
@@ -352,46 +318,18 @@ meta_workspace_add_window (MetaWorkspace *workspace,
|
||||
meta_workspace_invalidate_work_area (workspace);
|
||||
}
|
||||
|
||||
/* queue a move_resize since changing workspaces may change
|
||||
* the relevant struts
|
||||
*/
|
||||
meta_window_queue (window, META_QUEUE_CALC_SHOWING|META_QUEUE_MOVE_RESIZE);
|
||||
|
||||
g_signal_emit (workspace, signals[WINDOW_ADDED], 0, window);
|
||||
g_object_notify (G_OBJECT (workspace), "n-windows");
|
||||
g_object_notify_by_pspec (G_OBJECT (workspace), obj_props[PROP_N_WINDOWS]);
|
||||
}
|
||||
|
||||
void
|
||||
meta_workspace_remove_window (MetaWorkspace *workspace,
|
||||
MetaWindow *window)
|
||||
{
|
||||
g_return_if_fail (window->workspace == workspace);
|
||||
|
||||
workspace->windows = g_list_remove (workspace->windows, window);
|
||||
window->workspace = NULL;
|
||||
|
||||
/* If the window is on all workspaces, we don't want to remove it
|
||||
* from the MRU list unless this causes it to be removed from all
|
||||
* workspaces
|
||||
*/
|
||||
if (window->on_all_workspaces)
|
||||
{
|
||||
GList* tmp = window->screen->workspaces;
|
||||
while (tmp)
|
||||
{
|
||||
MetaWorkspace* work = (MetaWorkspace*) tmp->data;
|
||||
work->mru_list = g_list_remove (work->mru_list, window);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
workspace->mru_list = g_list_remove (workspace->mru_list, window);
|
||||
g_assert (g_list_find (workspace->mru_list, window) == NULL);
|
||||
}
|
||||
|
||||
meta_window_current_workspace_changed (window);
|
||||
workspace->mru_list = g_list_remove (workspace->mru_list, window);
|
||||
g_assert (g_list_find (workspace->mru_list, window) == NULL);
|
||||
|
||||
if (window->struts)
|
||||
{
|
||||
@@ -401,11 +339,6 @@ meta_workspace_remove_window (MetaWorkspace *workspace,
|
||||
meta_workspace_invalidate_work_area (workspace);
|
||||
}
|
||||
|
||||
/* queue a move_resize since changing workspaces may change
|
||||
* the relevant struts
|
||||
*/
|
||||
meta_window_queue (window, META_QUEUE_CALC_SHOWING|META_QUEUE_MOVE_RESIZE);
|
||||
|
||||
g_signal_emit (workspace, signals[WINDOW_REMOVED], 0, window);
|
||||
g_object_notify (G_OBJECT (workspace), "n-windows");
|
||||
}
|
||||
@@ -414,42 +347,33 @@ void
|
||||
meta_workspace_relocate_windows (MetaWorkspace *workspace,
|
||||
MetaWorkspace *new_home)
|
||||
{
|
||||
GList *tmp;
|
||||
GList *copy;
|
||||
GList *copy, *l;
|
||||
|
||||
g_return_if_fail (workspace != new_home);
|
||||
|
||||
/* can't modify list we're iterating over */
|
||||
copy = g_list_copy (workspace->windows);
|
||||
|
||||
tmp = copy;
|
||||
while (tmp != NULL)
|
||||
for (l = copy; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWindow *window = tmp->data;
|
||||
MetaWindow *window = l->data;
|
||||
|
||||
meta_workspace_remove_window (workspace, window);
|
||||
meta_workspace_add_window (new_home, window);
|
||||
|
||||
tmp = tmp->next;
|
||||
if (!window->override_redirect)
|
||||
meta_window_change_workspace (window, new_home);
|
||||
}
|
||||
|
||||
g_list_free (copy);
|
||||
|
||||
g_assert (workspace->windows == NULL);
|
||||
assert_workspace_empty (workspace);
|
||||
}
|
||||
|
||||
void
|
||||
meta_workspace_queue_calc_showing (MetaWorkspace *workspace)
|
||||
{
|
||||
GList *tmp;
|
||||
GList *l;
|
||||
|
||||
tmp = workspace->windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
meta_window_queue (tmp->data, META_QUEUE_CALC_SHOWING);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
for (l = workspace->windows; l != NULL; l = l->next)
|
||||
meta_window_queue (l->data, META_QUEUE_CALC_SHOWING);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -572,22 +496,18 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
||||
* or the new one *but not both*, then update the
|
||||
* _net_showing_desktop hint
|
||||
*/
|
||||
if (old && (old->showing_desktop ^ workspace->showing_desktop))
|
||||
if (old && (old->showing_desktop != workspace->showing_desktop))
|
||||
meta_screen_update_showing_desktop_hint (workspace->screen);
|
||||
|
||||
if (old == NULL)
|
||||
return;
|
||||
|
||||
move_window = NULL;
|
||||
if (workspace->screen->display->grab_op == META_GRAB_OP_MOVING ||
|
||||
workspace->screen->display->grab_op == META_GRAB_OP_KEYBOARD_MOVING)
|
||||
if (meta_grab_op_is_moving (workspace->screen->display->grab_op))
|
||||
move_window = workspace->screen->display->grab_window;
|
||||
|
||||
if (move_window != NULL)
|
||||
{
|
||||
if (move_window->on_all_workspaces)
|
||||
move_window = NULL; /* don't move it after all */
|
||||
|
||||
/* We put the window on the new workspace, flip spaces,
|
||||
* then remove from old workspace, so the window
|
||||
* never gets unmapped and we maintain the button grab
|
||||
@@ -595,21 +515,13 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
||||
*
|
||||
* \bug This comment appears to be the reverse of what happens
|
||||
*/
|
||||
if (move_window && (move_window->workspace != workspace))
|
||||
{
|
||||
meta_workspace_remove_window (old, move_window);
|
||||
meta_workspace_add_window (workspace, move_window);
|
||||
}
|
||||
if (!meta_window_located_on_workspace (move_window, workspace))
|
||||
meta_window_change_workspace (move_window, workspace);
|
||||
}
|
||||
|
||||
meta_workspace_queue_calc_showing (old);
|
||||
meta_workspace_queue_calc_showing (workspace);
|
||||
|
||||
/* FIXME: Why do we need this?!? Isn't it handled in the lines above? */
|
||||
if (move_window)
|
||||
/* Removes window from other spaces */
|
||||
meta_window_change_workspace (move_window, workspace);
|
||||
|
||||
/*
|
||||
* Notify the compositor that the active workspace is changing.
|
||||
*/
|
||||
@@ -627,7 +539,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
||||
meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
|
||||
new_space, &layout2);
|
||||
|
||||
if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
|
||||
if (meta_get_locale_direction () == META_LOCALE_DIRECTION_RTL)
|
||||
{
|
||||
if (layout1.current_col > layout2.current_col)
|
||||
direction = META_MOTION_RIGHT;
|
||||
@@ -711,17 +623,16 @@ meta_workspace_index (MetaWorkspace *workspace)
|
||||
}
|
||||
|
||||
void
|
||||
meta_workspace_update_window_hints (MetaWorkspace *workspace)
|
||||
meta_workspace_index_changed (MetaWorkspace *workspace)
|
||||
{
|
||||
GList *l = workspace->windows;
|
||||
while (l)
|
||||
GList *l;
|
||||
for (l = workspace->windows; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWindow *win = l->data;
|
||||
|
||||
meta_window_current_workspace_changed (win);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (workspace), obj_props[PROP_WORKSPACE_INDEX]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -736,24 +647,20 @@ meta_workspace_update_window_hints (MetaWorkspace *workspace)
|
||||
GList*
|
||||
meta_workspace_list_windows (MetaWorkspace *workspace)
|
||||
{
|
||||
GSList *display_windows;
|
||||
GSList *tmp;
|
||||
GSList *display_windows, *l;
|
||||
GList *workspace_windows;
|
||||
|
||||
display_windows = meta_display_list_windows (workspace->screen->display,
|
||||
META_LIST_DEFAULT);
|
||||
|
||||
workspace_windows = NULL;
|
||||
tmp = display_windows;
|
||||
while (tmp != NULL)
|
||||
for (l = display_windows; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWindow *window = tmp->data;
|
||||
MetaWindow *window = l->data;
|
||||
|
||||
if (meta_window_located_on_workspace (window, workspace))
|
||||
workspace_windows = g_list_prepend (workspace_windows,
|
||||
window);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
g_slist_free (display_windows);
|
||||
@@ -764,8 +671,7 @@ meta_workspace_list_windows (MetaWorkspace *workspace)
|
||||
void
|
||||
meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
|
||||
{
|
||||
GList *tmp;
|
||||
GList *windows;
|
||||
GList *windows, *l;
|
||||
int i;
|
||||
|
||||
if (workspace->work_areas_invalid)
|
||||
@@ -805,14 +711,11 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
|
||||
|
||||
/* redo the size/position constraints on all windows */
|
||||
windows = meta_workspace_list_windows (workspace);
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
|
||||
for (l = windows; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
|
||||
MetaWindow *w = l->data;
|
||||
meta_window_queue (w, META_QUEUE_MOVE_RESIZE);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
g_list_free (windows);
|
||||
@@ -831,11 +734,8 @@ copy_strut_list(GSList *original)
|
||||
{
|
||||
GSList *result = NULL;
|
||||
|
||||
while (original)
|
||||
{
|
||||
result = g_slist_prepend (result, copy_strut (original->data));
|
||||
original = original->next;
|
||||
}
|
||||
for (; original != NULL; original = original->next)
|
||||
result = g_slist_prepend (result, copy_strut (original->data));
|
||||
|
||||
return g_slist_reverse (result);
|
||||
}
|
||||
@@ -1202,7 +1102,7 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace,
|
||||
meta_verbose ("Getting neighbor of %d in direction %s\n",
|
||||
current_space, meta_motion_direction_to_string (direction));
|
||||
|
||||
ltr = meta_ui_get_direction() == META_UI_DIRECTION_LTR;
|
||||
ltr = (meta_get_locale_direction () == META_LOCALE_DIRECTION_LTR);
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
|
||||
@@ -111,41 +111,75 @@ typedef enum
|
||||
* @META_GRAB_OP_COMPOSITOR: Compositor asked for grab
|
||||
*/
|
||||
|
||||
/* when changing this enum, there are various switch statements
|
||||
* you have to update
|
||||
/* The lower 16 bits of the grab operation is its type.
|
||||
*
|
||||
* Window grab operations have the following layout:
|
||||
*
|
||||
* 0000 0000 | 0000 0011
|
||||
* NSEW flags | type
|
||||
*
|
||||
* Flags contains whether the operation is a keyboard operation,
|
||||
* and whether the keyboard operation is "unknown".
|
||||
*
|
||||
* The rest of the flags tell you which direction the resize is
|
||||
* going in.
|
||||
*
|
||||
* If the directions field is 0000, then the operation is a move,
|
||||
* not a resize.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
META_GRAB_OP_WINDOW_FLAG_KEYBOARD = 0x0100,
|
||||
META_GRAB_OP_WINDOW_FLAG_UNKNOWN = 0x0200,
|
||||
META_GRAB_OP_WINDOW_DIR_WEST = 0x1000,
|
||||
META_GRAB_OP_WINDOW_DIR_EAST = 0x2000,
|
||||
META_GRAB_OP_WINDOW_DIR_SOUTH = 0x4000,
|
||||
META_GRAB_OP_WINDOW_DIR_NORTH = 0x8000,
|
||||
META_GRAB_OP_WINDOW_DIR_MASK = 0xF000,
|
||||
|
||||
/* WGO = "window grab op". shorthand for below */
|
||||
_WGO_K = META_GRAB_OP_WINDOW_FLAG_KEYBOARD,
|
||||
_WGO_U = META_GRAB_OP_WINDOW_FLAG_UNKNOWN,
|
||||
_WGO_W = META_GRAB_OP_WINDOW_DIR_WEST,
|
||||
_WGO_E = META_GRAB_OP_WINDOW_DIR_EAST,
|
||||
_WGO_S = META_GRAB_OP_WINDOW_DIR_SOUTH,
|
||||
_WGO_N = META_GRAB_OP_WINDOW_DIR_NORTH,
|
||||
};
|
||||
|
||||
#define GRAB_OP_GET_BASE_TYPE(op) (op & 0x00FF)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_GRAB_OP_NONE,
|
||||
|
||||
/* Mouse ops */
|
||||
META_GRAB_OP_MOVING,
|
||||
META_GRAB_OP_RESIZING_SE,
|
||||
META_GRAB_OP_RESIZING_S,
|
||||
META_GRAB_OP_RESIZING_SW,
|
||||
META_GRAB_OP_RESIZING_N,
|
||||
META_GRAB_OP_RESIZING_NE,
|
||||
META_GRAB_OP_RESIZING_NW,
|
||||
META_GRAB_OP_RESIZING_W,
|
||||
META_GRAB_OP_RESIZING_E,
|
||||
|
||||
/* Keyboard ops */
|
||||
META_GRAB_OP_KEYBOARD_MOVING,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_S,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_N,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_W,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_E,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_SE,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_NE,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_SW,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_NW,
|
||||
|
||||
/* Special grab op when the compositor asked for a grab */
|
||||
META_GRAB_OP_COMPOSITOR,
|
||||
|
||||
/* For when a Wayland client takes a popup grab */
|
||||
META_GRAB_OP_WAYLAND_POPUP,
|
||||
|
||||
/* Window grab ops. */
|
||||
META_GRAB_OP_WINDOW_BASE,
|
||||
|
||||
META_GRAB_OP_MOVING = META_GRAB_OP_WINDOW_BASE,
|
||||
META_GRAB_OP_RESIZING_NW = META_GRAB_OP_WINDOW_BASE | _WGO_N | _WGO_W,
|
||||
META_GRAB_OP_RESIZING_N = META_GRAB_OP_WINDOW_BASE | _WGO_N,
|
||||
META_GRAB_OP_RESIZING_NE = META_GRAB_OP_WINDOW_BASE | _WGO_N | _WGO_E,
|
||||
META_GRAB_OP_RESIZING_E = META_GRAB_OP_WINDOW_BASE | _WGO_E,
|
||||
META_GRAB_OP_RESIZING_SW = META_GRAB_OP_WINDOW_BASE | _WGO_S | _WGO_W,
|
||||
META_GRAB_OP_RESIZING_S = META_GRAB_OP_WINDOW_BASE | _WGO_S,
|
||||
META_GRAB_OP_RESIZING_SE = META_GRAB_OP_WINDOW_BASE | _WGO_S | _WGO_E,
|
||||
META_GRAB_OP_RESIZING_W = META_GRAB_OP_WINDOW_BASE | _WGO_W,
|
||||
META_GRAB_OP_KEYBOARD_MOVING = META_GRAB_OP_WINDOW_BASE | _WGO_K,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN = META_GRAB_OP_WINDOW_BASE | _WGO_K | _WGO_U,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_NW = META_GRAB_OP_WINDOW_BASE | _WGO_N | _WGO_W | _WGO_K,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_N = META_GRAB_OP_WINDOW_BASE | _WGO_N | _WGO_K,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_NE = META_GRAB_OP_WINDOW_BASE | _WGO_N | _WGO_E | _WGO_K,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_E = META_GRAB_OP_WINDOW_BASE | _WGO_E | _WGO_K,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_SW = META_GRAB_OP_WINDOW_BASE | _WGO_S | _WGO_W | _WGO_K,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_S = META_GRAB_OP_WINDOW_BASE | _WGO_S | _WGO_K,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_SE = META_GRAB_OP_WINDOW_BASE | _WGO_S | _WGO_E | _WGO_K,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_W = META_GRAB_OP_WINDOW_BASE | _WGO_W | _WGO_K,
|
||||
} MetaGrabOp;
|
||||
|
||||
/**
|
||||
|
||||
@@ -109,9 +109,6 @@ void meta_compositor_queue_frame_drawn (MetaCompositor *compositor,
|
||||
|
||||
void meta_compositor_sync_stack (MetaCompositor *compositor,
|
||||
GList *stack);
|
||||
void meta_compositor_sync_screen_size (MetaCompositor *compositor,
|
||||
guint width,
|
||||
guint height);
|
||||
|
||||
void meta_compositor_flash_screen (MetaCompositor *compositor,
|
||||
MetaScreen *screen);
|
||||
|
||||
@@ -66,9 +66,6 @@ GType meta_display_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#define meta_XFree(p) do { if ((p)) XFree ((p)); } while (0)
|
||||
|
||||
void meta_display_get_compositor_version (MetaDisplay *display,
|
||||
int *major,
|
||||
int *minor);
|
||||
int meta_display_get_xinput_opcode (MetaDisplay *display);
|
||||
gboolean meta_display_supports_extended_barriers (MetaDisplay *display);
|
||||
Display *meta_display_get_xdisplay (MetaDisplay *display);
|
||||
@@ -182,4 +179,7 @@ void meta_display_ungrab_keyboard (MetaDisplay *display,
|
||||
guint32 timestamp);
|
||||
void meta_display_unfreeze_keyboard (MetaDisplay *display,
|
||||
guint32 timestamp);
|
||||
gboolean meta_display_is_pointer_emulating_sequence (MetaDisplay *display,
|
||||
ClutterEventSequence *sequence);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,6 +27,7 @@ const char *meta_key_binding_get_name (MetaKeyBinding *binding);
|
||||
MetaVirtualModifier meta_key_binding_get_modifiers (MetaKeyBinding *binding);
|
||||
guint meta_key_binding_get_mask (MetaKeyBinding *binding);
|
||||
gboolean meta_key_binding_is_builtin (MetaKeyBinding *binding);
|
||||
gboolean meta_key_binding_is_reversed (MetaKeyBinding *binding);
|
||||
|
||||
gboolean meta_keybindings_set_custom_handler (const gchar *name,
|
||||
MetaKeyHandlerFunc handler,
|
||||
|
||||
@@ -27,9 +27,7 @@
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <meta/meta-idle-monitor.h>
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-cursor-renderer.h"
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
typedef struct _MetaBackend MetaBackend;
|
||||
typedef struct _MetaBackendClass MetaBackendClass;
|
||||
@@ -38,21 +36,15 @@ GType meta_backend_get_type (void);
|
||||
|
||||
MetaBackend * meta_get_backend (void);
|
||||
|
||||
MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend,
|
||||
int device_id);
|
||||
MetaMonitorManager * meta_backend_get_monitor_manager (MetaBackend *backend);
|
||||
MetaCursorRenderer * meta_backend_get_cursor_renderer (MetaBackend *backend);
|
||||
void meta_backend_set_keymap (MetaBackend *backend,
|
||||
const char *layouts,
|
||||
const char *variants,
|
||||
const char *options);
|
||||
|
||||
gboolean meta_backend_grab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
uint32_t timestamp);
|
||||
gboolean meta_backend_ungrab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
uint32_t timestamp);
|
||||
void meta_backend_lock_layout_group (MetaBackend *backend,
|
||||
guint idx);
|
||||
|
||||
void meta_backend_warp_pointer (MetaBackend *backend,
|
||||
int x,
|
||||
int y);
|
||||
ClutterActor *meta_backend_get_stage (MetaBackend *backend);
|
||||
|
||||
void meta_clutter_init (void);
|
||||
|
||||
@@ -94,6 +94,15 @@ struct _MetaPluginClass
|
||||
void (*minimize) (MetaPlugin *plugin,
|
||||
MetaWindowActor *actor);
|
||||
|
||||
/**
|
||||
* MetaPluginClass::unminimize:
|
||||
* @actor: a #MetaWindowActor
|
||||
*
|
||||
* Virtual function called when the window represented by @actor is unminimized.
|
||||
*/
|
||||
void (*unminimize) (MetaPlugin *plugin,
|
||||
MetaWindowActor *actor);
|
||||
|
||||
/**
|
||||
* MetaPluginClass::maximize:
|
||||
* @actor: a #MetaWindowActor
|
||||
@@ -372,6 +381,10 @@ void
|
||||
meta_plugin_minimize_completed (MetaPlugin *plugin,
|
||||
MetaWindowActor *actor);
|
||||
|
||||
void
|
||||
meta_plugin_unminimize_completed (MetaPlugin *plugin,
|
||||
MetaWindowActor *actor);
|
||||
|
||||
void
|
||||
meta_plugin_maximize_completed (MetaPlugin *plugin,
|
||||
MetaWindowActor *actor);
|
||||
|
||||
@@ -102,7 +102,8 @@ typedef enum
|
||||
META_PREF_WORKSPACES_ONLY_ON_PRIMARY,
|
||||
META_PREF_DRAGGABLE_BORDER_WIDTH,
|
||||
META_PREF_AUTO_MAXIMIZE,
|
||||
META_PREF_CENTER_NEW_WINDOWS
|
||||
META_PREF_CENTER_NEW_WINDOWS,
|
||||
META_PREF_DRAG_THRESHOLD,
|
||||
} MetaPreference;
|
||||
|
||||
typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
|
||||
@@ -166,6 +167,7 @@ void meta_prefs_set_force_fullscreen (gboolean whether);
|
||||
gboolean meta_prefs_get_workspaces_only_on_primary (void);
|
||||
|
||||
int meta_prefs_get_draggable_border_width (void);
|
||||
int meta_prefs_get_drag_threshold (void);
|
||||
|
||||
gboolean meta_prefs_get_ignore_request_hide_titlebar (void);
|
||||
void meta_prefs_set_ignore_request_hide_titlebar (gboolean whether);
|
||||
@@ -367,7 +369,6 @@ typedef enum _MetaKeyBindingAction
|
||||
* @META_KEY_BINDING_NONE: none
|
||||
* @META_KEY_BINDING_PER_WINDOW: per-window
|
||||
* @META_KEY_BINDING_BUILTIN: built-in
|
||||
* @META_KEY_BINDING_REVERSES: reverses
|
||||
* @META_KEY_BINDING_IS_REVERSED: is reversed
|
||||
*/
|
||||
typedef enum
|
||||
@@ -375,8 +376,7 @@ typedef enum
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEY_BINDING_PER_WINDOW = 1 << 0,
|
||||
META_KEY_BINDING_BUILTIN = 1 << 1,
|
||||
META_KEY_BINDING_REVERSES = 1 << 2,
|
||||
META_KEY_BINDING_IS_REVERSED = 1 << 3
|
||||
META_KEY_BINDING_IS_REVERSED = 1 << 2,
|
||||
} MetaKeyBindingFlags;
|
||||
|
||||
/**
|
||||
@@ -405,7 +405,3 @@ gboolean meta_prefs_bell_is_audible (void);
|
||||
GDesktopVisualBellType meta_prefs_get_visual_bell_type (void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -181,6 +181,14 @@ guint meta_later_add (MetaLaterType when,
|
||||
GDestroyNotify notify);
|
||||
void meta_later_remove (guint later_id);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_LOCALE_DIRECTION_LTR,
|
||||
META_LOCALE_DIRECTION_RTL,
|
||||
} MetaLocaleDirection;
|
||||
|
||||
MetaLocaleDirection meta_get_locale_direction (void);
|
||||
|
||||
#endif /* META_UTIL_H */
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@ void meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
||||
MetaWindow *focus_this,
|
||||
guint32 timestamp);
|
||||
|
||||
void meta_workspace_update_window_hints (MetaWorkspace *workspace);
|
||||
void meta_workspace_set_builtin_struts (MetaWorkspace *workspace,
|
||||
GSList *struts);
|
||||
|
||||
|
||||
102
src/ui/frames.c
102
src/ui/frames.c
@@ -65,9 +65,6 @@ static void meta_frames_paint (MetaFrames *frames,
|
||||
MetaUIFrame *frame,
|
||||
cairo_t *cr);
|
||||
|
||||
static void meta_frames_set_window_background (MetaFrames *frames,
|
||||
MetaUIFrame *frame);
|
||||
|
||||
static void meta_frames_calc_geometry (MetaFrames *frames,
|
||||
MetaUIFrame *frame,
|
||||
MetaFrameGeometry *fgeom);
|
||||
@@ -300,12 +297,6 @@ queue_recalc_func (gpointer key, gpointer value, gpointer data)
|
||||
frames = META_FRAMES (data);
|
||||
frame = value;
|
||||
|
||||
/* If a resize occurs it will cause a redraw, but the
|
||||
* resize may not actually be needed so we always redraw
|
||||
* in case of color change.
|
||||
*/
|
||||
meta_frames_set_window_background (frames, frame);
|
||||
|
||||
invalidate_whole_window (frames, frame);
|
||||
meta_core_queue_frame_resize (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
|
||||
frame->xwindow);
|
||||
@@ -345,12 +336,6 @@ queue_draw_func (gpointer key, gpointer value, gpointer data)
|
||||
frames = META_FRAMES (data);
|
||||
frame = value;
|
||||
|
||||
/* If a resize occurs it will cause a redraw, but the
|
||||
* resize may not actually be needed so we always redraw
|
||||
* in case of color change.
|
||||
*/
|
||||
meta_frames_set_window_background (frames, frame);
|
||||
|
||||
invalidate_whole_window (frames, frame);
|
||||
}
|
||||
|
||||
@@ -589,11 +574,6 @@ meta_frames_manage_window (MetaFrames *frames,
|
||||
frame->shape_applied = FALSE;
|
||||
frame->prelit_control = META_FRAME_CONTROL_NONE;
|
||||
|
||||
/* Don't set the window background yet; we need frame->xwindow to be
|
||||
* registered with its MetaWindow, which happens after this function
|
||||
* and meta_ui_create_frame_window() return to meta_window_ensure_frame().
|
||||
*/
|
||||
|
||||
meta_core_grab_buttons (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow);
|
||||
|
||||
g_hash_table_replace (frames->frames, &frame->xwindow, frame);
|
||||
@@ -723,42 +703,6 @@ meta_ui_frame_get_corner_radiuses (MetaFrames *frames,
|
||||
*bottom_right = fgeom.bottom_right_corner_rounded_radius + sqrt(fgeom.bottom_right_corner_rounded_radius);
|
||||
}
|
||||
|
||||
void
|
||||
meta_frames_reset_bg (MetaFrames *frames,
|
||||
Window xwindow)
|
||||
{
|
||||
MetaUIFrame *frame;
|
||||
|
||||
frame = meta_frames_lookup_window (frames, xwindow);
|
||||
|
||||
meta_frames_set_window_background (frames, frame);
|
||||
}
|
||||
|
||||
static void
|
||||
set_background_none (Display *xdisplay,
|
||||
Window xwindow)
|
||||
{
|
||||
XSetWindowAttributes attrs;
|
||||
|
||||
attrs.background_pixmap = None;
|
||||
XChangeWindowAttributes (xdisplay, xwindow,
|
||||
CWBackPixmap, &attrs);
|
||||
}
|
||||
|
||||
void
|
||||
meta_frames_unflicker_bg (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
int target_width,
|
||||
int target_height)
|
||||
{
|
||||
MetaUIFrame *frame;
|
||||
|
||||
frame = meta_frames_lookup_window (frames, xwindow);
|
||||
g_return_if_fail (frame != NULL);
|
||||
|
||||
set_background_none (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow);
|
||||
}
|
||||
|
||||
/* The client rectangle surrounds client window; it subtracts both
|
||||
* the visible and invisible borders from the frame window's size.
|
||||
*/
|
||||
@@ -1901,52 +1845,6 @@ meta_frames_paint (MetaFrames *frames,
|
||||
mini_icon, icon);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_frames_set_window_background (MetaFrames *frames,
|
||||
MetaUIFrame *frame)
|
||||
{
|
||||
MetaFrameFlags flags;
|
||||
MetaFrameType type;
|
||||
MetaFrameStyle *style = NULL;
|
||||
gboolean frame_exists;
|
||||
|
||||
meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow,
|
||||
META_CORE_WINDOW_HAS_FRAME, &frame_exists,
|
||||
META_CORE_GET_FRAME_FLAGS, &flags,
|
||||
META_CORE_GET_FRAME_TYPE, &type,
|
||||
META_CORE_GET_END);
|
||||
|
||||
if (frame_exists)
|
||||
{
|
||||
style = meta_theme_get_frame_style (meta_theme_get_current (),
|
||||
type, flags);
|
||||
}
|
||||
|
||||
if (frame_exists && style->window_background_color != NULL)
|
||||
{
|
||||
GdkRGBA color;
|
||||
GdkVisual *visual;
|
||||
|
||||
meta_color_spec_render (style->window_background_color,
|
||||
frame->style,
|
||||
&color);
|
||||
|
||||
/* Set A in ARGB to window_background_alpha, if we have ARGB */
|
||||
|
||||
visual = gtk_widget_get_visual (GTK_WIDGET (frames));
|
||||
if (gdk_visual_get_depth (visual) == 32) /* we have ARGB */
|
||||
{
|
||||
color.alpha = style->window_background_alpha / 255.0;
|
||||
}
|
||||
|
||||
gdk_window_set_background_rgba (frame->window, &color);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_style_context_set_background (frame->style, frame->window);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_frames_enter_notify_event (GtkWidget *widget,
|
||||
GdkEventCrossing *event)
|
||||
|
||||
@@ -138,13 +138,6 @@ void meta_frames_get_borders (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
MetaFrameBorders *borders);
|
||||
|
||||
void meta_frames_reset_bg (MetaFrames *frames,
|
||||
Window xwindow);
|
||||
void meta_frames_unflicker_bg (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
int target_width,
|
||||
int target_height);
|
||||
|
||||
cairo_region_t *meta_frames_get_frame_bounds (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
int window_width,
|
||||
|
||||
53
src/ui/ui.c
53
src/ui/ui.c
@@ -331,6 +331,17 @@ meta_ui_get_frame_borders (MetaUI *ui,
|
||||
borders);
|
||||
}
|
||||
|
||||
static void
|
||||
set_background_none (Display *xdisplay,
|
||||
Window xwindow)
|
||||
{
|
||||
XSetWindowAttributes attrs;
|
||||
|
||||
attrs.background_pixmap = None;
|
||||
XChangeWindowAttributes (xdisplay, xwindow,
|
||||
CWBackPixmap, &attrs);
|
||||
}
|
||||
|
||||
Window
|
||||
meta_ui_create_frame_window (MetaUI *ui,
|
||||
Display *xdisplay,
|
||||
@@ -397,6 +408,7 @@ meta_ui_create_frame_window (MetaUI *ui,
|
||||
&attrs, attributes_mask);
|
||||
|
||||
gdk_window_resize (window, width, height);
|
||||
set_background_none (xdisplay, GDK_WINDOW_XID (window));
|
||||
|
||||
meta_frames_manage_window (ui->frames, GDK_WINDOW_XID (window), window);
|
||||
|
||||
@@ -449,16 +461,6 @@ meta_ui_unmap_frame (MetaUI *ui,
|
||||
gdk_window_hide (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_unflicker_frame_bg (MetaUI *ui,
|
||||
Window xwindow,
|
||||
int target_width,
|
||||
int target_height)
|
||||
{
|
||||
meta_frames_unflicker_bg (ui->frames, xwindow,
|
||||
target_width, target_height);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_update_frame_style (MetaUI *ui,
|
||||
Window xwindow)
|
||||
@@ -473,13 +475,6 @@ meta_ui_repaint_frame (MetaUI *ui,
|
||||
meta_frames_repaint_frame (ui->frames, xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_reset_frame_bg (MetaUI *ui,
|
||||
Window xwindow)
|
||||
{
|
||||
meta_frames_reset_bg (ui->frames, xwindow);
|
||||
}
|
||||
|
||||
cairo_region_t *
|
||||
meta_ui_get_frame_bounds (MetaUI *ui,
|
||||
Window xwindow,
|
||||
@@ -658,27 +653,3 @@ meta_ui_window_is_widget (MetaUI *ui,
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
meta_ui_get_drag_threshold (MetaUI *ui)
|
||||
{
|
||||
GtkSettings *settings;
|
||||
int threshold;
|
||||
|
||||
settings = gtk_widget_get_settings (GTK_WIDGET (ui->frames));
|
||||
|
||||
threshold = 8;
|
||||
g_object_get (G_OBJECT (settings), "gtk-dnd-drag-threshold", &threshold, NULL);
|
||||
|
||||
return threshold;
|
||||
}
|
||||
|
||||
MetaUIDirection
|
||||
meta_ui_get_direction (void)
|
||||
{
|
||||
if (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL)
|
||||
return META_UI_DIRECTION_RTL;
|
||||
|
||||
return META_UI_DIRECTION_LTR;
|
||||
}
|
||||
|
||||
|
||||
17
src/ui/ui.h
17
src/ui/ui.h
@@ -34,12 +34,6 @@ typedef struct _MetaUI MetaUI;
|
||||
|
||||
typedef gboolean (* MetaEventFunc) (XEvent *xevent, gpointer data);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_UI_DIRECTION_LTR,
|
||||
META_UI_DIRECTION_RTL
|
||||
} MetaUIDirection;
|
||||
|
||||
void meta_ui_init (void);
|
||||
|
||||
Display* meta_ui_get_display (void);
|
||||
@@ -88,13 +82,6 @@ void meta_ui_map_frame (MetaUI *ui,
|
||||
void meta_ui_unmap_frame (MetaUI *ui,
|
||||
Window xwindow);
|
||||
|
||||
void meta_ui_unflicker_frame_bg (MetaUI *ui,
|
||||
Window xwindow,
|
||||
int target_width,
|
||||
int target_height);
|
||||
void meta_ui_reset_frame_bg (MetaUI *ui,
|
||||
Window xwindow);
|
||||
|
||||
cairo_region_t *meta_ui_get_frame_bounds (MetaUI *ui,
|
||||
Window xwindow,
|
||||
int window_width,
|
||||
@@ -130,8 +117,4 @@ gboolean meta_ui_have_a_theme (void);
|
||||
gboolean meta_ui_window_is_widget (MetaUI *ui,
|
||||
Window xwindow);
|
||||
|
||||
int meta_ui_get_drag_threshold (MetaUI *ui);
|
||||
|
||||
MetaUIDirection meta_ui_get_direction (void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -125,14 +125,9 @@ meta_wayland_data_source_send_offer (MetaWaylandDataSource *source,
|
||||
offer->source = source;
|
||||
offer->source_destroy_listener.notify = destroy_offer_data_source;
|
||||
|
||||
offer->resource = wl_resource_create (wl_resource_get_client (target),
|
||||
&wl_data_offer_interface,
|
||||
MIN (META_WL_DATA_OFFER_VERSION,
|
||||
wl_resource_get_version (target)), 0);
|
||||
wl_resource_set_implementation (offer->resource, &data_offer_interface,
|
||||
offer, destroy_data_offer);
|
||||
wl_resource_add_destroy_listener (source->resource,
|
||||
&offer->source_destroy_listener);
|
||||
offer->resource = wl_resource_create (wl_resource_get_client (target), &wl_data_offer_interface, wl_resource_get_version (target), 0);
|
||||
wl_resource_set_implementation (offer->resource, &data_offer_interface, offer, destroy_data_offer);
|
||||
wl_resource_add_destroy_listener (source->resource, &offer->source_destroy_listener);
|
||||
|
||||
wl_data_device_send_data_offer (target, offer->resource);
|
||||
|
||||
@@ -484,11 +479,8 @@ create_data_source (struct wl_client *client,
|
||||
{
|
||||
MetaWaylandDataSource *source = g_slice_new0 (MetaWaylandDataSource);
|
||||
|
||||
source->resource = wl_resource_create (client, &wl_data_source_interface,
|
||||
MIN (META_WL_DATA_SOURCE_VERSION,
|
||||
wl_resource_get_version (resource)), id);
|
||||
wl_resource_set_implementation (source->resource, &data_source_interface,
|
||||
source, destroy_data_source);
|
||||
source->resource = wl_resource_create (client, &wl_data_source_interface, wl_resource_get_version (resource), id);
|
||||
wl_resource_set_implementation (source->resource, &data_source_interface, source, destroy_data_source);
|
||||
|
||||
wl_array_init (&source->mime_types);
|
||||
}
|
||||
@@ -501,8 +493,7 @@ get_data_device (struct wl_client *client,
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||
struct wl_resource *cr;
|
||||
|
||||
cr = wl_resource_create (client, &wl_data_device_interface,
|
||||
MIN (META_WL_DATA_DEVICE_VERSION, wl_resource_get_version (manager_resource)), id);
|
||||
cr = wl_resource_create (client, &wl_data_device_interface, wl_resource_get_version (manager_resource), id);
|
||||
wl_resource_set_implementation (cr, &data_device_interface, &seat->data_device, unbind_resource);
|
||||
wl_list_insert (&seat->data_device.resource_list, wl_resource_get_link (cr));
|
||||
}
|
||||
@@ -517,9 +508,7 @@ bind_manager (struct wl_client *client,
|
||||
void *data, guint32 version, guint32 id)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, &wl_data_device_manager_interface,
|
||||
MIN (version, META_WL_DATA_DEVICE_MANAGER_VERSION), id);
|
||||
resource = wl_resource_create (client, &wl_data_device_manager_interface, version, id);
|
||||
wl_resource_set_implementation (resource, &manager_interface, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,10 +56,16 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <clutter/evdev/clutter-evdev.h>
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
static void meta_wayland_keyboard_update_xkb_state (MetaWaylandKeyboard *keyboard);
|
||||
static void notify_modifiers (MetaWaylandKeyboard *keyboard, uint32_t serial,
|
||||
uint32_t mods_depressed, uint32_t mods_latched,
|
||||
uint32_t mods_locked, uint32_t group);
|
||||
|
||||
static void
|
||||
unbind_resource (struct wl_resource *resource)
|
||||
{
|
||||
@@ -105,33 +111,29 @@ create_anonymous_file (off_t size,
|
||||
}
|
||||
|
||||
static void
|
||||
inform_clients_of_new_keymap (MetaWaylandKeyboard *keyboard,
|
||||
int flags)
|
||||
inform_clients_of_new_keymap (MetaWaylandKeyboard *keyboard)
|
||||
{
|
||||
MetaWaylandCompositor *compositor;
|
||||
struct wl_client *xclient;
|
||||
struct wl_resource *keyboard_resource;
|
||||
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
xclient = compositor->xwayland_manager.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);
|
||||
}
|
||||
wl_resource_for_each (keyboard_resource, &keyboard->focus_resource_list)
|
||||
{
|
||||
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)
|
||||
struct xkb_keymap *keymap)
|
||||
{
|
||||
MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
|
||||
GError *error = NULL;
|
||||
@@ -145,10 +147,9 @@ meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard,
|
||||
}
|
||||
|
||||
xkb_keymap_unref (xkb_info->keymap);
|
||||
xkb_info->keymap = keymap;
|
||||
xkb_info->keymap = xkb_keymap_ref (keymap);
|
||||
|
||||
xkb_state_unref (xkb_info->state);
|
||||
xkb_info->state = xkb_state_new (keymap);
|
||||
meta_wayland_keyboard_update_xkb_state (keyboard);
|
||||
|
||||
keymap_str = xkb_map_get_as_string (xkb_info->keymap);
|
||||
if (keymap_str == NULL)
|
||||
@@ -187,20 +188,14 @@ meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard,
|
||||
strcpy (xkb_info->keymap_area, keymap_str);
|
||||
free (keymap_str);
|
||||
|
||||
#if defined(CLUTTER_WINDOWING_EGL)
|
||||
/* XXX -- the evdev backend can be used regardless of the
|
||||
* windowing backend. To do this properly we need a Clutter
|
||||
* API to check the input backend. */
|
||||
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
|
||||
{
|
||||
ClutterDeviceManager *manager;
|
||||
manager = clutter_device_manager_get_default ();
|
||||
clutter_evdev_set_keyboard_map (manager, xkb_info->keymap);
|
||||
}
|
||||
#endif
|
||||
|
||||
inform_clients_of_new_keymap (keyboard, flags);
|
||||
inform_clients_of_new_keymap (keyboard);
|
||||
|
||||
notify_modifiers (keyboard,
|
||||
wl_display_next_serial (keyboard->display),
|
||||
xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_DEPRESSED),
|
||||
xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LATCHED),
|
||||
xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LOCKED),
|
||||
xkb_state_serialize_layout (xkb_info->state, XKB_STATE_LAYOUT_EFFECTIVE));
|
||||
return;
|
||||
|
||||
err_dev_zero:
|
||||
@@ -259,6 +254,85 @@ notify_modifiers (MetaWaylandKeyboard *keyboard, uint32_t serial,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_keyboard_update_xkb_state (MetaWaylandKeyboard *keyboard)
|
||||
{
|
||||
MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
|
||||
xkb_mod_mask_t latched, locked, group;
|
||||
|
||||
/* Preserve latched/locked modifiers state */
|
||||
if (xkb_info->state)
|
||||
{
|
||||
latched = xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LATCHED);
|
||||
locked = xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LOCKED);
|
||||
group = xkb_state_serialize_layout (xkb_info->state, XKB_STATE_LAYOUT_EFFECTIVE);
|
||||
xkb_state_unref (xkb_info->state);
|
||||
}
|
||||
else
|
||||
latched = locked = group = 0;
|
||||
|
||||
xkb_info->state = xkb_state_new (xkb_info->keymap);
|
||||
|
||||
if (latched || locked || group)
|
||||
xkb_state_update_mask (xkb_info->state, 0, latched, locked, 0, 0, group);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_key_repeat_for_resource (MetaWaylandKeyboard *keyboard,
|
||||
struct wl_resource *keyboard_resource)
|
||||
{
|
||||
if (wl_resource_get_version (keyboard_resource) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
|
||||
{
|
||||
gboolean repeat;
|
||||
unsigned int delay, rate;
|
||||
|
||||
repeat = g_settings_get_boolean (keyboard->settings, "repeat");
|
||||
|
||||
if (repeat)
|
||||
{
|
||||
unsigned int interval;
|
||||
interval = g_settings_get_uint (keyboard->settings, "repeat-interval");
|
||||
/* Our setting is in the milliseconds between keys. "rate" is the number
|
||||
* of keys per second. */
|
||||
rate = (1000 / interval);
|
||||
delay = g_settings_get_uint (keyboard->settings, "delay");
|
||||
}
|
||||
else
|
||||
{
|
||||
rate = 0;
|
||||
delay = 0;
|
||||
}
|
||||
|
||||
wl_keyboard_send_repeat_info (keyboard_resource, rate, delay);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
notify_key_repeat (MetaWaylandKeyboard *keyboard)
|
||||
{
|
||||
struct wl_resource *keyboard_resource;
|
||||
|
||||
wl_resource_for_each (keyboard_resource, &keyboard->resource_list)
|
||||
{
|
||||
notify_key_repeat_for_resource (keyboard, keyboard_resource);
|
||||
}
|
||||
|
||||
wl_resource_for_each (keyboard_resource, &keyboard->focus_resource_list)
|
||||
{
|
||||
notify_key_repeat_for_resource (keyboard, keyboard_resource);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
settings_changed (GSettings *settings,
|
||||
const char *key,
|
||||
gpointer data)
|
||||
{
|
||||
MetaWaylandKeyboard *keyboard = data;
|
||||
|
||||
notify_key_repeat (keyboard);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
||||
struct wl_display *display)
|
||||
@@ -272,18 +346,16 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
||||
|
||||
keyboard->focus_surface_listener.notify = keyboard_handle_focus_surface_destroy;
|
||||
|
||||
wl_array_init (&keyboard->keys);
|
||||
wl_array_init (&keyboard->pressed_keys);
|
||||
|
||||
keyboard->xkb_context = xkb_context_new (0 /* flags */);
|
||||
keyboard->xkb_info.keymap_fd = -1;
|
||||
|
||||
/* Compute a default until gnome-settings-daemon starts and sets
|
||||
the appropriate values
|
||||
*/
|
||||
meta_wayland_keyboard_set_keymap_names (keyboard,
|
||||
"evdev",
|
||||
"pc105",
|
||||
"us", "", "", 0);
|
||||
keyboard->settings = g_settings_new ("org.gnome.settings-daemon.peripherals.keyboard");
|
||||
g_signal_connect (keyboard->settings, "changed",
|
||||
G_CALLBACK (settings_changed), keyboard);
|
||||
|
||||
meta_wayland_keyboard_take_keymap (keyboard,
|
||||
meta_backend_get_keymap (meta_get_backend ()));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -303,44 +375,40 @@ meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard)
|
||||
{
|
||||
meta_wayland_keyboard_set_focus (keyboard, NULL);
|
||||
meta_wayland_xkb_info_destroy (&keyboard->xkb_info);
|
||||
xkb_context_unref (keyboard->xkb_context);
|
||||
|
||||
/* XXX: What about keyboard->resource_list? */
|
||||
wl_array_release (&keyboard->keys);
|
||||
wl_array_release (&keyboard->pressed_keys);
|
||||
|
||||
g_object_unref (keyboard->settings);
|
||||
}
|
||||
|
||||
static void
|
||||
update_pressed_keys (MetaWaylandKeyboard *keyboard,
|
||||
uint32_t evdev_code,
|
||||
gboolean is_press)
|
||||
update_pressed_keys (struct wl_array *keys,
|
||||
uint32_t evdev_code,
|
||||
gboolean is_press)
|
||||
{
|
||||
uint32_t *end = (void *) ((char *) keys->data + keys->size);
|
||||
uint32_t *k;
|
||||
|
||||
if (is_press)
|
||||
{
|
||||
uint32_t *end = (void *) ((char *) keyboard->keys.data +
|
||||
keyboard->keys.size);
|
||||
uint32_t *k;
|
||||
|
||||
/* Make sure we don't already have this key. */
|
||||
for (k = keyboard->keys.data; k < end; k++)
|
||||
for (k = keys->data; k < end; k++)
|
||||
if (*k == evdev_code)
|
||||
return;
|
||||
|
||||
/* Otherwise add the key to the list of pressed keys */
|
||||
k = wl_array_add (&keyboard->keys, sizeof (*k));
|
||||
k = wl_array_add (keys, sizeof (*k));
|
||||
*k = evdev_code;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t *end = (void *) ((char *) keyboard->keys.data +
|
||||
keyboard->keys.size);
|
||||
uint32_t *k;
|
||||
|
||||
/* Remove the key from the array */
|
||||
for (k = keyboard->keys.data; k < end; k++)
|
||||
for (k = keys->data; k < end; k++)
|
||||
if (*k == evdev_code)
|
||||
{
|
||||
*k = *(end - 1);
|
||||
keyboard->keys.size -= sizeof (*k);
|
||||
keys->size -= sizeof (*k);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -364,7 +432,7 @@ meta_wayland_keyboard_update (MetaWaylandKeyboard *keyboard,
|
||||
struct xkb_state *state = keyboard->xkb_info.state;
|
||||
enum xkb_state_component changed_state;
|
||||
|
||||
update_pressed_keys (keyboard, evdev_code (event), is_press);
|
||||
update_pressed_keys (&keyboard->pressed_keys, evdev_code (event), is_press);
|
||||
|
||||
changed_state = xkb_state_update_key (state,
|
||||
event->hardware_keycode,
|
||||
@@ -488,7 +556,7 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard,
|
||||
xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED),
|
||||
xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE));
|
||||
wl_keyboard_send_enter (resource, serial, keyboard->focus_surface->resource,
|
||||
&keyboard->keys);
|
||||
&keyboard->pressed_keys);
|
||||
}
|
||||
|
||||
keyboard->focus_serial = serial;
|
||||
@@ -496,30 +564,6 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard,
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
struct wl_client *
|
||||
meta_wayland_keyboard_get_focus_client (MetaWaylandKeyboard *keyboard)
|
||||
{
|
||||
@@ -548,8 +592,7 @@ meta_wayland_keyboard_create_new_resource (MetaWaylandKeyboard *keyboard,
|
||||
{
|
||||
struct wl_resource *cr;
|
||||
|
||||
cr = wl_resource_create (client, &wl_keyboard_interface,
|
||||
MIN (META_WL_KEYBOARD_VERSION, wl_resource_get_version (seat_resource)), id);
|
||||
cr = wl_resource_create (client, &wl_keyboard_interface, wl_resource_get_version (seat_resource), id);
|
||||
wl_resource_set_implementation (cr, &keyboard_interface, keyboard, unbind_resource);
|
||||
wl_list_insert (&keyboard->resource_list, wl_resource_get_link (cr));
|
||||
|
||||
@@ -558,6 +601,8 @@ meta_wayland_keyboard_create_new_resource (MetaWaylandKeyboard *keyboard,
|
||||
keyboard->xkb_info.keymap_fd,
|
||||
keyboard->xkb_info.keymap_size);
|
||||
|
||||
notify_key_repeat_for_resource (keyboard, cr);
|
||||
|
||||
if (keyboard->focus_surface && wl_resource_get_client (keyboard->focus_surface->resource) == client)
|
||||
meta_wayland_keyboard_set_focus (keyboard, keyboard->focus_surface);
|
||||
}
|
||||
|
||||
@@ -69,10 +69,11 @@ struct _MetaWaylandKeyboard
|
||||
struct wl_listener focus_surface_listener;
|
||||
uint32_t focus_serial;
|
||||
|
||||
struct wl_array keys;
|
||||
struct wl_array pressed_keys;
|
||||
|
||||
struct xkb_context *xkb_context;
|
||||
MetaWaylandXkbInfo xkb_info;
|
||||
|
||||
GSettings *settings;
|
||||
};
|
||||
|
||||
void meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
||||
@@ -89,18 +90,6 @@ gboolean meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
|
||||
void meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
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);
|
||||
|
||||
struct wl_client * meta_wayland_keyboard_get_focus_client (MetaWaylandKeyboard *keyboard);
|
||||
|
||||
void meta_wayland_keyboard_create_new_resource (MetaWaylandKeyboard *keyboard,
|
||||
|
||||
@@ -102,8 +102,7 @@ bind_output (struct wl_client *client,
|
||||
struct wl_resource *resource;
|
||||
guint mode_flags;
|
||||
|
||||
resource = wl_resource_create (client, &wl_output_interface,
|
||||
MIN (META_WL_OUTPUT_VERSION, version), id);
|
||||
resource = wl_resource_create (client, &wl_output_interface, version, id);
|
||||
wayland_output->resources = g_list_prepend (wayland_output->resources, resource);
|
||||
|
||||
wl_resource_set_user_data (resource, wayland_output);
|
||||
@@ -115,18 +114,17 @@ bind_output (struct wl_client *client,
|
||||
output->crtc->rect.width, output->crtc->rect.height,
|
||||
output->crtc->current_mode->refresh_rate);
|
||||
|
||||
wl_resource_post_event (resource,
|
||||
WL_OUTPUT_GEOMETRY,
|
||||
(int)output->crtc->rect.x,
|
||||
(int)output->crtc->rect.y,
|
||||
output->width_mm,
|
||||
output->height_mm,
|
||||
/* Cogl values reflect XRandR values,
|
||||
and so does wayland */
|
||||
output->subpixel_order,
|
||||
output->vendor,
|
||||
output->product,
|
||||
output->crtc->transform);
|
||||
wl_output_send_geometry (resource,
|
||||
(int)output->crtc->rect.x,
|
||||
(int)output->crtc->rect.y,
|
||||
output->width_mm,
|
||||
output->height_mm,
|
||||
/* Cogl values reflect XRandR values,
|
||||
and so does wayland */
|
||||
output->subpixel_order,
|
||||
output->vendor,
|
||||
output->product,
|
||||
output->crtc->transform);
|
||||
|
||||
g_assert (output->crtc->current_mode != NULL);
|
||||
|
||||
@@ -134,22 +132,18 @@ bind_output (struct wl_client *client,
|
||||
if (output->crtc->current_mode == output->preferred_mode)
|
||||
mode_flags |= WL_OUTPUT_MODE_PREFERRED;
|
||||
|
||||
wl_resource_post_event (resource,
|
||||
WL_OUTPUT_MODE,
|
||||
mode_flags,
|
||||
(int)output->crtc->current_mode->width,
|
||||
(int)output->crtc->current_mode->height,
|
||||
(int)output->crtc->current_mode->refresh_rate);
|
||||
wl_output_send_mode (resource,
|
||||
mode_flags,
|
||||
(int)output->crtc->current_mode->width,
|
||||
(int)output->crtc->current_mode->height,
|
||||
(int)output->crtc->current_mode->refresh_rate);
|
||||
|
||||
output->scale = compute_scale (output);
|
||||
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
|
||||
wl_resource_post_event (resource,
|
||||
WL_OUTPUT_SCALE,
|
||||
output->scale);
|
||||
wl_output_send_scale (resource, output->scale);
|
||||
|
||||
if (version >= WL_OUTPUT_DONE_SINCE_VERSION)
|
||||
wl_resource_post_event (resource,
|
||||
WL_OUTPUT_DONE);
|
||||
wl_output_send_done (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -246,14 +246,25 @@ sync_focus_surface (MetaWaylandPointer *pointer)
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
MetaWaylandSurface *focus_surface;
|
||||
|
||||
/* Don't update the focus surface while we have a move/resize grab. */
|
||||
if (meta_grab_op_is_moving_or_resizing (display->grab_op))
|
||||
return;
|
||||
switch (display->event_route)
|
||||
{
|
||||
case META_EVENT_ROUTE_WINDOW_OP:
|
||||
/* Don't update the focus surface while we're grabbing a window. */
|
||||
return;
|
||||
|
||||
if (meta_grab_op_should_block_wayland (display->grab_op))
|
||||
focus_surface = NULL;
|
||||
else
|
||||
focus_surface = pointer->current;
|
||||
case META_EVENT_ROUTE_COMPOSITOR_GRAB:
|
||||
/* The compositor has focus, so remove our focus... */
|
||||
focus_surface = NULL;
|
||||
break;
|
||||
|
||||
case META_EVENT_ROUTE_NORMAL:
|
||||
case META_EVENT_ROUTE_WAYLAND_POPUP:
|
||||
focus_surface = pointer->current;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (focus_surface != pointer->focus_surface)
|
||||
{
|
||||
@@ -304,14 +315,6 @@ meta_wayland_pointer_update (MetaWaylandPointer *pointer,
|
||||
repick_for_event (pointer, event);
|
||||
|
||||
pointer->button_count = count_buttons (event);
|
||||
|
||||
if (pointer->cursor_tracker)
|
||||
{
|
||||
ClutterPoint pos;
|
||||
|
||||
clutter_input_device_get_coords (pointer->device, NULL, &pos);
|
||||
meta_cursor_tracker_update_position (pointer->cursor_tracker, pos.x, pos.y);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -802,8 +805,7 @@ meta_wayland_pointer_create_new_resource (MetaWaylandPointer *pointer,
|
||||
{
|
||||
struct wl_resource *cr;
|
||||
|
||||
cr = wl_resource_create (client, &wl_pointer_interface,
|
||||
MIN (META_WL_POINTER_VERSION, wl_resource_get_version (seat_resource)), id);
|
||||
cr = wl_resource_create (client, &wl_pointer_interface, wl_resource_get_version (seat_resource), id);
|
||||
wl_resource_set_implementation (cr, &pointer_interface, pointer, unbind_resource);
|
||||
wl_list_insert (&pointer->resource_list, wl_resource_get_link (cr));
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ typedef struct
|
||||
struct _MetaWaylandCompositor
|
||||
{
|
||||
struct wl_display *wayland_display;
|
||||
char *display_name;
|
||||
const char *display_name;
|
||||
ClutterActor *stage;
|
||||
GHashTable *outputs;
|
||||
struct wl_list frame_callbacks;
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
#include "meta-wayland-versions.h"
|
||||
#include "meta-wayland-data-device.h"
|
||||
|
||||
#define CAPABILITY_ENABLED(prev, cur, capability) ((cur & (capability)) && !(prev & (capability)))
|
||||
#define CAPABILITY_DISABLED(prev, cur, capability) ((prev & (capability)) && !(cur & (capability)))
|
||||
|
||||
static void
|
||||
unbind_resource (struct wl_resource *resource)
|
||||
{
|
||||
@@ -81,32 +84,140 @@ bind_seat (struct wl_client *client,
|
||||
MetaWaylandSeat *seat = data;
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, &wl_seat_interface,
|
||||
MIN (META_WL_SEAT_VERSION, version), id);
|
||||
resource = wl_resource_create (client, &wl_seat_interface, version, id);
|
||||
wl_resource_set_implementation (resource, &seat_interface, seat, unbind_resource);
|
||||
wl_list_insert (&seat->base_resource_list, wl_resource_get_link (resource));
|
||||
|
||||
wl_seat_send_capabilities (resource,
|
||||
WL_SEAT_CAPABILITY_POINTER |
|
||||
WL_SEAT_CAPABILITY_KEYBOARD |
|
||||
WL_SEAT_CAPABILITY_TOUCH);
|
||||
wl_seat_send_capabilities (resource, seat->capabilities);
|
||||
|
||||
if (version >= WL_SEAT_NAME_SINCE_VERSION)
|
||||
wl_seat_send_name (resource, "seat0");
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
lookup_device_capabilities (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
const GSList *devices, *l;
|
||||
uint32_t capabilities = 0;
|
||||
|
||||
devices = clutter_device_manager_peek_devices (device_manager);
|
||||
|
||||
for (l = devices; l; l = l->next)
|
||||
{
|
||||
ClutterInputDeviceType device_type;
|
||||
|
||||
/* Only look for physical devices, master devices have rather generic
|
||||
* keyboard/pointer device types, which is not truly representative of
|
||||
* the slave devices connected to them.
|
||||
*/
|
||||
if (clutter_input_device_get_device_mode (l->data) == CLUTTER_INPUT_MODE_MASTER)
|
||||
continue;
|
||||
|
||||
device_type = clutter_input_device_get_device_type (l->data);
|
||||
|
||||
switch (device_type)
|
||||
{
|
||||
case CLUTTER_POINTER_DEVICE:
|
||||
capabilities |= WL_SEAT_CAPABILITY_POINTER;
|
||||
break;
|
||||
case CLUTTER_KEYBOARD_DEVICE:
|
||||
capabilities |= WL_SEAT_CAPABILITY_KEYBOARD;
|
||||
break;
|
||||
case CLUTTER_TOUCHSCREEN_DEVICE:
|
||||
capabilities |= WL_SEAT_CAPABILITY_TOUCH;
|
||||
break;
|
||||
default:
|
||||
g_debug ("Ignoring device '%s' with unhandled type %d",
|
||||
clutter_input_device_get_device_name (l->data),
|
||||
device_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_seat_set_capabilities (MetaWaylandSeat *seat,
|
||||
uint32_t flags)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
uint32_t prev_flags;
|
||||
|
||||
prev_flags = seat->capabilities;
|
||||
|
||||
if (prev_flags == flags)
|
||||
return;
|
||||
|
||||
seat->capabilities = flags;
|
||||
|
||||
if (CAPABILITY_ENABLED (prev_flags, flags, WL_SEAT_CAPABILITY_POINTER))
|
||||
meta_wayland_pointer_init (&seat->pointer, seat->wl_display);
|
||||
else if (CAPABILITY_DISABLED (prev_flags, flags, WL_SEAT_CAPABILITY_POINTER))
|
||||
meta_wayland_pointer_release (&seat->pointer);
|
||||
|
||||
if (CAPABILITY_ENABLED (prev_flags, flags, WL_SEAT_CAPABILITY_KEYBOARD))
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
meta_wayland_keyboard_init (&seat->keyboard, seat->wl_display);
|
||||
display = meta_get_display ();
|
||||
|
||||
/* Post-initialization, ensure the input focus is in sync */
|
||||
if (display)
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
}
|
||||
else if (CAPABILITY_DISABLED (prev_flags, flags, WL_SEAT_CAPABILITY_KEYBOARD))
|
||||
meta_wayland_keyboard_release (&seat->keyboard);
|
||||
|
||||
if (CAPABILITY_ENABLED (prev_flags, flags, WL_SEAT_CAPABILITY_TOUCH))
|
||||
meta_wayland_touch_init (&seat->touch, seat->wl_display);
|
||||
else if (CAPABILITY_DISABLED (prev_flags, flags, WL_SEAT_CAPABILITY_TOUCH))
|
||||
meta_wayland_touch_release (&seat->touch);
|
||||
|
||||
/* Broadcast capability changes */
|
||||
wl_resource_for_each (resource, &seat->base_resource_list)
|
||||
{
|
||||
wl_seat_send_capabilities (resource, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_seat_update_capabilities (MetaWaylandSeat *seat,
|
||||
ClutterDeviceManager *device_manager)
|
||||
{
|
||||
uint32_t capabilities;
|
||||
|
||||
capabilities = lookup_device_capabilities (device_manager);
|
||||
meta_wayland_seat_set_capabilities (seat, capabilities);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_seat_devices_updated (ClutterDeviceManager *device_manager,
|
||||
ClutterInputDevice *input_device,
|
||||
MetaWaylandSeat *seat)
|
||||
{
|
||||
meta_wayland_seat_update_capabilities (seat, device_manager);
|
||||
}
|
||||
|
||||
static MetaWaylandSeat *
|
||||
meta_wayland_seat_new (struct wl_display *display)
|
||||
{
|
||||
MetaWaylandSeat *seat = g_new0 (MetaWaylandSeat, 1);
|
||||
ClutterDeviceManager *device_manager;
|
||||
|
||||
wl_list_init (&seat->base_resource_list);
|
||||
seat->wl_display = display;
|
||||
|
||||
meta_wayland_pointer_init (&seat->pointer, display);
|
||||
meta_wayland_keyboard_init (&seat->keyboard, display);
|
||||
meta_wayland_touch_init (&seat->touch, display);
|
||||
meta_wayland_data_device_init (&seat->data_device);
|
||||
|
||||
device_manager = clutter_device_manager_get_default ();
|
||||
meta_wayland_seat_update_capabilities (seat, device_manager);
|
||||
g_signal_connect (device_manager, "device-added",
|
||||
G_CALLBACK (meta_wayland_seat_devices_updated), seat);
|
||||
g_signal_connect (device_manager, "device-removed",
|
||||
G_CALLBACK (meta_wayland_seat_devices_updated), seat);
|
||||
|
||||
wl_global_create (display, &wl_seat_interface, META_WL_SEAT_VERSION, seat, bind_seat);
|
||||
|
||||
return seat;
|
||||
@@ -121,9 +232,11 @@ meta_wayland_seat_init (MetaWaylandCompositor *compositor)
|
||||
void
|
||||
meta_wayland_seat_free (MetaWaylandSeat *seat)
|
||||
{
|
||||
meta_wayland_pointer_release (&seat->pointer);
|
||||
meta_wayland_keyboard_release (&seat->keyboard);
|
||||
meta_wayland_touch_release (&seat->touch);
|
||||
ClutterDeviceManager *device_manager;
|
||||
|
||||
device_manager = clutter_device_manager_get_default ();
|
||||
g_signal_handlers_disconnect_by_data (device_manager, seat);
|
||||
meta_wayland_seat_set_capabilities (seat, 0);
|
||||
|
||||
g_slice_free (MetaWaylandSeat, seat);
|
||||
}
|
||||
@@ -206,9 +319,27 @@ meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat)
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_seat_can_grab_surface (MetaWaylandSeat *seat,
|
||||
MetaWaylandSurface *surface,
|
||||
uint32_t serial)
|
||||
meta_wayland_seat_get_grab_info (MetaWaylandSeat *seat,
|
||||
MetaWaylandSurface *surface,
|
||||
uint32_t serial,
|
||||
gfloat *x,
|
||||
gfloat *y)
|
||||
{
|
||||
return meta_wayland_pointer_can_grab_surface (&seat->pointer, surface, serial);
|
||||
ClutterEventSequence *sequence;
|
||||
|
||||
sequence = meta_wayland_touch_find_grab_sequence (&seat->touch, surface, serial);
|
||||
|
||||
if (sequence)
|
||||
meta_wayland_touch_get_press_coords (&seat->touch, sequence, x, y);
|
||||
else if (meta_wayland_pointer_can_grab_surface (&seat->pointer, surface, serial))
|
||||
{
|
||||
if (x)
|
||||
*x = seat->pointer.grab_x;
|
||||
if (y)
|
||||
*y = seat->pointer.grab_y;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -34,11 +34,14 @@
|
||||
struct _MetaWaylandSeat
|
||||
{
|
||||
struct wl_list base_resource_list;
|
||||
struct wl_display *wl_display;
|
||||
|
||||
MetaWaylandPointer pointer;
|
||||
MetaWaylandKeyboard keyboard;
|
||||
MetaWaylandTouch touch;
|
||||
MetaWaylandDataDevice data_device;
|
||||
|
||||
guint capabilities;
|
||||
};
|
||||
|
||||
void meta_wayland_seat_init (MetaWaylandCompositor *compositor);
|
||||
@@ -57,8 +60,10 @@ void meta_wayland_seat_set_input_focus (MetaWaylandSeat *seat,
|
||||
void meta_wayland_seat_repick (MetaWaylandSeat *seat);
|
||||
void meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat);
|
||||
|
||||
gboolean meta_wayland_seat_can_grab_surface (MetaWaylandSeat *seat,
|
||||
MetaWaylandSurface *surface,
|
||||
uint32_t serial);
|
||||
gboolean meta_wayland_seat_get_grab_info (MetaWaylandSeat *seat,
|
||||
MetaWaylandSurface *surface,
|
||||
uint32_t serial,
|
||||
gfloat *x,
|
||||
gfloat *y);
|
||||
|
||||
#endif /* META_WAYLAND_SEAT_H */
|
||||
|
||||
@@ -109,11 +109,15 @@ surface_process_damage (MetaWaylandSurface *surface,
|
||||
int i, n_rectangles;
|
||||
cairo_rectangle_int_t buffer_rect;
|
||||
int scale = surface->scale;
|
||||
CoglTexture *texture;
|
||||
struct wl_shm_buffer *shm_buffer;
|
||||
|
||||
/* Damage without a buffer makes no sense so ignore that, otherwise we would crash */
|
||||
if (!surface->buffer)
|
||||
return;
|
||||
|
||||
texture = surface->buffer->texture;
|
||||
|
||||
buffer_rect.x = 0;
|
||||
buffer_rect.y = 0;
|
||||
buffer_rect.width = cogl_texture_get_width (surface->buffer->texture);
|
||||
@@ -125,10 +129,16 @@ surface_process_damage (MetaWaylandSurface *surface,
|
||||
|
||||
n_rectangles = cairo_region_num_rectangles (region);
|
||||
|
||||
shm_buffer = wl_shm_buffer_get (surface->buffer->resource);
|
||||
|
||||
for (i = 0; i < n_rectangles; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
|
||||
if (shm_buffer)
|
||||
cogl_wayland_texture_set_region_from_shm_buffer (texture, rect.x, rect.y, rect.width, rect.height, shm_buffer, rect.x, rect.y, 0, NULL);
|
||||
|
||||
meta_surface_actor_process_damage (surface->surface_actor,
|
||||
rect.x * scale, rect.y * scale, rect.width * scale, rect.height * scale);
|
||||
}
|
||||
@@ -177,6 +187,9 @@ calculate_surface_window_geometry (MetaWaylandSurface *surface,
|
||||
if (!CLUTTER_ACTOR_IS_VISIBLE (surface_actor))
|
||||
return;
|
||||
|
||||
if (!surface->buffer)
|
||||
return;
|
||||
|
||||
/* XXX: Is there a better way to do this using Clutter APIs? */
|
||||
clutter_actor_get_position (surface_actor, &x, &y);
|
||||
|
||||
@@ -212,7 +225,12 @@ toplevel_surface_commit (MetaWaylandSurface *surface,
|
||||
/* We resize X based surfaces according to X events */
|
||||
if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
|
||||
{
|
||||
MetaRectangle geom;
|
||||
MetaRectangle geom = { 0 };
|
||||
|
||||
CoglTexture *texture = surface->buffer->texture;
|
||||
/* Update the buffer rect immediately. */
|
||||
window->buffer_rect.width = cogl_texture_get_width (texture);
|
||||
window->buffer_rect.height = cogl_texture_get_height (texture);
|
||||
|
||||
if (pending->has_new_geometry)
|
||||
{
|
||||
@@ -243,7 +261,10 @@ toplevel_surface_commit (MetaWaylandSurface *surface,
|
||||
return;
|
||||
}
|
||||
|
||||
meta_window_wayland_move_resize (window, geom, pending->dx, pending->dy);
|
||||
meta_window_wayland_move_resize (window,
|
||||
&surface->acked_configure_serial,
|
||||
geom, pending->dx, pending->dy);
|
||||
surface->acked_configure_serial.set = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,7 +416,7 @@ commit_pending_state (MetaWaylandSurface *surface,
|
||||
if (pending->buffer)
|
||||
{
|
||||
ensure_buffer_texture (pending->buffer);
|
||||
meta_surface_actor_wayland_set_buffer (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor), pending->buffer);
|
||||
meta_surface_actor_wayland_set_texture (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor), pending->buffer->texture);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,6 +426,9 @@ commit_pending_state (MetaWaylandSurface *surface,
|
||||
if (!cairo_region_is_empty (pending->damage))
|
||||
surface_process_damage (surface, pending->damage);
|
||||
|
||||
surface->offset_x += pending->dx;
|
||||
surface->offset_y += pending->dy;
|
||||
|
||||
if (pending->opaque_region)
|
||||
{
|
||||
pending->opaque_region = scale_region (pending->opaque_region, surface->scale);
|
||||
@@ -598,7 +622,7 @@ wl_surface_set_buffer_scale (struct wl_client *client,
|
||||
g_warning ("Trying to set invalid buffer_scale of %d\n", scale);
|
||||
}
|
||||
|
||||
const struct wl_surface_interface meta_wayland_wl_surface_interface = {
|
||||
static const struct wl_surface_interface meta_wayland_wl_surface_interface = {
|
||||
wl_surface_destroy,
|
||||
wl_surface_attach,
|
||||
wl_surface_damage,
|
||||
@@ -688,8 +712,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
|
||||
surface->compositor = compositor;
|
||||
surface->scale = 1;
|
||||
|
||||
surface->resource = wl_resource_create (client, &wl_surface_interface,
|
||||
MIN (META_WL_SURFACE_VERSION, wl_resource_get_version (compositor_resource)), id);
|
||||
surface->resource = wl_resource_create (client, &wl_surface_interface, wl_resource_get_version (compositor_resource), id);
|
||||
wl_resource_set_implementation (surface->resource, &meta_wayland_wl_surface_interface, surface, wl_surface_destructor);
|
||||
|
||||
surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy;
|
||||
@@ -707,7 +730,6 @@ destroy_surface_extension (MetaWaylandSurfaceExtension *extension)
|
||||
|
||||
static gboolean
|
||||
create_surface_extension (MetaWaylandSurfaceExtension *extension,
|
||||
int max_version,
|
||||
const struct wl_interface *interface,
|
||||
const void *implementation,
|
||||
wl_resource_destroy_func_t destructor,
|
||||
@@ -721,8 +743,7 @@ create_surface_extension (MetaWaylandSurfaceExtension *extension,
|
||||
return FALSE;
|
||||
|
||||
client = wl_resource_get_client (surface->resource);
|
||||
extension->resource = wl_resource_create (client, interface,
|
||||
MIN (max_version, wl_resource_get_version (master_resource)), id);
|
||||
extension->resource = wl_resource_create (client, interface, wl_resource_get_version (master_resource), id);
|
||||
wl_resource_set_implementation (extension->resource, implementation, surface, destructor);
|
||||
|
||||
return TRUE;
|
||||
@@ -811,16 +832,20 @@ xdg_surface_show_window_menu (struct wl_client *client,
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
|
||||
if (!meta_wayland_seat_can_grab_surface (seat, surface, serial))
|
||||
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, NULL, NULL))
|
||||
return;
|
||||
|
||||
meta_window_show_menu (surface->window, META_WINDOW_MENU_WM, x, y);
|
||||
meta_window_show_menu (surface->window, META_WINDOW_MENU_WM,
|
||||
surface->window->buffer_rect.x + x,
|
||||
surface->window->buffer_rect.y + y);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
begin_grab_op_on_surface (MetaWaylandSurface *surface,
|
||||
MetaWaylandSeat *seat,
|
||||
MetaGrabOp grab_op)
|
||||
MetaGrabOp grab_op,
|
||||
gfloat x,
|
||||
gfloat y)
|
||||
{
|
||||
MetaWindow *window = surface->window;
|
||||
|
||||
@@ -836,8 +861,7 @@ begin_grab_op_on_surface (MetaWaylandSurface *surface,
|
||||
1, /* button. XXX? */
|
||||
0, /* modmask */
|
||||
meta_display_get_current_time_roundtrip (window->display),
|
||||
seat->pointer.grab_x,
|
||||
seat->pointer.grab_y);
|
||||
x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -848,38 +872,35 @@ xdg_surface_move (struct wl_client *client,
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
gfloat x, y;
|
||||
|
||||
if (!meta_wayland_seat_can_grab_surface (seat, surface, serial))
|
||||
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, &x, &y))
|
||||
return;
|
||||
|
||||
begin_grab_op_on_surface (surface, seat, META_GRAB_OP_MOVING);
|
||||
begin_grab_op_on_surface (surface, seat, META_GRAB_OP_MOVING, x, y);
|
||||
}
|
||||
|
||||
static MetaGrabOp
|
||||
grab_op_for_xdg_surface_resize_edge (int edge)
|
||||
{
|
||||
switch (edge)
|
||||
MetaGrabOp op = META_GRAB_OP_WINDOW_BASE;
|
||||
|
||||
if (edge & XDG_SURFACE_RESIZE_EDGE_TOP)
|
||||
op |= META_GRAB_OP_WINDOW_DIR_NORTH;
|
||||
if (edge & XDG_SURFACE_RESIZE_EDGE_BOTTOM)
|
||||
op |= META_GRAB_OP_WINDOW_DIR_SOUTH;
|
||||
if (edge & XDG_SURFACE_RESIZE_EDGE_LEFT)
|
||||
op |= META_GRAB_OP_WINDOW_DIR_WEST;
|
||||
if (edge & XDG_SURFACE_RESIZE_EDGE_RIGHT)
|
||||
op |= META_GRAB_OP_WINDOW_DIR_EAST;
|
||||
|
||||
if (op == META_GRAB_OP_WINDOW_BASE)
|
||||
{
|
||||
case XDG_SURFACE_RESIZE_EDGE_TOP_LEFT:
|
||||
return META_GRAB_OP_RESIZING_NW;
|
||||
case XDG_SURFACE_RESIZE_EDGE_TOP:
|
||||
return META_GRAB_OP_RESIZING_N;
|
||||
case XDG_SURFACE_RESIZE_EDGE_TOP_RIGHT:
|
||||
return META_GRAB_OP_RESIZING_NE;
|
||||
case XDG_SURFACE_RESIZE_EDGE_RIGHT:
|
||||
return META_GRAB_OP_RESIZING_E;
|
||||
case XDG_SURFACE_RESIZE_EDGE_BOTTOM_RIGHT:
|
||||
return META_GRAB_OP_RESIZING_SE;
|
||||
case XDG_SURFACE_RESIZE_EDGE_BOTTOM:
|
||||
return META_GRAB_OP_RESIZING_S;
|
||||
case XDG_SURFACE_RESIZE_EDGE_BOTTOM_LEFT:
|
||||
return META_GRAB_OP_RESIZING_SW;
|
||||
case XDG_SURFACE_RESIZE_EDGE_LEFT:
|
||||
return META_GRAB_OP_RESIZING_W;
|
||||
default:
|
||||
g_warning ("invalid edge: %d", edge);
|
||||
return META_GRAB_OP_NONE;
|
||||
}
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -891,11 +912,12 @@ xdg_surface_resize (struct wl_client *client,
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
gfloat x, y;
|
||||
|
||||
if (!meta_wayland_seat_can_grab_surface (seat, surface, serial))
|
||||
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, &x, &y))
|
||||
return;
|
||||
|
||||
begin_grab_op_on_surface (surface, seat, grab_op_for_xdg_surface_resize_edge (edges));
|
||||
begin_grab_op_on_surface (surface, seat, grab_op_for_xdg_surface_resize_edge (edges), x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -903,11 +925,10 @@ xdg_surface_ack_configure (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial)
|
||||
{
|
||||
/* Do nothing for now. In the future, we'd imagine that
|
||||
* we'd ignore attaches when we have a state pending that
|
||||
* we haven't had the client ACK'd, to prevent a race
|
||||
* condition when we have an in-flight attach when the
|
||||
* client gets the new state. */
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
|
||||
surface->acked_configure_serial.set = TRUE;
|
||||
surface->acked_configure_serial.value = serial;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -992,7 +1013,6 @@ xdg_shell_get_xdg_surface (struct wl_client *client,
|
||||
MetaWindow *window;
|
||||
|
||||
if (!create_surface_extension (&surface->xdg_surface,
|
||||
META_XDG_SURFACE_VERSION,
|
||||
&xdg_surface_interface,
|
||||
&meta_wayland_xdg_surface_interface,
|
||||
xdg_surface_destructor,
|
||||
@@ -1004,6 +1024,8 @@ xdg_shell_get_xdg_surface (struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
|
||||
surface->xdg_shell_resource = resource;
|
||||
|
||||
window = meta_window_wayland_new (meta_get_display (), surface);
|
||||
meta_wayland_surface_set_window (surface, window);
|
||||
}
|
||||
@@ -1049,7 +1071,6 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
|
||||
return;
|
||||
|
||||
if (!create_surface_extension (&surface->xdg_popup,
|
||||
META_XDG_POPUP_VERSION,
|
||||
&xdg_popup_interface,
|
||||
&meta_wayland_xdg_popup_interface,
|
||||
xdg_popup_destructor,
|
||||
@@ -1061,6 +1082,8 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
|
||||
surface->xdg_shell_resource = resource;
|
||||
|
||||
window = meta_window_wayland_new (meta_get_display (), surface);
|
||||
meta_window_move_frame (window, FALSE,
|
||||
parent_surf->window->rect.x + x,
|
||||
@@ -1082,41 +1105,13 @@ static const struct xdg_shell_interface meta_wayland_xdg_shell_interface = {
|
||||
xdg_shell_pong,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct wl_resource *resource;
|
||||
struct wl_listener client_destroy_listener;
|
||||
} XdgShell;
|
||||
|
||||
static void
|
||||
xdg_shell_handle_client_destroy (struct wl_listener *listener, void *data)
|
||||
{
|
||||
XdgShell *xdg_shell = wl_container_of (listener, xdg_shell, client_destroy_listener);
|
||||
g_slice_free (XdgShell, xdg_shell);
|
||||
}
|
||||
|
||||
static struct wl_resource *
|
||||
get_xdg_shell_for_client (struct wl_client *client)
|
||||
{
|
||||
struct wl_listener *listener;
|
||||
XdgShell *xdg_shell;
|
||||
|
||||
listener = wl_client_get_destroy_listener (client, xdg_shell_handle_client_destroy);
|
||||
|
||||
/* No xdg_shell has been bound for this client */
|
||||
if (listener == NULL)
|
||||
return NULL;
|
||||
|
||||
xdg_shell = wl_container_of (listener, xdg_shell, client_destroy_listener);
|
||||
return xdg_shell->resource;
|
||||
}
|
||||
|
||||
static void
|
||||
bind_xdg_shell (struct wl_client *client,
|
||||
void *data,
|
||||
guint32 version,
|
||||
guint32 id)
|
||||
{
|
||||
XdgShell *xdg_shell;
|
||||
struct wl_resource *resource;
|
||||
|
||||
if (version != META_XDG_SHELL_VERSION)
|
||||
{
|
||||
@@ -1124,13 +1119,8 @@ bind_xdg_shell (struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
|
||||
xdg_shell = g_slice_new (XdgShell);
|
||||
|
||||
xdg_shell->resource = wl_resource_create (client, &xdg_shell_interface, META_XDG_SHELL_VERSION, id);
|
||||
wl_resource_set_implementation (xdg_shell->resource, &meta_wayland_xdg_shell_interface, data, NULL);
|
||||
|
||||
xdg_shell->client_destroy_listener.notify = xdg_shell_handle_client_destroy;
|
||||
wl_client_add_destroy_listener (client, &xdg_shell->client_destroy_listener);
|
||||
resource = wl_resource_create (client, &xdg_shell_interface, version, id);
|
||||
wl_resource_set_implementation (resource, &meta_wayland_xdg_shell_interface, data, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1159,38 +1149,35 @@ wl_shell_surface_move (struct wl_client *client,
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
gfloat x, y;
|
||||
|
||||
if (!meta_wayland_seat_can_grab_surface (seat, surface, serial))
|
||||
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, &x, &y))
|
||||
return;
|
||||
|
||||
begin_grab_op_on_surface (surface, seat, META_GRAB_OP_MOVING);
|
||||
begin_grab_op_on_surface (surface, seat, META_GRAB_OP_MOVING, x, y);
|
||||
}
|
||||
|
||||
static MetaGrabOp
|
||||
grab_op_for_wl_shell_surface_resize_edge (int edge)
|
||||
{
|
||||
switch (edge)
|
||||
MetaGrabOp op = META_GRAB_OP_WINDOW_BASE;
|
||||
|
||||
if (edge & WL_SHELL_SURFACE_RESIZE_TOP)
|
||||
op |= META_GRAB_OP_WINDOW_DIR_NORTH;
|
||||
if (edge & WL_SHELL_SURFACE_RESIZE_BOTTOM)
|
||||
op |= META_GRAB_OP_WINDOW_DIR_SOUTH;
|
||||
if (edge & WL_SHELL_SURFACE_RESIZE_LEFT)
|
||||
op |= META_GRAB_OP_WINDOW_DIR_WEST;
|
||||
if (edge & WL_SHELL_SURFACE_RESIZE_RIGHT)
|
||||
op |= META_GRAB_OP_WINDOW_DIR_EAST;
|
||||
|
||||
if (op == META_GRAB_OP_WINDOW_BASE)
|
||||
{
|
||||
case WL_SHELL_SURFACE_RESIZE_TOP_LEFT:
|
||||
return META_GRAB_OP_RESIZING_NW;
|
||||
case WL_SHELL_SURFACE_RESIZE_TOP:
|
||||
return META_GRAB_OP_RESIZING_N;
|
||||
case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT:
|
||||
return META_GRAB_OP_RESIZING_NE;
|
||||
case WL_SHELL_SURFACE_RESIZE_RIGHT:
|
||||
return META_GRAB_OP_RESIZING_E;
|
||||
case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT:
|
||||
return META_GRAB_OP_RESIZING_SE;
|
||||
case WL_SHELL_SURFACE_RESIZE_BOTTOM:
|
||||
return META_GRAB_OP_RESIZING_S;
|
||||
case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT:
|
||||
return META_GRAB_OP_RESIZING_SW;
|
||||
case WL_SHELL_SURFACE_RESIZE_LEFT:
|
||||
return META_GRAB_OP_RESIZING_W;
|
||||
default:
|
||||
g_warning ("invalid edge: %d", edge);
|
||||
return META_GRAB_OP_NONE;
|
||||
}
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1202,11 +1189,12 @@ wl_shell_surface_resize (struct wl_client *client,
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
gfloat x, y;
|
||||
|
||||
if (!meta_wayland_seat_can_grab_surface (seat, surface, serial))
|
||||
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, &x, &y))
|
||||
return;
|
||||
|
||||
begin_grab_op_on_surface (surface, seat, grab_op_for_wl_shell_surface_resize_edge (edges));
|
||||
begin_grab_op_on_surface (surface, seat, grab_op_for_wl_shell_surface_resize_edge (edges), x, y);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
@@ -1349,7 +1337,6 @@ wl_shell_get_shell_surface (struct wl_client *client,
|
||||
MetaWindow *window;
|
||||
|
||||
if (!create_surface_extension (&surface->wl_shell_surface,
|
||||
META_WL_SHELL_SURFACE_VERSION,
|
||||
&wl_shell_surface_interface,
|
||||
&meta_wayland_wl_shell_surface_interface,
|
||||
wl_shell_surface_destructor,
|
||||
@@ -1377,8 +1364,7 @@ bind_wl_shell (struct wl_client *client,
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, &wl_shell_interface,
|
||||
MIN (META_WL_SHELL_VERSION, version), id);
|
||||
resource = wl_resource_create (client, &wl_shell_interface, version, id);
|
||||
wl_resource_set_implementation (resource, &meta_wayland_wl_shell_interface, data, NULL);
|
||||
}
|
||||
|
||||
@@ -1431,7 +1417,6 @@ get_gtk_surface (struct wl_client *client,
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
||||
|
||||
if (!create_surface_extension (&surface->gtk_surface,
|
||||
META_GTK_SURFACE_VERSION,
|
||||
>k_surface_interface,
|
||||
&meta_wayland_gtk_surface_interface,
|
||||
gtk_surface_destructor,
|
||||
@@ -1456,8 +1441,7 @@ bind_gtk_shell (struct wl_client *client,
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, >k_shell_interface,
|
||||
MIN (META_GTK_SHELL_VERSION, version), id);
|
||||
resource = wl_resource_create (client, >k_shell_interface, version, id);
|
||||
wl_resource_set_implementation (resource, &meta_wayland_gtk_shell_interface, data, NULL);
|
||||
|
||||
/* FIXME: ask the plugin */
|
||||
@@ -1705,7 +1689,6 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
|
||||
MetaWaylandSurface *parent = wl_resource_get_user_data (parent_resource);
|
||||
|
||||
if (!create_surface_extension (&surface->subsurface,
|
||||
META_GTK_SURFACE_VERSION,
|
||||
&wl_subsurface_interface,
|
||||
&meta_wayland_subsurface_interface,
|
||||
wl_subsurface_destructor,
|
||||
@@ -1743,8 +1726,7 @@ bind_subcompositor (struct wl_client *client,
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, &wl_subcompositor_interface,
|
||||
MIN (META_WL_SUBCOMPOSITOR_VERSION, version), id);
|
||||
resource = wl_resource_create (client, &wl_subcompositor_interface, version, id);
|
||||
wl_resource_set_implementation (resource, &meta_wayland_subcompositor_interface, data, NULL);
|
||||
}
|
||||
|
||||
@@ -1806,7 +1788,8 @@ fill_states (struct wl_array *states, MetaWindow *window)
|
||||
void
|
||||
meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,
|
||||
int new_width,
|
||||
int new_height)
|
||||
int new_height,
|
||||
MetaWaylandSerial *sent_serial)
|
||||
{
|
||||
if (surface->xdg_surface.resource)
|
||||
{
|
||||
@@ -1827,33 +1810,33 @@ meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,
|
||||
xdg_surface_send_configure (surface->xdg_surface.resource, new_width, new_height, &states, serial);
|
||||
|
||||
wl_array_release (&states);
|
||||
|
||||
if (sent_serial)
|
||||
{
|
||||
sent_serial->set = TRUE;
|
||||
sent_serial->value = serial;
|
||||
}
|
||||
}
|
||||
else if (surface->xdg_popup.resource)
|
||||
{
|
||||
/* This can happen if the popup window loses or receives focus.
|
||||
* Just ignore it. */
|
||||
}
|
||||
else if (surface->wl_shell_surface.resource)
|
||||
wl_shell_surface_send_configure (surface->wl_shell_surface.resource,
|
||||
0, new_width, new_height);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_ping (MetaWaylandSurface *surface,
|
||||
guint32 serial)
|
||||
{
|
||||
if (surface->xdg_surface.resource)
|
||||
{
|
||||
struct wl_client *client = wl_resource_get_client (surface->resource);
|
||||
struct wl_resource *xdg_shell = get_xdg_shell_for_client (client);
|
||||
|
||||
if (xdg_shell == NULL)
|
||||
{
|
||||
g_warning ("Trying to ping a surface without an xdg_shell bound. How does this happen?");
|
||||
return;
|
||||
}
|
||||
|
||||
xdg_shell_send_ping (xdg_shell, serial);
|
||||
}
|
||||
if (surface->xdg_shell_resource)
|
||||
xdg_shell_send_ping (surface->xdg_shell_resource, serial);
|
||||
else if (surface->wl_shell_surface.resource)
|
||||
{
|
||||
wl_shell_surface_send_ping (surface->wl_shell_surface.resource, serial);
|
||||
}
|
||||
wl_shell_surface_send_ping (surface->wl_shell_surface.resource, serial);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
#include "meta-wayland-types.h"
|
||||
#include "meta-surface-actor.h"
|
||||
|
||||
struct _MetaWaylandSerial {
|
||||
gboolean set;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
struct _MetaWaylandBuffer
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
@@ -76,6 +81,7 @@ struct _MetaWaylandSurface
|
||||
MetaWaylandCompositor *compositor;
|
||||
MetaSurfaceActor *surface_actor;
|
||||
MetaWindow *window;
|
||||
struct wl_resource *xdg_shell_resource;
|
||||
MetaWaylandSurfaceExtension xdg_surface;
|
||||
MetaWaylandSurfaceExtension xdg_popup;
|
||||
MetaWaylandSurfaceExtension wl_shell_surface;
|
||||
@@ -109,10 +115,14 @@ struct _MetaWaylandSurface
|
||||
GSList *pending_placement_ops;
|
||||
} sub;
|
||||
|
||||
int32_t offset_x, offset_y;
|
||||
|
||||
gboolean has_set_geometry;
|
||||
|
||||
/* All the pending state that wl_surface.commit will apply. */
|
||||
MetaWaylandPendingState pending;
|
||||
|
||||
MetaWaylandSerial acked_configure_serial;
|
||||
};
|
||||
|
||||
void meta_wayland_shell_init (MetaWaylandCompositor *compositor);
|
||||
@@ -126,8 +136,9 @@ void meta_wayland_surface_set_window (MetaWaylandSurface *surface
|
||||
MetaWindow *window);
|
||||
|
||||
void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,
|
||||
int width,
|
||||
int height);
|
||||
int width,
|
||||
int height,
|
||||
MetaWaylandSerial *sent_serial);
|
||||
|
||||
void meta_wayland_surface_ping (MetaWaylandSurface *surface,
|
||||
guint32 serial);
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
#include "meta-surface-actor-wayland.h"
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#endif
|
||||
|
||||
struct _MetaWaylandTouchSurface
|
||||
{
|
||||
MetaWaylandSurface *surface;
|
||||
@@ -46,6 +50,8 @@ struct _MetaWaylandTouchInfo
|
||||
MetaWaylandTouchSurface *touch_surface;
|
||||
guint32 slot_serial;
|
||||
gint32 slot;
|
||||
gfloat start_x;
|
||||
gfloat start_y;
|
||||
gfloat x;
|
||||
gfloat y;
|
||||
guint updated : 1;
|
||||
@@ -231,6 +237,7 @@ meta_wayland_touch_update (MetaWaylandTouch *touch,
|
||||
|
||||
touch_info = touch_get_info (touch, sequence, TRUE);
|
||||
touch_info->touch_surface = touch_surface_get (touch, surface);
|
||||
clutter_event_get_coords (event, &touch_info->start_x, &touch_info->start_y);
|
||||
}
|
||||
else
|
||||
touch_info = touch_get_info (touch, sequence, FALSE);
|
||||
@@ -245,7 +252,7 @@ meta_wayland_touch_update (MetaWaylandTouch *touch,
|
||||
struct wl_client *client = wl_resource_get_client (surface->resource);
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
|
||||
touch_info->slot_serial = wl_display_next_serial (display);
|
||||
touch_info->slot_serial = wl_display_get_serial (display);
|
||||
}
|
||||
|
||||
touch_get_relative_coordinates (touch, touch_info->touch_surface->surface,
|
||||
@@ -361,7 +368,7 @@ touch_send_frame_event (MetaWaylandTouch *touch)
|
||||
{
|
||||
GList *surfaces, *s;
|
||||
|
||||
surfaces = s = touch_get_surfaces (touch, TRUE);
|
||||
surfaces = touch_get_surfaces (touch, TRUE);
|
||||
|
||||
for (s = surfaces; s; s = s->next)
|
||||
{
|
||||
@@ -444,15 +451,17 @@ touch_info_free (MetaWaylandTouchInfo *touch_info)
|
||||
g_free (touch_info);
|
||||
}
|
||||
|
||||
static void
|
||||
touch_handle_cancel_event (MetaWaylandTouch *touch,
|
||||
struct libinput_event *event)
|
||||
void
|
||||
meta_wayland_touch_cancel (MetaWaylandTouch *touch)
|
||||
{
|
||||
GList *surfaces, *s;
|
||||
|
||||
if (touch->display == NULL)
|
||||
return;
|
||||
|
||||
surfaces = s = touch_get_surfaces (touch, FALSE);
|
||||
|
||||
while (s)
|
||||
for (s = surfaces; s; s = s->next)
|
||||
{
|
||||
MetaWaylandTouchSurface *touch_surface = s->data;
|
||||
struct wl_resource *resource;
|
||||
@@ -467,6 +476,7 @@ touch_handle_cancel_event (MetaWaylandTouch *touch,
|
||||
g_list_free (surfaces);
|
||||
}
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static gboolean
|
||||
evdev_filter_func (struct libinput_event *event,
|
||||
gpointer data)
|
||||
@@ -495,7 +505,7 @@ evdev_filter_func (struct libinput_event *event,
|
||||
* which are not so useful when sending a global signal as the protocol
|
||||
* requires.
|
||||
*/
|
||||
touch_handle_cancel_event (touch, event);
|
||||
meta_wayland_touch_cancel (touch);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -503,6 +513,7 @@ evdev_filter_func (struct libinput_event *event,
|
||||
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
meta_wayland_touch_init (MetaWaylandTouch *touch,
|
||||
@@ -522,15 +533,26 @@ meta_wayland_touch_init (MetaWaylandTouch *touch,
|
||||
|
||||
manager = clutter_device_manager_get_default ();
|
||||
touch->device = clutter_device_manager_get_core_device (manager, CLUTTER_TOUCHSCREEN_DEVICE);
|
||||
clutter_evdev_add_filter (evdev_filter_func, touch, NULL);
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
if (META_IS_BACKEND_NATIVE (backend))
|
||||
clutter_evdev_add_filter (evdev_filter_func, touch, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_touch_release (MetaWaylandTouch *touch)
|
||||
{
|
||||
clutter_evdev_remove_filter (evdev_filter_func, touch);
|
||||
g_hash_table_unref (touch->touch_surfaces);
|
||||
g_hash_table_unref (touch->touches);
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
if (META_IS_BACKEND_NATIVE (backend))
|
||||
clutter_evdev_remove_filter (evdev_filter_func, touch);
|
||||
#endif
|
||||
|
||||
g_clear_pointer (&touch->touch_surfaces, (GDestroyNotify) g_hash_table_unref);
|
||||
g_clear_pointer (&touch->touches, (GDestroyNotify) g_hash_table_unref);
|
||||
touch->display = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -541,8 +563,63 @@ meta_wayland_touch_create_new_resource (MetaWaylandTouch *touch,
|
||||
{
|
||||
struct wl_resource *cr;
|
||||
|
||||
cr = wl_resource_create (client, &wl_touch_interface,
|
||||
MIN (META_WL_TOUCH_VERSION, wl_resource_get_version (seat_resource)), id);
|
||||
if (touch->display == NULL)
|
||||
{
|
||||
wl_resource_post_error (seat_resource, WL_DISPLAY_ERROR_INVALID_METHOD,
|
||||
"Cannot retrieve touch interface without touch capability");
|
||||
return;
|
||||
}
|
||||
|
||||
cr = wl_resource_create (client, &wl_touch_interface, wl_resource_get_version (seat_resource), id);
|
||||
wl_resource_set_implementation (cr, &touch_interface, touch, unbind_resource);
|
||||
wl_list_insert (&touch->resource_list, wl_resource_get_link (cr));
|
||||
}
|
||||
|
||||
ClutterEventSequence *
|
||||
meta_wayland_touch_find_grab_sequence (MetaWaylandTouch *touch,
|
||||
MetaWaylandSurface *surface,
|
||||
uint32_t serial)
|
||||
{
|
||||
MetaWaylandTouchInfo *touch_info;
|
||||
ClutterEventSequence *sequence;
|
||||
GHashTableIter iter;
|
||||
|
||||
if (!touch->touches)
|
||||
return NULL;
|
||||
|
||||
g_hash_table_iter_init (&iter, touch->touches);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, (gpointer*) &sequence,
|
||||
(gpointer*) &touch_info))
|
||||
{
|
||||
if (touch_info->slot_serial == serial &&
|
||||
touch_info->touch_surface->surface == surface)
|
||||
return sequence;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_touch_get_press_coords (MetaWaylandTouch *touch,
|
||||
ClutterEventSequence *sequence,
|
||||
gfloat *x,
|
||||
gfloat *y)
|
||||
{
|
||||
MetaWaylandTouchInfo *touch_info;
|
||||
|
||||
if (!touch->touches)
|
||||
return FALSE;
|
||||
|
||||
touch_info = g_hash_table_lookup (touch->touches, sequence);
|
||||
|
||||
if (!touch_info)
|
||||
return FALSE;
|
||||
|
||||
if (x)
|
||||
*x = touch_info->start_x;
|
||||
if (y)
|
||||
*y = touch_info->start_y;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -58,5 +58,16 @@ void meta_wayland_touch_create_new_resource (MetaWaylandTouch *touch,
|
||||
struct wl_client *client,
|
||||
struct wl_resource *seat_resource,
|
||||
uint32_t id);
|
||||
void meta_wayland_touch_cancel (MetaWaylandTouch *touch);
|
||||
|
||||
|
||||
ClutterEventSequence * meta_wayland_touch_find_grab_sequence (MetaWaylandTouch *touch,
|
||||
MetaWaylandSurface *surface,
|
||||
uint32_t serial);
|
||||
|
||||
gboolean meta_wayland_touch_get_press_coords (MetaWaylandTouch *touch,
|
||||
ClutterEventSequence *sequence,
|
||||
gfloat *x,
|
||||
gfloat *y);
|
||||
|
||||
#endif /* META_WAYLAND_TOUCH_H */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user