Compare commits
162 Commits
3.13.1
...
wip/xtogls
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ac563307e | ||
|
|
24956fadcc | ||
|
|
fc5de438b5 | ||
|
|
94cee3ef09 | ||
|
|
1e6b042778 | ||
|
|
048f035d30 | ||
|
|
b32c837df9 | ||
|
|
dd03a76d51 | ||
|
|
806a666950 | ||
|
|
b240a5e819 | ||
|
|
fe823b3553 | ||
|
|
d380d30ef4 | ||
|
|
1fe5b3e7d5 | ||
|
|
a8df208a5c | ||
|
|
f3f3c94831 | ||
|
|
6e06648f7a | ||
|
|
afb41f715b | ||
|
|
19d26dde92 | ||
|
|
4acb902423 | ||
|
|
626516d12e | ||
|
|
1c94df2553 | ||
|
|
43762da9d3 | ||
|
|
266166a2d6 | ||
|
|
3a0af0faae | ||
|
|
0890eaa3fe | ||
|
|
d4058d947b | ||
|
|
b704659899 | ||
|
|
0a9187a6e9 | ||
|
|
31db32e826 | ||
|
|
c2ea650b3c | ||
|
|
969131f00e | ||
|
|
c98090c061 | ||
|
|
3168d3b5e6 | ||
|
|
efcd7d86e7 | ||
|
|
04449923bd | ||
|
|
47b3336ffa | ||
|
|
0f37c1b58e | ||
|
|
a3747725ed | ||
|
|
c448650a60 | ||
|
|
c45f616fdc | ||
|
|
9402691aaa | ||
|
|
cbffbb0be0 | ||
|
|
9df5b17940 | ||
|
|
feae23506b | ||
|
|
6408e59c7c | ||
|
|
47d72680ff | ||
|
|
6513cbb470 | ||
|
|
50b81fe4b9 | ||
|
|
f38c1f6ab4 | ||
|
|
f159611fab | ||
|
|
f1a7231ac2 | ||
|
|
21991a7edb | ||
|
|
3f1b6ddc8f | ||
|
|
aa84813400 | ||
|
|
dd243813e1 | ||
|
|
d8c2933c58 | ||
|
|
2b798511de | ||
|
|
6c37f6e601 | ||
|
|
92e9f3d467 | ||
|
|
05419b8450 | ||
|
|
e215c07439 | ||
|
|
5b7dff7a57 | ||
|
|
1a3aa75385 | ||
|
|
41880778b5 | ||
|
|
ecb4e09ec5 | ||
|
|
d02505852d | ||
|
|
3941dc7537 | ||
|
|
e790c45303 | ||
|
|
ae4e553ddb | ||
|
|
809568280b | ||
|
|
4053c92abf | ||
|
|
56906a29e0 | ||
|
|
2c0ad5bef7 | ||
|
|
4a7939268c | ||
|
|
80266d3071 | ||
|
|
8e5cfccf49 | ||
|
|
dcf64ca167 | ||
|
|
f93fc1506b | ||
|
|
4ee8fb8154 | ||
|
|
446b75907e | ||
|
|
550f1989ff | ||
|
|
91a6f42345 | ||
|
|
e97cae0eb3 | ||
|
|
8640982e68 | ||
|
|
480a853263 | ||
|
|
b05953d960 | ||
|
|
3a0de6a4f1 | ||
|
|
fb9f22c02f | ||
|
|
10ac1000f7 | ||
|
|
c81a0dede2 | ||
|
|
fc8a2b8a42 | ||
|
|
2ae0a72dad | ||
|
|
5b17c72047 | ||
|
|
8d9653dece | ||
|
|
e2b7b26f28 | ||
|
|
ff2eb77fcd | ||
|
|
0588399ac7 | ||
|
|
71544fbf4e | ||
|
|
c8f3820956 | ||
|
|
f57b0726a0 | ||
|
|
da175bca52 | ||
|
|
33cb7f4a2c | ||
|
|
7732447abc | ||
|
|
c49c37999c | ||
|
|
91f35d6a01 | ||
|
|
549df04ed8 | ||
|
|
4334135c52 | ||
|
|
03c4de5590 | ||
|
|
7a109a18af | ||
|
|
d9b72b0f43 | ||
|
|
a7ea54bd7d | ||
|
|
df642b96e2 | ||
|
|
f56cc1f733 | ||
|
|
f5bff4b7f3 | ||
|
|
bbfdf5dd2a | ||
|
|
9b95eda42a | ||
|
|
2d225a3386 | ||
|
|
7b3cdc8f96 | ||
|
|
b6f9500ccc | ||
|
|
ea354e96cb | ||
|
|
098c8908ed | ||
|
|
ab632e36a5 | ||
|
|
1427d20922 | ||
|
|
aed671810c | ||
|
|
324d7d720d | ||
|
|
413e39ecbb | ||
|
|
2ca2c18c2a | ||
|
|
01cd4b2ba0 | ||
|
|
bca210db45 | ||
|
|
66d6f73af2 | ||
|
|
bc8799d7d7 | ||
|
|
fd5c14550a | ||
|
|
a5cca5296c | ||
|
|
f4ef4b79f9 | ||
|
|
6c7a51378f | ||
|
|
9c4908b44a | ||
|
|
afaab8aef2 | ||
|
|
845fdda22c | ||
|
|
fa29a1a99e | ||
|
|
f9bffae9fd | ||
|
|
31c925c602 | ||
|
|
5d310e06ba | ||
|
|
25a16c3379 | ||
|
|
730ed6f75f | ||
|
|
a6601e92aa | ||
|
|
f3a2bb7779 | ||
|
|
73e2d7049a | ||
|
|
a6353944f6 | ||
|
|
43d6088ebb | ||
|
|
e3001794f2 | ||
|
|
e97ca325e6 | ||
|
|
c9c6645284 | ||
|
|
57bb297450 | ||
|
|
06ca99c3a3 | ||
|
|
4b5593c67f | ||
|
|
acb3dc6754 | ||
|
|
4c21a46452 | ||
|
|
900ae2c1fa | ||
|
|
01b6445708 | ||
|
|
292d502205 | ||
|
|
adf2e44a82 | ||
|
|
b075d576a0 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -48,7 +48,6 @@ po/*.pot
|
||||
50-metacity-key.xml
|
||||
libmutter.pc
|
||||
mutter
|
||||
mutter-launch
|
||||
org.gnome.mutter.gschema.valid
|
||||
org.gnome.mutter.gschema.xml
|
||||
org.gnome.mutter.wayland.gschema.valid
|
||||
@@ -78,6 +77,7 @@ src/mutter-marshal.[ch]
|
||||
src/stamp-mutter-marshal.h
|
||||
src/meta-dbus-display-config.[ch]
|
||||
src/meta-dbus-idle-monitor.[ch]
|
||||
src/meta-dbus-login1.[ch]
|
||||
src/gtk-shell-protocol.c
|
||||
src/gtk-shell-server-protocol.h
|
||||
src/xdg-shell-protocol.c
|
||||
|
||||
18
NEWS
18
NEWS
@@ -1,3 +1,21 @@
|
||||
3.13.2
|
||||
======
|
||||
* Add basic HiDPI support on wayland [Adel; #728902]
|
||||
* Fix crash when monitors change during suspend [Giovanni; #725637]
|
||||
* Replace mutter-launch with logind integration [Jasper; #724604]
|
||||
* Move window menu into the compositor [Jasper; #726352]
|
||||
* Fix delayed focus-follows-mouse support [Florian; #730541]
|
||||
* Support fallback app menu in window decorations [Florian; #730752]
|
||||
* Misc. bug fixes and cleanups [Giovanni, Jonas, Jasper; #729732, #729602,
|
||||
#726714]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Giovanni Campagna, Adel Gadllah, Florian Müllner,
|
||||
Jasper St. Pierre, Rico Tzschichholz
|
||||
|
||||
Translations:
|
||||
Pau Iranzo [ca], Daniel Mustieles [es]
|
||||
|
||||
3.13.1
|
||||
======
|
||||
* Fix opacity values from _NET_WM_WINDOW_OPACITY [Nirbheek; #727874]
|
||||
|
||||
26
configure.ac
26
configure.ac
@@ -3,7 +3,7 @@ AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [13])
|
||||
m4_define([mutter_micro_version], [1])
|
||||
m4_define([mutter_micro_version], [2])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
@@ -117,16 +117,6 @@ AC_ARG_ENABLE(shape,
|
||||
[disable mutter's use of the shaped window extension]),,
|
||||
enable_shape=auto)
|
||||
|
||||
## Wayland support requires the xserver.xml protocol extension found in the weston
|
||||
## repository but since there aren't currently established conventions for
|
||||
## installing and discovering these we simply require a location to be given
|
||||
## explicitly...
|
||||
AC_ARG_WITH([wayland-protocols],
|
||||
[AS_HELP_STRING([--with-wayland-protocols], [Location for wayland extension protocol specs])],
|
||||
[
|
||||
],
|
||||
[])
|
||||
|
||||
AC_ARG_WITH([xwayland-path],
|
||||
[AS_HELP_STRING([--with-xwayland-path], [Absolute path for an X Wayland server])],
|
||||
[XWAYLAND_PATH="$withval"],
|
||||
@@ -137,7 +127,6 @@ AM_GLIB_GNU_GETTEXT
|
||||
## here we get the flags we'll actually use
|
||||
# GRegex requires Glib-2.14.0
|
||||
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
|
||||
PKG_CHECK_MODULES(MUTTER_LAUNCH, libdrm libsystemd-login)
|
||||
|
||||
# Unconditionally use this dir to avoid a circular dep with gnomecc
|
||||
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
|
||||
@@ -210,9 +199,15 @@ AS_IF([test "x$WAYLAND_SCANNER" = "xno"],
|
||||
AC_SUBST([WAYLAND_SCANNER])
|
||||
AC_SUBST(XWAYLAND_PATH)
|
||||
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES clutter-wayland-1.0 clutter-wayland-compositor-1.0 clutter-egl-1.0 wayland-server libdrm"
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES clutter-wayland-1.0 clutter-wayland-compositor-1.0 clutter-egl-1.0 wayland-server >= 1.4.93"
|
||||
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
|
||||
|
||||
PKG_CHECK_MODULES(MUTTER_NATIVE_BACKEND, [libdrm libsystemd], [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_EXISTS([xi >= 1.6.99.1],
|
||||
AC_DEFINE([HAVE_XI23],[1],[Define if you have support for XInput 2.3 or greater]))
|
||||
|
||||
@@ -329,6 +324,11 @@ fi
|
||||
|
||||
GTK_DOC_CHECK([1.15], [--flavour no-tmpl])
|
||||
|
||||
AC_CHECK_DECL([GL_EXT_x11_sync_object],
|
||||
[],
|
||||
[AC_MSG_ERROR([GL_EXT_x11_sync_object definition not found, please update your GL headers])],
|
||||
[#include <GL/glx.h>])
|
||||
|
||||
#### Warnings (last since -Werror can disturb other tests)
|
||||
|
||||
# Stay command-line compatible with the gnome-common configure option. Here
|
||||
|
||||
@@ -79,8 +79,6 @@ IGNORE_HFILES= \
|
||||
iconcache.h \
|
||||
inlinepixbufs.h \
|
||||
keybindings-private.h \
|
||||
menu.h \
|
||||
metaaccellabel.h \
|
||||
meta-background-actor-private.h \
|
||||
meta-background-group-private.h \
|
||||
meta-module.h \
|
||||
|
||||
@@ -22,8 +22,6 @@ src/mutter.desktop.in
|
||||
src/org.gnome.mutter.gschema.xml.in
|
||||
src/org.gnome.mutter.wayland.gschema.xml.in
|
||||
src/ui/frames.c
|
||||
src/ui/menu.c
|
||||
src/ui/metaaccellabel.c
|
||||
src/ui/resizepopup.c
|
||||
src/ui/theme.c
|
||||
src/ui/theme-parser.c
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
src/metacity.schemas.in
|
||||
|
||||
src/mutter-wayland.desktop.in
|
||||
|
||||
148
po/es.po
148
po/es.po
@@ -14,16 +14,16 @@ msgstr ""
|
||||
"Project-Id-Version: mutter.master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
|
||||
"product=mutter&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2014-04-09 22:40+0000\n"
|
||||
"PO-Revision-Date: 2014-04-10 11:04+0200\n"
|
||||
"POT-Creation-Date: 2014-05-08 09:39+0000\n"
|
||||
"PO-Revision-Date: 2014-05-10 19:21+0200\n"
|
||||
"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
|
||||
"Language-Team: Español <gnome-es-list@gnome.org>\n"
|
||||
"Language-Team: Español; Castellano <gnome-es-list@gnome.org>\n"
|
||||
"Language: \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: Gtranslator 2.91.5\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Gtranslator 2.91.6\n"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:1
|
||||
msgid "Navigation"
|
||||
@@ -46,98 +46,108 @@ msgid "Move window to workspace 4"
|
||||
msgstr "Mover la ventana al área de trabajo 4"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:6
|
||||
#| msgid "Move window to workspace 1"
|
||||
msgid "Move window to last workspace"
|
||||
msgstr "Mover la ventana a la última área de trabajo"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:7
|
||||
msgid "Move window one workspace to the left"
|
||||
msgstr "Mover la ventana un área de trabajo a la izquierda"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:7
|
||||
#: ../src/50-mutter-navigation.xml.in.h:8
|
||||
msgid "Move window one workspace to the right"
|
||||
msgstr "Mover la ventana un área de trabajo a la derecha"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:8
|
||||
#: ../src/50-mutter-navigation.xml.in.h:9
|
||||
msgid "Move window one workspace up"
|
||||
msgstr "Subir la ventana un área de trabajo"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:9
|
||||
#: ../src/50-mutter-navigation.xml.in.h:10
|
||||
msgid "Move window one workspace down"
|
||||
msgstr "Bajar la ventana un área de trabajo"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:10
|
||||
#: ../src/50-mutter-navigation.xml.in.h:11
|
||||
msgid "Move window one monitor to the left"
|
||||
msgstr "Mover la ventana una pantalla a la izquierda"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:11
|
||||
#: ../src/50-mutter-navigation.xml.in.h:12
|
||||
msgid "Move window one monitor to the right"
|
||||
msgstr "Mover la ventana una pantalla a la derecha"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:12
|
||||
#: ../src/50-mutter-navigation.xml.in.h:13
|
||||
msgid "Move window one monitor up"
|
||||
msgstr "Subir la ventana una pantalla"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:13
|
||||
#: ../src/50-mutter-navigation.xml.in.h:14
|
||||
msgid "Move window one monitor down"
|
||||
msgstr "Bajar la ventana una pantalla"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:14
|
||||
#: ../src/50-mutter-navigation.xml.in.h:15
|
||||
msgid "Switch applications"
|
||||
msgstr "Cambiar entre aplicaciones"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:15
|
||||
#: ../src/50-mutter-navigation.xml.in.h:16
|
||||
msgid "Switch windows"
|
||||
msgstr "Cambiar entre ventanas"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:16
|
||||
#: ../src/50-mutter-navigation.xml.in.h:17
|
||||
msgid "Switch windows of an application"
|
||||
msgstr "Cambiar entre ventanas de una aplicación"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:17
|
||||
#: ../src/50-mutter-navigation.xml.in.h:18
|
||||
msgid "Switch system controls"
|
||||
msgstr "Cambiar entre controles del sistema"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:18
|
||||
#: ../src/50-mutter-navigation.xml.in.h:19
|
||||
msgid "Switch windows directly"
|
||||
msgstr "Cambiar entre ventanas directamente"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:19
|
||||
#: ../src/50-mutter-navigation.xml.in.h:20
|
||||
msgid "Switch windows of an app directly"
|
||||
msgstr "Cambiar entre ventanas de una aplicación directamente"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:20
|
||||
#: ../src/50-mutter-navigation.xml.in.h:21
|
||||
msgid "Switch system controls directly"
|
||||
msgstr "Cambiar entre controles del sistema directamente"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:21
|
||||
#: ../src/50-mutter-navigation.xml.in.h:22
|
||||
msgid "Hide all normal windows"
|
||||
msgstr "Ocultar todas las ventanas normales"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:22
|
||||
#: ../src/50-mutter-navigation.xml.in.h:23
|
||||
msgid "Switch to workspace 1"
|
||||
msgstr "Cambiar al área de trabajo 1"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:23
|
||||
#: ../src/50-mutter-navigation.xml.in.h:24
|
||||
msgid "Switch to workspace 2"
|
||||
msgstr "Cambiar al área de trabajo 2"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:24
|
||||
#: ../src/50-mutter-navigation.xml.in.h:25
|
||||
msgid "Switch to workspace 3"
|
||||
msgstr "Cambiar al área de trabajo 3"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:25
|
||||
#: ../src/50-mutter-navigation.xml.in.h:26
|
||||
msgid "Switch to workspace 4"
|
||||
msgstr "Cambiar al área de trabajo 4"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:26
|
||||
#: ../src/50-mutter-navigation.xml.in.h:27
|
||||
#| msgid "Switch to workspace 1"
|
||||
msgid "Switch to last workspace"
|
||||
msgstr "Cambiar a la útima área de trabajo"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:28
|
||||
msgid "Move to workspace left"
|
||||
msgstr "Mover al área de trabajo de la izquierda"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:27
|
||||
#: ../src/50-mutter-navigation.xml.in.h:29
|
||||
msgid "Move to workspace right"
|
||||
msgstr "Mover al área de trabajo de la derecha"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:28
|
||||
#: ../src/50-mutter-navigation.xml.in.h:30
|
||||
msgid "Move to workspace above"
|
||||
msgstr "Mover al área de trabajo de la arriba"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:29
|
||||
#: ../src/50-mutter-navigation.xml.in.h:31
|
||||
msgid "Move to workspace below"
|
||||
msgstr "Mover al área de trabajo de abajo"
|
||||
|
||||
@@ -229,29 +239,29 @@ msgstr "Ver división a la izquierda"
|
||||
msgid "View split on right"
|
||||
msgstr "Ver división a la derecha"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:465
|
||||
#: ../src/backends/meta-monitor-manager.c:412
|
||||
msgid "Built-in display"
|
||||
msgstr "Pantalla integrada"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:490
|
||||
#: ../src/backends/meta-monitor-manager.c:437
|
||||
msgid "Unknown"
|
||||
msgstr "Desconocida"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:492
|
||||
#: ../src/backends/meta-monitor-manager.c:439
|
||||
msgid "Unknown Display"
|
||||
msgstr "Pantalla desconocida"
|
||||
|
||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
#. * size in inches, like 'Dell 15"'
|
||||
#.
|
||||
#: ../src/backends/meta-monitor-manager.c:500
|
||||
#: ../src/backends/meta-monitor-manager.c:447
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
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:505
|
||||
#: ../src/compositor/compositor.c:464
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
@@ -264,7 +274,7 @@ msgstr ""
|
||||
msgid "background texture could not be created from file"
|
||||
msgstr "no se pudo crear la textura de fondo a partir de archivo"
|
||||
|
||||
#: ../src/core/bell.c:213
|
||||
#: ../src/core/bell.c:215
|
||||
msgid "Bell event"
|
||||
msgstr "Evento de campana"
|
||||
|
||||
@@ -293,49 +303,49 @@ msgstr "_Esperar"
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Forzar la salida"
|
||||
|
||||
#: ../src/core/display.c:453
|
||||
#: ../src/core/display.c:451
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Ocurrió un error al abrir la pantalla de X Window System «%s»\n"
|
||||
|
||||
#: ../src/core/main.c:200
|
||||
#: ../src/core/main.c:190
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "Desactivar conexión al gestor de sesión"
|
||||
|
||||
#: ../src/core/main.c:206
|
||||
#: ../src/core/main.c:196
|
||||
msgid "Replace the running window manager"
|
||||
msgstr "Reemplazar el gestor de ventanas en ejecución"
|
||||
|
||||
#: ../src/core/main.c:212
|
||||
#: ../src/core/main.c:202
|
||||
msgid "Specify session management ID"
|
||||
msgstr "Especificar el ID se gestión de sesión"
|
||||
|
||||
#: ../src/core/main.c:217
|
||||
#: ../src/core/main.c:207
|
||||
msgid "X Display to use"
|
||||
msgstr "Pantalla X que usar"
|
||||
|
||||
#: ../src/core/main.c:223
|
||||
#: ../src/core/main.c:213
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "Inicializar sesión desde el archivo de salvaguarda"
|
||||
|
||||
#: ../src/core/main.c:229
|
||||
#: ../src/core/main.c:219
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "Hacer que las llamadas a las X sean síncronas"
|
||||
|
||||
#: ../src/core/main.c:235
|
||||
#: ../src/core/main.c:225
|
||||
msgid "Run as a wayland compositor"
|
||||
msgstr "Ejecutar como compositor Wayland"
|
||||
|
||||
#: ../src/core/main.c:241
|
||||
#: ../src/core/main.c:231
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Ejecutar como servidor completo, en lugar de anidado"
|
||||
|
||||
#: ../src/core/main.c:486
|
||||
#: ../src/core/main.c:476
|
||||
#, c-format
|
||||
msgid "Failed to scan themes directory: %s\n"
|
||||
msgstr "Falló al inspeccionar la carpeta de temas: %s\n"
|
||||
|
||||
#: ../src/core/main.c:502
|
||||
#: ../src/core/main.c:492
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
|
||||
@@ -366,17 +376,17 @@ msgstr "Imprimir versión"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Complemento de mutter que usar"
|
||||
|
||||
#: ../src/core/prefs.c:1985
|
||||
#: ../src/core/prefs.c:2005
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Área de trabajo %d"
|
||||
|
||||
#: ../src/core/screen.c:543
|
||||
#: ../src/core/screen.c:529
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "La ventana %d en la pantalla «%s» no es válida\n"
|
||||
|
||||
#: ../src/core/screen.c:559
|
||||
#: ../src/core/screen.c:545
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
@@ -385,7 +395,7 @@ msgstr ""
|
||||
"La ventana %d en la pantalla «%s» ya tiene un gestor de ventanas, intente "
|
||||
"usar la opción «--replace» para reemplazar el gestor de ventanas activo.\n"
|
||||
|
||||
#: ../src/core/screen.c:664
|
||||
#: ../src/core/screen.c:650
|
||||
#, c-format
|
||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||
msgstr "La ventana %d en la pantalla «%s» ya tiene un gestor de ventanas\n"
|
||||
@@ -398,10 +408,6 @@ msgstr "Mutter fue compilado sin soporte para modo prolijo\n"
|
||||
msgid "Mutter"
|
||||
msgstr "Mutter"
|
||||
|
||||
#: ../src/mutter-wayland.desktop.in.h:1
|
||||
msgid "Mutter (wayland compositor)"
|
||||
msgstr "Mutter (compositor Wayland)"
|
||||
|
||||
#: ../src/org.gnome.mutter.gschema.xml.in.h:1
|
||||
msgid "Modifier to use for extended window management operations"
|
||||
msgstr ""
|
||||
@@ -530,45 +536,50 @@ msgstr ""
|
||||
"la pantalla, se maximizan."
|
||||
|
||||
#: ../src/org.gnome.mutter.gschema.xml.in.h:19
|
||||
msgid "Place new windows in the center"
|
||||
msgstr "Colocar las ventanas nuevas en el centro"
|
||||
|
||||
#: ../src/org.gnome.mutter.gschema.xml.in.h:20
|
||||
msgid ""
|
||||
"When true, the new windows will always be put in the center of the active "
|
||||
"screen of the monitor."
|
||||
msgstr ""
|
||||
"Cuando es cierto, las ventanas nuevas se colocarán siempre en el centro de "
|
||||
"la pantalla activa del monitor."
|
||||
|
||||
#: ../src/org.gnome.mutter.gschema.xml.in.h:21
|
||||
msgid "Select window from tab popup"
|
||||
msgstr "Seleccionar ventana de la pestaña emergente"
|
||||
|
||||
#: ../src/org.gnome.mutter.gschema.xml.in.h:20
|
||||
#: ../src/org.gnome.mutter.gschema.xml.in.h:22
|
||||
msgid "Cancel tab popup"
|
||||
msgstr "Cancelar pestaña emergente"
|
||||
|
||||
#: ../src/org.gnome.mutter.wayland.gschema.xml.in.h:1
|
||||
#| msgid "Switch to workspace 1"
|
||||
msgid "Switch to VT 1"
|
||||
msgstr "Cambiar al VT 1"
|
||||
|
||||
#: ../src/org.gnome.mutter.wayland.gschema.xml.in.h:2
|
||||
#| msgid "Switch to workspace 2"
|
||||
msgid "Switch to VT 2"
|
||||
msgstr "Cambiar al VT 2"
|
||||
|
||||
#: ../src/org.gnome.mutter.wayland.gschema.xml.in.h:3
|
||||
#| msgid "Switch to workspace 3"
|
||||
msgid "Switch to VT 3"
|
||||
msgstr "Cambiar al VT 3"
|
||||
|
||||
#: ../src/org.gnome.mutter.wayland.gschema.xml.in.h:4
|
||||
#| msgid "Switch to workspace 4"
|
||||
msgid "Switch to VT 4"
|
||||
msgstr "Cambiar al VT 4"
|
||||
|
||||
#: ../src/org.gnome.mutter.wayland.gschema.xml.in.h:5
|
||||
#| msgid "Switch to workspace 5"
|
||||
msgid "Switch to VT 5"
|
||||
msgstr "Cambiar al VT 5"
|
||||
|
||||
#: ../src/org.gnome.mutter.wayland.gschema.xml.in.h:6
|
||||
#| msgid "Switch to workspace 6"
|
||||
msgid "Switch to VT 6"
|
||||
msgstr "Cambiar al VT 6"
|
||||
|
||||
#: ../src/org.gnome.mutter.wayland.gschema.xml.in.h:7
|
||||
#| msgid "Switch to workspace 7"
|
||||
msgid "Switch to VT 7"
|
||||
msgstr "Cambiar al VT 7"
|
||||
|
||||
@@ -654,22 +665,22 @@ msgstr "Mover al área de trabajo de a_bajo"
|
||||
msgid "_Close"
|
||||
msgstr "_Cerrar"
|
||||
|
||||
#: ../src/ui/menu.c:200
|
||||
#: ../src/ui/menu.c:198
|
||||
#, c-format
|
||||
msgid "Workspace %d%n"
|
||||
msgstr "Área de trabajo %d%n"
|
||||
|
||||
#: ../src/ui/menu.c:210
|
||||
#: ../src/ui/menu.c:208
|
||||
#, c-format
|
||||
msgid "Workspace 1_0"
|
||||
msgstr "Área de trabajo 1_0"
|
||||
|
||||
#: ../src/ui/menu.c:212
|
||||
#: ../src/ui/menu.c:210
|
||||
#, c-format
|
||||
msgid "Workspace %s%d"
|
||||
msgstr "Área de trabajo %s%d"
|
||||
|
||||
#: ../src/ui/menu.c:382
|
||||
#: ../src/ui/menu.c:380
|
||||
msgid "Move to Another _Workspace"
|
||||
msgstr "Mover a _otro área de trabajo"
|
||||
|
||||
@@ -1482,6 +1493,9 @@ msgstr ""
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (on %s)"
|
||||
|
||||
#~ msgid "Mutter (wayland compositor)"
|
||||
#~ msgstr "Mutter (compositor Wayland)"
|
||||
|
||||
#~ msgid "Unknown window information request: %d"
|
||||
#~ msgstr "Petición de información de ventana desconocida: %d"
|
||||
|
||||
@@ -2015,11 +2029,11 @@ msgstr "%s (on %s)"
|
||||
|
||||
#~ msgid "GConf key %s is already in use and can't be used to override %s\n"
|
||||
#~ msgstr ""
|
||||
#~ "La clave de GConf %s ya está en uso y no se puede usar para sobreescribir "
|
||||
#~ "La clave de GConf %s ya está en uso y no se puede usar para sobrescribir "
|
||||
#~ "%s\n"
|
||||
|
||||
#~ msgid "Can't override GConf key, %s not found\n"
|
||||
#~ msgstr "No se puede sobreescribir la clave de GConf, no se encontró %s\n"
|
||||
#~ msgstr "No se puede sobrescribir la clave de GConf, no se encontró %s\n"
|
||||
|
||||
#~ msgid "Error setting number of workspaces to %d: %s\n"
|
||||
#~ msgstr ""
|
||||
|
||||
@@ -11,6 +11,7 @@ INCLUDES= \
|
||||
-DCOGL_ENABLE_EXPERIMENTAL_API \
|
||||
-DCOGL_ENABLE_EXPERIMENTAL_2_0_API \
|
||||
$(MUTTER_CFLAGS) \
|
||||
$(MUTTER_NATIVE_BACKEND_CFLAGS) \
|
||||
-I$(srcdir) \
|
||||
-I$(srcdir)/backends \
|
||||
-I$(srcdir)/core \
|
||||
@@ -35,6 +36,7 @@ INCLUDES= \
|
||||
mutter_built_sources = \
|
||||
$(dbus_idle_built_sources) \
|
||||
$(dbus_display_config_built_sources) \
|
||||
$(dbus_login1_built_sources) \
|
||||
mutter-enum-types.h \
|
||||
mutter-enum-types.c \
|
||||
gtk-shell-protocol.c \
|
||||
@@ -70,18 +72,10 @@ libmutter_la_SOURCES = \
|
||||
backends/meta-monitor-manager-dummy.h \
|
||||
backends/edid-parse.c \
|
||||
backends/edid.h \
|
||||
backends/native/meta-backend-native.c \
|
||||
backends/native/meta-backend-native.h \
|
||||
backends/native/meta-cursor-renderer-native.c \
|
||||
backends/native/meta-cursor-renderer-native.h \
|
||||
backends/native/meta-idle-monitor-native.c \
|
||||
backends/native/meta-idle-monitor-native.h \
|
||||
backends/native/meta-monitor-manager-kms.c \
|
||||
backends/native/meta-monitor-manager-kms.h \
|
||||
backends/native/meta-launcher.c \
|
||||
backends/native/meta-launcher.h \
|
||||
backends/x11/meta-backend-x11.c \
|
||||
backends/x11/meta-backend-x11.h \
|
||||
backends/x11/meta-cursor-renderer-x11.c \
|
||||
backends/x11/meta-cursor-renderer-x11.h \
|
||||
backends/x11/meta-idle-monitor-xsync.c \
|
||||
backends/x11/meta-idle-monitor-xsync.h \
|
||||
backends/x11/meta-monitor-manager-xrandr.c \
|
||||
@@ -124,6 +118,8 @@ libmutter_la_SOURCES = \
|
||||
compositor/meta-surface-actor-wayland.h \
|
||||
compositor/meta-stage.h \
|
||||
compositor/meta-stage.c \
|
||||
compositor/meta-sync-ring.c \
|
||||
compositor/meta-sync-ring.h \
|
||||
compositor/meta-texture-rectangle.c \
|
||||
compositor/meta-texture-rectangle.h \
|
||||
compositor/meta-texture-tower.c \
|
||||
@@ -189,10 +185,6 @@ libmutter_la_SOURCES = \
|
||||
ui/ui.h \
|
||||
ui/frames.c \
|
||||
ui/frames.h \
|
||||
ui/menu.c \
|
||||
ui/menu.h \
|
||||
ui/metaaccellabel.c \
|
||||
ui/metaaccellabel.h \
|
||||
ui/resizepopup.c \
|
||||
ui/resizepopup.h \
|
||||
ui/theme-parser.c \
|
||||
@@ -242,11 +234,27 @@ libmutter_la_SOURCES = \
|
||||
wayland/window-wayland.c \
|
||||
wayland/window-wayland.h
|
||||
|
||||
if HAVE_NATIVE_BACKEND
|
||||
libmutter_la_SOURCES += \
|
||||
backends/native/meta-backend-native.c \
|
||||
backends/native/meta-backend-native.h \
|
||||
backends/native/meta-cursor-renderer-native.c \
|
||||
backends/native/meta-cursor-renderer-native.h \
|
||||
backends/native/meta-idle-monitor-native.c \
|
||||
backends/native/meta-idle-monitor-native.h \
|
||||
backends/native/meta-monitor-manager-kms.c \
|
||||
backends/native/meta-monitor-manager-kms.h \
|
||||
backends/native/meta-launcher.c \
|
||||
backends/native/meta-launcher.h \
|
||||
backends/native/dbus-utils.c \
|
||||
backends/native/dbus-utils.h
|
||||
endif
|
||||
|
||||
nodist_libmutter_la_SOURCES = \
|
||||
$(mutter_built_sources)
|
||||
|
||||
libmutter_la_LDFLAGS = -no-undefined
|
||||
libmutter_la_LIBADD = $(MUTTER_LIBS)
|
||||
libmutter_la_LIBADD = $(MUTTER_LIBS) $(MUTTER_NATIVE_BACKEND_LIBS)
|
||||
|
||||
# Headers installed for plugins; introspected information will
|
||||
# be extracted into Mutter-<version>.gir
|
||||
@@ -295,19 +303,6 @@ bin_PROGRAMS=mutter
|
||||
mutter_SOURCES = core/mutter.c
|
||||
mutter_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
|
||||
bin_PROGRAMS+=mutter-launch
|
||||
|
||||
mutter_launch_SOURCES = \
|
||||
backends/native/weston-launch.c \
|
||||
backends/native/weston-launch.h
|
||||
|
||||
mutter_launch_CFLAGS = $(MUTTER_LAUNCH_CFLAGS) -DLIBDIR=\"$(libdir)\"
|
||||
mutter_launch_LDFLAGS = $(MUTTER_LAUNCH_LIBS) -lpam
|
||||
|
||||
install-exec-hook:
|
||||
-chown root $(DESTDIR)$(bindir)/mutter-launch
|
||||
-chmod u+s $(DESTDIR)$(bindir)/mutter-launch
|
||||
|
||||
if HAVE_INTROSPECTION
|
||||
include $(INTROSPECTION_MAKEFILE)
|
||||
|
||||
@@ -401,6 +396,7 @@ EXTRA_DIST=$(desktopfiles_files) \
|
||||
libmutter.pc.in \
|
||||
mutter-enum-types.h.in \
|
||||
mutter-enum-types.c.in \
|
||||
org.freedesktop.login1.xml \
|
||||
org.gnome.Mutter.DisplayConfig.xml \
|
||||
org.gnome.Mutter.IdleMonitor.xml
|
||||
|
||||
@@ -444,6 +440,15 @@ $(dbus_idle_built_sources) : Makefile.am org.gnome.Mutter.IdleMonitor.xml
|
||||
--c-generate-object-manager \
|
||||
$(srcdir)/org.gnome.Mutter.IdleMonitor.xml
|
||||
|
||||
dbus_login1_built_sources = meta-dbus-login1.c meta-dbus-login1.h
|
||||
|
||||
$(dbus_login1_built_sources) : Makefile.am org.freedesktop.login1.xml
|
||||
$(AM_V_GEN)gdbus-codegen \
|
||||
--interface-prefix org.freedesktop.login1 \
|
||||
--c-namespace Login1 \
|
||||
--generate-c-code meta-dbus-login1 \
|
||||
$(srcdir)/org.freedesktop.login1.xml
|
||||
|
||||
%-protocol.c : $(srcdir)/wayland/protocol/%.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
|
||||
%-server-protocol.h : $(srcdir)/wayland/protocol/%.xml
|
||||
|
||||
@@ -179,7 +179,7 @@ decode_display_parameters (const uchar *edid, MonitorInfo *info)
|
||||
else if (edid[0x16] == 0)
|
||||
{
|
||||
info->width_mm = -1;
|
||||
info->height_mm = -1;
|
||||
info->height_mm = -1;
|
||||
info->aspect_ratio = 100.0 / (edid[0x15] + 99);
|
||||
}
|
||||
else if (edid[0x15] == 0)
|
||||
@@ -267,7 +267,7 @@ decode_color_characteristics (const uchar *edid, MonitorInfo *info)
|
||||
static int
|
||||
decode_established_timings (const uchar *edid, MonitorInfo *info)
|
||||
{
|
||||
static const Timing established[][8] =
|
||||
static const Timing established[][8] =
|
||||
{
|
||||
{
|
||||
{ 800, 600, 60 },
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/* edid.h
|
||||
*
|
||||
* Copyright 2007, 2008, Red Hat, Inc.
|
||||
*
|
||||
*
|
||||
* This file is part of the Gnome Library.
|
||||
*
|
||||
*
|
||||
* The Gnome Library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -13,12 +13,12 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with the Gnome Library; see the file COPYING.LIB. If not,
|
||||
* write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*
|
||||
* Author: Soren Sandmann <sandmann@redhat.com>
|
||||
*/
|
||||
|
||||
@@ -177,7 +177,7 @@ struct MonitorInfo
|
||||
DetailedTiming detailed_timings[4]; /* If monitor has a preferred
|
||||
* mode, it is the first one
|
||||
* (whether it has, is
|
||||
* determined by the
|
||||
* determined by the
|
||||
* preferred_timing_includes
|
||||
* bit.
|
||||
*/
|
||||
|
||||
@@ -62,6 +62,10 @@ struct _MetaBackendClass
|
||||
gboolean (* ungrab_device) (MetaBackend *backend,
|
||||
int device_id,
|
||||
uint32_t timestamp);
|
||||
|
||||
void (* warp_pointer) (MetaBackend *backend,
|
||||
int x,
|
||||
int y);
|
||||
};
|
||||
|
||||
#endif /* META_BACKEND_PRIVATE_H */
|
||||
|
||||
@@ -30,7 +30,10 @@
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#endif
|
||||
|
||||
static MetaBackend *_backend;
|
||||
|
||||
@@ -72,8 +75,8 @@ meta_backend_real_post_init (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
|
||||
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
|
||||
priv->monitor_manager = META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend);
|
||||
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
|
||||
}
|
||||
|
||||
static MetaCursorRenderer *
|
||||
@@ -100,6 +103,14 @@ meta_backend_real_ungrab_device (MetaBackend *backend,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_real_warp_pointer (MetaBackend *backend,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_class_init (MetaBackendClass *klass)
|
||||
{
|
||||
@@ -111,6 +122,7 @@ 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->warp_pointer = meta_backend_real_warp_pointer;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -189,6 +201,14 @@ meta_backend_ungrab_device (MetaBackend *backend,
|
||||
return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_backend_warp_pointer (MetaBackend *backend,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
META_BACKEND_GET_CLASS (backend)->warp_pointer (backend, x, y);
|
||||
}
|
||||
|
||||
static GType
|
||||
get_backend_type (void)
|
||||
{
|
||||
@@ -197,7 +217,7 @@ get_backend_type (void)
|
||||
return META_TYPE_BACKEND_X11;
|
||||
#endif
|
||||
|
||||
#if defined(CLUTTER_WINDOWING_EGL)
|
||||
#if defined(CLUTTER_WINDOWING_EGL) && defined(HAVE_NATIVE_BACKEND)
|
||||
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
|
||||
return META_TYPE_BACKEND_NATIVE;
|
||||
#endif
|
||||
|
||||
@@ -50,6 +50,10 @@ gboolean meta_backend_ungrab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
uint32_t timestamp);
|
||||
|
||||
void meta_backend_warp_pointer (MetaBackend *backend,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
void meta_clutter_init (void);
|
||||
|
||||
#endif /* META_BACKEND_H */
|
||||
|
||||
@@ -41,6 +41,7 @@ struct _MetaCursorRendererPrivate
|
||||
MetaRectangle current_rect;
|
||||
|
||||
MetaCursorReference *displayed_cursor;
|
||||
gboolean handled_by_backend;
|
||||
};
|
||||
typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
|
||||
|
||||
@@ -57,19 +58,16 @@ queue_redraw (MetaCursorRenderer *renderer)
|
||||
if (!stage)
|
||||
return;
|
||||
|
||||
/* If we're not using a MetaStage, quit early */
|
||||
if (!META_IS_STAGE (stage))
|
||||
return;
|
||||
|
||||
meta_stage_set_cursor (META_STAGE (stage),
|
||||
priv->displayed_cursor,
|
||||
&priv->current_rect);
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer)
|
||||
{
|
||||
queue_redraw (renderer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -87,6 +85,8 @@ static void
|
||||
update_cursor (MetaCursorRenderer *renderer)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
gboolean handled_by_backend;
|
||||
gboolean should_redraw = FALSE;
|
||||
|
||||
if (priv->displayed_cursor)
|
||||
{
|
||||
@@ -108,7 +108,18 @@ update_cursor (MetaCursorRenderer *renderer)
|
||||
priv->current_rect.height = 0;
|
||||
}
|
||||
|
||||
META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer);
|
||||
handled_by_backend = META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer);
|
||||
if (handled_by_backend != priv->handled_by_backend)
|
||||
{
|
||||
priv->handled_by_backend = handled_by_backend;
|
||||
should_redraw = TRUE;
|
||||
}
|
||||
|
||||
if (!handled_by_backend)
|
||||
should_redraw = TRUE;
|
||||
|
||||
if (should_redraw)
|
||||
queue_redraw (renderer);
|
||||
}
|
||||
|
||||
MetaCursorRenderer *
|
||||
|
||||
@@ -51,7 +51,7 @@ struct _MetaCursorRendererClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* update_cursor) (MetaCursorRenderer *renderer);
|
||||
gboolean (* update_cursor) (MetaCursorRenderer *renderer);
|
||||
};
|
||||
|
||||
GType meta_cursor_renderer_get_type (void) G_GNUC_CONST;
|
||||
|
||||
@@ -37,23 +37,9 @@ struct _MetaCursorTracker {
|
||||
|
||||
gboolean is_showing;
|
||||
|
||||
/* The cursor tracker stores the cursor for the current grab
|
||||
* operation, the cursor for the window with pointer focus, and
|
||||
* the cursor for the root window, which contains either the
|
||||
* default arrow cursor or the 'busy' hourglass if we're launching
|
||||
* an app.
|
||||
*
|
||||
* We choose the first one available -- if there's a grab cursor,
|
||||
* we choose that cursor, if there's window cursor, we choose that,
|
||||
* otherwise we choose the root cursor.
|
||||
*
|
||||
* The displayed_cursor contains the chosen cursor.
|
||||
*/
|
||||
MetaCursorReference *displayed_cursor;
|
||||
|
||||
MetaCursorReference *grab_cursor;
|
||||
|
||||
/* Wayland clients can set a NULL buffer as their cursor
|
||||
/* Wayland clients can set a NULL buffer as their cursor
|
||||
* explicitly, which means that we shouldn't display anything.
|
||||
* So, we can't simply store a NULL in window_cursor to
|
||||
* determine an unset window cursor; we need an extra boolean.
|
||||
@@ -62,6 +48,9 @@ struct _MetaCursorTracker {
|
||||
MetaCursorReference *window_cursor;
|
||||
|
||||
MetaCursorReference *root_cursor;
|
||||
|
||||
/* The cursor from the X11 server. */
|
||||
MetaCursorReference *xfixes_cursor;
|
||||
};
|
||||
|
||||
struct _MetaCursorTrackerClass {
|
||||
@@ -71,8 +60,6 @@ struct _MetaCursorTrackerClass {
|
||||
gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
XEvent *xevent);
|
||||
|
||||
void meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor);
|
||||
void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor);
|
||||
void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright 2013 Red Hat, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -12,7 +12,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
@@ -63,11 +63,11 @@ get_displayed_cursor (MetaCursorTracker *tracker)
|
||||
if (!tracker->is_showing)
|
||||
return NULL;
|
||||
|
||||
if (tracker->grab_cursor)
|
||||
return tracker->grab_cursor;
|
||||
|
||||
if (tracker->has_window_cursor)
|
||||
return tracker->window_cursor;
|
||||
if (tracker->screen->display->grab_op == META_GRAB_OP_NONE)
|
||||
{
|
||||
if (tracker->has_window_cursor)
|
||||
return tracker->window_cursor;
|
||||
}
|
||||
|
||||
return tracker->root_cursor;
|
||||
}
|
||||
@@ -97,11 +97,6 @@ sync_cursor (MetaCursorTracker *tracker)
|
||||
static void
|
||||
meta_cursor_tracker_init (MetaCursorTracker *self)
|
||||
{
|
||||
/* (JS) Best (?) that can be assumed since XFixes doesn't provide a way of
|
||||
detecting if the system mouse cursor is showing or not.
|
||||
|
||||
On wayland we start with the cursor showing
|
||||
*/
|
||||
self->is_showing = TRUE;
|
||||
}
|
||||
|
||||
@@ -224,7 +219,7 @@ meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
if (notify_event->subtype != XFixesDisplayCursorNotify)
|
||||
return FALSE;
|
||||
|
||||
set_window_cursor (tracker, FALSE, NULL);
|
||||
g_clear_pointer (&tracker->xfixes_cursor, meta_cursor_reference_unref);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -254,7 +249,7 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
gboolean free_cursor_data;
|
||||
CoglContext *ctx;
|
||||
|
||||
if (tracker->has_window_cursor)
|
||||
if (tracker->xfixes_cursor)
|
||||
return;
|
||||
|
||||
cursor_image = XFixesGetCursorImage (tracker->screen->display->xdisplay);
|
||||
@@ -304,7 +299,7 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
MetaCursorReference *cursor = meta_cursor_reference_take_texture (sprite,
|
||||
cursor_image->xhot,
|
||||
cursor_image->yhot);
|
||||
set_window_cursor (tracker, TRUE, cursor);
|
||||
tracker->xfixes_cursor = cursor;
|
||||
}
|
||||
XFree (cursor_image);
|
||||
}
|
||||
@@ -317,13 +312,22 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
CoglTexture *
|
||||
meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaCursorReference *cursor;
|
||||
|
||||
g_return_val_if_fail (META_IS_CURSOR_TRACKER (tracker), NULL);
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
ensure_xfixes_cursor (tracker);
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
cursor = tracker->displayed_cursor;
|
||||
}
|
||||
else
|
||||
{
|
||||
ensure_xfixes_cursor (tracker);
|
||||
cursor = tracker->xfixes_cursor;
|
||||
}
|
||||
|
||||
if (tracker->displayed_cursor)
|
||||
return meta_cursor_reference_get_cogl_texture (tracker->displayed_cursor, NULL, NULL);
|
||||
if (cursor)
|
||||
return meta_cursor_reference_get_cogl_texture (cursor, NULL, NULL);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@@ -340,13 +344,22 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
MetaCursorReference *cursor;
|
||||
|
||||
g_return_if_fail (META_IS_CURSOR_TRACKER (tracker));
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
ensure_xfixes_cursor (tracker);
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
cursor = tracker->displayed_cursor;
|
||||
}
|
||||
else
|
||||
{
|
||||
ensure_xfixes_cursor (tracker);
|
||||
cursor = tracker->xfixes_cursor;
|
||||
}
|
||||
|
||||
if (tracker->displayed_cursor)
|
||||
meta_cursor_reference_get_cogl_texture (tracker->displayed_cursor, x, y);
|
||||
if (cursor)
|
||||
meta_cursor_reference_get_cogl_texture (cursor, x, y);
|
||||
else
|
||||
{
|
||||
if (x)
|
||||
@@ -356,17 +369,6 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor)
|
||||
{
|
||||
g_clear_pointer (&tracker->grab_cursor, meta_cursor_reference_unref);
|
||||
if (cursor)
|
||||
tracker->grab_cursor = meta_cursor_reference_ref (cursor);
|
||||
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor)
|
||||
@@ -466,19 +468,7 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
|
||||
return;
|
||||
tracker->is_showing = visible;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (visible)
|
||||
XFixesShowCursor (tracker->screen->display->xdisplay,
|
||||
tracker->screen->xroot);
|
||||
else
|
||||
XFixesHideCursor (tracker->screen->display->xdisplay,
|
||||
tracker->screen->xroot);
|
||||
}
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
|
||||
MetaCursorReference *
|
||||
|
||||
@@ -28,7 +28,10 @@
|
||||
#include "display-private.h"
|
||||
#include "screen-private.h"
|
||||
#include "meta-backend.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-cursor-renderer-native.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -171,13 +174,15 @@ meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm,
|
||||
static struct gbm_device *
|
||||
get_gbm_device (void)
|
||||
{
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
MetaBackend *meta_backend = meta_get_backend ();
|
||||
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
|
||||
|
||||
if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
|
||||
return meta_cursor_renderer_native_get_gbm_device (META_CURSOR_RENDERER_NATIVE (renderer));
|
||||
else
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2013 Red Hat Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -11,7 +11,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@@ -180,6 +180,9 @@ create_monitor_skeleton (GDBusObjectManagerServer *manager,
|
||||
meta_dbus_object_skeleton_set_idle_monitor (object, skeleton);
|
||||
|
||||
g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
|
||||
|
||||
g_object_unref (skeleton);
|
||||
g_object_unref (object);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright 2013 Red Hat, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -12,7 +12,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright 2013 Red Hat, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -12,7 +12,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
@@ -210,9 +210,9 @@ make_watch (MetaIdleMonitor *monitor,
|
||||
* meta_idle_monitor_add_idle_watch:
|
||||
* @monitor: A #MetaIdleMonitor
|
||||
* @interval_msec: The idletime interval, in milliseconds
|
||||
* @callback: (allow-none): The callback to call when the user has
|
||||
* @callback: (nullable): The callback to call when the user has
|
||||
* accumulated @interval_msec milliseconds of idle time.
|
||||
* @user_data: (allow-none): The user data to pass to the callback
|
||||
* @user_data: (nullable): The user data to pass to the callback
|
||||
* @notify: A #GDestroyNotify
|
||||
*
|
||||
* Returns: a watch id
|
||||
@@ -252,9 +252,9 @@ meta_idle_monitor_add_idle_watch (MetaIdleMonitor *monitor,
|
||||
/**
|
||||
* meta_idle_monitor_add_user_active_watch:
|
||||
* @monitor: A #MetaIdleMonitor
|
||||
* @callback: (allow-none): The callback to call when the user is
|
||||
* @callback: (nullable): The callback to call when the user is
|
||||
* active again.
|
||||
* @user_data: (allow-none): The user data to pass to the callback
|
||||
* @user_data: (nullable): The user data to pass to the callback
|
||||
* @notify: A #GDestroyNotify
|
||||
*
|
||||
* Returns: a watch id
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001, 2002 Havoc Pennington
|
||||
* Copyright (C) 2002, 2003 Red Hat Inc.
|
||||
* Some ICCCM manager selection code derived from fvwm2,
|
||||
@@ -8,7 +8,7 @@
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
* Copyright (C) 2013 Red Hat Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -18,7 +18,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -78,6 +78,7 @@ struct _MetaMonitorConfig {
|
||||
GHashTable *configs;
|
||||
MetaConfiguration *current;
|
||||
gboolean current_is_stored;
|
||||
gboolean current_is_for_laptop_lid;
|
||||
MetaConfiguration *previous;
|
||||
|
||||
GFile *file;
|
||||
@@ -570,7 +571,7 @@ is_all_whitespace (const char *text,
|
||||
gsize text_len)
|
||||
{
|
||||
gsize i;
|
||||
|
||||
|
||||
for (i = 0; i < text_len; i++)
|
||||
if (!g_ascii_isspace (text[i]))
|
||||
return FALSE;
|
||||
@@ -877,7 +878,8 @@ apply_configuration (MetaMonitorConfig *self,
|
||||
|
||||
/* Stored (persistent) configurations override the previous one always.
|
||||
Also, we clear the previous configuration if the current one (which is
|
||||
about to become previous) is stored.
|
||||
about to become previous) is stored, or if the current one has
|
||||
different outputs.
|
||||
*/
|
||||
if (stored ||
|
||||
(self->current && self->current_is_stored))
|
||||
@@ -888,11 +890,27 @@ apply_configuration (MetaMonitorConfig *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
self->previous = self->current;
|
||||
/* Despite the name, config_equal() only checks the set of outputs,
|
||||
not their modes
|
||||
*/
|
||||
if (self->current && config_equal (self->current, config))
|
||||
{
|
||||
self->previous = self->current;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self->current)
|
||||
config_free (self->current);
|
||||
self->previous = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
self->current = config;
|
||||
self->current_is_stored = stored;
|
||||
/* If true, we'll be overridden at the end of this call
|
||||
inside turn_off_laptop_display()
|
||||
*/
|
||||
self->current_is_for_laptop_lid = FALSE;
|
||||
|
||||
if (self->current == self->previous)
|
||||
self->previous = NULL;
|
||||
@@ -1009,8 +1027,16 @@ meta_monitor_config_apply_stored (MetaMonitorConfig *self,
|
||||
if (self->lid_is_closed &&
|
||||
stored->n_outputs > 1 &&
|
||||
laptop_display_is_on (stored))
|
||||
return apply_configuration (self, make_laptop_lid_config (stored),
|
||||
manager, FALSE);
|
||||
{
|
||||
if (apply_configuration (self, make_laptop_lid_config (stored),
|
||||
manager, FALSE))
|
||||
{
|
||||
self->current_is_for_laptop_lid = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return apply_configuration (self, stored, manager, TRUE);
|
||||
}
|
||||
@@ -1357,6 +1383,7 @@ turn_off_laptop_display (MetaMonitorConfig *self,
|
||||
|
||||
new = make_laptop_lid_config (self->current);
|
||||
apply_configuration (self, new, manager, FALSE);
|
||||
self->current_is_for_laptop_lid = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1376,7 +1403,7 @@ power_client_changed_cb (UpClient *client,
|
||||
|
||||
if (is_closed)
|
||||
turn_off_laptop_display (self, manager);
|
||||
else
|
||||
else if (self->current_is_for_laptop_lid)
|
||||
meta_monitor_config_restore_previous (self, manager);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001, 2002 Havoc Pennington
|
||||
* Copyright (C) 2002, 2003 Red Hat Inc.
|
||||
* Some ICCCM manager selection code derived from fvwm2,
|
||||
@@ -8,7 +8,7 @@
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
* Copyright (C) 2013 Red Hat Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -18,7 +18,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -852,7 +852,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
/* If we were in progress of making a persistent change and we see a
|
||||
new request, it's likely that the old one failed in some way, so
|
||||
don't save it, but also don't queue for restoring it.
|
||||
*/
|
||||
*/
|
||||
if (manager->persistent_timeout_id && persistent)
|
||||
{
|
||||
g_source_remove (manager->persistent_timeout_id);
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
* at MetaScreen instead.
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
* Copyright (C) 2013 Red Hat Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -27,7 +27,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -73,6 +73,7 @@ struct _MetaOutput
|
||||
int width_mm;
|
||||
int height_mm;
|
||||
CoglSubpixelOrder subpixel_order;
|
||||
int scale;
|
||||
|
||||
MetaMonitorMode *preferred_mode;
|
||||
MetaMonitorMode **modes;
|
||||
|
||||
107
src/backends/native/dbus-utils.c
Normal file
107
src/backends/native/dbus-utils.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* 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 "dbus-utils.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/* Stolen from tp_escape_as_identifier, from tp-glib,
|
||||
* which follows the same escaping convention as systemd.
|
||||
*/
|
||||
static inline gboolean
|
||||
_esc_ident_bad (gchar c, gboolean is_first)
|
||||
{
|
||||
return ((c < 'a' || c > 'z') &&
|
||||
(c < 'A' || c > 'Z') &&
|
||||
(c < '0' || c > '9' || is_first));
|
||||
}
|
||||
|
||||
static gchar *
|
||||
escape_dbus_component (const gchar *name)
|
||||
{
|
||||
gboolean bad = FALSE;
|
||||
size_t len = 0;
|
||||
GString *op;
|
||||
const gchar *ptr, *first_ok;
|
||||
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
/* fast path for empty name */
|
||||
if (name[0] == '\0')
|
||||
return g_strdup ("_");
|
||||
|
||||
for (ptr = name; *ptr; ptr++)
|
||||
{
|
||||
if (_esc_ident_bad (*ptr, ptr == name))
|
||||
{
|
||||
bad = TRUE;
|
||||
len += 3;
|
||||
}
|
||||
else
|
||||
len++;
|
||||
}
|
||||
|
||||
/* fast path if it's clean */
|
||||
if (!bad)
|
||||
return g_strdup (name);
|
||||
|
||||
/* If strictly less than ptr, first_ok is the first uncopied safe character.
|
||||
*/
|
||||
first_ok = name;
|
||||
op = g_string_sized_new (len);
|
||||
for (ptr = name; *ptr; ptr++)
|
||||
{
|
||||
if (_esc_ident_bad (*ptr, ptr == name))
|
||||
{
|
||||
/* copy preceding safe characters if any */
|
||||
if (first_ok < ptr)
|
||||
{
|
||||
g_string_append_len (op, first_ok, ptr - first_ok);
|
||||
}
|
||||
/* escape the unsafe character */
|
||||
g_string_append_printf (op, "_%02x", (unsigned char)(*ptr));
|
||||
/* restart after it */
|
||||
first_ok = ptr + 1;
|
||||
}
|
||||
}
|
||||
/* copy trailing safe characters if any */
|
||||
if (first_ok < ptr)
|
||||
{
|
||||
g_string_append_len (op, first_ok, ptr - first_ok);
|
||||
}
|
||||
return g_string_free (op, FALSE);
|
||||
}
|
||||
|
||||
char *
|
||||
get_escaped_dbus_path (const char *prefix,
|
||||
const char *component)
|
||||
{
|
||||
char *escaped_component = escape_dbus_component (component);
|
||||
char *path = g_strconcat (prefix, "/", escaped_component, NULL);
|
||||
|
||||
g_free (escaped_component);
|
||||
return path;
|
||||
}
|
||||
32
src/backends/native/dbus-utils.h
Normal file
32
src/backends/native/dbus-utils.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef DBUS_UTILS_H
|
||||
#define DBUS_UTILS_H
|
||||
|
||||
char *
|
||||
get_escaped_dbus_path (const char *prefix,
|
||||
const char *component);
|
||||
|
||||
#endif /* DBUS_UTILS_H */
|
||||
@@ -120,7 +120,7 @@ update_hw_cursor (MetaCursorRendererNative *native,
|
||||
|
||||
set_crtc_cursor (native, &crtcs[i], crtc_cursor, force);
|
||||
|
||||
if (cursor)
|
||||
if (crtc_cursor)
|
||||
{
|
||||
drmModeMoveCursor (priv->drm_fd, crtcs[i].crtc_id,
|
||||
cursor_rect->x - crtc_rect->x,
|
||||
@@ -140,7 +140,7 @@ should_have_hw_cursor (MetaCursorRenderer *renderer)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer)
|
||||
{
|
||||
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
|
||||
@@ -148,10 +148,7 @@ meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer)
|
||||
|
||||
priv->has_hw_cursor = should_have_hw_cursor (renderer);
|
||||
update_hw_cursor (native, FALSE);
|
||||
|
||||
/* Fall back to the stage-based cursor if we don't have HW cursors. */
|
||||
if (!priv->has_hw_cursor)
|
||||
META_CURSOR_RENDERER_CLASS (meta_cursor_renderer_native_parent_class)->update_cursor (renderer);
|
||||
return priv->has_hw_cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -20,9 +20,8 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-launcher.h"
|
||||
#include "weston-launch.h"
|
||||
|
||||
#include <gio/gunixfdmessage.h>
|
||||
#include <gio/gunixfdlist.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <clutter/egl/clutter-egl.h>
|
||||
@@ -30,10 +29,17 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <malloc.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <systemd/sd-login.h>
|
||||
|
||||
#include "dbus-utils.h"
|
||||
#include "meta-dbus-login1.h"
|
||||
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#include "backends/meta-backend.h"
|
||||
@@ -41,156 +47,42 @@
|
||||
|
||||
struct _MetaLauncher
|
||||
{
|
||||
GSocket *weston_launch;
|
||||
Login1Session *session_proxy;
|
||||
Login1Seat *seat_proxy;
|
||||
|
||||
gboolean vt_switched;
|
||||
|
||||
GMainContext *nested_context;
|
||||
GMainLoop *nested_loop;
|
||||
|
||||
GSource *inner_source;
|
||||
GSource *outer_source;
|
||||
gboolean session_active;
|
||||
};
|
||||
|
||||
static void handle_request_vt_switch (MetaLauncher *self);
|
||||
|
||||
static gboolean
|
||||
request_vt_switch_idle (gpointer user_data)
|
||||
static Login1Session *
|
||||
get_session_proxy (GCancellable *cancellable)
|
||||
{
|
||||
handle_request_vt_switch (user_data);
|
||||
char *proxy_path;
|
||||
char *session_id;
|
||||
Login1Session *session_proxy;
|
||||
|
||||
return FALSE;
|
||||
if (sd_pid_get_session (getpid (), &session_id) < 0)
|
||||
return NULL;
|
||||
|
||||
proxy_path = get_escaped_dbus_path ("/org/freedesktop/login1/session", session_id);
|
||||
|
||||
session_proxy = login1_session_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
"org.freedesktop.login1",
|
||||
proxy_path,
|
||||
cancellable, NULL);
|
||||
free (proxy_path);
|
||||
|
||||
return session_proxy;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
send_message_to_wl (MetaLauncher *self,
|
||||
void *message,
|
||||
gsize size,
|
||||
GSocketControlMessage *out_cmsg,
|
||||
GSocketControlMessage **in_cmsg,
|
||||
GError **error)
|
||||
static Login1Seat *
|
||||
get_seat_proxy (GCancellable *cancellable)
|
||||
{
|
||||
struct weston_launcher_reply reply;
|
||||
GInputVector in_iov = { &reply, sizeof (reply) };
|
||||
GOutputVector out_iov = { message, size };
|
||||
GSocketControlMessage *out_all_cmsg[2];
|
||||
GSocketControlMessage **in_all_cmsg;
|
||||
int flags = 0;
|
||||
int i;
|
||||
|
||||
out_all_cmsg[0] = out_cmsg;
|
||||
out_all_cmsg[1] = NULL;
|
||||
if (g_socket_send_message (self->weston_launch, NULL,
|
||||
&out_iov, 1,
|
||||
out_all_cmsg, -1,
|
||||
flags, NULL, error) != (gssize)size)
|
||||
return FALSE;
|
||||
|
||||
if (g_socket_receive_message (self->weston_launch, NULL,
|
||||
&in_iov, 1,
|
||||
&in_all_cmsg, NULL,
|
||||
&flags, NULL, error) != sizeof (reply))
|
||||
return FALSE;
|
||||
|
||||
while (reply.header.opcode != ((struct weston_launcher_message*)message)->opcode)
|
||||
{
|
||||
guint id;
|
||||
|
||||
/* There were events queued */
|
||||
g_assert ((reply.header.opcode & WESTON_LAUNCHER_EVENT) == WESTON_LAUNCHER_EVENT);
|
||||
|
||||
/* This can never happen, because the only time mutter-launch can queue
|
||||
this event is after confirming a VT switch, and we don't make requests
|
||||
during that time.
|
||||
|
||||
Note that getting this event would be really bad, because we would be
|
||||
in the wrong loop/context.
|
||||
*/
|
||||
g_assert (reply.header.opcode != WESTON_LAUNCHER_SERVER_VT_ENTER);
|
||||
|
||||
switch (reply.header.opcode)
|
||||
{
|
||||
case WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH:
|
||||
id = g_idle_add (request_vt_switch_idle, self);
|
||||
g_source_set_name_by_id (id, "[mutter] request_vt_switch_idle");
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (g_socket_receive_message (self->weston_launch, NULL,
|
||||
&in_iov, 1,
|
||||
NULL, NULL,
|
||||
&flags, NULL, error) != sizeof (reply))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (reply.ret != 0)
|
||||
{
|
||||
if (reply.ret == -1)
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Got failure from weston-launch");
|
||||
else
|
||||
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-reply.ret),
|
||||
"Got failure from weston-launch: %s", strerror (-reply.ret));
|
||||
|
||||
for (i = 0; in_all_cmsg && in_all_cmsg[i]; i++)
|
||||
g_object_unref (in_all_cmsg[i]);
|
||||
g_free (in_all_cmsg);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (in_all_cmsg && in_all_cmsg[0])
|
||||
{
|
||||
for (i = 1; in_all_cmsg[i]; i++)
|
||||
g_object_unref (in_all_cmsg[i]);
|
||||
*in_cmsg = in_all_cmsg[0];
|
||||
}
|
||||
|
||||
g_free (in_all_cmsg);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
meta_launcher_open_device (MetaLauncher *self,
|
||||
const char *name,
|
||||
int flags,
|
||||
GError **error)
|
||||
{
|
||||
struct weston_launcher_open *message;
|
||||
GSocketControlMessage *cmsg;
|
||||
gboolean ok;
|
||||
gsize size;
|
||||
int *fds, n_fd;
|
||||
int ret;
|
||||
|
||||
size = sizeof (struct weston_launcher_open) + strlen (name) + 1;
|
||||
message = g_malloc (size);
|
||||
message->header.opcode = WESTON_LAUNCHER_OPEN;
|
||||
message->flags = flags;
|
||||
strcpy (message->path, name);
|
||||
message->path[strlen(name)] = 0;
|
||||
|
||||
ok = send_message_to_wl (self, message, size, NULL, &cmsg, error);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
g_assert (G_IS_UNIX_FD_MESSAGE (cmsg));
|
||||
|
||||
fds = g_unix_fd_message_steal_fds (G_UNIX_FD_MESSAGE (cmsg), &n_fd);
|
||||
g_assert (n_fd == 1);
|
||||
|
||||
ret = fds[0];
|
||||
g_free (fds);
|
||||
g_object_unref (cmsg);
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
|
||||
g_free (message);
|
||||
return ret;
|
||||
return login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1/seat/self",
|
||||
cancellable, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -206,6 +98,7 @@ session_unpause (void)
|
||||
cogl_kms_display_queue_modes_reset (cogl_display);
|
||||
|
||||
clutter_evdev_reclaim_devices ();
|
||||
clutter_egl_thaw_master_clock ();
|
||||
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
@@ -225,6 +118,92 @@ static void
|
||||
session_pause (void)
|
||||
{
|
||||
clutter_evdev_release_devices ();
|
||||
clutter_egl_freeze_master_clock ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
take_device (Login1Session *session_proxy,
|
||||
int dev_major,
|
||||
int dev_minor,
|
||||
int *out_fd,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GVariant *fd_variant = NULL;
|
||||
int fd = -1;
|
||||
GUnixFDList *fd_list;
|
||||
|
||||
if (!login1_session_call_take_device_sync (session_proxy,
|
||||
dev_major,
|
||||
dev_minor,
|
||||
NULL,
|
||||
&fd_variant,
|
||||
NULL, /* paused */
|
||||
&fd_list,
|
||||
cancellable,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (fd_variant), error);
|
||||
if (fd == -1)
|
||||
goto out;
|
||||
|
||||
*out_fd = fd;
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
if (fd_variant)
|
||||
g_variant_unref (fd_variant);
|
||||
if (fd_list)
|
||||
g_object_unref (fd_list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_device_info_from_path (const char *path,
|
||||
int *out_major,
|
||||
int *out_minor)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
int r;
|
||||
struct stat st;
|
||||
|
||||
r = stat (path, &st);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
if (!S_ISCHR (st.st_mode))
|
||||
goto out;
|
||||
|
||||
*out_major = major (st.st_rdev);
|
||||
*out_minor = minor (st.st_rdev);
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_device_info_from_fd (int fd,
|
||||
int *out_major,
|
||||
int *out_minor)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
int r;
|
||||
struct stat st;
|
||||
|
||||
r = fstat (fd, &st);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
if (!S_ISCHR (st.st_mode))
|
||||
goto out;
|
||||
|
||||
*out_major = major (st.st_rdev);
|
||||
*out_minor = minor (st.st_rdev);
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -233,169 +212,151 @@ on_evdev_device_open (const char *path,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
MetaLauncher *launcher = user_data;
|
||||
MetaLauncher *self = user_data;
|
||||
int fd;
|
||||
int major, minor;
|
||||
|
||||
return meta_launcher_open_device (launcher, path, flags, error);
|
||||
if (!get_device_info_from_path (path, &major, &minor))
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"Could not get device info for path %s: %m", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!take_device (self->session_proxy, major, minor, &fd, NULL, error))
|
||||
return -1;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void
|
||||
on_evdev_device_close (int fd,
|
||||
gpointer user_data)
|
||||
{
|
||||
close (fd);
|
||||
MetaLauncher *self = user_data;
|
||||
int major, minor;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!get_device_info_from_fd (fd, &major, &minor))
|
||||
{
|
||||
g_warning ("Could not get device info for fd %d: %m", fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!login1_session_call_release_device_sync (self->session_proxy,
|
||||
major, minor,
|
||||
NULL, &error))
|
||||
{
|
||||
g_warning ("Could not release device %d,%d: %s", major, minor, error->message);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_vt_enter (MetaLauncher *launcher)
|
||||
sync_active (MetaLauncher *self)
|
||||
{
|
||||
g_assert (launcher->vt_switched);
|
||||
|
||||
g_main_loop_quit (launcher->nested_loop);
|
||||
|
||||
session_unpause ();
|
||||
}
|
||||
|
||||
static void
|
||||
handle_request_vt_switch (MetaLauncher *launcher)
|
||||
{
|
||||
struct weston_launcher_message message;
|
||||
GError *error;
|
||||
gboolean ok;
|
||||
|
||||
session_pause ();
|
||||
|
||||
message.opcode = WESTON_LAUNCHER_CONFIRM_VT_SWITCH;
|
||||
|
||||
error = NULL;
|
||||
ok = send_message_to_wl (launcher, &message, sizeof (message), NULL, NULL, &error);
|
||||
if (!ok) {
|
||||
g_warning ("Failed to acknowledge VT switch: %s", error->message);
|
||||
g_error_free (error);
|
||||
gboolean active = login1_session_get_active (LOGIN1_SESSION (self->session_proxy));
|
||||
|
||||
if (active == self->session_active)
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert (!launcher->vt_switched);
|
||||
launcher->vt_switched = TRUE;
|
||||
self->session_active = active;
|
||||
|
||||
/* We can't do anything at this point, because we don't
|
||||
have input devices and we don't have the DRM master,
|
||||
so let's run a nested busy loop until the VT is reentered */
|
||||
g_main_loop_run (launcher->nested_loop);
|
||||
if (active)
|
||||
session_unpause ();
|
||||
else
|
||||
session_pause ();
|
||||
}
|
||||
|
||||
g_assert (launcher->vt_switched);
|
||||
launcher->vt_switched = FALSE;
|
||||
|
||||
session_unpause ();
|
||||
static void
|
||||
on_active_changed (Login1Session *session,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaLauncher *self = user_data;
|
||||
sync_active (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_socket_readable (GSocket *socket,
|
||||
GIOCondition condition,
|
||||
gpointer user_data)
|
||||
get_kms_fd (Login1Session *session_proxy,
|
||||
int *fd_out)
|
||||
{
|
||||
MetaLauncher *launcher = user_data;
|
||||
struct weston_launcher_event event;
|
||||
gssize read;
|
||||
GError *error;
|
||||
int major, minor;
|
||||
int fd;
|
||||
GError *error = NULL;
|
||||
|
||||
if ((condition & G_IO_IN) == 0)
|
||||
return TRUE;
|
||||
|
||||
error = NULL;
|
||||
read = g_socket_receive (socket, (char*)&event, sizeof(event), NULL, &error);
|
||||
if (read < (gssize)sizeof(event))
|
||||
/* XXX -- use udev to find the DRM master device */
|
||||
if (!get_device_info_from_path ("/dev/dri/card0", &major, &minor))
|
||||
{
|
||||
g_warning ("Error reading from weston-launcher socket: %s", error->message);
|
||||
g_warning ("Could not stat /dev/dri/card0: %m");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!take_device (session_proxy, major, minor, &fd, NULL, &error))
|
||||
{
|
||||
g_warning ("Could not open DRM device: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (event.header.opcode)
|
||||
{
|
||||
case WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH:
|
||||
handle_request_vt_switch (launcher);
|
||||
break;
|
||||
|
||||
case WESTON_LAUNCHER_SERVER_VT_ENTER:
|
||||
handle_vt_enter (launcher);
|
||||
break;
|
||||
}
|
||||
*fd_out = fd;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
env_get_fd (const char *env)
|
||||
{
|
||||
const char *value;
|
||||
|
||||
value = g_getenv (env);
|
||||
|
||||
if (value == NULL)
|
||||
return -1;
|
||||
else
|
||||
return g_ascii_strtoll (value, NULL, 10);
|
||||
}
|
||||
|
||||
MetaLauncher *
|
||||
meta_launcher_new (void)
|
||||
{
|
||||
MetaLauncher *self = g_slice_new0 (MetaLauncher);
|
||||
MetaLauncher *self;
|
||||
Login1Session *session_proxy;
|
||||
GError *error = NULL;
|
||||
int launch_fd;
|
||||
int kms_fd;
|
||||
|
||||
launch_fd = env_get_fd ("WESTON_LAUNCHER_SOCK");
|
||||
if (launch_fd < 0)
|
||||
g_error ("Invalid mutter-launch socket");
|
||||
session_proxy = get_session_proxy (NULL);
|
||||
if (!login1_session_call_take_control_sync (session_proxy, FALSE, NULL, &error))
|
||||
{
|
||||
g_warning ("Could not take control: %s", error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self->weston_launch = g_socket_new_from_fd (launch_fd, NULL);
|
||||
if (!get_kms_fd (session_proxy, &kms_fd))
|
||||
return NULL;
|
||||
|
||||
self->nested_context = g_main_context_new ();
|
||||
self->nested_loop = g_main_loop_new (self->nested_context, FALSE);
|
||||
self = g_slice_new0 (MetaLauncher);
|
||||
self->session_proxy = session_proxy;
|
||||
self->seat_proxy = get_seat_proxy (NULL);
|
||||
|
||||
self->outer_source = g_socket_create_source (self->weston_launch, G_IO_IN, NULL);
|
||||
g_source_set_callback (self->outer_source, (GSourceFunc)on_socket_readable, self, NULL);
|
||||
g_source_attach (self->outer_source, NULL);
|
||||
g_source_unref (self->outer_source);
|
||||
|
||||
self->inner_source = g_socket_create_source (self->weston_launch, G_IO_IN, NULL);
|
||||
g_source_set_callback (self->inner_source, (GSourceFunc)on_socket_readable, self, NULL);
|
||||
g_source_attach (self->inner_source, self->nested_context);
|
||||
g_source_unref (self->inner_source);
|
||||
|
||||
kms_fd = meta_launcher_open_device (self, "/dev/dri/card0", O_RDWR, &error);
|
||||
if (error)
|
||||
g_error ("Failed to open /dev/dri/card0: %s", error->message);
|
||||
self->session_active = TRUE;
|
||||
|
||||
clutter_egl_set_kms_fd (kms_fd);
|
||||
clutter_evdev_set_device_callbacks (on_evdev_device_open,
|
||||
on_evdev_device_close,
|
||||
self);
|
||||
|
||||
g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
meta_launcher_free (MetaLauncher *launcher)
|
||||
meta_launcher_free (MetaLauncher *self)
|
||||
{
|
||||
g_source_destroy (launcher->outer_source);
|
||||
g_source_destroy (launcher->inner_source);
|
||||
|
||||
g_main_loop_unref (launcher->nested_loop);
|
||||
g_main_context_unref (launcher->nested_context);
|
||||
|
||||
g_object_unref (launcher->weston_launch);
|
||||
|
||||
g_slice_free (MetaLauncher, launcher);
|
||||
g_object_unref (self->seat_proxy);
|
||||
g_object_unref (self->session_proxy);
|
||||
g_slice_free (MetaLauncher, self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_launcher_activate_session (MetaLauncher *launcher,
|
||||
GError **error)
|
||||
{
|
||||
return meta_launcher_activate_vt (launcher, -1, error);
|
||||
if (!login1_session_call_activate_sync (launcher->session_proxy, NULL, error))
|
||||
return FALSE;
|
||||
|
||||
sync_active (launcher);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -403,10 +364,5 @@ meta_launcher_activate_vt (MetaLauncher *launcher,
|
||||
signed char vt,
|
||||
GError **error)
|
||||
{
|
||||
struct weston_launcher_activate_vt message;
|
||||
|
||||
message.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT;
|
||||
message.vt = vt;
|
||||
|
||||
return send_message_to_wl (launcher, &message, sizeof (message), NULL, NULL, error);
|
||||
return login1_seat_call_switch_to_sync (launcher->seat_proxy, vt, NULL, error);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2013 Red Hat Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -12,7 +12,7 @@
|
||||
* 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
|
||||
|
||||
@@ -1,711 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Benjamin Franzke
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of the copyright holders not be used in
|
||||
* advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The copyright holders make
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <error.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <termios.h>
|
||||
#include <linux/vt.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/kd.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include <xf86drm.h>
|
||||
|
||||
#include <systemd/sd-login.h>
|
||||
|
||||
#include "weston-launch.h"
|
||||
|
||||
#define MAX_ARGV_SIZE 256
|
||||
#define DRM_MAJOR 226
|
||||
|
||||
enum vt_state {
|
||||
VT_HAS_VT,
|
||||
VT_PENDING_CONFIRM,
|
||||
VT_NOT_HAVE_VT,
|
||||
};
|
||||
|
||||
struct weston_launch {
|
||||
int tty;
|
||||
int ttynr;
|
||||
int sock[2];
|
||||
struct passwd *pw;
|
||||
|
||||
int signalfd;
|
||||
|
||||
pid_t child;
|
||||
int verbose;
|
||||
|
||||
struct termios terminal_attributes;
|
||||
int kb_mode;
|
||||
enum vt_state vt_state;
|
||||
unsigned vt;
|
||||
|
||||
int drm_fd;
|
||||
};
|
||||
|
||||
union cmsg_data { unsigned char b[4]; int fd; };
|
||||
|
||||
static void quit (struct weston_launch *wl, int status);
|
||||
|
||||
static int
|
||||
weston_launch_allowed(struct weston_launch *wl)
|
||||
{
|
||||
char *session, *seat;
|
||||
int err;
|
||||
|
||||
if (getuid() == 0)
|
||||
return 1;
|
||||
|
||||
err = sd_pid_get_session(getpid(), &session);
|
||||
if (err == 0 && session) {
|
||||
if (sd_session_is_active(session) &&
|
||||
sd_session_get_seat(session, &seat) == 0) {
|
||||
free(seat);
|
||||
free(session);
|
||||
return 1;
|
||||
}
|
||||
free(session);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
setup_launcher_socket(struct weston_launch *wl)
|
||||
{
|
||||
if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, wl->sock) < 0)
|
||||
error(1, errno, "socketpair failed");
|
||||
|
||||
fcntl(wl->sock[0], F_SETFD, O_CLOEXEC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
setup_signals(struct weston_launch *wl)
|
||||
{
|
||||
int ret;
|
||||
sigset_t mask;
|
||||
struct sigaction sa;
|
||||
|
||||
memset(&sa, 0, sizeof sa);
|
||||
sa.sa_handler = SIG_DFL;
|
||||
sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
|
||||
ret = sigaction(SIGCHLD, &sa, NULL);
|
||||
assert(ret == 0);
|
||||
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sa.sa_flags = 0;
|
||||
sigaction(SIGHUP, &sa, NULL);
|
||||
|
||||
ret = sigemptyset(&mask);
|
||||
assert(ret == 0);
|
||||
sigaddset(&mask, SIGCHLD);
|
||||
sigaddset(&mask, SIGINT);
|
||||
sigaddset(&mask, SIGTERM);
|
||||
sigaddset(&mask, SIGUSR1);
|
||||
ret = sigprocmask(SIG_BLOCK, &mask, NULL);
|
||||
assert(ret == 0);
|
||||
|
||||
wl->signalfd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
|
||||
if (wl->signalfd < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
setenv_fd(const char *env, int fd)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
snprintf(buf, sizeof buf, "%d", fd);
|
||||
setenv(env, buf, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
handle_confirm_vt_switch(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
{
|
||||
struct weston_launcher_reply reply;
|
||||
|
||||
reply.header.opcode = WESTON_LAUNCHER_CONFIRM_VT_SWITCH;
|
||||
reply.ret = -1;
|
||||
|
||||
if (wl->vt_state != VT_PENDING_CONFIRM) {
|
||||
error(0, 0, "unexpected CONFIRM_VT_SWITCH");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (wl->drm_fd != -1) {
|
||||
int ret;
|
||||
|
||||
ret = drmDropMaster(wl->drm_fd);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to drop DRM master: %m\n");
|
||||
} else if (wl->verbose) {
|
||||
fprintf(stderr, "dropped DRM master for VT switch\n");
|
||||
}
|
||||
}
|
||||
|
||||
wl->vt_state = VT_NOT_HAVE_VT;
|
||||
ioctl(wl->tty, VT_RELDISP, 1);
|
||||
|
||||
if (wl->verbose)
|
||||
fprintf(stderr, "mutter-launcher: confirmed VT switch\n");
|
||||
|
||||
reply.ret = 0;
|
||||
|
||||
out:
|
||||
do {
|
||||
len = send(wl->sock[0], &reply, sizeof reply, 0);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
handle_activate_vt(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
{
|
||||
struct weston_launcher_reply reply;
|
||||
struct weston_launcher_activate_vt *message;
|
||||
unsigned vt;
|
||||
|
||||
reply.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT;
|
||||
reply.ret = -1;
|
||||
|
||||
if (len != sizeof(*message)) {
|
||||
error(0, 0, "missing value in activate_vt request");
|
||||
goto out;
|
||||
}
|
||||
|
||||
message = msg->msg_iov->iov_base;
|
||||
|
||||
/* Negative values mean that we're activating our own VT */
|
||||
if (message->vt > 0)
|
||||
vt = message->vt;
|
||||
else
|
||||
vt = wl->vt;
|
||||
|
||||
reply.ret = ioctl(wl->tty, VT_ACTIVATE, vt);
|
||||
if (reply.ret < 0)
|
||||
reply.ret = -errno;
|
||||
|
||||
if (wl->verbose)
|
||||
fprintf(stderr, "mutter-launch: activate VT, ret: %d\n", reply.ret);
|
||||
|
||||
out:
|
||||
do {
|
||||
len = send(wl->sock[0], &reply, sizeof reply, 0);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
{
|
||||
struct weston_launcher_reply reply;
|
||||
int fd = -1;
|
||||
char control[CMSG_SPACE(sizeof(fd))];
|
||||
struct cmsghdr *cmsg;
|
||||
struct stat s;
|
||||
struct msghdr nmsg;
|
||||
struct iovec iov;
|
||||
struct weston_launcher_open *message;
|
||||
union cmsg_data *data;
|
||||
int dev_major;
|
||||
|
||||
reply.header.opcode = WESTON_LAUNCHER_OPEN;
|
||||
reply.ret = -1;
|
||||
|
||||
message = msg->msg_iov->iov_base;
|
||||
if ((size_t)len < sizeof(*message))
|
||||
goto err0;
|
||||
|
||||
/* Ensure path is null-terminated */
|
||||
((char *) message)[len-1] = '\0';
|
||||
|
||||
if (stat(message->path, &s) < 0) {
|
||||
reply.ret = -errno;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
dev_major = major(s.st_rdev);
|
||||
|
||||
if (dev_major != INPUT_MAJOR &&
|
||||
dev_major != DRM_MAJOR) {
|
||||
fprintf(stderr, "Device %s is not an input or DRM device\n",
|
||||
message->path);
|
||||
reply.ret = -EPERM;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
if (dev_major == DRM_MAJOR && wl->drm_fd != -1) {
|
||||
fprintf(stderr, "Already have a DRM device open\n");
|
||||
reply.ret = -EPERM;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
fd = open(message->path, message->flags);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error opening device %s: %m\n",
|
||||
message->path);
|
||||
reply.ret = -errno;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
if (dev_major == DRM_MAJOR) {
|
||||
wl->drm_fd = fd;
|
||||
}
|
||||
|
||||
err0:
|
||||
memset(&nmsg, 0, sizeof nmsg);
|
||||
nmsg.msg_iov = &iov;
|
||||
nmsg.msg_iovlen = 1;
|
||||
if (fd != -1) {
|
||||
nmsg.msg_control = control;
|
||||
nmsg.msg_controllen = sizeof control;
|
||||
cmsg = CMSG_FIRSTHDR(&nmsg);
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
|
||||
data = (union cmsg_data *) CMSG_DATA(cmsg);
|
||||
data->fd = fd;
|
||||
nmsg.msg_controllen = cmsg->cmsg_len;
|
||||
reply.ret = 0;
|
||||
}
|
||||
iov.iov_base = &reply;
|
||||
iov.iov_len = sizeof reply;
|
||||
|
||||
if (wl->verbose)
|
||||
fprintf(stderr, "mutter-launch: opened %s: ret: %d, fd: %d\n",
|
||||
message->path, reply.ret, fd);
|
||||
do {
|
||||
len = sendmsg(wl->sock[0], &nmsg, 0);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
|
||||
close(fd);
|
||||
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
handle_socket_msg(struct weston_launch *wl)
|
||||
{
|
||||
char control[CMSG_SPACE(sizeof(int))];
|
||||
char buf[BUFSIZ];
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
int ret = -1;
|
||||
ssize_t len;
|
||||
struct weston_launcher_message *message;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = sizeof buf;
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = control;
|
||||
msg.msg_controllen = sizeof control;
|
||||
|
||||
do {
|
||||
len = recvmsg(wl->sock[0], &msg, 0);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
|
||||
if (len < 1)
|
||||
return -1;
|
||||
|
||||
message = (void *) buf;
|
||||
switch (message->opcode) {
|
||||
case WESTON_LAUNCHER_OPEN:
|
||||
ret = handle_open(wl, &msg, len);
|
||||
break;
|
||||
case WESTON_LAUNCHER_CONFIRM_VT_SWITCH:
|
||||
ret = handle_confirm_vt_switch(wl, &msg, len);
|
||||
break;
|
||||
case WESTON_LAUNCHER_ACTIVATE_VT:
|
||||
ret = handle_activate_vt(wl, &msg, len);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
tty_reset(struct weston_launch *wl)
|
||||
{
|
||||
struct vt_mode mode = { 0 };
|
||||
|
||||
if (ioctl(wl->tty, KDSKBMODE, wl->kb_mode))
|
||||
fprintf(stderr, "failed to restore keyboard mode: %m\n");
|
||||
|
||||
if (ioctl(wl->tty, KDSETMODE, KD_TEXT))
|
||||
fprintf(stderr, "failed to set KD_TEXT mode on tty: %m\n");
|
||||
|
||||
if (tcsetattr(wl->tty, TCSANOW, &wl->terminal_attributes) < 0)
|
||||
fprintf(stderr, "could not restore terminal to canonical mode\n");
|
||||
|
||||
mode.mode = VT_AUTO;
|
||||
if (ioctl(wl->tty, VT_SETMODE, &mode) < 0)
|
||||
fprintf(stderr, "could not reset vt handling\n");
|
||||
}
|
||||
|
||||
static void
|
||||
quit(struct weston_launch *wl, int status)
|
||||
{
|
||||
if (wl->child > 0)
|
||||
kill(wl->child, SIGKILL);
|
||||
|
||||
close(wl->signalfd);
|
||||
close(wl->sock[0]);
|
||||
|
||||
if (wl->drm_fd > 0)
|
||||
close(wl->drm_fd);
|
||||
|
||||
tty_reset(wl);
|
||||
|
||||
exit(status);
|
||||
}
|
||||
|
||||
static int
|
||||
handle_vt_switch(struct weston_launch *wl)
|
||||
{
|
||||
struct weston_launcher_event message;
|
||||
ssize_t len;
|
||||
|
||||
if (wl->vt_state == VT_HAS_VT) {
|
||||
wl->vt_state = VT_PENDING_CONFIRM;
|
||||
message.header.opcode = WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH;
|
||||
} else if (wl->vt_state == VT_NOT_HAVE_VT) {
|
||||
wl->vt_state = VT_HAS_VT;
|
||||
ioctl(wl->tty, VT_RELDISP, VT_ACKACQ);
|
||||
|
||||
if (wl->drm_fd != -1) {
|
||||
int ret;
|
||||
|
||||
ret = drmSetMaster(wl->drm_fd);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to become DRM master: %m\n");
|
||||
/* This is very, very bad, and the compositor will crash soon,
|
||||
but oh well... */
|
||||
} else if (wl->verbose) {
|
||||
fprintf(stderr, "became DRM master after VT switch\n");
|
||||
}
|
||||
}
|
||||
|
||||
message.header.opcode = WESTON_LAUNCHER_SERVER_VT_ENTER;
|
||||
} else
|
||||
return -1;
|
||||
|
||||
message.detail = 0;
|
||||
|
||||
do {
|
||||
len = send(wl->sock[0], &message, sizeof(message), 0);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
handle_signal(struct weston_launch *wl)
|
||||
{
|
||||
struct signalfd_siginfo sig;
|
||||
int pid, status, ret;
|
||||
|
||||
if (read(wl->signalfd, &sig, sizeof sig) != sizeof sig) {
|
||||
error(0, errno, "reading signalfd failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (sig.ssi_signo) {
|
||||
case SIGCHLD:
|
||||
pid = waitpid(-1, &status, 0);
|
||||
if (pid == wl->child) {
|
||||
wl->child = 0;
|
||||
if (WIFEXITED(status))
|
||||
ret = WEXITSTATUS(status);
|
||||
else if (WIFSIGNALED(status))
|
||||
/*
|
||||
* If weston dies because of signal N, we
|
||||
* return 10+N. This is distinct from
|
||||
* weston-launch dying because of a signal
|
||||
* (128+N).
|
||||
*/
|
||||
ret = 10 + WTERMSIG(status);
|
||||
else
|
||||
ret = 0;
|
||||
quit(wl, ret);
|
||||
}
|
||||
break;
|
||||
case SIGTERM:
|
||||
case SIGINT:
|
||||
if (wl->child)
|
||||
kill(wl->child, sig.ssi_signo);
|
||||
break;
|
||||
case SIGUSR1:
|
||||
return handle_vt_switch(wl);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
setup_tty(struct weston_launch *wl)
|
||||
{
|
||||
struct stat buf;
|
||||
struct termios raw_attributes;
|
||||
struct vt_mode mode = { 0 };
|
||||
char *session;
|
||||
char path[PATH_MAX];
|
||||
int ok;
|
||||
|
||||
ok = sd_pid_get_session(getpid(), &session);
|
||||
if (ok < 0)
|
||||
error(1, -ok, "could not determine current session");
|
||||
|
||||
ok = sd_session_get_vt(session, &wl->vt);
|
||||
if (ok < 0)
|
||||
error(1, -ok, "could not determine current TTY");
|
||||
|
||||
snprintf(path, PATH_MAX, "/dev/tty%u", wl->vt);
|
||||
wl->tty = open(path, O_RDWR | O_NOCTTY | O_CLOEXEC);
|
||||
|
||||
if (wl->tty < 0)
|
||||
error(1, errno, "failed to open tty");
|
||||
|
||||
if (fstat(wl->tty, &buf) < 0)
|
||||
error(1, errno, "stat %s failed", path);
|
||||
|
||||
if (major(buf.st_rdev) != TTY_MAJOR)
|
||||
error(1, 0, "invalid tty device: %s", path);
|
||||
|
||||
wl->ttynr = minor(buf.st_rdev);
|
||||
|
||||
if (tcgetattr(wl->tty, &wl->terminal_attributes) < 0)
|
||||
error(1, errno, "could not get terminal attributes");
|
||||
|
||||
/* Ignore control characters and disable echo */
|
||||
raw_attributes = wl->terminal_attributes;
|
||||
cfmakeraw(&raw_attributes);
|
||||
|
||||
/* Fix up line endings to be normal (cfmakeraw hoses them) */
|
||||
raw_attributes.c_oflag |= OPOST | OCRNL;
|
||||
/* Don't generate ttou signals */
|
||||
raw_attributes.c_oflag &= ~TOSTOP;
|
||||
|
||||
if (tcsetattr(wl->tty, TCSANOW, &raw_attributes) < 0)
|
||||
error(1, errno, "could not put terminal into raw mode");
|
||||
|
||||
ioctl(wl->tty, KDGKBMODE, &wl->kb_mode);
|
||||
ok = ioctl(wl->tty, KDSKBMODE, K_OFF);
|
||||
if (ok < 0) {
|
||||
ok = ioctl(wl->tty, KDSKBMODE, K_RAW);
|
||||
if (ok < 0)
|
||||
error(1, errno, "failed to set keyboard mode on tty");
|
||||
}
|
||||
|
||||
ok = ioctl(wl->tty, KDSETMODE, KD_GRAPHICS);
|
||||
if (ok < 0)
|
||||
error(1, errno, "failed to set KD_GRAPHICS mode on tty");
|
||||
|
||||
wl->vt_state = VT_HAS_VT;
|
||||
mode.mode = VT_PROCESS;
|
||||
mode.relsig = SIGUSR1;
|
||||
mode.acqsig = SIGUSR1;
|
||||
ok = ioctl(wl->tty, VT_SETMODE, &mode);
|
||||
if (ok < 0)
|
||||
error(1, errno, "failed to take control of vt handling");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
drop_privileges(struct weston_launch *wl)
|
||||
{
|
||||
if (setgid(wl->pw->pw_gid) < 0 ||
|
||||
#ifdef HAVE_INITGROUPS
|
||||
initgroups(wl->pw->pw_name, wl->pw->pw_gid) < 0 ||
|
||||
#endif
|
||||
setuid(wl->pw->pw_uid) < 0)
|
||||
error(1, errno, "dropping privileges failed");
|
||||
}
|
||||
|
||||
static void
|
||||
launch_compositor(struct weston_launch *wl, int argc, char *argv[])
|
||||
{
|
||||
char command[PATH_MAX];
|
||||
char *child_argv[MAX_ARGV_SIZE];
|
||||
sigset_t mask;
|
||||
int i;
|
||||
|
||||
if (wl->verbose)
|
||||
printf("weston-launch: spawned weston with pid: %d\n", getpid());
|
||||
|
||||
drop_privileges(wl);
|
||||
|
||||
setenv_fd("WESTON_LAUNCHER_SOCK", wl->sock[1]);
|
||||
setenv("LD_LIBRARY_PATH", LIBDIR, 1);
|
||||
unsetenv("DISPLAY");
|
||||
|
||||
/* Do not give our signal mask to the new process. */
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGTERM);
|
||||
sigaddset(&mask, SIGCHLD);
|
||||
sigaddset(&mask, SIGINT);
|
||||
sigaddset(&mask, SIGUSR1);
|
||||
sigprocmask(SIG_UNBLOCK, &mask, NULL);
|
||||
|
||||
snprintf (command, PATH_MAX, "%s \"$@\"", argv[0]);
|
||||
|
||||
child_argv[0] = wl->pw->pw_shell;
|
||||
child_argv[1] = "-l";
|
||||
child_argv[2] = "-c";
|
||||
child_argv[3] = command;
|
||||
for (i = 0; i < argc; ++i)
|
||||
child_argv[4 + i] = argv[i];
|
||||
child_argv[4 + i] = NULL;
|
||||
|
||||
execv(child_argv[0], child_argv);
|
||||
error(1, errno, "exec failed");
|
||||
}
|
||||
|
||||
static void
|
||||
help(const char *name)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [args...] [-- [weston args..]]\n", name);
|
||||
fprintf(stderr, " -u, --user Start session as specified username\n");
|
||||
fprintf(stderr, " -v, --verbose Be verbose\n");
|
||||
fprintf(stderr, " -h, --help Display this help message\n");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct weston_launch wl;
|
||||
int i, c;
|
||||
struct option opts[] = {
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ 0, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
memset(&wl, 0, sizeof wl);
|
||||
wl.drm_fd = -1;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "u:t::vh", opts, &i)) != -1) {
|
||||
switch (c) {
|
||||
case 'v':
|
||||
wl.verbose = 1;
|
||||
break;
|
||||
case 'h':
|
||||
help("mutter-launch");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((argc - optind) > (MAX_ARGV_SIZE - 6))
|
||||
error(1, E2BIG, "Too many arguments to pass to weston");
|
||||
|
||||
if (optind >= argc)
|
||||
error(1, 0, "Expected program argument");
|
||||
|
||||
wl.pw = getpwuid(getuid());
|
||||
if (wl.pw == NULL)
|
||||
error(1, errno, "failed to get username");
|
||||
|
||||
if (!weston_launch_allowed(&wl))
|
||||
error(1, 0, "Permission denied. You must run from an active and local (systemd) session.");
|
||||
|
||||
if (setup_tty(&wl) < 0)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
if (setup_launcher_socket(&wl) < 0)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
if (setup_signals(&wl) < 0)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
wl.child = fork();
|
||||
if (wl.child == -1) {
|
||||
error(1, errno, "fork failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (wl.child == 0)
|
||||
launch_compositor(&wl, argc - optind, argv + optind);
|
||||
|
||||
close(wl.sock[1]);
|
||||
|
||||
while (1) {
|
||||
struct pollfd fds[2];
|
||||
int n;
|
||||
|
||||
fds[0].fd = wl.sock[0];
|
||||
fds[0].events = POLLIN;
|
||||
fds[1].fd = wl.signalfd;
|
||||
fds[1].events = POLLIN;
|
||||
|
||||
n = poll(fds, 2, -1);
|
||||
if (n < 0)
|
||||
error(0, errno, "poll failed");
|
||||
if (fds[0].revents & POLLIN)
|
||||
handle_socket_msg(&wl);
|
||||
if (fds[1].revents)
|
||||
handle_signal(&wl);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Benjamin Franzke
|
||||
* 2013 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of the copyright holders not be used in
|
||||
* advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The copyright holders make
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _WESTON_LAUNCH_H_
|
||||
#define _WESTON_LAUNCH_H_
|
||||
|
||||
enum weston_launcher_message_type {
|
||||
WESTON_LAUNCHER_REQUEST,
|
||||
WESTON_LAUNCHER_EVENT,
|
||||
};
|
||||
|
||||
enum weston_launcher_opcode {
|
||||
WESTON_LAUNCHER_OPEN = (1 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
WESTON_LAUNCHER_ACTIVATE_VT = (2 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (3 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
};
|
||||
|
||||
enum weston_launcher_server_opcode {
|
||||
WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH = (1 << 1 | WESTON_LAUNCHER_EVENT),
|
||||
WESTON_LAUNCHER_SERVER_VT_ENTER = (2 << 1 | WESTON_LAUNCHER_EVENT),
|
||||
};
|
||||
|
||||
struct weston_launcher_message {
|
||||
int opcode;
|
||||
};
|
||||
|
||||
struct weston_launcher_open {
|
||||
struct weston_launcher_message header;
|
||||
int flags;
|
||||
char path[0];
|
||||
};
|
||||
|
||||
struct weston_launcher_activate_vt {
|
||||
struct weston_launcher_message header;
|
||||
signed char vt;
|
||||
};
|
||||
|
||||
struct weston_launcher_reply {
|
||||
struct weston_launcher_message header;
|
||||
int ret;
|
||||
};
|
||||
|
||||
struct weston_launcher_event {
|
||||
struct weston_launcher_message header;
|
||||
int detail; /* unused, but makes sure replies and events are serialized the same */
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -33,9 +33,8 @@
|
||||
#include "meta-idle-monitor-xsync.h"
|
||||
#include "meta-monitor-manager-xrandr.h"
|
||||
#include "backends/meta-monitor-manager-dummy.h"
|
||||
#include "meta-cursor-renderer-x11.h"
|
||||
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include "meta-cursor.h"
|
||||
#include <meta/util.h>
|
||||
#include "display-private.h"
|
||||
#include "compositor/compositor-private.h"
|
||||
@@ -68,21 +67,11 @@ handle_alarm_notify (MetaBackend *backend,
|
||||
meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], (XSyncAlarmNotifyEvent*) event);
|
||||
}
|
||||
|
||||
static Window
|
||||
get_stage_window (MetaBackendX11 *x11)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
MetaCompositor *compositor = display->compositor;
|
||||
ClutterStage *stage = CLUTTER_STAGE (compositor->stage);
|
||||
|
||||
return clutter_x11_get_stage_window (stage);
|
||||
}
|
||||
|
||||
static void
|
||||
translate_device_event (MetaBackendX11 *x11,
|
||||
XIDeviceEvent *device_event)
|
||||
{
|
||||
Window stage_window = get_stage_window (x11);
|
||||
Window stage_window = meta_backend_x11_get_xwindow (x11);
|
||||
|
||||
if (device_event->event != stage_window)
|
||||
{
|
||||
@@ -307,6 +296,12 @@ meta_backend_x11_create_monitor_manager (MetaBackend *backend)
|
||||
return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL);
|
||||
}
|
||||
|
||||
static MetaCursorRenderer *
|
||||
meta_backend_x11_create_cursor_renderer (MetaBackend *backend)
|
||||
{
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_backend_x11_grab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
@@ -326,14 +321,10 @@ meta_backend_x11_grab_device (MetaBackend *backend,
|
||||
XISetMask (mask.mask, XI_KeyPress);
|
||||
XISetMask (mask.mask, XI_KeyRelease);
|
||||
|
||||
MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
MetaCursorReference *cursor_ref = meta_cursor_tracker_get_displayed_cursor (tracker);
|
||||
MetaCursor cursor = meta_cursor_reference_get_meta_cursor (cursor_ref);
|
||||
|
||||
ret = XIGrabDevice (priv->xdisplay, device_id,
|
||||
get_stage_window (x11),
|
||||
meta_backend_x11_get_xwindow (x11),
|
||||
timestamp,
|
||||
meta_cursor_create_x_cursor (priv->xdisplay, cursor),
|
||||
None,
|
||||
XIGrabModeAsync, XIGrabModeAsync,
|
||||
False, /* owner_events */
|
||||
&mask);
|
||||
@@ -355,6 +346,22 @@ meta_backend_x11_ungrab_device (MetaBackend *backend,
|
||||
return (ret == Success);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_warp_pointer (MetaBackend *backend,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
|
||||
XIWarpPointer (priv->xdisplay,
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
None,
|
||||
meta_backend_x11_get_xwindow (x11),
|
||||
0, 0, 0, 0,
|
||||
x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_class_init (MetaBackendX11Class *klass)
|
||||
{
|
||||
@@ -363,9 +370,11 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
|
||||
backend_class->post_init = meta_backend_x11_post_init;
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -383,3 +392,15 @@ meta_backend_x11_get_xdisplay (MetaBackendX11 *x11)
|
||||
return priv->xdisplay;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -53,4 +53,6 @@ GType meta_backend_x11_get_type (void) G_GNUC_CONST;
|
||||
|
||||
Display * meta_backend_x11_get_xdisplay (MetaBackendX11 *backend);
|
||||
|
||||
Window meta_backend_x11_get_xwindow (MetaBackendX11 *backend);
|
||||
|
||||
#endif /* META_BACKEND_X11_H */
|
||||
|
||||
99
src/backends/x11/meta-cursor-renderer-x11.c
Normal file
99
src/backends/x11/meta-cursor-renderer-x11.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* 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-cursor-renderer-x11.h"
|
||||
|
||||
#include "meta-backend-x11.h"
|
||||
#include "meta-stage.h"
|
||||
|
||||
struct _MetaCursorRendererX11Private
|
||||
{
|
||||
gboolean server_cursor_visible;
|
||||
};
|
||||
typedef struct _MetaCursorRendererX11Private MetaCursorRendererX11Private;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererX11, meta_cursor_renderer_x11, META_TYPE_CURSOR_RENDERER);
|
||||
|
||||
static gboolean
|
||||
meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer)
|
||||
{
|
||||
MetaCursorRendererX11 *x11 = META_CURSOR_RENDERER_X11 (renderer);
|
||||
MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11);
|
||||
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
Window xwindow = meta_backend_x11_get_xwindow (backend);
|
||||
|
||||
if (xwindow == None)
|
||||
return FALSE;
|
||||
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
|
||||
|
||||
MetaCursorReference *cursor_ref = meta_cursor_renderer_get_cursor (renderer);
|
||||
gboolean has_server_cursor = FALSE;
|
||||
|
||||
if (cursor_ref)
|
||||
{
|
||||
MetaCursor cursor = meta_cursor_reference_get_meta_cursor (cursor_ref);
|
||||
if (cursor != META_CURSOR_NONE)
|
||||
{
|
||||
Cursor xcursor = meta_cursor_create_x_cursor (xdisplay, cursor);
|
||||
XDefineCursor (xdisplay, xwindow, xcursor);
|
||||
XFlush (xdisplay);
|
||||
XFreeCursor (xdisplay, xcursor);
|
||||
|
||||
has_server_cursor = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_server_cursor != priv->server_cursor_visible)
|
||||
{
|
||||
if (has_server_cursor)
|
||||
XFixesShowCursor (xdisplay, xwindow);
|
||||
else
|
||||
XFixesHideCursor (xdisplay, xwindow);
|
||||
|
||||
priv->server_cursor_visible = has_server_cursor;
|
||||
}
|
||||
|
||||
return priv->server_cursor_visible;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_x11_class_init (MetaCursorRendererX11Class *klass)
|
||||
{
|
||||
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_CLASS (klass);
|
||||
|
||||
renderer_class->update_cursor = meta_cursor_renderer_x11_update_cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_x11_init (MetaCursorRendererX11 *x11)
|
||||
{
|
||||
MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11);
|
||||
|
||||
/* XFixes has no way to retrieve the current cursor visibility. */
|
||||
priv->server_cursor_visible = TRUE;
|
||||
}
|
||||
52
src/backends/x11/meta-cursor-renderer-x11.h
Normal file
52
src/backends/x11/meta-cursor-renderer-x11.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef META_CURSOR_RENDERER_X11_H
|
||||
#define META_CURSOR_RENDERER_X11_H
|
||||
|
||||
#include "meta-cursor-renderer.h"
|
||||
|
||||
#define META_TYPE_CURSOR_RENDERER_X11 (meta_cursor_renderer_x11_get_type ())
|
||||
#define META_CURSOR_RENDERER_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11))
|
||||
#define META_CURSOR_RENDERER_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11Class))
|
||||
#define META_IS_CURSOR_RENDERER_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CURSOR_RENDERER_X11))
|
||||
#define META_IS_CURSOR_RENDERER_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_CURSOR_RENDERER_X11))
|
||||
#define META_CURSOR_RENDERER_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11Class))
|
||||
|
||||
typedef struct _MetaCursorRendererX11 MetaCursorRendererX11;
|
||||
typedef struct _MetaCursorRendererX11Class MetaCursorRendererX11Class;
|
||||
|
||||
struct _MetaCursorRendererX11
|
||||
{
|
||||
MetaCursorRenderer parent;
|
||||
};
|
||||
|
||||
struct _MetaCursorRendererX11Class
|
||||
{
|
||||
MetaCursorRendererClass parent_class;
|
||||
};
|
||||
|
||||
GType meta_cursor_renderer_x11_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#endif /* META_CURSOR_RENDERER_X11_H */
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001, 2002 Havoc Pennington
|
||||
* Copyright (C) 2002, 2003 Red Hat Inc.
|
||||
* Some ICCCM manager selection code derived from fvwm2,
|
||||
@@ -8,7 +8,7 @@
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
* Copyright (C) 2013 Red Hat Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -18,7 +18,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -272,7 +272,7 @@ get_edid_property (Display *dpy,
|
||||
}
|
||||
|
||||
XFree (prop);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -918,6 +918,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
}
|
||||
|
||||
XUngrabServer (manager_xrandr->xdisplay);
|
||||
XFlush (manager_xrandr->xdisplay);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -68,7 +68,7 @@ meta_create_color_texture_4ub (guint8 red,
|
||||
|
||||
/**
|
||||
* meta_create_texture_pipeline:
|
||||
* @src_texture: (allow-none): texture to use initially for the layer
|
||||
* @src_texture: (nullable): texture to use initially for the layer
|
||||
*
|
||||
* Creates a pipeline with a single layer. Using a common template
|
||||
* makes it easier for Cogl to share a shader for different uses in
|
||||
|
||||
@@ -15,7 +15,8 @@ struct _MetaCompositor
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
guint repaint_func_id;
|
||||
guint pre_paint_func_id;
|
||||
guint post_paint_func_id;
|
||||
|
||||
gint64 server_time_query_time;
|
||||
gint64 server_time_offset;
|
||||
@@ -38,6 +39,9 @@ struct _MetaCompositor
|
||||
gint switch_workspace_in_progress;
|
||||
|
||||
MetaPluginManager *plugin_mgr;
|
||||
|
||||
gboolean frame_has_updated_xsurfaces;
|
||||
gboolean have_x11_sync_object;
|
||||
};
|
||||
|
||||
/* Wait 2ms after vblank before starting to draw next frame */
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
#include "frame.h"
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
#include "meta-sync-ring.h"
|
||||
|
||||
#include "backends/meta-backend.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
@@ -136,7 +137,11 @@ meta_switch_workspace_completed (MetaCompositor *compositor)
|
||||
void
|
||||
meta_compositor_destroy (MetaCompositor *compositor)
|
||||
{
|
||||
clutter_threads_remove_repaint_func (compositor->repaint_func_id);
|
||||
clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
|
||||
clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
|
||||
|
||||
if (compositor->have_x11_sync_object)
|
||||
meta_sync_ring_destroy ();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -146,6 +151,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;
|
||||
}
|
||||
|
||||
static Window
|
||||
@@ -555,10 +562,10 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
|
||||
meta_empty_stage_input_region (screen);
|
||||
|
||||
/* Make sure there isn't any left-over output shape on the
|
||||
/* Make sure there isn't any left-over output shape on the
|
||||
* overlay window by setting the whole screen to be an
|
||||
* output region.
|
||||
*
|
||||
*
|
||||
* Note: there doesn't seem to be any real chance of that
|
||||
* because the X server will destroy the overlay window
|
||||
* when the last client using it exits.
|
||||
@@ -569,6 +576,8 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
* contents until we show the stage.
|
||||
*/
|
||||
XMapWindow (xdisplay, compositor->output);
|
||||
|
||||
compositor->have_x11_sync_object = meta_sync_ring_init (display);
|
||||
}
|
||||
|
||||
redirect_windows (display->screen);
|
||||
@@ -595,7 +604,7 @@ meta_compositor_unmanage (MetaCompositor *compositor)
|
||||
/**
|
||||
* meta_shape_cow_for_window:
|
||||
* @compositor: A #MetaCompositor
|
||||
* @window: (allow-none): A #MetaWindow to shape the COW for
|
||||
* @window: (nullable): A #MetaWindow to shape the COW for
|
||||
*
|
||||
* Sets an bounding shape on the COW so that the given window
|
||||
* is exposed. If @window is %NULL it clears the shape again.
|
||||
@@ -746,9 +755,9 @@ meta_compositor_window_surface_changed (MetaCompositor *compositor,
|
||||
|
||||
/**
|
||||
* meta_compositor_process_event: (skip)
|
||||
* @compositor:
|
||||
* @event:
|
||||
* @window:
|
||||
* @compositor:
|
||||
* @event:
|
||||
* @window:
|
||||
*
|
||||
*/
|
||||
gboolean
|
||||
@@ -780,6 +789,10 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
||||
if (!meta_is_wayland_compositor () && event->type == MapNotify)
|
||||
clutter_x11_handle_event (event);
|
||||
|
||||
if (compositor->have_x11_sync_object &&
|
||||
event->type == (compositor->display->xsync_event_base + XSyncAlarmNotify))
|
||||
meta_sync_ring_handle_event ((XSyncAlarmNotifyEvent *) event);
|
||||
|
||||
/* The above handling is basically just "observing" the events, so we return
|
||||
* FALSE to indicate that the event should not be filtered out; if we have
|
||||
* GTK+ windows in the same process, GTK+ needs the ConfigureNotify event, for example.
|
||||
@@ -1125,11 +1138,12 @@ frame_callback (CoglOnscreen *onscreen,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pre_paint_windows (MetaCompositor *compositor)
|
||||
static gboolean
|
||||
meta_pre_paint_func (gpointer data)
|
||||
{
|
||||
GList *l;
|
||||
MetaWindowActor *top_window;
|
||||
MetaCompositor *compositor = data;
|
||||
|
||||
if (compositor->onscreen == NULL)
|
||||
{
|
||||
@@ -1141,7 +1155,7 @@ pre_paint_windows (MetaCompositor *compositor)
|
||||
}
|
||||
|
||||
if (compositor->windows == NULL)
|
||||
return;
|
||||
return TRUE;
|
||||
|
||||
top_window = g_list_last (compositor->windows)->data;
|
||||
|
||||
@@ -1153,13 +1167,53 @@ 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 standardized way to do this is
|
||||
* GL_EXT_X11_sync_object. Since this isn't implemented yet in
|
||||
* mesa, we also have a path that relies on the implementation
|
||||
* of the open source drivers.
|
||||
*
|
||||
* Anything else, we just hope for the best.
|
||||
*
|
||||
* Xorg and open source driver specifics:
|
||||
*
|
||||
* The X server makes sure to flush drawing to the kernel before
|
||||
* sending out damage events, but since we use
|
||||
* DamageReportBoundingBox there may be drawing between the last
|
||||
* damage event and the XDamageSubtract() that needs to be
|
||||
* flushed as well.
|
||||
*
|
||||
* Xorg always makes sure that drawing is flushed to the kernel
|
||||
* before writing events or responses to the client, so any
|
||||
* round trip request at this point is sufficient to flush the
|
||||
* GLX buffers.
|
||||
*/
|
||||
if (compositor->have_x11_sync_object)
|
||||
compositor->have_x11_sync_object = meta_sync_ring_insert_wait ();
|
||||
else
|
||||
XSync (compositor->display->xdisplay, False);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_repaint_func (gpointer data)
|
||||
meta_post_paint_func (gpointer data)
|
||||
{
|
||||
MetaCompositor *compositor = data;
|
||||
pre_paint_windows (compositor);
|
||||
|
||||
if (compositor->frame_has_updated_xsurfaces)
|
||||
{
|
||||
if (compositor->have_x11_sync_object)
|
||||
compositor->have_x11_sync_object = meta_sync_ring_after_frame ();
|
||||
|
||||
compositor->frame_has_updated_xsurfaces = FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1198,10 +1252,16 @@ meta_compositor_new (MetaDisplay *display)
|
||||
G_CALLBACK (on_shadow_factory_changed),
|
||||
compositor);
|
||||
|
||||
compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func,
|
||||
compositor,
|
||||
NULL);
|
||||
|
||||
compositor->pre_paint_func_id =
|
||||
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_PRE_PAINT,
|
||||
meta_pre_paint_func,
|
||||
compositor,
|
||||
NULL);
|
||||
compositor->post_paint_func_id =
|
||||
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
|
||||
meta_post_paint_func,
|
||||
compositor,
|
||||
NULL);
|
||||
return compositor;
|
||||
}
|
||||
|
||||
@@ -1356,3 +1416,13 @@ meta_compositor_hide_tile_preview (MetaCompositor *compositor)
|
||||
{
|
||||
meta_plugin_manager_hide_tile_preview (compositor->plugin_mgr);
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_show_window_menu (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
meta_plugin_manager_show_window_menu (compositor->plugin_mgr, window, menu, x, y);
|
||||
}
|
||||
|
||||
@@ -356,3 +356,21 @@ meta_plugin_manager_hide_tile_preview (MetaPluginManager *plugin_mgr)
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_plugin_manager_show_window_menu (MetaPluginManager *plugin_mgr,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
MetaPlugin *plugin = plugin_mgr->plugin;
|
||||
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
|
||||
MetaDisplay *display = plugin_mgr->compositor->display;
|
||||
|
||||
if (display->display_opening)
|
||||
return;
|
||||
|
||||
if (klass->show_window_menu)
|
||||
klass->show_window_menu (plugin, window, menu, x, y);
|
||||
}
|
||||
|
||||
@@ -80,4 +80,12 @@ gboolean meta_plugin_manager_show_tile_preview (MetaPluginManager *mgr,
|
||||
MetaRectangle *tile_rect,
|
||||
int tile_monitor_number);
|
||||
gboolean meta_plugin_manager_hide_tile_preview (MetaPluginManager *mgr);
|
||||
|
||||
void meta_plugin_manager_show_window_menu (MetaPluginManager *mgr,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -189,7 +189,7 @@ meta_shadow_unref (MetaShadow *shadow)
|
||||
* @window_y: y position of the region to paint a shadow for
|
||||
* @window_width: actual width of the region to paint a shadow for
|
||||
* @window_height: actual height of the region to paint a shadow for
|
||||
* @clip: (allow-none): if non-%NULL specifies the visible portion
|
||||
* @clip: (nullable): if non-%NULL specifies the visible portion
|
||||
* of the shadow.
|
||||
* @clip_strictly: if %TRUE, drawing will be clipped strictly
|
||||
* to @clip, otherwise, it will be only used to optimize
|
||||
|
||||
@@ -108,6 +108,62 @@ meta_surface_actor_wayland_is_unredirected (MetaSurfaceActor *actor)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
get_output_scale (int output_id)
|
||||
{
|
||||
MetaMonitorManager *monitor_manager = meta_monitor_manager_get ();
|
||||
MetaOutput *outputs;
|
||||
guint n_outputs, i;
|
||||
int output_scale = 1;
|
||||
|
||||
outputs = meta_monitor_manager_get_outputs (monitor_manager, &n_outputs);
|
||||
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
if (outputs[i].output_id == output_id)
|
||||
{
|
||||
output_scale = outputs[i].scale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return output_scale;
|
||||
}
|
||||
|
||||
double
|
||||
meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor)
|
||||
{
|
||||
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (actor);
|
||||
MetaWaylandSurface *surface = priv->surface;
|
||||
MetaWindow *window = surface->window;
|
||||
int output_scale = 1;
|
||||
|
||||
while (surface)
|
||||
{
|
||||
if (surface->window)
|
||||
{
|
||||
window = surface->window;
|
||||
break;
|
||||
}
|
||||
surface = surface->sub.parent;
|
||||
}
|
||||
|
||||
/* XXX: We do not handle x11 clients yet */
|
||||
if (window && window->client_type != META_WINDOW_CLIENT_TYPE_X11)
|
||||
output_scale = get_output_scale (window->monitor->output_id);
|
||||
|
||||
return (double)output_scale / (double)priv->surface->scale;
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_wayland_scale_texture (MetaSurfaceActorWayland *actor)
|
||||
{
|
||||
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (actor));
|
||||
double output_scale = meta_surface_actor_wayland_get_scale (actor);
|
||||
|
||||
clutter_actor_set_scale (CLUTTER_ACTOR (stex), output_scale, output_scale);
|
||||
}
|
||||
|
||||
static MetaWindow *
|
||||
meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
|
||||
{
|
||||
@@ -116,6 +172,42 @@ meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
|
||||
return priv->surface->window;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_get_preferred_width (ClutterActor *self,
|
||||
gfloat for_height,
|
||||
gfloat *min_width_p,
|
||||
gfloat *natural_width_p)
|
||||
{
|
||||
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||
double scale = meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND (self));
|
||||
|
||||
clutter_actor_get_preferred_width (CLUTTER_ACTOR (stex), for_height, min_width_p, natural_width_p);
|
||||
|
||||
if (min_width_p)
|
||||
*min_width_p *= scale;
|
||||
|
||||
if (natural_width_p)
|
||||
*natural_width_p *= scale;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_get_preferred_height (ClutterActor *self,
|
||||
gfloat for_width,
|
||||
gfloat *min_height_p,
|
||||
gfloat *natural_height_p)
|
||||
{
|
||||
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||
double scale = meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND (self));
|
||||
|
||||
clutter_actor_get_preferred_height (CLUTTER_ACTOR (stex), for_width, min_height_p, natural_height_p);
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p *= scale;
|
||||
|
||||
if (natural_height_p)
|
||||
*natural_height_p *= scale;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_dispose (GObject *object)
|
||||
{
|
||||
@@ -130,8 +222,12 @@ static void
|
||||
meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
|
||||
{
|
||||
MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
actor_class->get_preferred_width = meta_surface_actor_wayland_get_preferred_width;
|
||||
actor_class->get_preferred_height = meta_surface_actor_wayland_get_preferred_height;
|
||||
|
||||
surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage;
|
||||
surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint;
|
||||
surface_actor_class->is_visible = meta_surface_actor_wayland_is_visible;
|
||||
|
||||
@@ -61,6 +61,9 @@ MetaWaylandSurface * meta_surface_actor_wayland_get_surface (MetaSurfaceActorWay
|
||||
void meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self,
|
||||
MetaWaylandBuffer *buffer);
|
||||
|
||||
double meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor);
|
||||
|
||||
void meta_surface_actor_wayland_scale_texture (MetaSurfaceActorWayland *actor);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */
|
||||
|
||||
@@ -238,26 +238,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;
|
||||
}
|
||||
|
||||
|
||||
574
src/compositor/meta-sync-ring.c
Normal file
574
src/compositor/meta-sync-ring.c
Normal file
@@ -0,0 +1,574 @@
|
||||
/*
|
||||
* This is based on an original C++ implementation for compiz that
|
||||
* carries the following copyright notice:
|
||||
*
|
||||
*
|
||||
* Copyright © 2011 NVIDIA Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of NVIDIA
|
||||
* Corporation not be used in advertising or publicity pertaining to
|
||||
* distribution of the software without specific, written prior
|
||||
* permission. NVIDIA Corporation makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Authors: James Jones <jajones@nvidia.com>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include <meta/display.h>
|
||||
#include <meta/util.h>
|
||||
|
||||
#include "meta-sync-ring.h"
|
||||
|
||||
/* Theory of operation:
|
||||
*
|
||||
* We use a ring of NUM_SYNCS fence objects. On each frame we advance
|
||||
* to the next fence in the ring. For each fence we do:
|
||||
*
|
||||
* 1. fence is XSyncTriggerFence()'d and glWaitSync()'d
|
||||
* 2. NUM_SYNCS / 2 frames later, fence should be triggered
|
||||
* 3. fence is XSyncResetFence()'d
|
||||
* 4. NUM_SYNCS / 2 frames later, fence should be reset
|
||||
* 5. go back to 1 and re-use fence
|
||||
*
|
||||
* glClientWaitSync() and XAlarms are used in steps 2 and 4,
|
||||
* respectively, to double-check the expectections.
|
||||
*/
|
||||
|
||||
#define NUM_SYNCS 10
|
||||
#define MAX_SYNC_WAIT_TIME (1 * 1000 * 1000 * 1000) /* one sec */
|
||||
#define MAX_REBOOT_ATTEMPTS 2
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_SYNC_STATE_READY,
|
||||
META_SYNC_STATE_WAITING,
|
||||
META_SYNC_STATE_DONE,
|
||||
META_SYNC_STATE_RESET_PENDING,
|
||||
} MetaSyncState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Display *xdisplay;
|
||||
|
||||
XSyncFence xfence;
|
||||
GLsync glsync;
|
||||
|
||||
XSyncCounter xcounter;
|
||||
XSyncAlarm xalarm;
|
||||
XSyncValue next_counter_value;
|
||||
|
||||
MetaSyncState state;
|
||||
} MetaSync;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
GHashTable *alarm_to_sync;
|
||||
|
||||
MetaSync *syncs_array[NUM_SYNCS];
|
||||
guint current_sync_idx;
|
||||
MetaSync *current_sync;
|
||||
guint warmup_syncs;
|
||||
|
||||
guint reboots;
|
||||
} MetaSyncRing;
|
||||
|
||||
static MetaSyncRing meta_sync_ring = { 0 };
|
||||
|
||||
static XSyncValue SYNC_VALUE_ZERO;
|
||||
static XSyncValue SYNC_VALUE_ONE;
|
||||
|
||||
static void (*meta_gl_get_integerv) (GLenum pname,
|
||||
GLint *params);
|
||||
static const char* (*meta_gl_get_stringi) (GLenum name,
|
||||
GLuint index);
|
||||
static void (*meta_gl_delete_sync) (GLsync sync);
|
||||
static GLenum (*meta_gl_client_wait_sync) (GLsync sync,
|
||||
GLbitfield flags,
|
||||
GLuint64 timeout);
|
||||
static void (*meta_gl_wait_sync) (GLsync sync,
|
||||
GLbitfield flags,
|
||||
GLuint64 timeout);
|
||||
static GLsync (*meta_gl_import_sync) (GLenum external_sync_type,
|
||||
GLintptr external_sync,
|
||||
GLbitfield flags);
|
||||
|
||||
static GLenum (*meta_gl_get_error) (void);
|
||||
static GLboolean (*meta_gl_is_sync) (GLsync sync);
|
||||
|
||||
static MetaSyncRing *
|
||||
meta_sync_ring_get (void)
|
||||
{
|
||||
if (meta_sync_ring.reboots > MAX_REBOOT_ATTEMPTS)
|
||||
return NULL;
|
||||
|
||||
return &meta_sync_ring;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_gl_symbol (const char *name,
|
||||
void **func)
|
||||
{
|
||||
*func = cogl_get_proc_address (name);
|
||||
if (!*func)
|
||||
{
|
||||
meta_verbose ("MetaSyncRing: failed to resolve required GL symbol \"%s\"\n", name);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_gl_extensions (void)
|
||||
{
|
||||
int num_extensions, i;
|
||||
gboolean sync = FALSE;
|
||||
gboolean x11_sync_object = FALSE;
|
||||
|
||||
meta_gl_get_integerv (GL_NUM_EXTENSIONS, &num_extensions);
|
||||
|
||||
for (i = 0; i < num_extensions; ++i)
|
||||
{
|
||||
const char *ext = meta_gl_get_stringi (GL_EXTENSIONS, i);
|
||||
|
||||
if (g_strcmp0 ("GL_ARB_sync", ext) == 0)
|
||||
sync = TRUE;
|
||||
else if (g_strcmp0 ("GL_EXT_x11_sync_object", ext) == 0)
|
||||
x11_sync_object = TRUE;
|
||||
}
|
||||
|
||||
return sync && x11_sync_object;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_required_symbols (void)
|
||||
{
|
||||
static gboolean success = FALSE;
|
||||
|
||||
if (success)
|
||||
return TRUE;
|
||||
|
||||
/* We don't link against libGL directly because cogl may want to
|
||||
* use something else. This assumes that cogl has been initialized
|
||||
* and dynamically loaded libGL at this point.
|
||||
*/
|
||||
|
||||
if (!load_gl_symbol ("glGetIntegerv", (void **) &meta_gl_get_integerv))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glGetStringi", (void **) &meta_gl_get_stringi))
|
||||
goto out;
|
||||
|
||||
if (!check_gl_extensions ())
|
||||
{
|
||||
meta_verbose ("MetaSyncRing: couldn't find required GL extensions\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!load_gl_symbol ("glDeleteSync", (void **) &meta_gl_delete_sync))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glClientWaitSync", (void **) &meta_gl_client_wait_sync))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glWaitSync", (void **) &meta_gl_wait_sync))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync))
|
||||
goto out;
|
||||
|
||||
if (!load_gl_symbol ("glGetError", (void **) &meta_gl_get_error))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glIsSync", (void **) &meta_gl_is_sync))
|
||||
goto out;
|
||||
|
||||
success = TRUE;
|
||||
out:
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
print_gl_error (void)
|
||||
{
|
||||
GLenum e;
|
||||
switch (e = meta_gl_get_error ())
|
||||
{
|
||||
case GL_NO_ERROR:
|
||||
meta_warning ("GL_NO_ERROR\n");
|
||||
break;
|
||||
case GL_INVALID_ENUM:
|
||||
meta_warning ("GL_INVALID_ENUM\n");
|
||||
break;
|
||||
case GL_INVALID_VALUE:
|
||||
meta_warning ("GL_INVALID_VALUE\n");
|
||||
break;
|
||||
case GL_INVALID_OPERATION:
|
||||
meta_warning ("GL_INVALID_OPERATION\n");
|
||||
break;
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||
meta_warning ("GL_INVALID_FRAMEBUFFER_OPERATION\n");
|
||||
break;
|
||||
case GL_OUT_OF_MEMORY:
|
||||
meta_warning ("GL_OUT_OF_MEMORY\n");
|
||||
break;
|
||||
case GL_STACK_OVERFLOW:
|
||||
meta_warning ("GL_STACK_OVERFLOW\n");
|
||||
break;
|
||||
case GL_STACK_UNDERFLOW:
|
||||
meta_warning ("GL_STACK_UNDERFLOW\n");
|
||||
break;
|
||||
default:
|
||||
meta_warning ("GL error 0x%x\n", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_insert (MetaSync *self)
|
||||
{
|
||||
g_return_if_fail (self->state == META_SYNC_STATE_READY);
|
||||
|
||||
XSyncTriggerFence (self->xdisplay, self->xfence);
|
||||
XFlush (self->xdisplay);
|
||||
|
||||
meta_gl_wait_sync (self->glsync, 0, GL_TIMEOUT_IGNORED);
|
||||
|
||||
self->state = META_SYNC_STATE_WAITING;
|
||||
}
|
||||
|
||||
static GLenum
|
||||
meta_sync_check_update_finished (MetaSync *self,
|
||||
GLuint64 timeout)
|
||||
{
|
||||
GLenum status = GL_WAIT_FAILED;
|
||||
|
||||
switch (self->state)
|
||||
{
|
||||
case META_SYNC_STATE_DONE:
|
||||
status = GL_ALREADY_SIGNALED;
|
||||
break;
|
||||
case META_SYNC_STATE_WAITING:
|
||||
status = meta_gl_client_wait_sync (self->glsync, 0, timeout);
|
||||
if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED)
|
||||
self->state = META_SYNC_STATE_DONE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_warn_if_fail (status != GL_WAIT_FAILED);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_reset (MetaSync *self)
|
||||
{
|
||||
XSyncAlarmAttributes attrs;
|
||||
int overflow;
|
||||
|
||||
g_return_if_fail (self->state == META_SYNC_STATE_DONE);
|
||||
|
||||
XSyncResetFence (self->xdisplay, self->xfence);
|
||||
|
||||
attrs.trigger.wait_value = self->next_counter_value;
|
||||
|
||||
XSyncChangeAlarm (self->xdisplay, self->xalarm, XSyncCAValue, &attrs);
|
||||
XSyncSetCounter (self->xdisplay, self->xcounter, self->next_counter_value);
|
||||
|
||||
XSyncValueAdd (&self->next_counter_value,
|
||||
self->next_counter_value,
|
||||
SYNC_VALUE_ONE,
|
||||
&overflow);
|
||||
|
||||
self->state = META_SYNC_STATE_RESET_PENDING;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_handle_event (MetaSync *self,
|
||||
XSyncAlarmNotifyEvent *event)
|
||||
{
|
||||
g_return_if_fail (event->alarm == self->xalarm);
|
||||
g_return_if_fail (self->state == META_SYNC_STATE_RESET_PENDING);
|
||||
|
||||
self->state = META_SYNC_STATE_READY;
|
||||
}
|
||||
|
||||
static MetaSync *
|
||||
meta_sync_new (Display *xdisplay)
|
||||
{
|
||||
MetaSync *self;
|
||||
XSyncAlarmAttributes attrs;
|
||||
|
||||
self = g_malloc0 (sizeof (MetaSync));
|
||||
|
||||
self->xdisplay = xdisplay;
|
||||
|
||||
self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), FALSE);
|
||||
meta_warning ("created X fence 0x%x\n", self->xfence);
|
||||
self->glsync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0);
|
||||
print_gl_error ();
|
||||
|
||||
self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO);
|
||||
|
||||
attrs.trigger.counter = self->xcounter;
|
||||
attrs.trigger.value_type = XSyncAbsolute;
|
||||
attrs.trigger.wait_value = SYNC_VALUE_ONE;
|
||||
attrs.trigger.test_type = XSyncPositiveTransition;
|
||||
attrs.events = TRUE;
|
||||
self->xalarm = XSyncCreateAlarm (xdisplay,
|
||||
XSyncCACounter |
|
||||
XSyncCAValueType |
|
||||
XSyncCAValue |
|
||||
XSyncCATestType |
|
||||
XSyncCAEvents,
|
||||
&attrs);
|
||||
|
||||
XSyncIntToValue (&self->next_counter_value, 1);
|
||||
|
||||
self->state = META_SYNC_STATE_READY;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static Bool
|
||||
alarm_event_predicate (Display *dpy,
|
||||
XEvent *event,
|
||||
XPointer data)
|
||||
{
|
||||
int xsync_event_base;
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return False;
|
||||
|
||||
xsync_event_base = meta_display_get_sync_event_base (ring->display);
|
||||
|
||||
if (event->type == xsync_event_base + XSyncAlarmNotify)
|
||||
{
|
||||
if (((MetaSync *) data)->xalarm == ((XSyncAlarmNotifyEvent *) event)->alarm)
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_free (MetaSync *self)
|
||||
{
|
||||
/* When our assumptions don't hold, something has gone wrong but we
|
||||
* don't know what, so we reboot the ring. While doing that, we
|
||||
* trigger fences before deleting them to try to get ourselves out
|
||||
* of a potentially stuck GPU state.
|
||||
*/
|
||||
switch (self->state)
|
||||
{
|
||||
case META_SYNC_STATE_WAITING:
|
||||
case META_SYNC_STATE_DONE:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case META_SYNC_STATE_RESET_PENDING:
|
||||
{
|
||||
XEvent event;
|
||||
XIfEvent (self->xdisplay, &event, alarm_event_predicate, (XPointer) self);
|
||||
meta_sync_handle_event (self, (XSyncAlarmNotifyEvent *) &event);
|
||||
}
|
||||
/* fall through */
|
||||
case META_SYNC_STATE_READY:
|
||||
XSyncTriggerFence (self->xdisplay, self->xfence);
|
||||
XFlush (self->xdisplay);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
meta_gl_delete_sync (self->glsync);
|
||||
XSyncDestroyFence (self->xdisplay, self->xfence);
|
||||
XSyncDestroyCounter (self->xdisplay, self->xcounter);
|
||||
XSyncDestroyAlarm (self->xdisplay, self->xalarm);
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_sync_ring_init (MetaDisplay *display)
|
||||
{
|
||||
guint i;
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
g_return_val_if_fail (display != NULL, FALSE);
|
||||
g_return_val_if_fail (ring->display == NULL, FALSE);
|
||||
|
||||
if (!load_required_symbols ())
|
||||
return FALSE;
|
||||
|
||||
if (!meta_display_has_sync (display))
|
||||
return FALSE;
|
||||
|
||||
print_gl_error ();
|
||||
|
||||
XSyncIntToValue (&SYNC_VALUE_ZERO, 0);
|
||||
XSyncIntToValue (&SYNC_VALUE_ONE, 1);
|
||||
|
||||
ring->display = display;
|
||||
|
||||
ring->alarm_to_sync = g_hash_table_new (NULL, NULL);
|
||||
|
||||
for (i = 0; i < NUM_SYNCS; ++i)
|
||||
{
|
||||
MetaSync *sync = meta_sync_new (meta_display_get_xdisplay (display));
|
||||
ring->syncs_array[i] = sync;
|
||||
g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, sync);
|
||||
}
|
||||
|
||||
ring->current_sync_idx = 0;
|
||||
ring->current_sync = ring->syncs_array[0];
|
||||
ring->warmup_syncs = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_sync_ring_destroy (void)
|
||||
{
|
||||
guint i;
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return;
|
||||
|
||||
g_return_if_fail (ring->display != NULL);
|
||||
|
||||
ring->current_sync_idx = 0;
|
||||
ring->current_sync = NULL;
|
||||
ring->warmup_syncs = 0;
|
||||
|
||||
for (i = 0; i < NUM_SYNCS; ++i)
|
||||
meta_sync_free (ring->syncs_array[i]);
|
||||
|
||||
g_hash_table_destroy (ring->alarm_to_sync);
|
||||
|
||||
ring->display = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_sync_ring_reboot (MetaDisplay *display)
|
||||
{
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
meta_sync_ring_destroy ();
|
||||
|
||||
ring->reboots += 1;
|
||||
|
||||
if (!meta_sync_ring_get ())
|
||||
{
|
||||
meta_warning ("MetaSyncRing: Too many reboots -- disabling\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return meta_sync_ring_init (display);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_sync_ring_after_frame (void)
|
||||
{
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
g_return_if_fail (ring->display != NULL);
|
||||
|
||||
if (ring->warmup_syncs >= NUM_SYNCS / 2)
|
||||
{
|
||||
guint reset_sync_idx = (ring->current_sync_idx + NUM_SYNCS - (NUM_SYNCS / 2)) % NUM_SYNCS;
|
||||
MetaSync *sync_to_reset = ring->syncs_array[reset_sync_idx];
|
||||
|
||||
GLenum status = meta_sync_check_update_finished (sync_to_reset, 0);
|
||||
if (status == GL_TIMEOUT_EXPIRED)
|
||||
{
|
||||
meta_warning ("MetaSyncRing: We should never wait for a sync -- add more syncs?\n");
|
||||
status = meta_sync_check_update_finished (sync_to_reset, MAX_SYNC_WAIT_TIME);
|
||||
}
|
||||
|
||||
if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED)
|
||||
{
|
||||
meta_warning ("MetaSyncRing: Timed out waiting for sync object.\n");
|
||||
return meta_sync_ring_reboot (ring->display);
|
||||
}
|
||||
|
||||
meta_sync_reset (sync_to_reset);
|
||||
}
|
||||
else
|
||||
{
|
||||
ring->warmup_syncs += 1;
|
||||
}
|
||||
|
||||
ring->current_sync_idx += 1;
|
||||
ring->current_sync_idx %= NUM_SYNCS;
|
||||
|
||||
ring->current_sync = ring->syncs_array[ring->current_sync_idx];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_sync_ring_insert_wait (void)
|
||||
{
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
g_return_if_fail (ring->display != NULL);
|
||||
|
||||
if (ring->current_sync->state != META_SYNC_STATE_READY)
|
||||
{
|
||||
meta_warning ("MetaSyncRing: Sync object is not ready -- were events handled properly?\n");
|
||||
if (!meta_sync_ring_reboot (ring->display))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
meta_sync_insert (ring->current_sync);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_sync_ring_handle_event (XSyncAlarmNotifyEvent *event)
|
||||
{
|
||||
MetaSync *sync;
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return;
|
||||
|
||||
g_return_if_fail (ring->display != NULL);
|
||||
|
||||
sync = g_hash_table_lookup (ring->alarm_to_sync, (gpointer) event->alarm);
|
||||
if (sync)
|
||||
meta_sync_handle_event (sync, event);
|
||||
}
|
||||
17
src/compositor/meta-sync-ring.h
Normal file
17
src/compositor/meta-sync-ring.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _META_SYNC_RING_H_
|
||||
#define _META_SYNC_RING_H_
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/sync.h>
|
||||
|
||||
#include <meta/display.h>
|
||||
|
||||
gboolean meta_sync_ring_init (MetaDisplay *dpy);
|
||||
void meta_sync_ring_destroy (void);
|
||||
gboolean meta_sync_ring_after_frame (void);
|
||||
gboolean meta_sync_ring_insert_wait (void);
|
||||
void meta_sync_ring_handle_event (XSyncAlarmNotifyEvent *event);
|
||||
|
||||
#endif /* _META_SYNC_RING_H_ */
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "meta-surface-actor.h"
|
||||
#include "meta-surface-actor-x11.h"
|
||||
#include "meta-surface-actor-wayland.h"
|
||||
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
|
||||
@@ -549,6 +550,16 @@ meta_window_actor_get_shape_bounds (MetaWindowActor *self,
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
cairo_region_get_extents (priv->shape_region, bounds);
|
||||
|
||||
if (META_IS_SURFACE_ACTOR_WAYLAND (priv->surface))
|
||||
{
|
||||
double scale = priv->surface ?
|
||||
meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND (priv->surface)) : 1.;
|
||||
bounds->x *= scale;
|
||||
bounds->y *= scale;
|
||||
bounds->width *= scale;
|
||||
bounds->height *= scale;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -121,7 +121,7 @@ meta_region_builder_finish (MetaRegionBuilder *builder)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* MetaRegionIterator */
|
||||
|
||||
@@ -171,7 +171,7 @@ meta_region_iterator_next (MetaRegionIterator *iter)
|
||||
iter->line_end = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_expanded_rect (MetaRegionBuilder *builder,
|
||||
int x,
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
/* Mutter visual bell */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2002 Sun Microsystems Inc.
|
||||
* Copyright (C) 2005, 2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -15,7 +15,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -71,7 +71,7 @@
|
||||
*/
|
||||
#ifdef HAVE_XKB
|
||||
static void
|
||||
bell_flash_fullscreen (MetaDisplay *display,
|
||||
bell_flash_fullscreen (MetaDisplay *display,
|
||||
XkbAnyEvent *xkb_ev)
|
||||
{
|
||||
g_assert (xkb_ev->xkb_type == XkbBellNotify);
|
||||
@@ -96,7 +96,7 @@ bell_flash_fullscreen (MetaDisplay *display,
|
||||
* Bug: This is the parallel to bell_flash_window_frame(), so it should
|
||||
* really be called meta_bell_unflash_window_frame().
|
||||
*/
|
||||
static gboolean
|
||||
static gboolean
|
||||
bell_unflash_frame (gpointer data)
|
||||
{
|
||||
MetaFrame *frame = (MetaFrame *) data;
|
||||
@@ -143,12 +143,12 @@ bell_flash_window_frame (MetaWindow *window)
|
||||
* flashes the screen.
|
||||
*/
|
||||
static void
|
||||
bell_flash_frame (MetaDisplay *display,
|
||||
bell_flash_frame (MetaDisplay *display,
|
||||
XkbAnyEvent *xkb_ev)
|
||||
{
|
||||
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))
|
||||
@@ -180,10 +180,10 @@ bell_flash_frame (MetaDisplay *display,
|
||||
* Bug: This should be merged with meta_bell_notify().
|
||||
*/
|
||||
static void
|
||||
bell_visual_notify (MetaDisplay *display,
|
||||
bell_visual_notify (MetaDisplay *display,
|
||||
XkbAnyEvent *xkb_ev)
|
||||
{
|
||||
switch (meta_prefs_get_visual_bell_type ())
|
||||
switch (meta_prefs_get_visual_bell_type ())
|
||||
{
|
||||
case G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH:
|
||||
bell_flash_fullscreen (display, xkb_ev);
|
||||
@@ -195,7 +195,7 @@ bell_visual_notify (MetaDisplay *display,
|
||||
}
|
||||
|
||||
void
|
||||
meta_bell_notify (MetaDisplay *display,
|
||||
meta_bell_notify (MetaDisplay *display,
|
||||
XkbAnyEvent *xkb_ev)
|
||||
{
|
||||
/* flash something */
|
||||
@@ -271,19 +271,19 @@ meta_bell_init (MetaDisplay *display)
|
||||
#ifdef HAVE_XKB
|
||||
int xkb_base_error_type, xkb_opcode;
|
||||
|
||||
if (!XkbQueryExtension (display->xdisplay, &xkb_opcode,
|
||||
&display->xkb_base_event_type,
|
||||
&xkb_base_error_type,
|
||||
if (!XkbQueryExtension (display->xdisplay, &xkb_opcode,
|
||||
&display->xkb_base_event_type,
|
||||
&xkb_base_error_type,
|
||||
NULL, NULL))
|
||||
{
|
||||
display->xkb_base_event_type = -1;
|
||||
g_message ("could not find XKB extension.");
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
unsigned int mask = XkbBellNotifyMask;
|
||||
gboolean visual_bell_auto_reset = FALSE;
|
||||
gboolean visual_bell_auto_reset = FALSE;
|
||||
/* TRUE if and when non-broken version is available */
|
||||
XkbSelectEvents (display->xdisplay,
|
||||
XkbUseCoreKbd,
|
||||
@@ -326,6 +326,6 @@ meta_bell_shutdown (MetaDisplay *display)
|
||||
void
|
||||
meta_bell_notify_frame_destroy (MetaFrame *frame)
|
||||
{
|
||||
if (frame->is_flashing)
|
||||
if (frame->is_flashing)
|
||||
g_source_remove_by_funcs_user_data (&g_timeout_funcs, frame);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2002 Sun Microsystems Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -12,7 +12,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -28,7 +28,7 @@
|
||||
/**
|
||||
* meta_bell_notify:
|
||||
* @display: The display the bell event came in on
|
||||
* @xkb_ev: The bell event we just received
|
||||
* @xkb_ev: The bell event we just received
|
||||
*
|
||||
* Gives the user some kind of visual bell; in fact, this is our response
|
||||
* to any kind of bell request, but we set it up so that we only get
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
/* Simple box operations */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2005, 2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -43,7 +43,7 @@ typedef enum
|
||||
* region_to_string: (RECT_LENGTH+strlen(separator_string)) *
|
||||
* g_list_length (region)
|
||||
* edge_to_string: EDGE_LENGTH
|
||||
* edge_list_to_...: (EDGE_LENGTH+strlen(separator_string)) *
|
||||
* edge_list_to_...: (EDGE_LENGTH+strlen(separator_string)) *
|
||||
* g_list_length (edge_list)
|
||||
*/
|
||||
#define RECT_LENGTH 27
|
||||
@@ -181,7 +181,7 @@ void meta_rectangle_find_linepoint_closest_to_point (double x1, double y1,
|
||||
/* Return whether an edge overlaps or is adjacent to the rectangle in the
|
||||
* nonzero-width dimension of the edge.
|
||||
*/
|
||||
gboolean meta_rectangle_edge_aligns (const MetaRectangle *rect,
|
||||
gboolean meta_rectangle_edge_aligns (const MetaRectangle *rect,
|
||||
const MetaEdge *edge);
|
||||
|
||||
/* Compare two edges, so that sorting functions can put a list of edges in
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
* @Short_Description: Simple box operations
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2005, 2006 Elijah Newren
|
||||
* [meta_rectangle_intersect() is copyright the GTK+ Team according to Havoc,
|
||||
* see gdkrectangle.c. As far as Havoc knows, he probably wrote
|
||||
* meta_rectangle_equal(), and I'm guessing it's (C) Red Hat. So...]
|
||||
* Copyright (C) 1995-2000 GTK+ Team
|
||||
* Copyright (C) 2002 Red Hat, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -23,7 +23,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -69,7 +69,7 @@ meta_rectangle_to_string (const MetaRectangle *rect,
|
||||
* Should be more than enough space. Note that of this space, the
|
||||
* trailing \0 will be overwritten for all but the last rectangle.
|
||||
*/
|
||||
g_snprintf (output, RECT_LENGTH, "%d,%d +%d,%d",
|
||||
g_snprintf (output, RECT_LENGTH, "%d,%d +%d,%d",
|
||||
rect->x, rect->y, rect->width, rect->height);
|
||||
|
||||
return output;
|
||||
@@ -96,7 +96,7 @@ meta_rectangle_region_to_string (GList *region,
|
||||
while (tmp)
|
||||
{
|
||||
MetaRectangle *rect = tmp->data;
|
||||
g_snprintf (rect_string, RECT_LENGTH, "[%d,%d +%d,%d]",
|
||||
g_snprintf (rect_string, RECT_LENGTH, "[%d,%d +%d,%d]",
|
||||
rect->x, rect->y, rect->width, rect->height);
|
||||
cur = g_stpcpy (cur, rect_string);
|
||||
tmp = tmp->next;
|
||||
@@ -118,7 +118,7 @@ meta_rectangle_edge_to_string (const MetaEdge *edge,
|
||||
* Plus 2 for parenthesis, 4 for 2 more numbers, 2 more commas, and
|
||||
* 2 more spaces, for a total of 10 more.
|
||||
*/
|
||||
g_snprintf (output, EDGE_LENGTH, "[%d,%d +%d,%d], %2d, %2d",
|
||||
g_snprintf (output, EDGE_LENGTH, "[%d,%d +%d,%d], %2d, %2d",
|
||||
edge->rect.x, edge->rect.y, edge->rect.width, edge->rect.height,
|
||||
edge->side_type, edge->edge_type);
|
||||
|
||||
@@ -150,7 +150,7 @@ meta_rectangle_edge_list_to_string (GList *edge_list,
|
||||
{
|
||||
MetaEdge *edge = tmp->data;
|
||||
MetaRectangle *rect = &edge->rect;
|
||||
g_snprintf (rect_string, EDGE_LENGTH, "([%d,%d +%d,%d], %2d, %2d)",
|
||||
g_snprintf (rect_string, EDGE_LENGTH, "([%d,%d +%d,%d], %2d, %2d)",
|
||||
rect->x, rect->y, rect->width, rect->height,
|
||||
edge->side_type, edge->edge_type);
|
||||
cur = g_stpcpy (cur, rect_string);
|
||||
@@ -210,7 +210,7 @@ meta_rectangle_intersect (const MetaRectangle *src1,
|
||||
dest_y = MAX (src1->y, src2->y);
|
||||
dest_w = MIN (src1->x + src1->width, src2->x + src2->width) - dest_x;
|
||||
dest_h = MIN (src1->y + src1->height, src2->y + src2->height) - dest_y;
|
||||
|
||||
|
||||
if (dest_w > 0 && dest_h > 0)
|
||||
{
|
||||
dest->x = dest_x;
|
||||
@@ -320,7 +320,7 @@ gboolean
|
||||
meta_rectangle_contains_rect (const MetaRectangle *outer_rect,
|
||||
const MetaRectangle *inner_rect)
|
||||
{
|
||||
return
|
||||
return
|
||||
inner_rect->x >= outer_rect->x &&
|
||||
inner_rect->y >= outer_rect->y &&
|
||||
inner_rect->x + inner_rect->width <= outer_rect->x + outer_rect->width &&
|
||||
@@ -339,7 +339,7 @@ meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect,
|
||||
* boxes.h has a good comment, but I'm not sure if the below info is also
|
||||
* helpful on top of that (or whether it has superfluous info).
|
||||
*/
|
||||
|
||||
|
||||
/* These formulas may look overly simplistic at first but you can work
|
||||
* everything out with a left_frame_with, right_frame_width,
|
||||
* border_width, and old and new client area widths (instead of old total
|
||||
@@ -389,7 +389,7 @@ meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect,
|
||||
break;
|
||||
}
|
||||
rect->width = new_width;
|
||||
|
||||
|
||||
/* Next, the y direction */
|
||||
switch (gravity)
|
||||
{
|
||||
@@ -629,7 +629,7 @@ meta_rectangle_get_minimal_spanning_set_for_region (
|
||||
|
||||
for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next)
|
||||
{
|
||||
GList *rect_iter;
|
||||
GList *rect_iter;
|
||||
MetaRectangle *strut_rect = &((MetaStrut*)strut_iter->data)->rect;
|
||||
|
||||
tmp_list = ret;
|
||||
@@ -764,7 +764,7 @@ meta_rectangle_expand_to_avoiding_struts (MetaRectangle *rect,
|
||||
*/
|
||||
g_assert ((direction == META_DIRECTION_HORIZONTAL) ^
|
||||
(direction == META_DIRECTION_VERTICAL ));
|
||||
|
||||
|
||||
if (direction == META_DIRECTION_HORIZONTAL)
|
||||
{
|
||||
rect->x = expand_to->x;
|
||||
@@ -776,12 +776,12 @@ meta_rectangle_expand_to_avoiding_struts (MetaRectangle *rect,
|
||||
rect->height = expand_to->height;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Run over all struts */
|
||||
for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next)
|
||||
{
|
||||
MetaStrut *strut = (MetaStrut*) strut_iter->data;
|
||||
|
||||
|
||||
/* Skip struts that don't overlap */
|
||||
if (!meta_rectangle_overlap (&strut->rect, rect))
|
||||
continue;
|
||||
@@ -822,7 +822,7 @@ meta_rectangle_expand_to_avoiding_struts (MetaRectangle *rect,
|
||||
void
|
||||
meta_rectangle_free_list_and_elements (GList *filled_list)
|
||||
{
|
||||
g_list_foreach (filled_list,
|
||||
g_list_foreach (filled_list,
|
||||
(void (*)(gpointer,gpointer))&g_free, /* ew, for ugly */
|
||||
NULL);
|
||||
g_list_free (filled_list);
|
||||
@@ -900,20 +900,20 @@ meta_rectangle_clamp_to_fit_into_region (const GList *spanning_rects,
|
||||
{
|
||||
MetaRectangle *compare_rect = temp->data;
|
||||
int maximal_overlap_amount_for_compare;
|
||||
|
||||
|
||||
/* If x is fixed and the entire width of rect doesn't fit in compare,
|
||||
* skip this rectangle.
|
||||
*/
|
||||
if ((fixed_directions & FIXED_DIRECTION_X) &&
|
||||
(compare_rect->x > rect->x ||
|
||||
(compare_rect->x > rect->x ||
|
||||
compare_rect->x + compare_rect->width < rect->x + rect->width))
|
||||
continue;
|
||||
|
||||
|
||||
/* If y is fixed and the entire height of rect doesn't fit in compare,
|
||||
* skip this rectangle.
|
||||
*/
|
||||
if ((fixed_directions & FIXED_DIRECTION_Y) &&
|
||||
(compare_rect->y > rect->y ||
|
||||
(compare_rect->y > rect->y ||
|
||||
compare_rect->y + compare_rect->height < rect->y + rect->height))
|
||||
continue;
|
||||
|
||||
@@ -970,20 +970,20 @@ meta_rectangle_clip_to_region (const GList *spanning_rects,
|
||||
MetaRectangle *compare_rect = temp->data;
|
||||
MetaRectangle overlap;
|
||||
int maximal_overlap_amount_for_compare;
|
||||
|
||||
|
||||
/* If x is fixed and the entire width of rect doesn't fit in compare,
|
||||
* skip the rectangle.
|
||||
*/
|
||||
if ((fixed_directions & FIXED_DIRECTION_X) &&
|
||||
(compare_rect->x > rect->x ||
|
||||
(compare_rect->x > rect->x ||
|
||||
compare_rect->x + compare_rect->width < rect->x + rect->width))
|
||||
continue;
|
||||
|
||||
|
||||
/* If y is fixed and the entire height of rect doesn't fit in compare,
|
||||
* skip the rectangle.
|
||||
*/
|
||||
if ((fixed_directions & FIXED_DIRECTION_Y) &&
|
||||
(compare_rect->y > rect->y ||
|
||||
(compare_rect->y > rect->y ||
|
||||
compare_rect->y + compare_rect->height < rect->y + rect->height))
|
||||
continue;
|
||||
|
||||
@@ -1043,26 +1043,26 @@ meta_rectangle_shove_into_region (const GList *spanning_rects,
|
||||
/* First, find best rectangle from spanning_rects to which we will shove
|
||||
* rect into.
|
||||
*/
|
||||
|
||||
|
||||
for (temp = spanning_rects; temp; temp = temp->next)
|
||||
{
|
||||
MetaRectangle *compare_rect = temp->data;
|
||||
int maximal_overlap_amount_for_compare;
|
||||
int dist_to_compare;
|
||||
|
||||
|
||||
/* If x is fixed and the entire width of rect doesn't fit in compare,
|
||||
* skip this rectangle.
|
||||
*/
|
||||
if ((fixed_directions & FIXED_DIRECTION_X) &&
|
||||
(compare_rect->x > rect->x ||
|
||||
(compare_rect->x > rect->x ||
|
||||
compare_rect->x + compare_rect->width < rect->x + rect->width))
|
||||
continue;
|
||||
|
||||
|
||||
/* If y is fixed and the entire height of rect doesn't fit in compare,
|
||||
* skip this rectangle.
|
||||
*/
|
||||
if ((fixed_directions & FIXED_DIRECTION_Y) &&
|
||||
(compare_rect->y > rect->y ||
|
||||
(compare_rect->y > rect->y ||
|
||||
compare_rect->y + compare_rect->height < rect->y + rect->height))
|
||||
continue;
|
||||
|
||||
@@ -1218,7 +1218,7 @@ meta_rectangle_edge_aligns (const MetaRectangle *rect, const MetaEdge *edge)
|
||||
}
|
||||
|
||||
static GList*
|
||||
get_rect_minus_overlap (const GList *rect_in_list,
|
||||
get_rect_minus_overlap (const GList *rect_in_list,
|
||||
MetaRectangle *overlap)
|
||||
{
|
||||
MetaRectangle *temp;
|
||||
@@ -1263,7 +1263,7 @@ get_rect_minus_overlap (const GList *rect_in_list,
|
||||
}
|
||||
|
||||
static GList*
|
||||
replace_rect_with_list (GList *old_element,
|
||||
replace_rect_with_list (GList *old_element,
|
||||
GList *new_list)
|
||||
{
|
||||
GList *ret;
|
||||
@@ -1475,7 +1475,7 @@ rectangle_and_edge_intersection (const MetaRectangle *rect,
|
||||
overlap->edge_type = -1;
|
||||
overlap->side_type = -1;
|
||||
|
||||
/* Figure out what the intersection is */
|
||||
/* Figure out what the intersection is */
|
||||
result->x = MAX (rect->x, rect2->x);
|
||||
result->y = MAX (rect->y, rect2->y);
|
||||
result->width = MIN (BOX_RIGHT (*rect), BOX_RIGHT (*rect2)) - result->x;
|
||||
@@ -1546,7 +1546,7 @@ rectangle_and_edge_intersection (const MetaRectangle *rect,
|
||||
* TOP<->BOTTOM).
|
||||
*/
|
||||
static GList*
|
||||
add_edges (GList *cur_edges,
|
||||
add_edges (GList *cur_edges,
|
||||
const MetaRectangle *rect,
|
||||
gboolean rect_is_internal)
|
||||
{
|
||||
@@ -1560,23 +1560,23 @@ add_edges (GList *cur_edges,
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
temp_edge->side_type =
|
||||
temp_edge->side_type =
|
||||
rect_is_internal ? META_SIDE_LEFT : META_SIDE_RIGHT;
|
||||
temp_edge->rect.width = 0;
|
||||
break;
|
||||
case 1:
|
||||
temp_edge->side_type =
|
||||
temp_edge->side_type =
|
||||
rect_is_internal ? META_SIDE_RIGHT : META_SIDE_LEFT;
|
||||
temp_edge->rect.x += temp_edge->rect.width;
|
||||
temp_edge->rect.width = 0;
|
||||
break;
|
||||
case 2:
|
||||
temp_edge->side_type =
|
||||
temp_edge->side_type =
|
||||
rect_is_internal ? META_SIDE_TOP : META_SIDE_BOTTOM;
|
||||
temp_edge->rect.height = 0;
|
||||
break;
|
||||
case 3:
|
||||
temp_edge->side_type =
|
||||
temp_edge->side_type =
|
||||
rect_is_internal ? META_SIDE_BOTTOM : META_SIDE_TOP;
|
||||
temp_edge->rect.y += temp_edge->rect.height;
|
||||
temp_edge->rect.height = 0;
|
||||
@@ -1593,8 +1593,8 @@ add_edges (GList *cur_edges,
|
||||
* edges to cur_list. Return cur_list when finished.
|
||||
*/
|
||||
static GList*
|
||||
split_edge (GList *cur_list,
|
||||
const MetaEdge *old_edge,
|
||||
split_edge (GList *cur_list,
|
||||
const MetaEdge *old_edge,
|
||||
const MetaEdge *remove)
|
||||
{
|
||||
MetaEdge *temp_edge;
|
||||
@@ -1653,7 +1653,7 @@ split_edge (GList *cur_list,
|
||||
* if and how rect and edge intersect.
|
||||
*/
|
||||
static void
|
||||
fix_up_edges (MetaRectangle *rect, MetaEdge *edge,
|
||||
fix_up_edges (MetaRectangle *rect, MetaEdge *edge,
|
||||
GList **strut_edges, GList **edge_splits,
|
||||
gboolean *edge_needs_removal)
|
||||
{
|
||||
@@ -1777,7 +1777,7 @@ meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect,
|
||||
{
|
||||
GList *ret;
|
||||
GList *fixed_strut_rects;
|
||||
GList *edge_iter;
|
||||
GList *edge_iter;
|
||||
const GList *strut_rect_iter;
|
||||
|
||||
/* The algorithm is basically as follows:
|
||||
@@ -1817,7 +1817,7 @@ meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect,
|
||||
GList *splits_of_cur_edge = NULL;
|
||||
gboolean edge_needs_removal = FALSE;
|
||||
|
||||
fix_up_edges (strut_rect, cur_edge,
|
||||
fix_up_edges (strut_rect, cur_edge,
|
||||
&new_strut_edges, &splits_of_cur_edge,
|
||||
&edge_needs_removal);
|
||||
|
||||
@@ -1981,7 +1981,7 @@ meta_rectangle_find_nonintersected_monitor_edges (
|
||||
for (; all_struts; all_struts = all_struts->next)
|
||||
temp_rects = g_slist_prepend (temp_rects,
|
||||
&((MetaStrut*)all_struts->data)->rect);
|
||||
ret = meta_rectangle_remove_intersections_with_boxes_from_edges (ret,
|
||||
ret = meta_rectangle_remove_intersections_with_boxes_from_edges (ret,
|
||||
temp_rects);
|
||||
g_slist_free (temp_rects);
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
// "constrain_whatever".
|
||||
// 3) Add your function to the all_constraints and all_constraint_names
|
||||
// arrays (the latter of which is for debugging purposes)
|
||||
//
|
||||
//
|
||||
// An example constraint function, constrain_whatever:
|
||||
//
|
||||
// /* constrain_whatever does the following:
|
||||
@@ -246,7 +246,7 @@ do_all_constraints (MetaWindow *window,
|
||||
/* Log how the constraint modified the position */
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"info->current is %d,%d +%d,%d after %s\n",
|
||||
info->current.x, info->current.y,
|
||||
info->current.x, info->current.y,
|
||||
info->current.width, info->current.height,
|
||||
constraint->name);
|
||||
}
|
||||
@@ -275,11 +275,6 @@ meta_window_constrain (MetaWindow *window,
|
||||
ConstraintPriority priority = PRIORITY_MINIMUM;
|
||||
gboolean satisfied = FALSE;
|
||||
|
||||
/* WARNING: orig and new specify positions and sizes of the inner window,
|
||||
* not the outer. This is a common gotcha since half the constraints
|
||||
* deal with inner window position/size and half deal with outer. See
|
||||
* doc/how-constraints-works.txt for more information.
|
||||
*/
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Constraining %s in move from %d,%d %dx%d to %d,%d %dx%d\n",
|
||||
window->desc,
|
||||
@@ -287,7 +282,7 @@ meta_window_constrain (MetaWindow *window,
|
||||
new->x, new->y, new->width, new->height);
|
||||
|
||||
setup_constraint_info (&info,
|
||||
window,
|
||||
window,
|
||||
flags,
|
||||
resize_gravity,
|
||||
orig,
|
||||
@@ -300,7 +295,7 @@ meta_window_constrain (MetaWindow *window,
|
||||
/* Individually enforce all the high-enough priority constraints */
|
||||
do_all_constraints (window, &info, priority, !check_only);
|
||||
|
||||
/* Check if all high-enough priority constraints are simultaneously
|
||||
/* Check if all high-enough priority constraints are simultaneously
|
||||
* satisfied
|
||||
*/
|
||||
satisfied = do_all_constraints (window, &info, priority, check_only);
|
||||
@@ -403,10 +398,10 @@ setup_constraint_info (ConstraintInfo *info,
|
||||
}
|
||||
|
||||
cur_workspace = window->screen->active_workspace;
|
||||
info->usable_screen_region =
|
||||
info->usable_screen_region =
|
||||
meta_workspace_get_onscreen_region (cur_workspace);
|
||||
info->usable_monitor_region =
|
||||
meta_workspace_get_onmonitor_region (cur_workspace,
|
||||
info->usable_monitor_region =
|
||||
meta_workspace_get_onmonitor_region (cur_workspace,
|
||||
monitor_info->number);
|
||||
|
||||
/* Workaround braindead legacy apps that don't know how to
|
||||
@@ -446,7 +441,7 @@ setup_constraint_info (ConstraintInfo *info,
|
||||
" work_area_monitor: %d,%d +%d,%d\n"
|
||||
" entire_monitor : %d,%d +%d,%d\n",
|
||||
info->orig.x, info->orig.y, info->orig.width, info->orig.height,
|
||||
info->current.x, info->current.y,
|
||||
info->current.x, info->current.y,
|
||||
info->current.width, info->current.height,
|
||||
(info->action_type == ACTION_MOVE) ? "Move" :
|
||||
(info->action_type == ACTION_RESIZE) ? "Resize" :
|
||||
@@ -459,7 +454,7 @@ setup_constraint_info (ConstraintInfo *info,
|
||||
(info->fixed_directions == FIXED_DIRECTION_Y) ? "Y fixed" :
|
||||
"Freakin' Invalid Stupid",
|
||||
info->work_area_monitor.x, info->work_area_monitor.y,
|
||||
info->work_area_monitor.width,
|
||||
info->work_area_monitor.width,
|
||||
info->work_area_monitor.height,
|
||||
info->entire_monitor.x, info->entire_monitor.y,
|
||||
info->entire_monitor.width, info->entire_monitor.height);
|
||||
@@ -507,12 +502,10 @@ place_window_if_needed(MetaWindow *window,
|
||||
monitor_info->number,
|
||||
&info->work_area_monitor);
|
||||
cur_workspace = window->screen->active_workspace;
|
||||
info->usable_monitor_region =
|
||||
meta_workspace_get_onmonitor_region (cur_workspace,
|
||||
info->usable_monitor_region =
|
||||
meta_workspace_get_onmonitor_region (cur_workspace,
|
||||
monitor_info->number);
|
||||
|
||||
meta_window_frame_rect_to_client_rect (window, &placed_rect, &placed_rect);
|
||||
|
||||
info->current.x = placed_rect.x;
|
||||
info->current.y = placed_rect.y;
|
||||
|
||||
@@ -544,14 +537,14 @@ place_window_if_needed(MetaWindow *window,
|
||||
.083 * info->work_area_monitor.height;
|
||||
}
|
||||
|
||||
/* idle_move_resize() uses the user_rect, so make sure it uses the
|
||||
* placed coordinates (bug #556696).
|
||||
/* idle_move_resize() uses the unconstrained_rect, so make sure it
|
||||
* uses the placed coordinates (bug #556696).
|
||||
*/
|
||||
window->user_rect = info->current;
|
||||
window->unconstrained_rect = info->current;
|
||||
|
||||
if (window->maximize_horizontally_after_placement ||
|
||||
window->maximize_vertically_after_placement)
|
||||
meta_window_maximize_internal (window,
|
||||
meta_window_maximize_internal (window,
|
||||
(window->maximize_horizontally_after_placement ?
|
||||
META_MAXIMIZE_HORIZONTAL : 0 ) |
|
||||
(window->maximize_vertically_after_placement ?
|
||||
@@ -636,7 +629,7 @@ update_onscreen_requirements (MetaWindow *window,
|
||||
if (old ^ window->require_on_single_monitor)
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"require_on_single_monitor for %s toggled to %s\n",
|
||||
window->desc,
|
||||
window->desc,
|
||||
window->require_on_single_monitor ? "TRUE" : "FALSE");
|
||||
|
||||
/* Update whether we want future constraint runs to require the
|
||||
@@ -644,13 +637,10 @@ update_onscreen_requirements (MetaWindow *window,
|
||||
*/
|
||||
if (window->frame && window->decorated)
|
||||
{
|
||||
MetaFrameBorders borders;
|
||||
MetaRectangle titlebar_rect;
|
||||
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
meta_window_get_titlebar_rect (window, &titlebar_rect);
|
||||
|
||||
titlebar_rect = info->current;
|
||||
titlebar_rect.height = borders.visible.top;
|
||||
old = window->require_titlebar_visible;
|
||||
window->require_titlebar_visible =
|
||||
meta_rectangle_overlaps_with_region (info->usable_screen_region,
|
||||
@@ -910,38 +900,41 @@ constrain_size_increments (MetaWindow *window,
|
||||
int new_width, new_height;
|
||||
gboolean constraint_already_satisfied;
|
||||
MetaRectangle *start_rect;
|
||||
MetaRectangle client_rect;
|
||||
|
||||
if (priority > PRIORITY_SIZE_HINTS_INCREMENTS)
|
||||
return TRUE;
|
||||
|
||||
/* Determine whether constraint applies; exit if it doesn't */
|
||||
if (META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
|
||||
if (META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
|
||||
META_WINDOW_TILED_SIDE_BY_SIDE (window) ||
|
||||
info->action_type == ACTION_MOVE)
|
||||
return TRUE;
|
||||
|
||||
meta_window_frame_rect_to_client_rect (window, &info->current, &client_rect);
|
||||
|
||||
/* Determine whether constraint is already satisfied; exit if it is */
|
||||
bh = window->size_hints.base_height;
|
||||
hi = window->size_hints.height_inc;
|
||||
bw = window->size_hints.base_width;
|
||||
wi = window->size_hints.width_inc;
|
||||
extra_height = (info->current.height - bh) % hi;
|
||||
extra_width = (info->current.width - bw) % wi;
|
||||
extra_height = (client_rect.height - bh) % hi;
|
||||
extra_width = (client_rect.width - bw) % wi;
|
||||
/* ignore size increments for maximized windows */
|
||||
if (window->maximized_horizontally)
|
||||
extra_width *= 0;
|
||||
if (window->maximized_vertically)
|
||||
extra_height *= 0;
|
||||
/* constraint is satisfied iff there is no extra height or width */
|
||||
constraint_already_satisfied =
|
||||
constraint_already_satisfied =
|
||||
(extra_height == 0 && extra_width == 0);
|
||||
|
||||
if (check_only || constraint_already_satisfied)
|
||||
return constraint_already_satisfied;
|
||||
|
||||
/*** Enforce constraint ***/
|
||||
new_width = info->current.width - extra_width;
|
||||
new_height = info->current.height - extra_height;
|
||||
new_width = client_rect.width - extra_width;
|
||||
new_height = client_rect.height - extra_height;
|
||||
|
||||
/* Adjusting down instead of up (as done in the above two lines) may
|
||||
* violate minimum size constraints; fix the adjustment if this
|
||||
@@ -952,6 +945,14 @@ constrain_size_increments (MetaWindow *window,
|
||||
if (new_height < window->size_hints.min_height)
|
||||
new_height += ((window->size_hints.min_height - new_height)/hi + 1)*hi;
|
||||
|
||||
{
|
||||
client_rect.width = new_width;
|
||||
client_rect.height = new_height;
|
||||
meta_window_client_rect_to_frame_rect (window, &client_rect, &client_rect);
|
||||
new_width = client_rect.width;
|
||||
new_height = client_rect.height;
|
||||
}
|
||||
|
||||
/* Figure out what original rect to pass to meta_rectangle_resize_with_gravity
|
||||
* See bug 448183
|
||||
*/
|
||||
@@ -959,10 +960,10 @@ constrain_size_increments (MetaWindow *window,
|
||||
start_rect = &info->current;
|
||||
else
|
||||
start_rect = &info->orig;
|
||||
|
||||
|
||||
/* Resize to the new size */
|
||||
meta_rectangle_resize_with_gravity (start_rect,
|
||||
&info->current,
|
||||
&info->current,
|
||||
info->resize_gravity,
|
||||
new_width,
|
||||
new_height);
|
||||
@@ -1007,7 +1008,7 @@ constrain_size_limits (MetaWindow *window,
|
||||
/*** Enforce constraint ***/
|
||||
new_width = CLAMP (info->current.width, min_size.width, max_size.width);
|
||||
new_height = CLAMP (info->current.height, min_size.height, max_size.height);
|
||||
|
||||
|
||||
/* Figure out what original rect to pass to meta_rectangle_resize_with_gravity
|
||||
* See bug 448183
|
||||
*/
|
||||
@@ -1015,9 +1016,9 @@ constrain_size_limits (MetaWindow *window,
|
||||
start_rect = &info->current;
|
||||
else
|
||||
start_rect = &info->orig;
|
||||
|
||||
|
||||
meta_rectangle_resize_with_gravity (start_rect,
|
||||
&info->current,
|
||||
&info->current,
|
||||
info->resize_gravity,
|
||||
new_width,
|
||||
new_height);
|
||||
@@ -1047,7 +1048,7 @@ constrain_aspect_ratio (MetaWindow *window,
|
||||
(double)window->size_hints.max_aspect.y;
|
||||
constraints_are_inconsistent = minr > maxr;
|
||||
if (constraints_are_inconsistent ||
|
||||
META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
|
||||
META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
|
||||
META_WINDOW_TILED_SIDE_BY_SIDE (window) ||
|
||||
info->action_type == ACTION_MOVE)
|
||||
return TRUE;
|
||||
@@ -1087,7 +1088,7 @@ constrain_aspect_ratio (MetaWindow *window,
|
||||
fudge = 1;
|
||||
break;
|
||||
}
|
||||
constraint_already_satisfied =
|
||||
constraint_already_satisfied =
|
||||
info->current.width - (info->current.height * minr ) > -minr*fudge &&
|
||||
info->current.width - (info->current.height * maxr ) < maxr*fudge;
|
||||
if (check_only || constraint_already_satisfied)
|
||||
@@ -1151,7 +1152,7 @@ constrain_aspect_ratio (MetaWindow *window,
|
||||
start_rect = &info->orig;
|
||||
|
||||
meta_rectangle_resize_with_gravity (start_rect,
|
||||
&info->current,
|
||||
&info->current,
|
||||
info->resize_gravity,
|
||||
new_width,
|
||||
new_height);
|
||||
@@ -1199,7 +1200,7 @@ do_screen_and_monitor_relative_constraints (
|
||||
exit_early = TRUE;
|
||||
|
||||
/* Determine whether constraint is already satisfied; exit if it is */
|
||||
constraint_satisfied =
|
||||
constraint_satisfied =
|
||||
meta_rectangle_contained_in_region (region_spanning_rectangles,
|
||||
&info->current);
|
||||
if (exit_early || constraint_satisfied || check_only)
|
||||
@@ -1238,7 +1239,7 @@ constrain_to_single_monitor (MetaWindow *window,
|
||||
return TRUE;
|
||||
|
||||
/* Exit early if we know the constraint won't apply--note that this constraint
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* "onscreen" by their own strut) and we can't apply it to frameless windows
|
||||
* or else users will be unable to move windows such as XMMS across monitors.
|
||||
*/
|
||||
@@ -1251,7 +1252,7 @@ constrain_to_single_monitor (MetaWindow *window,
|
||||
return TRUE;
|
||||
|
||||
/* Have a helper function handle the constraint for us */
|
||||
return do_screen_and_monitor_relative_constraints (window,
|
||||
return do_screen_and_monitor_relative_constraints (window,
|
||||
info->usable_monitor_region,
|
||||
info,
|
||||
check_only);
|
||||
@@ -1267,18 +1268,18 @@ constrain_fully_onscreen (MetaWindow *window,
|
||||
return TRUE;
|
||||
|
||||
/* Exit early if we know the constraint won't apply--note that this constraint
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* "onscreen" by their own strut).
|
||||
*/
|
||||
if (window->type == META_WINDOW_DESKTOP ||
|
||||
window->type == META_WINDOW_DOCK ||
|
||||
window->fullscreen ||
|
||||
!window->require_fully_onscreen ||
|
||||
!window->require_fully_onscreen ||
|
||||
info->is_user_action)
|
||||
return TRUE;
|
||||
|
||||
/* Have a helper function handle the constraint for us */
|
||||
return do_screen_and_monitor_relative_constraints (window,
|
||||
return do_screen_and_monitor_relative_constraints (window,
|
||||
info->usable_screen_region,
|
||||
info,
|
||||
check_only);
|
||||
@@ -1306,7 +1307,7 @@ constrain_titlebar_visible (MetaWindow *window,
|
||||
info->is_user_action && !window->display->grab_frame_action;
|
||||
|
||||
/* Exit early if we know the constraint won't apply--note that this constraint
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* "onscreen" by their own strut).
|
||||
*/
|
||||
if (window->type == META_WINDOW_DESKTOP ||
|
||||
@@ -1350,13 +1351,13 @@ constrain_titlebar_visible (MetaWindow *window,
|
||||
*/
|
||||
meta_rectangle_expand_region_conditionally (info->usable_screen_region,
|
||||
horiz_amount_offscreen,
|
||||
horiz_amount_offscreen,
|
||||
horiz_amount_offscreen,
|
||||
0, /* Don't let titlebar off */
|
||||
bottom_amount,
|
||||
horiz_amount_onscreen,
|
||||
vert_amount_onscreen);
|
||||
retval =
|
||||
do_screen_and_monitor_relative_constraints (window,
|
||||
do_screen_and_monitor_relative_constraints (window,
|
||||
info->usable_screen_region,
|
||||
info,
|
||||
check_only);
|
||||
@@ -1386,7 +1387,7 @@ constrain_partially_onscreen (MetaWindow *window,
|
||||
return TRUE;
|
||||
|
||||
/* Exit early if we know the constraint won't apply--note that this constraint
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* "onscreen" by their own strut).
|
||||
*/
|
||||
if (window->type == META_WINDOW_DESKTOP ||
|
||||
@@ -1428,13 +1429,13 @@ constrain_partially_onscreen (MetaWindow *window,
|
||||
*/
|
||||
meta_rectangle_expand_region_conditionally (info->usable_screen_region,
|
||||
horiz_amount_offscreen,
|
||||
horiz_amount_offscreen,
|
||||
horiz_amount_offscreen,
|
||||
top_amount,
|
||||
bottom_amount,
|
||||
horiz_amount_onscreen,
|
||||
vert_amount_onscreen);
|
||||
retval =
|
||||
do_screen_and_monitor_relative_constraints (window,
|
||||
do_screen_and_monitor_relative_constraints (window,
|
||||
info->usable_screen_region,
|
||||
info,
|
||||
check_only);
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
/* Mutter size/position constraints */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2002 Red Hat, Inc.
|
||||
* Copyright (C) 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -15,7 +15,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
316
src/core/core.c
316
src/core/core.c
@@ -2,11 +2,11 @@
|
||||
|
||||
/* Mutter interface used by GTK+ UI to talk to core */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -16,7 +16,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -29,6 +29,9 @@
|
||||
#include <meta/errors.h>
|
||||
#include "util-private.h"
|
||||
|
||||
#include "x11/window-x11.h"
|
||||
#include "x11/window-x11-private.h"
|
||||
|
||||
/* Looks up the MetaWindow representing the frame of the given X window.
|
||||
* Used as a helper function by a bunch of the functions below.
|
||||
*
|
||||
@@ -46,7 +49,7 @@ get_window (Display *xdisplay,
|
||||
{
|
||||
MetaDisplay *display;
|
||||
MetaWindow *window;
|
||||
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
window = meta_display_lookup_x_window (display, frame_xwindow);
|
||||
|
||||
@@ -69,6 +72,8 @@ meta_core_get (Display *xdisplay,
|
||||
|
||||
MetaDisplay *display = meta_display_for_x_display (xdisplay);
|
||||
MetaWindow *window = meta_display_lookup_x_window (display, xwindow);
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = window_x11->priv;
|
||||
|
||||
va_start (args, xwindow);
|
||||
|
||||
@@ -86,78 +91,53 @@ meta_core_get (Display *xdisplay,
|
||||
*/
|
||||
|
||||
if (request != META_CORE_WINDOW_HAS_FRAME &&
|
||||
(window == NULL || window->frame == NULL)) {
|
||||
meta_bug ("No such frame window 0x%lx!\n", xwindow);
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (request != META_CORE_GET_END) {
|
||||
|
||||
gpointer answer = va_arg (args, gpointer);
|
||||
|
||||
switch (request) {
|
||||
case META_CORE_WINDOW_HAS_FRAME:
|
||||
*((gboolean*)answer) = window != NULL && window->frame != NULL;
|
||||
if (!*((gboolean*)answer)) goto out; /* see above */
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_WIDTH:
|
||||
*((gint*)answer) = window->rect.width;
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_HEIGHT:
|
||||
*((gint*)answer) = window->rect.height;
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_XWINDOW:
|
||||
*((Window*)answer) = window->xwindow;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_FLAGS:
|
||||
*((MetaFrameFlags*)answer) = meta_frame_get_flags (window->frame);
|
||||
break;
|
||||
case META_CORE_GET_FRAME_TYPE:
|
||||
*((MetaFrameType*)answer) = meta_window_get_frame_type (window);
|
||||
break;
|
||||
case META_CORE_GET_MINI_ICON:
|
||||
*((GdkPixbuf**)answer) = window->mini_icon;
|
||||
break;
|
||||
case META_CORE_GET_ICON:
|
||||
*((GdkPixbuf**)answer) = window->icon;
|
||||
break;
|
||||
case META_CORE_GET_X:
|
||||
meta_window_get_position (window, (int*)answer, NULL);
|
||||
break;
|
||||
case META_CORE_GET_Y:
|
||||
meta_window_get_position (window, NULL, (int*)answer);
|
||||
break;
|
||||
case META_CORE_GET_FRAME_WORKSPACE:
|
||||
*((gint*)answer) = meta_window_get_net_wm_desktop (window);
|
||||
break;
|
||||
case META_CORE_GET_FRAME_X:
|
||||
*((gint*)answer) = window->frame->rect.x;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_Y:
|
||||
*((gint*)answer) = window->frame->rect.y;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_WIDTH:
|
||||
*((gint*)answer) = window->frame->rect.width;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_HEIGHT:
|
||||
*((gint*)answer) = window->frame->rect.height;
|
||||
break;
|
||||
case META_CORE_GET_THEME_VARIANT:
|
||||
*((char**)answer) = window->gtk_theme_variant;
|
||||
break;
|
||||
case META_CORE_GET_SCREEN_WIDTH:
|
||||
*((gint*)answer) = window->screen->rect.width;
|
||||
break;
|
||||
case META_CORE_GET_SCREEN_HEIGHT:
|
||||
*((gint*)answer) = window->screen->rect.height;
|
||||
break;
|
||||
|
||||
default:
|
||||
meta_warning("Unknown window information request: %d\n", request);
|
||||
(window == NULL || window->frame == NULL))
|
||||
{
|
||||
meta_bug ("No such frame window 0x%lx!\n", xwindow);
|
||||
goto out;
|
||||
}
|
||||
|
||||
request = va_arg (args, MetaCoreGetType);
|
||||
}
|
||||
while (request != META_CORE_GET_END)
|
||||
{
|
||||
gpointer answer = va_arg (args, gpointer);
|
||||
|
||||
switch (request)
|
||||
{
|
||||
case META_CORE_WINDOW_HAS_FRAME:
|
||||
*((gboolean*)answer) = window != NULL && window->frame != NULL;
|
||||
if (!*((gboolean*)answer)) goto out; /* see above */
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_WIDTH:
|
||||
*((gint*)answer) = priv->client_rect.width;
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_HEIGHT:
|
||||
*((gint*)answer) = priv->client_rect.height;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_FLAGS:
|
||||
*((MetaFrameFlags*)answer) = meta_frame_get_flags (window->frame);
|
||||
break;
|
||||
case META_CORE_GET_FRAME_TYPE:
|
||||
*((MetaFrameType*)answer) = meta_window_get_frame_type (window);
|
||||
break;
|
||||
case META_CORE_GET_MINI_ICON:
|
||||
*((GdkPixbuf**)answer) = window->mini_icon;
|
||||
break;
|
||||
case META_CORE_GET_ICON:
|
||||
*((GdkPixbuf**)answer) = window->icon;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_RECT:
|
||||
meta_window_get_frame_rect (window, ((MetaRectangle*)answer));
|
||||
break;
|
||||
case META_CORE_GET_THEME_VARIANT:
|
||||
*((char**)answer) = window->gtk_theme_variant;
|
||||
break;
|
||||
|
||||
default:
|
||||
meta_warning("Unknown window information request: %d\n", request);
|
||||
}
|
||||
|
||||
request = va_arg (args, MetaCoreGetType);
|
||||
}
|
||||
|
||||
out:
|
||||
va_end (args);
|
||||
@@ -173,38 +153,6 @@ meta_core_queue_frame_resize (Display *xdisplay,
|
||||
meta_window_frame_size_changed (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_user_move (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_move (window, TRUE, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_user_resize (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int gravity,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_resize_with_gravity (window, TRUE, width, height, gravity);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_user_raise (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_raise (window);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
lower_window_and_transients (MetaWindow *window,
|
||||
gpointer data)
|
||||
@@ -221,21 +169,21 @@ lower_window_and_transients (MetaWindow *window,
|
||||
* (Borrowed from window.c.)
|
||||
*/
|
||||
if (window->screen->active_workspace &&
|
||||
meta_window_located_on_workspace (window,
|
||||
meta_window_located_on_workspace (window,
|
||||
window->screen->active_workspace))
|
||||
{
|
||||
GList* link;
|
||||
link = g_list_find (window->screen->active_workspace->mru_list,
|
||||
link = g_list_find (window->screen->active_workspace->mru_list,
|
||||
window);
|
||||
g_assert (link);
|
||||
|
||||
window->screen->active_workspace->mru_list =
|
||||
window->screen->active_workspace->mru_list =
|
||||
g_list_remove_link (window->screen->active_workspace->mru_list,
|
||||
link);
|
||||
g_list_free (link);
|
||||
|
||||
window->screen->active_workspace->mru_list =
|
||||
g_list_append (window->screen->active_workspace->mru_list,
|
||||
window->screen->active_workspace->mru_list =
|
||||
g_list_append (window->screen->active_workspace->mru_list,
|
||||
window);
|
||||
}
|
||||
}
|
||||
@@ -267,7 +215,7 @@ meta_core_user_focus (Display *xdisplay,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
|
||||
meta_window_focus (window, timestamp);
|
||||
}
|
||||
|
||||
@@ -355,7 +303,7 @@ meta_core_delete (Display *xdisplay,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
|
||||
meta_window_delete (window, timestamp);
|
||||
}
|
||||
|
||||
@@ -375,7 +323,7 @@ meta_core_shade (Display *xdisplay,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
|
||||
meta_window_shade (window, timestamp);
|
||||
}
|
||||
|
||||
@@ -428,134 +376,20 @@ meta_core_change_workspace (Display *xdisplay,
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_show_window_menu (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp)
|
||||
meta_core_show_window_menu (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
MetaWindowMenuType menu,
|
||||
int root_x,
|
||||
int root_y,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
meta_window_raise (window);
|
||||
meta_window_focus (window, timestamp);
|
||||
|
||||
meta_window_show_menu (window, root_x, root_y, button, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_get_menu_accelerator (MetaMenuOp menu_op,
|
||||
int workspace,
|
||||
unsigned int *keysym,
|
||||
MetaVirtualModifier *modifiers)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = NULL;
|
||||
|
||||
switch (menu_op)
|
||||
{
|
||||
case META_MENU_OP_NONE:
|
||||
/* No keybinding for this one */
|
||||
break;
|
||||
case META_MENU_OP_DELETE:
|
||||
name = "close";
|
||||
break;
|
||||
case META_MENU_OP_MINIMIZE:
|
||||
name = "minimize";
|
||||
break;
|
||||
case META_MENU_OP_UNMAXIMIZE:
|
||||
name = "unmaximize";
|
||||
break;
|
||||
case META_MENU_OP_MAXIMIZE:
|
||||
name = "maximize";
|
||||
break;
|
||||
case META_MENU_OP_UNSHADE:
|
||||
case META_MENU_OP_SHADE:
|
||||
name = "toggle_shaded";
|
||||
break;
|
||||
case META_MENU_OP_UNSTICK:
|
||||
case META_MENU_OP_STICK:
|
||||
name = "toggle-on-all-workspaces";
|
||||
break;
|
||||
case META_MENU_OP_ABOVE:
|
||||
case META_MENU_OP_UNABOVE:
|
||||
name = "toggle-above";
|
||||
break;
|
||||
case META_MENU_OP_WORKSPACES:
|
||||
switch (workspace)
|
||||
{
|
||||
case 1:
|
||||
name = "move-to-workspace-1";
|
||||
break;
|
||||
case 2:
|
||||
name = "move-to-workspace-2";
|
||||
break;
|
||||
case 3:
|
||||
name = "move-to-workspace-3";
|
||||
break;
|
||||
case 4:
|
||||
name = "move-to-workspace-4";
|
||||
break;
|
||||
case 5:
|
||||
name = "move-to-workspace-5";
|
||||
break;
|
||||
case 6:
|
||||
name = "move-to-workspace-6";
|
||||
break;
|
||||
case 7:
|
||||
name = "move-to-workspace-7";
|
||||
break;
|
||||
case 8:
|
||||
name = "move-to-workspace-8";
|
||||
break;
|
||||
case 9:
|
||||
name = "move-to-workspace-9";
|
||||
break;
|
||||
case 10:
|
||||
name = "move-to-workspace-10";
|
||||
break;
|
||||
case 11:
|
||||
name = "move-to-workspace-11";
|
||||
break;
|
||||
case 12:
|
||||
name = "move-to-workspace-12";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case META_MENU_OP_MOVE:
|
||||
name = "begin-move";
|
||||
break;
|
||||
case META_MENU_OP_RESIZE:
|
||||
name = "begin-resize";
|
||||
break;
|
||||
case META_MENU_OP_MOVE_LEFT:
|
||||
name = "move-to-workspace-left";
|
||||
break;
|
||||
case META_MENU_OP_MOVE_RIGHT:
|
||||
name = "move-to-workspace-right";
|
||||
break;
|
||||
case META_MENU_OP_MOVE_UP:
|
||||
name = "move-to-workspace-up";
|
||||
break;
|
||||
case META_MENU_OP_MOVE_DOWN:
|
||||
name = "move-to-workspace-down";
|
||||
break;
|
||||
case META_MENU_OP_RECOVER:
|
||||
/* No keybinding for this one */
|
||||
break;
|
||||
}
|
||||
|
||||
if (name)
|
||||
{
|
||||
meta_prefs_get_window_binding (name, keysym, modifiers);
|
||||
}
|
||||
else
|
||||
{
|
||||
*keysym = 0;
|
||||
*modifiers = 0;
|
||||
}
|
||||
meta_window_show_menu (window, menu, root_x, root_y);
|
||||
}
|
||||
|
||||
const char*
|
||||
@@ -586,12 +420,12 @@ meta_core_begin_grab_op (Display *xdisplay,
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
MetaDisplay *display;
|
||||
MetaScreen *screen;
|
||||
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
screen = display->screen;
|
||||
|
||||
g_assert (screen != NULL);
|
||||
|
||||
|
||||
return meta_display_begin_grab_op (display, screen, window,
|
||||
op, pointer_already_grabbed,
|
||||
frame_action,
|
||||
@@ -604,7 +438,7 @@ meta_core_end_grab_op (Display *xdisplay,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
|
||||
meta_display_end_grab_op (display, timestamp);
|
||||
@@ -614,7 +448,7 @@ MetaGrabOp
|
||||
meta_core_get_grab_op (Display *xdisplay)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
|
||||
return display->grab_op;
|
||||
@@ -625,7 +459,7 @@ meta_core_grab_buttons (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
|
||||
meta_verbose ("Grabbing buttons on frame 0x%lx\n", frame_xwindow);
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
/* Mutter interface used by GTK+ UI to talk to core */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -15,7 +15,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -33,21 +33,12 @@ typedef enum
|
||||
META_CORE_WINDOW_HAS_FRAME,
|
||||
META_CORE_GET_CLIENT_WIDTH,
|
||||
META_CORE_GET_CLIENT_HEIGHT,
|
||||
META_CORE_GET_CLIENT_XWINDOW,
|
||||
META_CORE_GET_FRAME_FLAGS,
|
||||
META_CORE_GET_FRAME_TYPE,
|
||||
META_CORE_GET_MINI_ICON,
|
||||
META_CORE_GET_ICON,
|
||||
META_CORE_GET_X,
|
||||
META_CORE_GET_Y,
|
||||
META_CORE_GET_FRAME_WORKSPACE,
|
||||
META_CORE_GET_FRAME_X,
|
||||
META_CORE_GET_FRAME_Y,
|
||||
META_CORE_GET_FRAME_WIDTH,
|
||||
META_CORE_GET_FRAME_HEIGHT,
|
||||
META_CORE_GET_FRAME_RECT,
|
||||
META_CORE_GET_THEME_VARIANT,
|
||||
META_CORE_GET_SCREEN_WIDTH,
|
||||
META_CORE_GET_SCREEN_HEIGHT,
|
||||
} MetaCoreGetType;
|
||||
|
||||
/* General information function about the given window. Pass in a sequence of
|
||||
@@ -56,8 +47,8 @@ typedef enum
|
||||
* For example:
|
||||
*
|
||||
* meta_core_get (my_display, my_window,
|
||||
* META_CORE_GET_X, &x,
|
||||
* META_CORE_GET_Y, &y,
|
||||
* META_CORE_GET_FRAME_WIDTH, &width,
|
||||
* META_CORE_GET_FRAME_HEIGHT, &height,
|
||||
* META_CORE_GET_END);
|
||||
*
|
||||
* If the window doesn't have a frame, this will raise a meta_bug. To suppress
|
||||
@@ -93,19 +84,6 @@ void meta_core_get (Display *xdisplay,
|
||||
void meta_core_queue_frame_resize (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
|
||||
/* Move as a result of user operation */
|
||||
void meta_core_user_move (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int x,
|
||||
int y);
|
||||
void meta_core_user_resize (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int gravity,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
void meta_core_user_raise (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_user_lower_and_unfocus (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
guint32 timestamp);
|
||||
@@ -153,17 +131,12 @@ const char* meta_core_get_workspace_name_with_index (Display *xdisplay,
|
||||
Window xroot,
|
||||
int index);
|
||||
|
||||
void meta_core_show_window_menu (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp);
|
||||
|
||||
void meta_core_get_menu_accelerator (MetaMenuOp menu_op,
|
||||
int workspace,
|
||||
unsigned int *keysym,
|
||||
MetaVirtualModifier *modifiers);
|
||||
void meta_core_show_window_menu (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
MetaWindowMenuType menu,
|
||||
int root_x,
|
||||
int root_y,
|
||||
guint32 timestamp);
|
||||
|
||||
gboolean meta_core_begin_grab_op (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
/* Mutter window deletion */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001, 2002 Havoc Pennington
|
||||
* Copyright (C) 2004 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -15,7 +15,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -39,47 +39,70 @@
|
||||
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
|
||||
static void meta_window_present_delete_dialog (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
|
||||
static void
|
||||
delete_ping_reply_func (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
void *user_data)
|
||||
{
|
||||
meta_topic (META_DEBUG_PING, "Got reply to delete ping for %s\n", window->desc);
|
||||
|
||||
/* we do nothing */
|
||||
}
|
||||
|
||||
static void
|
||||
dialog_exited (GPid pid, int status, gpointer user_data)
|
||||
{
|
||||
MetaWindow *ours = (MetaWindow*) user_data;
|
||||
MetaWindow *window = user_data;
|
||||
|
||||
ours->dialog_pid = -1;
|
||||
window->dialog_pid = -1;
|
||||
|
||||
/* exit status of 1 means the user pressed "Force Quit" */
|
||||
if (WIFEXITED (status) && WEXITSTATUS (status) == 1)
|
||||
meta_window_kill (ours);
|
||||
meta_window_kill (window);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_ping_timeout_func (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
void *user_data)
|
||||
present_existing_delete_dialog (MetaWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
meta_topic (META_DEBUG_PING,
|
||||
"Presenting existing ping dialog for %s\n",
|
||||
window->desc);
|
||||
|
||||
if (window->dialog_pid >= 0)
|
||||
{
|
||||
GSList *windows;
|
||||
GSList *tmp;
|
||||
|
||||
/* Activate transient for window that belongs to
|
||||
* mutter-dialog
|
||||
*/
|
||||
|
||||
windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
|
||||
if (w->transient_for == window && w->res_class &&
|
||||
g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0)
|
||||
{
|
||||
meta_window_activate (w, timestamp);
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
g_slist_free (windows);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_delete_dialog (MetaWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
char *window_title;
|
||||
gchar *window_content, *tmp;
|
||||
GPid dialog_pid;
|
||||
|
||||
|
||||
meta_topic (META_DEBUG_PING,
|
||||
"Got delete ping timeout for %s\n",
|
||||
window->desc);
|
||||
|
||||
if (window->dialog_pid >= 0)
|
||||
{
|
||||
meta_window_present_delete_dialog (window, timestamp);
|
||||
present_existing_delete_dialog (window, timestamp);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -128,15 +151,33 @@ delete_ping_timeout_func (MetaWindow *window,
|
||||
g_child_watch_add (dialog_pid, dialog_exited, window);
|
||||
}
|
||||
|
||||
static void
|
||||
kill_delete_dialog (MetaWindow *window)
|
||||
{
|
||||
if (window->dialog_pid > -1)
|
||||
kill (window->dialog_pid, SIGTERM);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_set_alive (MetaWindow *window,
|
||||
gboolean is_alive)
|
||||
{
|
||||
if (window->is_alive == is_alive)
|
||||
return;
|
||||
|
||||
window->is_alive = is_alive;
|
||||
|
||||
if (window->is_alive)
|
||||
kill_delete_dialog (window);
|
||||
else
|
||||
show_delete_dialog (window, CurrentTime);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_check_alive (MetaWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
meta_display_ping_window (window,
|
||||
timestamp,
|
||||
delete_ping_reply_func,
|
||||
delete_ping_timeout_func,
|
||||
NULL);
|
||||
meta_display_ping_window (window, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -149,7 +190,7 @@ meta_window_delete (MetaWindow *window,
|
||||
|
||||
if (window->has_focus)
|
||||
{
|
||||
/* FIXME Clean this up someday
|
||||
/* FIXME Clean this up someday
|
||||
* http://bugzilla.gnome.org/show_bug.cgi?id=108706
|
||||
*/
|
||||
#if 0
|
||||
@@ -191,39 +232,3 @@ meta_window_free_delete_dialog (MetaWindow *window)
|
||||
window->dialog_pid = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_present_delete_dialog (MetaWindow *window, guint32 timestamp)
|
||||
{
|
||||
meta_topic (META_DEBUG_PING,
|
||||
"Presenting existing ping dialog for %s\n",
|
||||
window->desc);
|
||||
|
||||
if (window->dialog_pid >= 0)
|
||||
{
|
||||
GSList *windows;
|
||||
GSList *tmp;
|
||||
|
||||
/* Activate transient for window that belongs to
|
||||
* mutter-dialog
|
||||
*/
|
||||
|
||||
windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
|
||||
if (w->transient_for == window && w->res_class &&
|
||||
g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0)
|
||||
{
|
||||
meta_window_activate (w, timestamp);
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
g_slist_free (windows);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
/* Mutter X display handler */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2002 Red Hat, Inc.
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -17,7 +17,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -53,10 +53,6 @@ typedef struct _MetaWindowPropHooks MetaWindowPropHooks;
|
||||
|
||||
typedef struct MetaEdgeResistanceData MetaEdgeResistanceData;
|
||||
|
||||
typedef void (* MetaWindowPingFunc) (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
gpointer user_data);
|
||||
|
||||
typedef enum {
|
||||
META_LIST_DEFAULT = 0, /* normal windows */
|
||||
META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */
|
||||
@@ -85,7 +81,7 @@ typedef enum {
|
||||
struct _MetaDisplay
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
|
||||
char *name;
|
||||
Display *xdisplay;
|
||||
|
||||
@@ -143,7 +139,7 @@ struct _MetaDisplay
|
||||
* multiple events with the same serial.
|
||||
*/
|
||||
guint focused_by_us : 1;
|
||||
|
||||
|
||||
/*< private-ish >*/
|
||||
MetaScreen *screen;
|
||||
GHashTable *xids;
|
||||
@@ -157,7 +153,7 @@ struct _MetaDisplay
|
||||
*/
|
||||
unsigned long ignored_crossing_serials[N_IGNORED_CROSSING_SERIALS];
|
||||
Window ungrab_should_not_cause_focus_window;
|
||||
|
||||
|
||||
guint32 current_time;
|
||||
|
||||
/* We maintain a sequence counter, incremented for each #MetaWindow
|
||||
@@ -181,7 +177,7 @@ struct _MetaDisplay
|
||||
|
||||
/* Alt+click button grabs */
|
||||
ClutterModifierType window_grab_modifiers;
|
||||
|
||||
|
||||
/* current window operation */
|
||||
MetaGrabOp grab_op;
|
||||
MetaWindow *grab_window;
|
||||
@@ -234,7 +230,7 @@ struct _MetaDisplay
|
||||
gboolean overlay_key_only_pressed;
|
||||
MetaKeyCombo *iso_next_group_combos;
|
||||
int n_iso_next_group_combos;
|
||||
|
||||
|
||||
/* Monitor cache */
|
||||
unsigned int monitor_cache_invalidated : 1;
|
||||
|
||||
@@ -247,10 +243,6 @@ struct _MetaDisplay
|
||||
/* Managed by group.c */
|
||||
GHashTable *groups_by_leader;
|
||||
|
||||
/* currently-active window menu if any */
|
||||
MetaWindowMenu *window_menu;
|
||||
MetaWindow *window_with_menu;
|
||||
|
||||
/* Managed by window-props.c */
|
||||
MetaWindowPropHooks *prop_hooks_table;
|
||||
GHashTable *prop_hooks;
|
||||
@@ -367,9 +359,7 @@ MetaDisplay* meta_get_display (void);
|
||||
Cursor meta_display_create_x_cursor (MetaDisplay *display,
|
||||
MetaCursor cursor);
|
||||
|
||||
void meta_display_set_grab_op_cursor (MetaDisplay *display,
|
||||
MetaGrabOp op,
|
||||
guint32 timestamp);
|
||||
void meta_display_update_cursor (MetaDisplay *display);
|
||||
|
||||
void meta_display_check_threshold_reached (MetaDisplay *display,
|
||||
int x,
|
||||
@@ -399,13 +389,10 @@ const char* meta_event_detail_to_string (int d);
|
||||
void meta_display_queue_retheme_all_windows (MetaDisplay *display);
|
||||
void meta_display_retheme_all (void);
|
||||
|
||||
void meta_display_ping_window (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
MetaWindowPingFunc ping_reply_func,
|
||||
MetaWindowPingFunc ping_timeout_func,
|
||||
void *user_data);
|
||||
void meta_display_pong_for_serial (MetaDisplay *display,
|
||||
guint32 serial);
|
||||
void meta_display_ping_window (MetaWindow *window,
|
||||
guint32 serial);
|
||||
void meta_display_pong_for_serial (MetaDisplay *display,
|
||||
guint32 serial);
|
||||
|
||||
int meta_resize_gravity_from_grab_op (MetaGrabOp op);
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
|
||||
* Copyright (C) 2003, 2004 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -15,7 +15,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -98,12 +98,9 @@
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
MetaWindow *window;
|
||||
guint32 timestamp;
|
||||
MetaWindowPingFunc ping_reply_func;
|
||||
MetaWindowPingFunc ping_timeout_func;
|
||||
void *user_data;
|
||||
guint ping_timeout_id;
|
||||
MetaWindow *window;
|
||||
guint32 serial;
|
||||
guint ping_timeout_id;
|
||||
} MetaPingData;
|
||||
|
||||
G_DEFINE_TYPE(MetaDisplay, meta_display, G_TYPE_OBJECT);
|
||||
@@ -441,11 +438,11 @@ meta_display_open (void)
|
||||
#undef item
|
||||
};
|
||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||
|
||||
|
||||
meta_verbose ("Opening display '%s'\n", XDisplayName (NULL));
|
||||
|
||||
xdisplay = meta_ui_get_display ();
|
||||
|
||||
|
||||
if (xdisplay == NULL)
|
||||
{
|
||||
meta_warning (_("Failed to open X Window System display '%s'\n"),
|
||||
@@ -458,12 +455,12 @@ meta_display_open (void)
|
||||
|
||||
if (meta_is_syncing ())
|
||||
XSynchronize (xdisplay, True);
|
||||
|
||||
|
||||
g_assert (the_display == NULL);
|
||||
the_display = g_object_new (META_TYPE_DISPLAY, NULL);
|
||||
|
||||
the_display->closing = 0;
|
||||
|
||||
|
||||
/* here we use XDisplayName which is what the user
|
||||
* probably put in, vs. DisplayString(display) which is
|
||||
* canonicalized by XOpenDisplay()
|
||||
@@ -484,7 +481,7 @@ meta_display_open (void)
|
||||
the_display->mouse_mode = TRUE; /* Only relevant for mouse or sloppy focus */
|
||||
the_display->allow_terminal_deactivation = TRUE; /* Only relevant for when a
|
||||
terminal has the focus */
|
||||
|
||||
|
||||
meta_bell_init (the_display);
|
||||
|
||||
meta_display_init_keys (the_display);
|
||||
@@ -497,7 +494,7 @@ meta_display_open (void)
|
||||
XInternAtoms (the_display->xdisplay, atom_names, G_N_ELEMENTS (atom_names),
|
||||
False, atoms);
|
||||
{
|
||||
int i = 0;
|
||||
int i = 0;
|
||||
#define item(x) the_display->atom_##x = atoms[i++];
|
||||
#include <meta/atomnames.h>
|
||||
#undef item
|
||||
@@ -507,7 +504,7 @@ meta_display_open (void)
|
||||
meta_display_init_window_prop_hooks (the_display);
|
||||
the_display->group_prop_hooks = NULL;
|
||||
meta_display_init_group_prop_hooks (the_display);
|
||||
|
||||
|
||||
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
|
||||
* created in screen_new
|
||||
*/
|
||||
@@ -518,11 +515,8 @@ meta_display_open (void)
|
||||
|
||||
the_display->groups_by_leader = NULL;
|
||||
|
||||
the_display->window_with_menu = NULL;
|
||||
the_display->window_menu = NULL;
|
||||
|
||||
the_display->screen = NULL;
|
||||
|
||||
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
the_display->sn_display = sn_display_new (the_display->xdisplay,
|
||||
sn_error_trap_push,
|
||||
@@ -543,14 +537,14 @@ meta_display_open (void)
|
||||
++i;
|
||||
}
|
||||
the_display->ungrab_should_not_cause_focus_window = None;
|
||||
|
||||
|
||||
the_display->current_time = CurrentTime;
|
||||
the_display->sentinel_counter = 0;
|
||||
|
||||
the_display->grab_resize_timeout_id = 0;
|
||||
the_display->grab_have_keyboard = FALSE;
|
||||
|
||||
#ifdef HAVE_XKB
|
||||
|
||||
#ifdef HAVE_XKB
|
||||
the_display->last_bell_time = 0;
|
||||
#endif
|
||||
|
||||
@@ -565,14 +559,14 @@ meta_display_open (void)
|
||||
int major, minor;
|
||||
|
||||
the_display->have_xsync = FALSE;
|
||||
|
||||
|
||||
the_display->xsync_error_base = 0;
|
||||
the_display->xsync_event_base = 0;
|
||||
|
||||
/* I don't think we really have to fill these in */
|
||||
major = SYNC_MAJOR_VERSION;
|
||||
minor = SYNC_MINOR_VERSION;
|
||||
|
||||
|
||||
if (!XSyncQueryExtension (the_display->xdisplay,
|
||||
&the_display->xsync_event_base,
|
||||
&the_display->xsync_error_base) ||
|
||||
@@ -596,10 +590,10 @@ meta_display_open (void)
|
||||
|
||||
{
|
||||
the_display->have_shape = FALSE;
|
||||
|
||||
|
||||
the_display->shape_error_base = 0;
|
||||
the_display->shape_event_base = 0;
|
||||
|
||||
|
||||
if (!XShapeQueryExtension (the_display->xdisplay,
|
||||
&the_display->shape_event_base,
|
||||
&the_display->shape_error_base))
|
||||
@@ -609,7 +603,7 @@ meta_display_open (void)
|
||||
}
|
||||
else
|
||||
the_display->have_shape = TRUE;
|
||||
|
||||
|
||||
meta_verbose ("Attempted to init Shape, found error base %d event base %d\n",
|
||||
the_display->shape_error_base,
|
||||
the_display->shape_event_base);
|
||||
@@ -627,7 +621,7 @@ meta_display_open (void)
|
||||
{
|
||||
the_display->composite_error_base = 0;
|
||||
the_display->composite_event_base = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
the_display->composite_major_version = 0;
|
||||
@@ -647,7 +641,7 @@ meta_display_open (void)
|
||||
|
||||
meta_verbose ("Attempted to init Composite, found error base %d event base %d "
|
||||
"extn ver %d %d\n",
|
||||
the_display->composite_error_base,
|
||||
the_display->composite_error_base,
|
||||
the_display->composite_event_base,
|
||||
the_display->composite_major_version,
|
||||
the_display->composite_minor_version);
|
||||
@@ -663,12 +657,12 @@ meta_display_open (void)
|
||||
{
|
||||
the_display->damage_error_base = 0;
|
||||
the_display->damage_event_base = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
the_display->have_damage = TRUE;
|
||||
|
||||
meta_verbose ("Attempted to init Damage, found error base %d event base %d\n",
|
||||
the_display->damage_error_base,
|
||||
the_display->damage_error_base,
|
||||
the_display->damage_event_base);
|
||||
|
||||
the_display->xfixes_error_base = 0;
|
||||
@@ -691,7 +685,7 @@ meta_display_open (void)
|
||||
}
|
||||
|
||||
meta_verbose ("Attempted to init XFixes, found error base %d event base %d\n",
|
||||
the_display->xfixes_error_base,
|
||||
the_display->xfixes_error_base,
|
||||
the_display->xfixes_event_base);
|
||||
}
|
||||
|
||||
@@ -751,7 +745,7 @@ meta_display_open (void)
|
||||
the_display->leader_window,
|
||||
the_display->atom__GNOME_WM_KEYBINDINGS,
|
||||
gnome_wm_keybindings);
|
||||
|
||||
|
||||
meta_prop_set_utf8_string_hint (the_display,
|
||||
the_display->leader_window,
|
||||
the_display->atom__MUTTER_VERSION,
|
||||
@@ -937,7 +931,7 @@ meta_display_list_windows (MetaDisplay *display,
|
||||
GSList *next;
|
||||
|
||||
next = tmp->next;
|
||||
|
||||
|
||||
if (next &&
|
||||
next->data == tmp->data)
|
||||
{
|
||||
@@ -948,7 +942,7 @@ meta_display_list_windows (MetaDisplay *display,
|
||||
|
||||
if (tmp == winlist)
|
||||
winlist = next;
|
||||
|
||||
|
||||
g_slist_free_1 (tmp);
|
||||
|
||||
/* leave prev unchanged */
|
||||
@@ -957,7 +951,7 @@ meta_display_list_windows (MetaDisplay *display,
|
||||
{
|
||||
prev = tmp;
|
||||
}
|
||||
|
||||
|
||||
tmp = next;
|
||||
}
|
||||
|
||||
@@ -979,7 +973,7 @@ meta_display_close (MetaDisplay *display,
|
||||
display->closing += 1;
|
||||
|
||||
meta_prefs_remove_listener (prefs_changed_callback, display);
|
||||
|
||||
|
||||
meta_display_remove_autoraise_callback (display);
|
||||
|
||||
if (display->focus_timeout_id)
|
||||
@@ -988,7 +982,7 @@ meta_display_close (MetaDisplay *display,
|
||||
|
||||
/* Stop caring about events */
|
||||
meta_display_free_events (display);
|
||||
|
||||
|
||||
meta_screen_free (display->screen, timestamp);
|
||||
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
@@ -998,11 +992,12 @@ meta_display_close (MetaDisplay *display,
|
||||
display->sn_display = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Must be after all calls to meta_window_unmanage() since they
|
||||
* unregister windows
|
||||
*/
|
||||
g_hash_table_destroy (display->xids);
|
||||
g_hash_table_destroy (display->wayland_windows);
|
||||
|
||||
if (display->leader_window != None)
|
||||
XDestroyWindow (display->xdisplay, display->leader_window);
|
||||
@@ -1011,14 +1006,14 @@ meta_display_close (MetaDisplay *display,
|
||||
|
||||
meta_display_free_window_prop_hooks (display);
|
||||
meta_display_free_group_prop_hooks (display);
|
||||
|
||||
|
||||
g_free (display->name);
|
||||
|
||||
meta_display_shutdown_keys (display);
|
||||
|
||||
if (display->compositor)
|
||||
meta_compositor_destroy (display->compositor);
|
||||
|
||||
|
||||
g_object_unref (display);
|
||||
the_display = NULL;
|
||||
|
||||
@@ -1054,7 +1049,7 @@ meta_display_ungrab (MetaDisplay *display)
|
||||
{
|
||||
if (display->server_grab_count == 0)
|
||||
meta_bug ("Ungrabbed non-grabbed server\n");
|
||||
|
||||
|
||||
display->server_grab_count -= 1;
|
||||
if (display->server_grab_count == 0)
|
||||
{
|
||||
@@ -1090,7 +1085,7 @@ meta_display_for_x_display (Display *xdisplay)
|
||||
|
||||
meta_warning ("Could not find display for X display %p, probably going to crash\n",
|
||||
xdisplay);
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1115,8 +1110,8 @@ meta_grab_op_is_mouse (MetaGrabOp 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_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:
|
||||
@@ -1157,8 +1152,8 @@ 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_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:
|
||||
@@ -1188,7 +1183,7 @@ meta_grab_op_is_moving (MetaGrabOp op)
|
||||
case META_GRAB_OP_MOVING:
|
||||
case META_GRAB_OP_KEYBOARD_MOVING:
|
||||
return TRUE;
|
||||
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1282,7 +1277,7 @@ guint32
|
||||
meta_display_get_current_time_roundtrip (MetaDisplay *display)
|
||||
{
|
||||
guint32 timestamp;
|
||||
|
||||
|
||||
timestamp = meta_display_get_current_time (display);
|
||||
if (timestamp == CurrentTime)
|
||||
{
|
||||
@@ -1323,7 +1318,7 @@ meta_display_add_ignored_crossing_serial (MetaDisplay *display,
|
||||
/* don't add the same serial more than once */
|
||||
if (display->ignored_crossing_serials[N_IGNORED_CROSSING_SERIALS-1] == serial)
|
||||
return;
|
||||
|
||||
|
||||
/* shift serials to the left */
|
||||
i = 0;
|
||||
while (i < (N_IGNORED_CROSSING_SERIALS - 1))
|
||||
@@ -1335,7 +1330,7 @@ meta_display_add_ignored_crossing_serial (MetaDisplay *display,
|
||||
display->ignored_crossing_serials[i] = serial;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static gboolean
|
||||
window_raise_with_delay_callback (void *data)
|
||||
{
|
||||
MetaWindow *window = data;
|
||||
@@ -1345,8 +1340,8 @@ window_raise_with_delay_callback (void *data)
|
||||
|
||||
/* If we aren't already on top, check whether the pointer is inside
|
||||
* the window and raise the window if so.
|
||||
*/
|
||||
if (meta_stack_get_top (window->screen->stack) != window)
|
||||
*/
|
||||
if (meta_stack_get_top (window->screen->stack) != window)
|
||||
{
|
||||
int x, y, root_x, root_y;
|
||||
Window root, child;
|
||||
@@ -1367,8 +1362,8 @@ window_raise_with_delay_callback (void *data)
|
||||
if (same_screen && point_in_window)
|
||||
meta_window_raise (window);
|
||||
else
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Pointer not inside window, not raising %s\n",
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Pointer not inside window, not raising %s\n",
|
||||
window->desc);
|
||||
}
|
||||
|
||||
@@ -1379,15 +1374,15 @@ void
|
||||
meta_display_queue_autoraise_callback (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Queuing an autoraise timeout for %s with delay %d\n",
|
||||
window->desc,
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Queuing an autoraise timeout for %s with delay %d\n",
|
||||
window->desc,
|
||||
meta_prefs_get_auto_raise_delay ());
|
||||
|
||||
|
||||
if (display->autoraise_timeout_id != 0)
|
||||
g_source_remove (display->autoraise_timeout_id);
|
||||
|
||||
display->autoraise_timeout_id =
|
||||
display->autoraise_timeout_id =
|
||||
g_timeout_add_full (G_PRIORITY_DEFAULT,
|
||||
meta_prefs_get_auto_raise_delay (),
|
||||
window_raise_with_delay_callback,
|
||||
@@ -1561,7 +1556,7 @@ meta_display_register_x_window (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
g_return_if_fail (g_hash_table_lookup (display->xids, xwindowp) == NULL);
|
||||
|
||||
|
||||
g_hash_table_insert (display->xids, xwindowp, window);
|
||||
}
|
||||
|
||||
@@ -1695,23 +1690,9 @@ meta_cursor_for_grab_op (MetaGrabOp op)
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_set_grab_op_cursor (MetaDisplay *display,
|
||||
MetaGrabOp op,
|
||||
guint32 timestamp)
|
||||
meta_display_update_cursor (MetaDisplay *display)
|
||||
{
|
||||
/* Set root cursor */
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (display->screen);
|
||||
MetaCursor cursor = meta_cursor_for_grab_op (op);
|
||||
MetaCursorReference *cursor_ref;
|
||||
|
||||
cursor_ref = meta_cursor_reference_from_theme (cursor);
|
||||
meta_cursor_tracker_set_grab_cursor (tracker, cursor_ref);
|
||||
if (cursor_ref)
|
||||
meta_cursor_reference_unref (cursor_ref);
|
||||
|
||||
if (meta_backend_grab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp))
|
||||
display->grab_have_pointer = TRUE;
|
||||
meta_screen_set_cursor (display->screen, meta_cursor_for_grab_op (display->grab_op));
|
||||
}
|
||||
|
||||
static MetaWindow *
|
||||
@@ -1739,24 +1720,25 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
int root_x,
|
||||
int root_y)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaWindow *grab_window = NULL;
|
||||
|
||||
g_assert (window != NULL);
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Doing grab op %u on window %s button %d pointer already grabbed: %d pointer pos %d,%d\n",
|
||||
op, window ? window->desc : "none", button, pointer_already_grabbed,
|
||||
op, window->desc, button, pointer_already_grabbed,
|
||||
root_x, root_y);
|
||||
|
||||
if (display->grab_op != META_GRAB_OP_NONE)
|
||||
{
|
||||
if (window)
|
||||
meta_warning ("Attempt to perform window operation %u on window %s when operation %u on %s already in effect\n",
|
||||
op, window->desc, display->grab_op,
|
||||
display->grab_window ? display->grab_window->desc : "none");
|
||||
meta_warning ("Attempt to perform window operation %u on window %s when operation %u on %s already in effect\n",
|
||||
op, window->desc, display->grab_op,
|
||||
display->grab_window ? display->grab_window->desc : "none");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (window &&
|
||||
(meta_grab_op_is_moving (op) || meta_grab_op_is_resizing (op)))
|
||||
if (meta_grab_op_is_moving (op) || meta_grab_op_is_resizing (op))
|
||||
{
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
meta_window_raise (window);
|
||||
@@ -1773,7 +1755,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
/* If window is a modal dialog attached to its parent,
|
||||
* grab the parent instead for moving.
|
||||
*/
|
||||
if (meta_grab_op_is_moving (op))
|
||||
if (meta_window_is_attached_dialog (window) && meta_grab_op_is_moving (op))
|
||||
grab_window = get_toplevel_transient_for (window);
|
||||
|
||||
g_assert (grab_window != NULL);
|
||||
@@ -1793,7 +1775,8 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
timestamp);
|
||||
XSync (display->xdisplay, False);
|
||||
|
||||
meta_display_set_grab_op_cursor (display, op, timestamp);
|
||||
if (meta_backend_grab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp))
|
||||
display->grab_have_pointer = TRUE;
|
||||
|
||||
if (!display->grab_have_pointer && !meta_grab_op_is_keyboard (op))
|
||||
{
|
||||
@@ -1808,7 +1791,6 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
|
||||
if (!display->grab_have_keyboard)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
meta_topic (META_DEBUG_WINDOW_OPS, "grabbing all keys failed, ungrabbing pointer\n");
|
||||
meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp);
|
||||
display->grab_have_pointer = FALSE;
|
||||
@@ -1832,6 +1814,8 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
display->grab_resize_unmaximize = 0;
|
||||
display->grab_timestamp = timestamp;
|
||||
|
||||
meta_display_update_cursor (display);
|
||||
|
||||
if (display->grab_resize_timeout_id)
|
||||
{
|
||||
g_source_remove (display->grab_resize_timeout_id);
|
||||
@@ -1842,8 +1826,8 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
"Grab op %u on window %s successful\n",
|
||||
display->grab_op, window ? window->desc : "(null)");
|
||||
|
||||
meta_window_get_client_root_coords (display->grab_window,
|
||||
&display->grab_initial_window_pos);
|
||||
meta_window_get_frame_rect (display->grab_window,
|
||||
&display->grab_initial_window_pos);
|
||||
display->grab_anchor_window_pos = display->grab_initial_window_pos;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
@@ -1861,8 +1845,6 @@ void
|
||||
meta_display_end_grab_op (MetaDisplay *display,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaCursorTracker *tracker;
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Ending grab op %u at time %u\n", display->grab_op, timestamp);
|
||||
|
||||
@@ -1903,15 +1885,14 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
meta_window_ungrab_all_keys (display->grab_window, timestamp);
|
||||
}
|
||||
|
||||
tracker = meta_cursor_tracker_get_for_screen (display->screen);
|
||||
meta_cursor_tracker_set_grab_cursor (tracker, NULL);
|
||||
|
||||
display->grab_timestamp = 0;
|
||||
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);
|
||||
|
||||
if (display->grab_resize_timeout_id)
|
||||
{
|
||||
g_source_remove (display->grab_resize_timeout_id);
|
||||
@@ -1990,7 +1971,7 @@ meta_change_button_grab (MetaDisplay *display,
|
||||
mods = (XIGrabModifiers) { modmask | ignored_mask, 0 };
|
||||
|
||||
/* GrabModeSync means freeze until XAllowEvents */
|
||||
|
||||
|
||||
if (grab)
|
||||
XIGrabButton (xdisplay,
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
@@ -2010,11 +1991,8 @@ meta_change_button_grab (MetaDisplay *display,
|
||||
void
|
||||
meta_display_grab_window_buttons (MetaDisplay *display,
|
||||
Window xwindow)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
/* Do nothing under non-X11 backends */
|
||||
if (!META_IS_BACKEND_X11 (backend))
|
||||
{
|
||||
if (meta_is_wayland_compositor ())
|
||||
return;
|
||||
|
||||
/* Grab Alt + button1 for moving window.
|
||||
@@ -2023,7 +2001,7 @@ meta_display_grab_window_buttons (MetaDisplay *display,
|
||||
* 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()
|
||||
@@ -2038,8 +2016,8 @@ meta_display_grab_window_buttons (MetaDisplay *display,
|
||||
meta_change_button_grab (display, xwindow,
|
||||
TRUE,
|
||||
FALSE,
|
||||
i, display->window_grab_modifiers);
|
||||
|
||||
i, display->window_grab_modifiers);
|
||||
|
||||
/* This is for debugging, since I end up moving the Xnest
|
||||
* otherwise ;-)
|
||||
*/
|
||||
@@ -2067,18 +2045,15 @@ void
|
||||
meta_display_ungrab_window_buttons (MetaDisplay *display,
|
||||
Window xwindow)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
/* Do nothing under non-X11 backends */
|
||||
if (!META_IS_BACKEND_X11 (backend))
|
||||
return;
|
||||
|
||||
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)
|
||||
@@ -2086,11 +2061,11 @@ meta_display_ungrab_window_buttons (MetaDisplay *display,
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -2101,10 +2076,7 @@ void
|
||||
meta_display_grab_focus_window_button (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
/* Do nothing under non-X11 backends */
|
||||
if (!META_IS_BACKEND_X11 (backend))
|
||||
if (meta_is_wayland_compositor ())
|
||||
return;
|
||||
|
||||
/* Grab button 1 for activating unfocused windows */
|
||||
@@ -2124,18 +2096,18 @@ meta_display_grab_focus_window_button (MetaDisplay *display,
|
||||
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)
|
||||
@@ -2144,7 +2116,7 @@ meta_display_grab_focus_window_button (MetaDisplay *display,
|
||||
window->xwindow,
|
||||
TRUE, TRUE,
|
||||
i, 0);
|
||||
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
@@ -2156,24 +2128,21 @@ void
|
||||
meta_display_ungrab_focus_window_button (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
/* Do nothing under non-X11 backends */
|
||||
if (!META_IS_BACKEND_X11 (backend))
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -2218,14 +2187,14 @@ meta_display_queue_retheme_all_windows (MetaDisplay *display)
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *window = tmp->data;
|
||||
|
||||
|
||||
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
|
||||
meta_window_frame_size_changed (window);
|
||||
if (window->frame)
|
||||
{
|
||||
meta_frame_queue_draw (window->frame);
|
||||
}
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
@@ -2331,15 +2300,16 @@ static gboolean
|
||||
meta_display_ping_timeout (gpointer data)
|
||||
{
|
||||
MetaPingData *ping_data = data;
|
||||
MetaDisplay *display = ping_data->window->display;
|
||||
MetaWindow *window = ping_data->window;
|
||||
MetaDisplay *display = window->display;
|
||||
|
||||
meta_window_set_alive (window, FALSE);
|
||||
|
||||
ping_data->ping_timeout_id = 0;
|
||||
|
||||
meta_topic (META_DEBUG_PING,
|
||||
"Ping %u on window %s timed out\n",
|
||||
ping_data->timestamp, ping_data->window->desc);
|
||||
|
||||
(* ping_data->ping_timeout_func) (ping_data->window, ping_data->timestamp, ping_data->user_data);
|
||||
ping_data->serial, ping_data->window->desc);
|
||||
|
||||
display->pending_pings = g_slist_remove (display->pending_pings, ping_data);
|
||||
ping_data_free (ping_data);
|
||||
@@ -2353,11 +2323,6 @@ meta_display_ping_timeout (gpointer data)
|
||||
* @window: The #MetaWindow to send the ping to
|
||||
* @timestamp: The timestamp of the ping. Used for uniqueness.
|
||||
* Cannot be CurrentTime; use a real timestamp!
|
||||
* @ping_reply_func: The callback to call if we get a response.
|
||||
* @ping_timeout_func: The callback to call if we don't get a response.
|
||||
* @user_data: Arbitrary data that will be passed to the callback
|
||||
* function. (In practice it's often a pointer to
|
||||
* the window.)
|
||||
*
|
||||
* Sends a ping request to a window. The window must respond to
|
||||
* the request within a certain amount of time. If it does, we
|
||||
@@ -2369,35 +2334,24 @@ meta_display_ping_timeout (gpointer data)
|
||||
* the callbacks will be called from the event loop.
|
||||
*/
|
||||
void
|
||||
meta_display_ping_window (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
MetaWindowPingFunc ping_reply_func,
|
||||
MetaWindowPingFunc ping_timeout_func,
|
||||
gpointer user_data)
|
||||
meta_display_ping_window (MetaWindow *window,
|
||||
guint32 serial)
|
||||
{
|
||||
MetaDisplay *display = window->display;
|
||||
MetaPingData *ping_data;
|
||||
|
||||
if (timestamp == CurrentTime)
|
||||
if (serial == 0)
|
||||
{
|
||||
meta_warning ("Tried to ping a window with CurrentTime! Not allowed.\n");
|
||||
meta_warning ("Tried to ping a window with a bad serial! Not allowed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!window->can_ping)
|
||||
{
|
||||
if (ping_reply_func)
|
||||
(* ping_reply_func) (window, timestamp, user_data);
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
ping_data = g_new (MetaPingData, 1);
|
||||
ping_data->window = window;
|
||||
ping_data->timestamp = timestamp;
|
||||
ping_data->ping_reply_func = ping_reply_func;
|
||||
ping_data->ping_timeout_func = ping_timeout_func;
|
||||
ping_data->user_data = user_data;
|
||||
ping_data->serial = serial;
|
||||
ping_data->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY,
|
||||
meta_display_ping_timeout,
|
||||
ping_data);
|
||||
@@ -2406,10 +2360,10 @@ meta_display_ping_window (MetaWindow *window,
|
||||
display->pending_pings = g_slist_prepend (display->pending_pings, ping_data);
|
||||
|
||||
meta_topic (META_DEBUG_PING,
|
||||
"Sending ping with timestamp %u to window %s\n",
|
||||
timestamp, window->desc);
|
||||
"Sending ping with serial %u to window %s\n",
|
||||
serial, window->desc);
|
||||
|
||||
META_WINDOW_GET_CLASS (window)->ping (window, timestamp);
|
||||
META_WINDOW_GET_CLASS (window)->ping (window, serial);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2433,11 +2387,11 @@ meta_display_pong_for_serial (MetaDisplay *display,
|
||||
{
|
||||
MetaPingData *ping_data = tmp->data;
|
||||
|
||||
if (serial == ping_data->timestamp)
|
||||
if (serial == ping_data->serial)
|
||||
{
|
||||
meta_topic (META_DEBUG_PING,
|
||||
"Matching ping found for pong %u\n",
|
||||
ping_data->timestamp);
|
||||
ping_data->serial);
|
||||
|
||||
/* Remove the ping data from the list */
|
||||
display->pending_pings = g_slist_remove (display->pending_pings,
|
||||
@@ -2450,13 +2404,8 @@ meta_display_pong_for_serial (MetaDisplay *display,
|
||||
ping_data->ping_timeout_id = 0;
|
||||
}
|
||||
|
||||
/* Call callback */
|
||||
(* ping_data->ping_reply_func) (ping_data->window,
|
||||
ping_data->timestamp,
|
||||
ping_data->user_data);
|
||||
|
||||
meta_window_set_alive (ping_data->window, TRUE);
|
||||
ping_data_free (ping_data);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2511,7 +2460,7 @@ find_tab_forward (MetaDisplay *display,
|
||||
return window;
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -2529,7 +2478,7 @@ find_tab_backward (MetaDisplay *display,
|
||||
g_return_val_if_fail (workspace != NULL, NULL);
|
||||
|
||||
tmp = start;
|
||||
if (skip_last)
|
||||
if (skip_last)
|
||||
tmp = tmp->prev;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
@@ -2577,7 +2526,7 @@ mru_cmp (gconstpointer a,
|
||||
* @display: a #MetaDisplay
|
||||
* @type: type of tab list
|
||||
* @screen: a #MetaScreen
|
||||
* @workspace: (allow-none): origin workspace
|
||||
* @workspace: (nullable): origin workspace
|
||||
*
|
||||
* Determine the list of windows that should be displayed for Alt-TAB
|
||||
* functionality. The windows are returned in most recently used order.
|
||||
@@ -2637,7 +2586,7 @@ meta_display_get_tab_list (MetaDisplay *display,
|
||||
|
||||
g_list_free (global_mru_list);
|
||||
g_slist_free (windows);
|
||||
|
||||
|
||||
return tab_list;
|
||||
}
|
||||
|
||||
@@ -2646,8 +2595,8 @@ meta_display_get_tab_list (MetaDisplay *display,
|
||||
* @display: a #MetaDisplay
|
||||
* @type: type of tab list
|
||||
* @workspace: origin workspace
|
||||
* @window: (allow-none): starting window
|
||||
* @backward: If %TRUE, look for the previous window.
|
||||
* @window: (nullable): starting window
|
||||
* @backward: If %TRUE, look for the previous window.
|
||||
*
|
||||
* Determine the next window that should be displayed for Alt-TAB
|
||||
* functionality.
|
||||
@@ -2669,11 +2618,11 @@ meta_display_get_tab_next (MetaDisplay *display,
|
||||
|
||||
if (tab_list == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
if (window != NULL)
|
||||
{
|
||||
g_assert (window->display == display);
|
||||
|
||||
|
||||
if (backward)
|
||||
ret = find_tab_backward (display, type, workspace, g_list_find (tab_list, window), TRUE);
|
||||
else
|
||||
@@ -2681,7 +2630,7 @@ meta_display_get_tab_next (MetaDisplay *display,
|
||||
}
|
||||
else
|
||||
{
|
||||
skip = display->focus_window != NULL &&
|
||||
skip = display->focus_window != NULL &&
|
||||
tab_list->data == display->focus_window;
|
||||
if (backward)
|
||||
ret = find_tab_backward (display, type, workspace, tab_list, skip);
|
||||
@@ -2712,7 +2661,7 @@ meta_display_get_tab_current (MetaDisplay *display,
|
||||
MetaWindow *window;
|
||||
|
||||
window = display->focus_window;
|
||||
|
||||
|
||||
if (window != NULL &&
|
||||
IN_TAB_CHAIN (window, type) &&
|
||||
(workspace == NULL ||
|
||||
@@ -2726,7 +2675,7 @@ int
|
||||
meta_resize_gravity_from_grab_op (MetaGrabOp op)
|
||||
{
|
||||
int gravity;
|
||||
|
||||
|
||||
gravity = -1;
|
||||
switch (op)
|
||||
{
|
||||
@@ -2808,7 +2757,7 @@ meta_display_unmanage_windows_for_screen (MetaDisplay *display,
|
||||
if (!window->unmanaging)
|
||||
meta_window_unmanage (window, timestamp);
|
||||
g_object_unref (window);
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
g_slist_free (winlist);
|
||||
@@ -2858,7 +2807,7 @@ meta_display_devirtualize_modifiers (MetaDisplay *display,
|
||||
unsigned int *mask)
|
||||
{
|
||||
*mask = 0;
|
||||
|
||||
|
||||
if (modifiers & META_VIRTUAL_SHIFT_MASK)
|
||||
*mask |= ShiftMask;
|
||||
if (modifiers & META_VIRTUAL_CONTROL_MASK)
|
||||
@@ -2878,7 +2827,7 @@ meta_display_devirtualize_modifiers (MetaDisplay *display,
|
||||
if (modifiers & META_VIRTUAL_MOD4_MASK)
|
||||
*mask |= Mod4Mask;
|
||||
if (modifiers & META_VIRTUAL_MOD5_MASK)
|
||||
*mask |= Mod5Mask;
|
||||
*mask |= Mod5Mask;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2886,11 +2835,11 @@ 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;
|
||||
}
|
||||
|
||||
@@ -2899,7 +2848,7 @@ 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.
|
||||
@@ -2910,9 +2859,9 @@ prefs_changed_callback (MetaPreference pref,
|
||||
MetaDisplay *display = data;
|
||||
GSList *windows;
|
||||
GSList *tmp;
|
||||
|
||||
|
||||
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
|
||||
|
||||
|
||||
/* Ungrab all */
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
@@ -2959,13 +2908,13 @@ meta_display_increment_focus_sentinel (MetaDisplay *display)
|
||||
unsigned long data[1];
|
||||
|
||||
data[0] = meta_display_get_current_time (display);
|
||||
|
||||
|
||||
XChangeProperty (display->xdisplay,
|
||||
display->screen->xroot,
|
||||
display->atom__MUTTER_SENTINEL,
|
||||
XA_CARDINAL,
|
||||
32, PropModeReplace, (guchar*) data, 1);
|
||||
|
||||
|
||||
display->sentinel_counter += 1;
|
||||
}
|
||||
|
||||
@@ -3014,7 +2963,7 @@ meta_display_sanity_check_timestamps (MetaDisplay *display,
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *window = tmp->data;
|
||||
|
||||
|
||||
if (XSERVER_TIME_IS_BEFORE (timestamp, window->net_wm_user_time))
|
||||
{
|
||||
meta_warning ("%s appears to be one of the offending windows "
|
||||
@@ -3031,7 +2980,7 @@ meta_display_sanity_check_timestamps (MetaDisplay *display,
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_set_input_focus_window (MetaDisplay *display,
|
||||
meta_display_set_input_focus_window (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
gboolean focus_frame,
|
||||
guint32 timestamp)
|
||||
@@ -3171,6 +3120,12 @@ meta_display_has_shape (MetaDisplay *display)
|
||||
return META_DISPLAY_HAS_SHAPE (display);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_display_has_sync (MetaDisplay *display)
|
||||
{
|
||||
return META_DISPLAY_HAS_XSYNC (display);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_get_focus_window:
|
||||
* @display: a #MetaDisplay
|
||||
@@ -3187,7 +3142,7 @@ meta_display_get_focus_window (MetaDisplay *display)
|
||||
return display->focus_window;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
meta_display_get_damage_event_base (MetaDisplay *display)
|
||||
{
|
||||
return display->damage_event_base;
|
||||
@@ -3199,6 +3154,12 @@ meta_display_get_shape_event_base (MetaDisplay *display)
|
||||
return display->shape_event_base;
|
||||
}
|
||||
|
||||
int
|
||||
meta_display_get_sync_event_base (MetaDisplay *display)
|
||||
{
|
||||
return display->xsync_event_base;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_clear_mouse_mode:
|
||||
* @display: a #MetaDisplay
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
/* Edge resistance for move/resize operations */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2005, 2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -245,8 +245,8 @@ find_nearest_position (const GArray *edges,
|
||||
{
|
||||
edge = g_array_index (edges, MetaEdge*, i);
|
||||
compare = horizontal ? edge->rect.x : edge->rect.y;
|
||||
|
||||
edges_align = horizontal ?
|
||||
|
||||
edges_align = horizontal ?
|
||||
meta_rectangle_vert_overlap (&edge->rect, new_rect) :
|
||||
meta_rectangle_horiz_overlap (&edge->rect, new_rect);
|
||||
|
||||
@@ -269,8 +269,8 @@ find_nearest_position (const GArray *edges,
|
||||
{
|
||||
edge = g_array_index (edges, MetaEdge*, i);
|
||||
compare = horizontal ? edge->rect.x : edge->rect.y;
|
||||
|
||||
edges_align = horizontal ?
|
||||
|
||||
edges_align = horizontal ?
|
||||
meta_rectangle_vert_overlap (&edge->rect, new_rect) :
|
||||
meta_rectangle_horiz_overlap (&edge->rect, new_rect);
|
||||
|
||||
@@ -433,7 +433,7 @@ apply_edge_resistance (MetaWindow *window,
|
||||
if (!resistance_data->timeout_setup &&
|
||||
timeout_length_ms != 0)
|
||||
{
|
||||
resistance_data->timeout_id =
|
||||
resistance_data->timeout_id =
|
||||
g_timeout_add (timeout_length_ms,
|
||||
edge_resistance_timeout,
|
||||
resistance_data);
|
||||
@@ -536,7 +536,7 @@ apply_edge_snapping (int old_pos,
|
||||
* display->grab_edge_resistance_data MUST already be setup or calling this
|
||||
* function will cause a crash.
|
||||
*/
|
||||
static gboolean
|
||||
static gboolean
|
||||
apply_edge_resistance_to_each_side (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
const MetaRectangle *old_outer,
|
||||
@@ -658,7 +658,7 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
|
||||
}
|
||||
|
||||
/* Determine whether anything changed, and save the changes */
|
||||
modified_rect = meta_rect (new_left,
|
||||
modified_rect = meta_rect (new_left,
|
||||
new_top,
|
||||
new_right - new_left,
|
||||
new_bottom - new_top);
|
||||
@@ -754,7 +754,7 @@ meta_display_cleanup_edges (MetaDisplay *display)
|
||||
}
|
||||
|
||||
static int
|
||||
stupid_sort_requiring_extra_pointer_dereference (gconstpointer a,
|
||||
stupid_sort_requiring_extra_pointer_dereference (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
const MetaEdge * const *a_edge = a;
|
||||
@@ -779,7 +779,7 @@ cache_edges (MetaDisplay *display,
|
||||
#ifdef WITH_VERBOSE_MODE
|
||||
if (meta_is_verbose())
|
||||
{
|
||||
int max_edges = MAX (MAX( g_list_length (window_edges),
|
||||
int max_edges = MAX (MAX( g_list_length (window_edges),
|
||||
g_list_length (monitor_edges)),
|
||||
g_list_length (screen_edges));
|
||||
char big_buffer[(EDGE_LENGTH+2)*max_edges];
|
||||
@@ -916,13 +916,13 @@ cache_edges (MetaDisplay *display,
|
||||
* avoided this sort by sticking them into the array with some simple
|
||||
* merging of the lists).
|
||||
*/
|
||||
g_array_sort (display->grab_edge_resistance_data->left_edges,
|
||||
g_array_sort (display->grab_edge_resistance_data->left_edges,
|
||||
stupid_sort_requiring_extra_pointer_dereference);
|
||||
g_array_sort (display->grab_edge_resistance_data->right_edges,
|
||||
g_array_sort (display->grab_edge_resistance_data->right_edges,
|
||||
stupid_sort_requiring_extra_pointer_dereference);
|
||||
g_array_sort (display->grab_edge_resistance_data->top_edges,
|
||||
g_array_sort (display->grab_edge_resistance_data->top_edges,
|
||||
stupid_sort_requiring_extra_pointer_dereference);
|
||||
g_array_sort (display->grab_edge_resistance_data->bottom_edges,
|
||||
g_array_sort (display->grab_edge_resistance_data->bottom_edges,
|
||||
stupid_sort_requiring_extra_pointer_dereference);
|
||||
}
|
||||
|
||||
@@ -986,7 +986,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
|
||||
new_rect = g_new (MetaRectangle, 1);
|
||||
meta_window_get_frame_rect (cur_window, new_rect);
|
||||
obscuring_windows = g_slist_prepend (obscuring_windows, new_rect);
|
||||
window_stacking =
|
||||
window_stacking =
|
||||
g_slist_prepend (window_stacking, GINT_TO_POINTER (stack_position));
|
||||
}
|
||||
|
||||
@@ -1026,7 +1026,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
|
||||
* is offscreen (we also don't care about parts of edges covered
|
||||
* by other windows or DOCKS, but that's handled below).
|
||||
*/
|
||||
meta_rectangle_intersect (&cur_rect,
|
||||
meta_rectangle_intersect (&cur_rect,
|
||||
&display->screen->rect,
|
||||
&reduced);
|
||||
|
||||
@@ -1052,7 +1052,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
|
||||
new_edge->side_type = META_SIDE_LEFT;
|
||||
new_edge->edge_type = META_EDGE_WINDOW;
|
||||
new_edges = g_list_prepend (new_edges, new_edge);
|
||||
|
||||
|
||||
/* Top side of this window is resistance for the bottom edge of
|
||||
* the window being moved.
|
||||
*/
|
||||
@@ -1077,7 +1077,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
|
||||
/* Update the remaining windows to only those at a higher
|
||||
* stacking position than this one.
|
||||
*/
|
||||
while (rem_win_stacking &&
|
||||
while (rem_win_stacking &&
|
||||
stack_position >= GPOINTER_TO_INT (rem_win_stacking->data))
|
||||
{
|
||||
rem_windows = rem_windows->next;
|
||||
@@ -1085,7 +1085,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
|
||||
}
|
||||
|
||||
/* Remove edge portions overlapped by rem_windows and rem_docks */
|
||||
new_edges =
|
||||
new_edges =
|
||||
meta_rectangle_remove_intersections_with_boxes_from_edges (
|
||||
new_edges,
|
||||
rem_windows);
|
||||
@@ -1107,7 +1107,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
|
||||
/* FIXME: Shouldn't there be a helper function to make this one line of code
|
||||
* to free a list instead of four ugly ones?
|
||||
*/
|
||||
g_slist_foreach (obscuring_windows,
|
||||
g_slist_foreach (obscuring_windows,
|
||||
(void (*)(gpointer,gpointer))&g_free, /* ew, for ugly */
|
||||
NULL);
|
||||
g_slist_free (obscuring_windows);
|
||||
@@ -1134,13 +1134,8 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
|
||||
initialize_grab_edge_resistance_data (display);
|
||||
}
|
||||
|
||||
/* Note that old_[xy] and new_[xy] are with respect to inner positions of
|
||||
* the window.
|
||||
*/
|
||||
void
|
||||
meta_window_edge_resistance_for_move (MetaWindow *window,
|
||||
int old_x,
|
||||
int old_y,
|
||||
int *new_x,
|
||||
int *new_y,
|
||||
GSourceFunc timeout_func,
|
||||
@@ -1153,8 +1148,8 @@ meta_window_edge_resistance_for_move (MetaWindow *window,
|
||||
meta_window_get_frame_rect (window, &old_outer);
|
||||
|
||||
proposed_outer = old_outer;
|
||||
proposed_outer.x += (*new_x - old_x);
|
||||
proposed_outer.y += (*new_y - old_y);
|
||||
proposed_outer.x = *new_x;
|
||||
proposed_outer.y = *new_y;
|
||||
new_outer = proposed_outer;
|
||||
|
||||
window->display->grab_last_user_action_was_snap = snap;
|
||||
@@ -1205,26 +1200,20 @@ meta_window_edge_resistance_for_move (MetaWindow *window,
|
||||
else
|
||||
smaller_y_change = bottom_change;
|
||||
|
||||
*new_x = old_x + smaller_x_change +
|
||||
*new_x = old_outer.x + smaller_x_change +
|
||||
(BOX_LEFT (*reference) - BOX_LEFT (old_outer));
|
||||
*new_y = old_y + smaller_y_change +
|
||||
*new_y = old_outer.y + smaller_y_change +
|
||||
(BOX_TOP (*reference) - BOX_TOP (old_outer));
|
||||
|
||||
meta_topic (META_DEBUG_EDGE_RESISTANCE,
|
||||
"outer x & y move-to coordinate changed from %d,%d to %d,%d\n",
|
||||
proposed_outer.x, proposed_outer.y,
|
||||
old_outer.x + (*new_x - old_x),
|
||||
old_outer.y + (*new_y - old_y));
|
||||
*new_x, *new_y);
|
||||
}
|
||||
}
|
||||
|
||||
/* Note that old_(width|height) and new_(width|height) are with respect to
|
||||
* sizes of the inner window.
|
||||
*/
|
||||
void
|
||||
meta_window_edge_resistance_for_resize (MetaWindow *window,
|
||||
int old_width,
|
||||
int old_height,
|
||||
int *new_width,
|
||||
int *new_height,
|
||||
int gravity,
|
||||
@@ -1237,9 +1226,9 @@ meta_window_edge_resistance_for_resize (MetaWindow *window,
|
||||
gboolean is_resize;
|
||||
|
||||
meta_window_get_frame_rect (window, &old_outer);
|
||||
proposed_outer_width = old_outer.width + (*new_width - old_width);
|
||||
proposed_outer_height = old_outer.height + (*new_height - old_height);
|
||||
meta_rectangle_resize_with_gravity (&old_outer,
|
||||
proposed_outer_width = *new_width;
|
||||
proposed_outer_height = *new_height;
|
||||
meta_rectangle_resize_with_gravity (&old_outer,
|
||||
&new_outer,
|
||||
gravity,
|
||||
proposed_outer_width,
|
||||
@@ -1256,8 +1245,8 @@ meta_window_edge_resistance_for_resize (MetaWindow *window,
|
||||
is_keyboard_op,
|
||||
is_resize))
|
||||
{
|
||||
*new_width = old_width + (new_outer.width - old_outer.width);
|
||||
*new_height = old_height + (new_outer.height - old_outer.height);
|
||||
*new_width = new_outer.width;
|
||||
*new_height = new_outer.height;
|
||||
|
||||
meta_topic (META_DEBUG_EDGE_RESISTANCE,
|
||||
"outer width & height got changed from %d,%d to %d,%d\n",
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
/* Edge resistance for move/resize operations */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -25,16 +25,12 @@
|
||||
#include "window-private.h"
|
||||
|
||||
void meta_window_edge_resistance_for_move (MetaWindow *window,
|
||||
int old_x,
|
||||
int old_y,
|
||||
int *new_x,
|
||||
int *new_y,
|
||||
GSourceFunc timeout_func,
|
||||
gboolean snap,
|
||||
gboolean is_keyboard_op);
|
||||
void meta_window_edge_resistance_for_resize (MetaWindow *window,
|
||||
int old_width,
|
||||
int old_height,
|
||||
int *new_width,
|
||||
int *new_height,
|
||||
int gravity,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington, error trapping inspired by GDK
|
||||
* code copyrighted by the GTK team.
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -13,7 +13,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@@ -33,9 +33,13 @@
|
||||
#include "bell.h"
|
||||
#include "workspace-private.h"
|
||||
#include "backends/meta-backend.h"
|
||||
#include "backends/native/meta-idle-monitor-native.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/native/meta-idle-monitor-native.h"
|
||||
#endif
|
||||
|
||||
#include "x11/window-x11.h"
|
||||
#include "x11/xprops.h"
|
||||
#include "wayland/meta-xwayland.h"
|
||||
@@ -888,22 +892,17 @@ handle_input_xevent (MetaDisplay *display,
|
||||
enter_event->time,
|
||||
enter_event->root_x,
|
||||
enter_event->root_y);
|
||||
|
||||
if (window->type == META_WINDOW_DOCK)
|
||||
meta_window_raise (window);
|
||||
}
|
||||
break;
|
||||
case XI_Leave:
|
||||
if (display->grab_op == META_GRAB_OP_COMPOSITOR)
|
||||
break;
|
||||
|
||||
if (window != NULL)
|
||||
if (window != NULL &&
|
||||
enter_event->mode != XINotifyGrab &&
|
||||
enter_event->mode != XINotifyUngrab)
|
||||
{
|
||||
if (window->type == META_WINDOW_DOCK &&
|
||||
enter_event->mode != XINotifyGrab &&
|
||||
enter_event->mode != XINotifyUngrab &&
|
||||
!window->has_focus)
|
||||
meta_window_lower (window);
|
||||
meta_window_handle_leave (window);
|
||||
}
|
||||
break;
|
||||
case XI_FocusIn:
|
||||
@@ -1683,20 +1682,6 @@ handle_other_xevent (MetaDisplay *display,
|
||||
return bypass_gtk;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
grab_op_should_block_mouse_events (MetaGrabOp op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case META_GRAB_OP_WAYLAND_POPUP:
|
||||
case META_GRAB_OP_COMPOSITOR:
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
window_has_xwindow (MetaWindow *window,
|
||||
Window xwindow)
|
||||
@@ -1743,6 +1728,7 @@ meta_display_handle_xevent (MetaDisplay *display,
|
||||
}
|
||||
#endif
|
||||
|
||||
display->current_time = event_get_time (display, event);
|
||||
display->monitor_cache_invalidated = TRUE;
|
||||
|
||||
if (display->focused_by_us &&
|
||||
@@ -1838,42 +1824,44 @@ meta_display_handle_xevent (MetaDisplay *display,
|
||||
bypass_gtk = TRUE;
|
||||
}
|
||||
|
||||
display->current_time = event_get_time (display, event);
|
||||
display->current_time = CurrentTime;
|
||||
return bypass_gtk;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_idletime_for_event (const ClutterEvent *event)
|
||||
{
|
||||
ClutterInputDevice *device, *source_device;
|
||||
MetaIdleMonitor *core_monitor, *device_monitor;
|
||||
int device_id;
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
/* This is handled by XSync under X11. */
|
||||
#if defined(CLUTTER_WINDOWING_X11)
|
||||
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
|
||||
return;
|
||||
#endif
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
device = clutter_event_get_device (event);
|
||||
if (device == NULL)
|
||||
return;
|
||||
|
||||
device_id = clutter_input_device_get_device_id (device);
|
||||
|
||||
core_monitor = meta_idle_monitor_get_core ();
|
||||
device_monitor = meta_idle_monitor_get_for_device (device_id);
|
||||
|
||||
meta_idle_monitor_native_reset_idletime (core_monitor);
|
||||
meta_idle_monitor_native_reset_idletime (device_monitor);
|
||||
|
||||
source_device = clutter_event_get_source_device (event);
|
||||
if (source_device != device)
|
||||
if (META_IS_BACKEND_NATIVE (backend))
|
||||
{
|
||||
ClutterInputDevice *device, *source_device;
|
||||
MetaIdleMonitor *core_monitor, *device_monitor;
|
||||
int device_id;
|
||||
|
||||
device = clutter_event_get_device (event);
|
||||
if (device == NULL)
|
||||
return;
|
||||
|
||||
device_id = clutter_input_device_get_device_id (device);
|
||||
|
||||
core_monitor = meta_idle_monitor_get_core ();
|
||||
device_monitor = meta_idle_monitor_get_for_device (device_id);
|
||||
|
||||
meta_idle_monitor_native_reset_idletime (core_monitor);
|
||||
meta_idle_monitor_native_reset_idletime (device_monitor);
|
||||
|
||||
source_device = clutter_event_get_source_device (event);
|
||||
if (source_device != device)
|
||||
{
|
||||
device_id = clutter_input_device_get_device_id (device);
|
||||
device_monitor = meta_idle_monitor_get_for_device (device_id);
|
||||
meta_idle_monitor_native_reset_idletime (device_monitor);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_NATIVE_BACKEND */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1927,196 +1915,48 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
}
|
||||
}
|
||||
|
||||
switch (event->type)
|
||||
/* For key events, it's important to enforce single-handling, or
|
||||
* we can get into a confused state. So if a keybinding is
|
||||
* handled (because it's one of our hot-keys, or because we are
|
||||
* in a keyboard-grabbed mode like moving a window, we don't
|
||||
* want to pass the key event to the compositor or Wayland at all.
|
||||
*/
|
||||
if (meta_keybindings_process_event (display, window, event))
|
||||
{
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
if (grab_op_should_block_mouse_events (display->grab_op))
|
||||
break;
|
||||
bypass_clutter = TRUE;
|
||||
bypass_wayland = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
display->overlay_key_only_pressed = FALSE;
|
||||
if (window)
|
||||
{
|
||||
/* Swallow all events on windows that come our way. */
|
||||
bypass_clutter = TRUE;
|
||||
|
||||
if (window && display->grab_op == META_GRAB_OP_NONE)
|
||||
{
|
||||
ClutterModifierType grab_mask;
|
||||
gboolean unmodified;
|
||||
gboolean fully_modified;
|
||||
|
||||
grab_mask = display->window_grab_modifiers;
|
||||
if (g_getenv ("MUTTER_DEBUG_BUTTON_GRABS"))
|
||||
grab_mask |= CLUTTER_CONTROL_MASK;
|
||||
|
||||
/* We have three passive button grabs:
|
||||
* - on any button, without modifiers => focuses and maybe raises the window
|
||||
* - on resize button, with modifiers => start an interactive resizing
|
||||
* (normally <Super>middle)
|
||||
* - on move button, with modifiers => start an interactive move
|
||||
* (normally <Super>left)
|
||||
* - on menu button, with modifiers => show the window menu
|
||||
* (normally <Super>right)
|
||||
*
|
||||
* We may get here because we actually have a button
|
||||
* grab on the window, or because we're a wayland
|
||||
* compositor and thus we see all the events, so we
|
||||
* need to check if the event is interesting.
|
||||
* We want an event that is not modified, for a window
|
||||
* that has (or would have, the wayland case) the
|
||||
* button grab active.
|
||||
*
|
||||
* We may have other events on the window, for example
|
||||
* a click on a frame button, but that's not for us to
|
||||
* care about. Just let the event through.
|
||||
*/
|
||||
unmodified = (event->button.modifier_state & grab_mask) == 0;
|
||||
fully_modified = grab_mask && (event->button.modifier_state & grab_mask) == grab_mask;
|
||||
|
||||
if (unmodified && window && window->have_focus_click_grab)
|
||||
{
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
meta_window_raise (window);
|
||||
else
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Not raising window on click due to don't-raise-on-click option\n");
|
||||
|
||||
/* Don't focus panels--they must explicitly request focus.
|
||||
* See bug 160470
|
||||
*/
|
||||
if (window->type != META_WINDOW_DOCK)
|
||||
{
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Focusing %s due to unmodified button %u press (display.c)\n",
|
||||
window->desc, event->button.button);
|
||||
meta_window_focus (window, event->any.time);
|
||||
}
|
||||
else
|
||||
/* However, do allow terminals to lose focus due to new
|
||||
* window mappings after the user clicks on a panel.
|
||||
*/
|
||||
display->allow_terminal_deactivation = TRUE;
|
||||
|
||||
meta_verbose ("Allowing events time %u\n",
|
||||
(unsigned int)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));
|
||||
XIAllowEvents (xdisplay, clutter_input_device_get_device_id (event->button.device),
|
||||
XIReplayDevice, event->button.time);
|
||||
}
|
||||
}
|
||||
|
||||
bypass_clutter = TRUE;
|
||||
}
|
||||
else if (fully_modified && (int) event->button.button == meta_prefs_get_mouse_button_resize ())
|
||||
{
|
||||
if (window->has_resize_func)
|
||||
{
|
||||
gboolean north, south;
|
||||
gboolean west, east;
|
||||
MetaRectangle frame_rect;
|
||||
MetaGrabOp op;
|
||||
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
|
||||
west = event->button.x < (frame_rect.x + 1 * frame_rect.width / 3);
|
||||
east = event->button.x > (frame_rect.x + 2 * frame_rect.width / 3);
|
||||
north = event->button.y < (frame_rect.y + 1 * frame_rect.height / 3);
|
||||
south = event->button.y > (frame_rect.y + 2 * frame_rect.height / 3);
|
||||
|
||||
if (north && west)
|
||||
op = META_GRAB_OP_RESIZING_NW;
|
||||
else if (north && east)
|
||||
op = META_GRAB_OP_RESIZING_NE;
|
||||
else if (south && west)
|
||||
op = META_GRAB_OP_RESIZING_SW;
|
||||
else if (south && east)
|
||||
op = META_GRAB_OP_RESIZING_SE;
|
||||
else if (north)
|
||||
op = META_GRAB_OP_RESIZING_N;
|
||||
else if (west)
|
||||
op = META_GRAB_OP_RESIZING_W;
|
||||
else if (east)
|
||||
op = META_GRAB_OP_RESIZING_E;
|
||||
else if (south)
|
||||
op = META_GRAB_OP_RESIZING_S;
|
||||
else /* Middle region is no-op to avoid user triggering wrong action */
|
||||
op = META_GRAB_OP_NONE;
|
||||
|
||||
if (op != META_GRAB_OP_NONE)
|
||||
meta_display_begin_grab_op (display,
|
||||
window->screen,
|
||||
window,
|
||||
op,
|
||||
TRUE,
|
||||
FALSE,
|
||||
event->button.button,
|
||||
0,
|
||||
event->any.time,
|
||||
event->button.x,
|
||||
event->button.y);
|
||||
}
|
||||
bypass_clutter = TRUE;
|
||||
bypass_wayland = TRUE;
|
||||
}
|
||||
else if (fully_modified && (int) event->button.button == meta_prefs_get_mouse_button_menu ())
|
||||
{
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
meta_window_raise (window);
|
||||
meta_window_show_menu (window,
|
||||
event->button.x,
|
||||
event->button.y,
|
||||
event->button.button,
|
||||
event->any.time);
|
||||
bypass_clutter = TRUE;
|
||||
bypass_wayland = TRUE;
|
||||
}
|
||||
else if (fully_modified && (int) event->button.button == 1)
|
||||
{
|
||||
if (window->has_move_func)
|
||||
{
|
||||
meta_display_begin_grab_op (display,
|
||||
window->screen,
|
||||
window,
|
||||
META_GRAB_OP_MOVING,
|
||||
TRUE,
|
||||
FALSE,
|
||||
event->button.button,
|
||||
0,
|
||||
event->any.time,
|
||||
event->button.x,
|
||||
event->button.y);
|
||||
}
|
||||
bypass_clutter = TRUE;
|
||||
bypass_wayland = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
if (grab_op_should_block_mouse_events (display->grab_op))
|
||||
break;
|
||||
|
||||
display->overlay_key_only_pressed = FALSE;
|
||||
break;
|
||||
|
||||
case CLUTTER_KEY_PRESS:
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
/* For key events, it's important to enforce single-handling, or
|
||||
* we can get into a confused state. So if a keybinding is
|
||||
* handled (because it's one of our hot-keys, or because we are
|
||||
* in a keyboard-grabbed mode like moving a window, we don't
|
||||
* want to pass the key event to the compositor or Wayland at all.
|
||||
/* 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_display_process_key_event (display, window, (ClutterKeyEvent *) event))
|
||||
if (meta_window_handle_ungrabbed_event (window, event))
|
||||
{
|
||||
bypass_clutter = TRUE;
|
||||
bypass_wayland = TRUE;
|
||||
}
|
||||
break;
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -2134,6 +1974,7 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
bypass_clutter = TRUE;
|
||||
}
|
||||
|
||||
display->current_time = CurrentTime;
|
||||
return bypass_clutter;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
/* Mutter X window decorations */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2003, 2004 Red Hat, Inc.
|
||||
* Copyright (C) 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -16,7 +16,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -43,10 +43,10 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
Visual *visual;
|
||||
gulong create_serial;
|
||||
MetaStackWindow stack_window;
|
||||
|
||||
|
||||
if (window->frame)
|
||||
return;
|
||||
|
||||
|
||||
frame = g_new (MetaFrame, 1);
|
||||
|
||||
frame->window = window;
|
||||
@@ -61,7 +61,7 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
|
||||
frame->is_flashing = FALSE;
|
||||
frame->borders_cached = FALSE;
|
||||
|
||||
|
||||
meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
|
||||
window->desc,
|
||||
XVisualIDFromVisual (window->xvisual) ==
|
||||
@@ -71,7 +71,7 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
meta_verbose ("Frame geometry %d,%d %dx%d\n",
|
||||
frame->rect.x, frame->rect.y,
|
||||
frame->rect.width, frame->rect.height);
|
||||
|
||||
|
||||
/* Default depth/visual handles clients with weird visuals; they can
|
||||
* always be children of the root depth/visual obviously, but
|
||||
* e.g. DRI games can't be children of a parent that has the same
|
||||
@@ -80,7 +80,7 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
* We look for an ARGB visual if we can find one, otherwise use
|
||||
* the default of NULL.
|
||||
*/
|
||||
|
||||
|
||||
/* Special case for depth 32 windows (assumed to be ARGB),
|
||||
* we use the window's visual. Otherwise we just use the system visual.
|
||||
*/
|
||||
@@ -88,7 +88,7 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
visual = window->xvisual;
|
||||
else
|
||||
visual = NULL;
|
||||
|
||||
|
||||
frame->xwindow = meta_ui_create_frame_window (window->screen->ui,
|
||||
window->display->xdisplay,
|
||||
visual,
|
||||
@@ -108,7 +108,7 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
attrs.event_mask = EVENT_MASK;
|
||||
XChangeWindowAttributes (window->display->xdisplay,
|
||||
frame->xwindow, CWEventMask, &attrs);
|
||||
|
||||
|
||||
meta_display_register_x_window (window->display, &frame->xwindow, window);
|
||||
|
||||
meta_error_trap_push (window->display);
|
||||
@@ -121,9 +121,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
"Incrementing unmaps_pending on %s for reparent\n", window->desc);
|
||||
window->unmaps_pending += 1;
|
||||
}
|
||||
/* window was reparented to this position */
|
||||
window->rect.x = 0;
|
||||
window->rect.y = 0;
|
||||
|
||||
stack_window.x11.xwindow = window->xwindow;
|
||||
meta_stack_tracker_record_remove (window->screen->stack_tracker,
|
||||
@@ -132,11 +129,11 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
XReparentWindow (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
frame->xwindow,
|
||||
window->rect.x,
|
||||
window->rect.y);
|
||||
frame->child_x,
|
||||
frame->child_y);
|
||||
/* FIXME handle this error */
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
|
||||
/* stick frame to the window */
|
||||
window->frame = frame;
|
||||
|
||||
@@ -145,16 +142,21 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
*/
|
||||
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,
|
||||
window->frame->xwindow,
|
||||
window->title);
|
||||
|
||||
meta_ui_map_frame (frame->window->screen->ui, frame->xwindow);
|
||||
|
||||
/* Since the backend takes keygrabs on another connection, make sure
|
||||
* to sync the GTK+ connection to ensure that the frame window has
|
||||
* been created on the server at this point. */
|
||||
XSync (window->display->xdisplay, False);
|
||||
|
||||
/* Move keybindings to frame instead of window */
|
||||
meta_window_grab_keys (window);
|
||||
|
||||
meta_ui_map_frame (frame->window->screen->ui, frame->xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -163,18 +165,18 @@ meta_window_destroy_frame (MetaWindow *window)
|
||||
MetaFrame *frame;
|
||||
MetaFrameBorders borders;
|
||||
MetaStackWindow stack_window;
|
||||
|
||||
|
||||
if (window->frame == NULL)
|
||||
return;
|
||||
|
||||
meta_verbose ("Unframing window %s\n", window->desc);
|
||||
|
||||
|
||||
frame = window->frame;
|
||||
|
||||
meta_frame_calc_borders (frame, &borders);
|
||||
|
||||
|
||||
meta_bell_notify_frame_destroy (frame);
|
||||
|
||||
|
||||
/* Unparent the client window; it may be destroyed,
|
||||
* thus the error trap.
|
||||
*/
|
||||
@@ -197,7 +199,7 @@ meta_window_destroy_frame (MetaWindow *window)
|
||||
XReparentWindow (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
window->screen->xroot,
|
||||
/* Using anything other than meta_window_get_position()
|
||||
/* Using anything other than client root window coordinates
|
||||
* coordinates here means we'll need to ensure a configure
|
||||
* notify event is sent; see bug 399552.
|
||||
*/
|
||||
@@ -209,7 +211,7 @@ meta_window_destroy_frame (MetaWindow *window)
|
||||
|
||||
meta_display_unregister_x_window (window->display,
|
||||
frame->xwindow);
|
||||
|
||||
|
||||
window->frame = NULL;
|
||||
if (window->frame_bounds)
|
||||
{
|
||||
@@ -219,9 +221,9 @@ meta_window_destroy_frame (MetaWindow *window)
|
||||
|
||||
/* Move keybindings to window instead of frame */
|
||||
meta_window_grab_keys (window);
|
||||
|
||||
|
||||
g_free (frame);
|
||||
|
||||
|
||||
/* Put our state back where it should be */
|
||||
meta_window_queue (window, META_QUEUE_CALC_SHOWING);
|
||||
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
|
||||
@@ -244,20 +246,24 @@ meta_frame_get_flags (MetaFrame *frame)
|
||||
else
|
||||
{
|
||||
flags |= META_FRAME_ALLOWS_MENU;
|
||||
|
||||
|
||||
if (meta_prefs_get_show_fallback_app_menu () &&
|
||||
frame->window->gtk_app_menu_object_path)
|
||||
flags |= META_FRAME_ALLOWS_APPMENU;
|
||||
|
||||
if (frame->window->has_close_func)
|
||||
flags |= META_FRAME_ALLOWS_DELETE;
|
||||
|
||||
|
||||
if (frame->window->has_maximize_func)
|
||||
flags |= META_FRAME_ALLOWS_MAXIMIZE;
|
||||
|
||||
|
||||
if (frame->window->has_minimize_func)
|
||||
flags |= META_FRAME_ALLOWS_MINIMIZE;
|
||||
|
||||
|
||||
if (frame->window->has_shade_func)
|
||||
flags |= META_FRAME_ALLOWS_SHADE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (META_WINDOW_ALLOWS_MOVE (frame->window))
|
||||
flags |= META_FRAME_ALLOWS_MOVE;
|
||||
|
||||
@@ -266,7 +272,7 @@ meta_frame_get_flags (MetaFrame *frame)
|
||||
|
||||
if (META_WINDOW_ALLOWS_VERTICAL_RESIZE (frame->window))
|
||||
flags |= META_FRAME_ALLOWS_VERTICAL_RESIZE;
|
||||
|
||||
|
||||
if (meta_window_appears_focused (frame->window))
|
||||
flags |= META_FRAME_HAS_FOCUS;
|
||||
|
||||
@@ -296,7 +302,7 @@ meta_frame_get_flags (MetaFrame *frame)
|
||||
|
||||
if (frame->window->wm_state_above)
|
||||
flags |= META_FRAME_ABOVE;
|
||||
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
@@ -418,7 +424,7 @@ meta_frame_set_screen_cursor (MetaFrame *frame,
|
||||
if (cursor == META_CURSOR_DEFAULT)
|
||||
XUndefineCursor (frame->window->display->xdisplay, frame->xwindow);
|
||||
else
|
||||
{
|
||||
{
|
||||
xcursor = meta_display_create_x_cursor (frame->window->display, cursor);
|
||||
XDefineCursor (frame->window->display->xdisplay, frame->xwindow, xcursor);
|
||||
XFlush (frame->window->display->xdisplay);
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
/* Mutter X window decorations */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
* the one to close a window. It also deals with incoming key events.
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -19,7 +19,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -100,9 +100,9 @@ gboolean meta_window_grab_all_keys (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
void meta_window_ungrab_all_keys (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
gboolean meta_display_process_key_event (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
ClutterKeyEvent *event);
|
||||
gboolean meta_keybindings_process_event (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
const ClutterEvent *event);
|
||||
void meta_display_process_mapping_event (MetaDisplay *display,
|
||||
XEvent *event);
|
||||
|
||||
|
||||
@@ -57,7 +57,10 @@
|
||||
|
||||
#include "wayland/meta-wayland.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#endif
|
||||
|
||||
#define SCHEMA_COMMON_KEYBINDINGS "org.gnome.desktop.wm.keybindings"
|
||||
#define SCHEMA_MUTTER_KEYBINDINGS "org.gnome.mutter.keybindings"
|
||||
@@ -1081,7 +1084,7 @@ typedef struct
|
||||
{
|
||||
MetaDisplay *display;
|
||||
Window xwindow;
|
||||
gboolean binding_per_window;
|
||||
gboolean only_per_window;
|
||||
gboolean grab;
|
||||
} ChangeKeygrabData;
|
||||
|
||||
@@ -1092,29 +1095,31 @@ change_keygrab_foreach (gpointer key,
|
||||
{
|
||||
ChangeKeygrabData *data = user_data;
|
||||
MetaKeyBinding *binding = value;
|
||||
gboolean binding_is_per_window = (binding->flags & META_KEY_BINDING_PER_WINDOW) != 0;
|
||||
|
||||
if (!!data->binding_per_window ==
|
||||
!!(binding->flags & META_KEY_BINDING_PER_WINDOW) &&
|
||||
binding->keycode != 0)
|
||||
{
|
||||
meta_change_keygrab (data->display, data->xwindow, data->grab,
|
||||
binding->keysym,
|
||||
binding->keycode,
|
||||
binding->mask);
|
||||
}
|
||||
if (data->only_per_window != binding_is_per_window)
|
||||
return;
|
||||
|
||||
if (binding->keycode == 0)
|
||||
return;
|
||||
|
||||
meta_change_keygrab (data->display, data->xwindow, data->grab,
|
||||
binding->keysym,
|
||||
binding->keycode,
|
||||
binding->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
change_binding_keygrabs (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
gboolean binding_per_window,
|
||||
gboolean grab)
|
||||
change_binding_keygrabs (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
gboolean only_per_window,
|
||||
gboolean grab)
|
||||
{
|
||||
ChangeKeygrabData data;
|
||||
|
||||
data.display = display;
|
||||
data.xwindow = xwindow;
|
||||
data.binding_per_window = binding_per_window;
|
||||
data.only_per_window = only_per_window;
|
||||
data.grab = grab;
|
||||
|
||||
g_hash_table_foreach (display->key_bindings, change_keygrab_foreach, &data);
|
||||
@@ -1259,6 +1264,7 @@ guint
|
||||
meta_display_grab_accelerator (MetaDisplay *display,
|
||||
const char *accelerator)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaKeyBinding *binding;
|
||||
MetaKeyGrab *grab;
|
||||
guint keysym = 0;
|
||||
@@ -1284,7 +1290,8 @@ meta_display_grab_accelerator (MetaDisplay *display,
|
||||
if (display_get_keybinding (display, keycode, mask))
|
||||
return META_KEYBINDING_ACTION_NONE;
|
||||
|
||||
meta_change_keygrab (display, display->screen->xroot, TRUE, keysym, keycode, mask);
|
||||
if (META_IS_BACKEND_X11 (backend))
|
||||
meta_change_keygrab (display, display->screen->xroot, TRUE, keysym, keycode, mask);
|
||||
|
||||
grab = g_new0 (MetaKeyGrab, 1);
|
||||
grab->action = next_dynamic_keybinding_action ();
|
||||
@@ -1314,6 +1321,7 @@ gboolean
|
||||
meta_display_ungrab_accelerator (MetaDisplay *display,
|
||||
guint action)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaKeyBinding *binding;
|
||||
MetaKeyGrab *grab;
|
||||
char *key;
|
||||
@@ -1335,10 +1343,11 @@ meta_display_ungrab_accelerator (MetaDisplay *display,
|
||||
{
|
||||
guint32 index_key;
|
||||
|
||||
meta_change_keygrab (display, display->screen->xroot, FALSE,
|
||||
binding->keysym,
|
||||
binding->keycode,
|
||||
binding->mask);
|
||||
if (META_IS_BACKEND_X11 (backend))
|
||||
meta_change_keygrab (display, display->screen->xroot, FALSE,
|
||||
binding->keysym,
|
||||
binding->keycode,
|
||||
binding->mask);
|
||||
|
||||
index_key = key_binding_key (binding->keycode, binding->mask);
|
||||
g_hash_table_remove (display->key_bindings_index, GINT_TO_POINTER (index_key));
|
||||
@@ -1594,11 +1603,12 @@ process_overlay_key (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
Display *xdisplay;
|
||||
|
||||
if (!META_IS_BACKEND_X11 (backend))
|
||||
return FALSE;
|
||||
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
||||
if (META_IS_BACKEND_X11 (backend))
|
||||
xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
||||
else
|
||||
xdisplay = NULL;
|
||||
|
||||
if (display->overlay_key_only_pressed)
|
||||
{
|
||||
@@ -1624,17 +1634,22 @@ process_overlay_key (MetaDisplay *display,
|
||||
* binding, we unfreeze the keyboard but keep the grab
|
||||
* (this is important for something like cycling
|
||||
* windows */
|
||||
XIAllowEvents (xdisplay,
|
||||
clutter_input_device_get_device_id (event->device),
|
||||
XIAsyncDevice, event->time);
|
||||
|
||||
if (xdisplay)
|
||||
XIAllowEvents (xdisplay,
|
||||
clutter_input_device_get_device_id (event->device),
|
||||
XIAsyncDevice, event->time);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Replay the event so it gets delivered to our
|
||||
* per-window key bindings or to the application */
|
||||
XIAllowEvents (xdisplay,
|
||||
clutter_input_device_get_device_id (event->device),
|
||||
XIReplayDevice, event->time);
|
||||
if (xdisplay)
|
||||
XIAllowEvents (xdisplay,
|
||||
clutter_input_device_get_device_id (event->device),
|
||||
XIReplayDevice, event->time);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (event->type == CLUTTER_KEY_RELEASE)
|
||||
@@ -1645,9 +1660,10 @@ process_overlay_key (MetaDisplay *display,
|
||||
|
||||
/* We want to unfreeze events, but keep the grab so that if the user
|
||||
* starts typing into the overlay we get all the keys */
|
||||
XIAllowEvents (xdisplay,
|
||||
clutter_input_device_get_device_id (event->device),
|
||||
XIAsyncDevice, event->time);
|
||||
if (xdisplay)
|
||||
XIAllowEvents (xdisplay,
|
||||
clutter_input_device_get_device_id (event->device),
|
||||
XIAsyncDevice, event->time);
|
||||
|
||||
binding = display_get_keybinding (display,
|
||||
display->overlay_key_combo.keycode,
|
||||
@@ -1671,9 +1687,10 @@ process_overlay_key (MetaDisplay *display,
|
||||
*
|
||||
* https://bugzilla.gnome.org/show_bug.cgi?id=666101
|
||||
*/
|
||||
XIAllowEvents (xdisplay,
|
||||
clutter_input_device_get_device_id (event->device),
|
||||
XIAsyncDevice, event->time);
|
||||
if (xdisplay)
|
||||
XIAllowEvents (xdisplay,
|
||||
clutter_input_device_get_device_id (event->device),
|
||||
XIAsyncDevice, event->time);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -1684,9 +1701,10 @@ process_overlay_key (MetaDisplay *display,
|
||||
display->overlay_key_only_pressed = TRUE;
|
||||
/* We keep the keyboard frozen - this allows us to use ReplayKeyboard
|
||||
* on the next event if it's not the release of the overlay key */
|
||||
XIAllowEvents (xdisplay,
|
||||
clutter_input_device_get_device_id (event->device),
|
||||
XISyncDevice, event->time);
|
||||
if (xdisplay)
|
||||
XIAllowEvents (xdisplay,
|
||||
clutter_input_device_get_device_id (event->device),
|
||||
XISyncDevice, event->time);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1725,24 +1743,10 @@ process_iso_next_group (MetaDisplay *display,
|
||||
return activate;
|
||||
}
|
||||
|
||||
/* Handle a key event. May be called recursively: some key events cause
|
||||
* grabs to be ended and then need to be processed again in their own
|
||||
* right. This cannot cause infinite recursion because we never call
|
||||
* ourselves when there wasn't a grab, and we always clear the grab
|
||||
* first; the invariant is enforced using an assertion. See #112560.
|
||||
*
|
||||
* The return value is whether we handled the key event.
|
||||
*
|
||||
* FIXME: We need to prove there are no race conditions here.
|
||||
* FIXME: Does it correctly handle alt-Tab being followed by another
|
||||
* grabbing keypress without letting go of alt?
|
||||
* FIXME: An iterative solution would probably be simpler to understand
|
||||
* (and help us solve the other fixmes).
|
||||
*/
|
||||
gboolean
|
||||
meta_display_process_key_event (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
ClutterKeyEvent *event)
|
||||
static gboolean
|
||||
process_key_event (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
ClutterKeyEvent *event)
|
||||
{
|
||||
gboolean keep_grab;
|
||||
gboolean all_keys_grabbed;
|
||||
@@ -1840,6 +1844,41 @@ meta_display_process_key_event (MetaDisplay *display,
|
||||
return process_event (display, screen, window, event);
|
||||
}
|
||||
|
||||
/* Handle a key event. May be called recursively: some key events cause
|
||||
* grabs to be ended and then need to be processed again in their own
|
||||
* right. This cannot cause infinite recursion because we never call
|
||||
* ourselves when there wasn't a grab, and we always clear the grab
|
||||
* first; the invariant is enforced using an assertion. See #112560.
|
||||
*
|
||||
* The return value is whether we handled the key event.
|
||||
*
|
||||
* FIXME: We need to prove there are no race conditions here.
|
||||
* FIXME: Does it correctly handle alt-Tab being followed by another
|
||||
* grabbing keypress without letting go of alt?
|
||||
* FIXME: An iterative solution would probably be simpler to understand
|
||||
* (and help us solve the other fixmes).
|
||||
*/
|
||||
gboolean
|
||||
meta_keybindings_process_event (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
display->overlay_key_only_pressed = FALSE;
|
||||
return FALSE;
|
||||
|
||||
case CLUTTER_KEY_PRESS:
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
return process_key_event (display, window, (ClutterKeyEvent *) event);
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_mouse_move_resize_grab (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
@@ -1870,12 +1909,12 @@ process_mouse_move_resize_grab (MetaDisplay *display,
|
||||
else if (window->tile_mode != META_TILE_NONE)
|
||||
meta_window_tile (window);
|
||||
else
|
||||
meta_window_move_resize (display->grab_window,
|
||||
TRUE,
|
||||
display->grab_initial_window_pos.x,
|
||||
display->grab_initial_window_pos.y,
|
||||
display->grab_initial_window_pos.width,
|
||||
display->grab_initial_window_pos.height);
|
||||
meta_window_move_resize_frame (display->grab_window,
|
||||
TRUE,
|
||||
display->grab_initial_window_pos.x,
|
||||
display->grab_initial_window_pos.y,
|
||||
display->grab_initial_window_pos.width,
|
||||
display->grab_initial_window_pos.height);
|
||||
|
||||
/* End grab */
|
||||
return FALSE;
|
||||
@@ -1891,6 +1930,7 @@ process_keyboard_move_grab (MetaDisplay *display,
|
||||
ClutterKeyEvent *event)
|
||||
{
|
||||
gboolean handled;
|
||||
MetaRectangle frame_rect;
|
||||
int x, y;
|
||||
int incr;
|
||||
gboolean smart_snap;
|
||||
@@ -1905,7 +1945,9 @@ process_keyboard_move_grab (MetaDisplay *display,
|
||||
if (is_modifier (event->keyval))
|
||||
return TRUE;
|
||||
|
||||
meta_window_get_position (window, &x, &y);
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
x = frame_rect.x;
|
||||
y = frame_rect.y;
|
||||
|
||||
smart_snap = (event->modifier_state & CLUTTER_SHIFT_MASK) != 0;
|
||||
|
||||
@@ -1929,12 +1971,12 @@ process_keyboard_move_grab (MetaDisplay *display,
|
||||
if (window->shaken_loose)
|
||||
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||
else
|
||||
meta_window_move_resize (display->grab_window,
|
||||
TRUE,
|
||||
display->grab_initial_window_pos.x,
|
||||
display->grab_initial_window_pos.y,
|
||||
display->grab_initial_window_pos.width,
|
||||
display->grab_initial_window_pos.height);
|
||||
meta_window_move_resize_frame (display->grab_window,
|
||||
TRUE,
|
||||
display->grab_initial_window_pos.x,
|
||||
display->grab_initial_window_pos.y,
|
||||
display->grab_initial_window_pos.width,
|
||||
display->grab_initial_window_pos.height);
|
||||
}
|
||||
|
||||
/* When moving by increments, we still snap to edges if the move
|
||||
@@ -1980,23 +2022,18 @@ process_keyboard_move_grab (MetaDisplay *display,
|
||||
|
||||
if (handled)
|
||||
{
|
||||
MetaRectangle old_rect;
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Computed new window location %d,%d due to keypress\n",
|
||||
x, y);
|
||||
|
||||
meta_window_get_client_root_coords (window, &old_rect);
|
||||
|
||||
meta_window_edge_resistance_for_move (window,
|
||||
old_rect.x,
|
||||
old_rect.y,
|
||||
&x,
|
||||
&y,
|
||||
NULL,
|
||||
smart_snap,
|
||||
TRUE);
|
||||
|
||||
meta_window_move (window, TRUE, x, y);
|
||||
meta_window_move_frame (window, TRUE, x, y);
|
||||
meta_window_update_keyboard_move (window);
|
||||
}
|
||||
|
||||
@@ -2130,6 +2167,7 @@ process_keyboard_resize_grab (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
ClutterKeyEvent *event)
|
||||
{
|
||||
MetaRectangle frame_rect;
|
||||
gboolean handled;
|
||||
int height_inc;
|
||||
int width_inc;
|
||||
@@ -2150,12 +2188,12 @@ process_keyboard_resize_grab (MetaDisplay *display,
|
||||
if (event->keyval == CLUTTER_KEY_Escape)
|
||||
{
|
||||
/* End resize and restore to original state. */
|
||||
meta_window_move_resize (display->grab_window,
|
||||
TRUE,
|
||||
display->grab_initial_window_pos.x,
|
||||
display->grab_initial_window_pos.y,
|
||||
display->grab_initial_window_pos.width,
|
||||
display->grab_initial_window_pos.height);
|
||||
meta_window_move_resize_frame (display->grab_window,
|
||||
TRUE,
|
||||
display->grab_initial_window_pos.x,
|
||||
display->grab_initial_window_pos.y,
|
||||
display->grab_initial_window_pos.width,
|
||||
display->grab_initial_window_pos.height);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2166,6 +2204,10 @@ process_keyboard_resize_grab (MetaDisplay *display,
|
||||
width = window->rect.width;
|
||||
height = window->rect.height;
|
||||
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
width = frame_rect.width;
|
||||
height = frame_rect.height;
|
||||
|
||||
gravity = meta_resize_gravity_from_grab_op (display->grab_op);
|
||||
|
||||
smart_snap = (event->modifier_state & CLUTTER_SHIFT_MASK) != 0;
|
||||
@@ -2323,18 +2365,13 @@ process_keyboard_resize_grab (MetaDisplay *display,
|
||||
|
||||
if (handled)
|
||||
{
|
||||
MetaRectangle old_rect;
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Computed new window size due to keypress: "
|
||||
"%dx%d, gravity %s\n",
|
||||
width, height, meta_gravity_to_string (gravity));
|
||||
|
||||
old_rect = window->rect; /* Don't actually care about x,y */
|
||||
|
||||
/* Do any edge resistance/snapping */
|
||||
meta_window_edge_resistance_for_resize (window,
|
||||
old_rect.width,
|
||||
old_rect.height,
|
||||
&width,
|
||||
&height,
|
||||
gravity,
|
||||
@@ -2342,15 +2379,11 @@ process_keyboard_resize_grab (MetaDisplay *display,
|
||||
smart_snap,
|
||||
TRUE);
|
||||
|
||||
/* We don't need to update unless the specified width and height
|
||||
* are actually different from what we had before.
|
||||
*/
|
||||
if (window->rect.width != width || window->rect.height != height)
|
||||
meta_window_resize_with_gravity (window,
|
||||
TRUE,
|
||||
width,
|
||||
height,
|
||||
gravity);
|
||||
meta_window_resize_frame_with_gravity (window,
|
||||
TRUE,
|
||||
width,
|
||||
height,
|
||||
gravity);
|
||||
|
||||
meta_window_update_keyboard_resize (window, FALSE);
|
||||
}
|
||||
@@ -2455,46 +2488,58 @@ handle_always_on_top (MetaDisplay *display,
|
||||
meta_window_unmake_above (window);
|
||||
}
|
||||
|
||||
/* Move a window to a corner; to_bottom/to_right are FALSE for the
|
||||
* top or left edge, or TRUE for the bottom/right edge. xchange/ychange
|
||||
* are FALSE if that dimension is not to be changed, TRUE otherwise.
|
||||
* Together they describe which of the four corners, or four sides,
|
||||
* is desired.
|
||||
*/
|
||||
static void
|
||||
handle_move_to_corner_backend (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
gboolean xchange,
|
||||
gboolean ychange,
|
||||
gboolean to_right,
|
||||
gboolean to_bottom,
|
||||
gpointer dummy)
|
||||
handle_move_to_corner_backend (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
int gravity)
|
||||
{
|
||||
MetaRectangle work_area;
|
||||
MetaRectangle frame_rect;
|
||||
int orig_x, orig_y;
|
||||
int new_x, new_y;
|
||||
|
||||
meta_window_get_work_area_all_monitors (window, &work_area);
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
meta_window_get_position (window, &orig_x, &orig_y);
|
||||
|
||||
if (xchange) {
|
||||
new_x = work_area.x + (to_right ?
|
||||
work_area.width - frame_rect.width :
|
||||
0);
|
||||
} else {
|
||||
new_x = orig_x;
|
||||
}
|
||||
switch (gravity)
|
||||
{
|
||||
case NorthWestGravity:
|
||||
case WestGravity:
|
||||
case SouthWestGravity:
|
||||
new_x = work_area.x;
|
||||
break;
|
||||
case NorthGravity:
|
||||
case SouthGravity:
|
||||
new_x = frame_rect.x;
|
||||
break;
|
||||
case NorthEastGravity:
|
||||
case EastGravity:
|
||||
case SouthEastGravity:
|
||||
new_x = work_area.x + work_area.width - frame_rect.width;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (ychange) {
|
||||
new_y = work_area.y + (to_bottom ?
|
||||
work_area.height - frame_rect.height :
|
||||
0);
|
||||
} else {
|
||||
new_y = orig_y;
|
||||
}
|
||||
switch (gravity)
|
||||
{
|
||||
case NorthWestGravity:
|
||||
case NorthGravity:
|
||||
case NorthEastGravity:
|
||||
new_y = work_area.y;
|
||||
break;
|
||||
case WestGravity:
|
||||
case EastGravity:
|
||||
new_y = frame_rect.y;
|
||||
break;
|
||||
case SouthWestGravity:
|
||||
case SouthGravity:
|
||||
case SouthEastGravity:
|
||||
new_y = work_area.y + work_area.height - frame_rect.height;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
meta_window_move_frame (window,
|
||||
TRUE,
|
||||
@@ -2510,7 +2555,7 @@ handle_move_to_corner_nw (MetaDisplay *display,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, FALSE, FALSE, dummy);
|
||||
handle_move_to_corner_backend (display, screen, window, NorthWestGravity);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2521,7 +2566,7 @@ handle_move_to_corner_ne (MetaDisplay *display,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, TRUE, FALSE, dummy);
|
||||
handle_move_to_corner_backend (display, screen, window, NorthEastGravity);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2532,7 +2577,7 @@ handle_move_to_corner_sw (MetaDisplay *display,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, FALSE, TRUE, dummy);
|
||||
handle_move_to_corner_backend (display, screen, window, SouthWestGravity);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2543,7 +2588,7 @@ handle_move_to_corner_se (MetaDisplay *display,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, TRUE, TRUE, TRUE, TRUE, dummy);
|
||||
handle_move_to_corner_backend (display, screen, window, SouthEastGravity);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2554,7 +2599,7 @@ handle_move_to_side_n (MetaDisplay *display,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, FALSE, TRUE, FALSE, FALSE, dummy);
|
||||
handle_move_to_corner_backend (display, screen, window, NorthGravity);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2565,7 +2610,7 @@ handle_move_to_side_s (MetaDisplay *display,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, FALSE, TRUE, FALSE, TRUE, dummy);
|
||||
handle_move_to_corner_backend (display, screen, window, SouthGravity);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2576,7 +2621,7 @@ handle_move_to_side_e (MetaDisplay *display,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, TRUE, FALSE, TRUE, FALSE, dummy);
|
||||
handle_move_to_corner_backend (display, screen, window, EastGravity);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2587,7 +2632,7 @@ handle_move_to_side_w (MetaDisplay *display,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
{
|
||||
handle_move_to_corner_backend (display, screen, window, TRUE, FALSE, FALSE, FALSE, dummy);
|
||||
handle_move_to_corner_backend (display, screen, window, WestGravity);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2600,22 +2645,14 @@ handle_move_to_center (MetaDisplay *display,
|
||||
{
|
||||
MetaRectangle work_area;
|
||||
MetaRectangle frame_rect;
|
||||
int orig_x, orig_y;
|
||||
int frame_width, frame_height;
|
||||
|
||||
meta_window_get_work_area_all_monitors (window, &work_area);
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
meta_window_get_position (window, &orig_x, &orig_y);
|
||||
|
||||
frame_width = (window->frame ? window->frame->child_x : 0);
|
||||
frame_height = (window->frame ? window->frame->child_y : 0);
|
||||
|
||||
meta_window_move_resize (window,
|
||||
TRUE,
|
||||
work_area.x + (work_area.width +frame_width -frame_rect.width )/2,
|
||||
work_area.y + (work_area.height+frame_height-frame_rect.height)/2,
|
||||
window->rect.width,
|
||||
window->rect.height);
|
||||
meta_window_move_frame (window,
|
||||
TRUE,
|
||||
work_area.x + (work_area.width - frame_rect.width ) / 2,
|
||||
work_area.y + (work_area.height - frame_rect.height) / 2);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2700,17 +2737,18 @@ handle_activate_window_menu (MetaDisplay *display,
|
||||
if (display->focus_window)
|
||||
{
|
||||
int x, y;
|
||||
MetaRectangle frame_rect;
|
||||
cairo_rectangle_int_t child_rect;
|
||||
|
||||
meta_window_get_position (display->focus_window,
|
||||
&x, &y);
|
||||
meta_window_get_frame_rect (display->focus_window, &frame_rect);
|
||||
meta_window_get_client_area_rect (display->focus_window, &child_rect);
|
||||
|
||||
x = frame_rect.x + child_rect.x;
|
||||
if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
|
||||
x += display->focus_window->rect.width;
|
||||
x += child_rect.width;
|
||||
|
||||
meta_window_show_menu (display->focus_window,
|
||||
x, y,
|
||||
0,
|
||||
event->time);
|
||||
y = frame_rect.y + child_rect.y;
|
||||
meta_window_show_menu (display->focus_window, META_WINDOW_MENU_WM, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2723,7 +2761,7 @@ do_choose_window (MetaDisplay *display,
|
||||
gboolean backward)
|
||||
{
|
||||
MetaTabList type = binding->handler->data;
|
||||
MetaWindow *initial_selection;
|
||||
MetaWindow *window;
|
||||
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Tab list = %u\n", type);
|
||||
@@ -2732,13 +2770,14 @@ do_choose_window (MetaDisplay *display,
|
||||
if (event->modifier_state & CLUTTER_SHIFT_MASK)
|
||||
backward = !backward;
|
||||
|
||||
initial_selection = meta_display_get_tab_next (display,
|
||||
type,
|
||||
screen->active_workspace,
|
||||
NULL,
|
||||
backward);
|
||||
window = meta_display_get_tab_next (display,
|
||||
type,
|
||||
screen->active_workspace,
|
||||
NULL,
|
||||
backward);
|
||||
|
||||
meta_window_activate (initial_selection, event->time);
|
||||
if (window)
|
||||
meta_window_activate (window, event->time);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3130,6 +3169,7 @@ handle_set_spew_mark (MetaDisplay *display,
|
||||
meta_verbose ("-- MARK MARK MARK MARK --\n");
|
||||
}
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static void
|
||||
handle_switch_vt (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
@@ -3147,11 +3187,12 @@ handle_switch_vt (MetaDisplay *display,
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_NATIVE_BACKEND */
|
||||
|
||||
/**
|
||||
* meta_keybindings_set_custom_handler:
|
||||
* @name: The name of the keybinding to set
|
||||
* @handler: (allow-none): The new handler function
|
||||
* @handler: (nullable): The new handler function
|
||||
* @user_data: User data to pass to the callback
|
||||
* @free_data: Will be called when this handler is overridden.
|
||||
*
|
||||
@@ -3439,7 +3480,9 @@ init_builtin_key_bindings (MetaDisplay *display)
|
||||
META_KEYBINDING_ACTION_SET_SPEW_MARK,
|
||||
handle_set_spew_mark, 0);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
if (META_IS_BACKEND_NATIVE (backend))
|
||||
{
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-session-1",
|
||||
@@ -3490,6 +3533,7 @@ init_builtin_key_bindings (MetaDisplay *display)
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 7);
|
||||
}
|
||||
#endif /* HAVE_NATIVE_BACKEND */
|
||||
|
||||
#undef REVERSES_AND_REVERSED
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
/* Mutter main() */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -15,7 +15,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -160,7 +160,7 @@ meta_print_self_identity (void)
|
||||
g_date_strftime (buf, sizeof (buf), "%x", &d);
|
||||
meta_verbose ("Mutter version %s running on %s\n",
|
||||
VERSION, buf);
|
||||
|
||||
|
||||
/* Locale and encoding. */
|
||||
g_get_charset (&charset);
|
||||
meta_verbose ("Running in locale \"%s\" with encoding \"%s\"\n",
|
||||
@@ -181,7 +181,9 @@ static gboolean opt_replace_wm;
|
||||
static gboolean opt_disable_sm;
|
||||
static gboolean opt_sync;
|
||||
static gboolean opt_wayland;
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static gboolean opt_display_server;
|
||||
#endif
|
||||
|
||||
static GOptionEntry meta_options[] = {
|
||||
{
|
||||
@@ -225,11 +227,13 @@ static GOptionEntry meta_options[] = {
|
||||
N_("Run as a wayland compositor"),
|
||||
NULL
|
||||
},
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
{
|
||||
"display-server", 0, 0, G_OPTION_ARG_NONE,
|
||||
&opt_display_server,
|
||||
N_("Run as a full display server, rather than nested")
|
||||
},
|
||||
#endif
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@@ -332,8 +336,10 @@ meta_init (void)
|
||||
if (g_getenv ("MUTTER_DEBUG"))
|
||||
meta_set_debugging (TRUE);
|
||||
|
||||
#if defined(CLUTTER_WINDOWING_EGL) && defined(HAVE_NATIVE_BACKEND)
|
||||
if (opt_display_server)
|
||||
clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL);
|
||||
#endif
|
||||
|
||||
meta_set_is_wayland_compositor (opt_wayland);
|
||||
|
||||
@@ -343,7 +349,7 @@ meta_init (void)
|
||||
g_get_home_dir ());
|
||||
|
||||
meta_print_self_identity ();
|
||||
|
||||
|
||||
#ifdef HAVE_INTROSPECTION
|
||||
g_irepository_prepend_search_path (MUTTER_PKGLIBDIR);
|
||||
#endif
|
||||
@@ -358,13 +364,13 @@ meta_init (void)
|
||||
meta_select_display (opt_display_name);
|
||||
|
||||
meta_set_syncing (opt_sync || (g_getenv ("MUTTER_SYNC") != NULL));
|
||||
|
||||
|
||||
if (opt_replace_wm)
|
||||
meta_set_replace_current_wm (TRUE);
|
||||
|
||||
if (opt_save_file && opt_client_id)
|
||||
meta_fatal ("Can't specify both SM save file and SM client id\n");
|
||||
|
||||
|
||||
meta_main_loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
meta_ui_init ();
|
||||
@@ -455,7 +461,7 @@ meta_run (void)
|
||||
|
||||
if (g_getenv ("MUTTER_G_FATAL_WARNINGS") != NULL)
|
||||
g_log_set_always_fatal (G_LOG_LEVEL_MASK);
|
||||
|
||||
|
||||
meta_ui_set_current_theme (meta_prefs_get_theme ());
|
||||
|
||||
/* Try to find some theme that'll work if the theme preference
|
||||
@@ -464,37 +470,37 @@ meta_run (void)
|
||||
*/
|
||||
if (!meta_ui_have_a_theme ())
|
||||
meta_ui_set_current_theme ("Simple");
|
||||
|
||||
|
||||
if (!meta_ui_have_a_theme ())
|
||||
{
|
||||
const char *dir_entry = NULL;
|
||||
GError *err = NULL;
|
||||
GDir *themes_dir = NULL;
|
||||
|
||||
|
||||
if (!(themes_dir = g_dir_open (MUTTER_DATADIR"/themes", 0, &err)))
|
||||
{
|
||||
meta_fatal (_("Failed to scan themes directory: %s\n"), err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
while (((dir_entry = g_dir_read_name (themes_dir)) != NULL) &&
|
||||
while (((dir_entry = g_dir_read_name (themes_dir)) != NULL) &&
|
||||
(!meta_ui_have_a_theme ()))
|
||||
{
|
||||
meta_ui_set_current_theme (dir_entry);
|
||||
}
|
||||
|
||||
|
||||
g_dir_close (themes_dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!meta_ui_have_a_theme ())
|
||||
meta_fatal (_("Could not find a theme! Be sure %s exists and contains the usual themes.\n"),
|
||||
MUTTER_DATADIR"/themes");
|
||||
|
||||
if (!meta_display_open ())
|
||||
meta_exit (META_EXIT_ERROR);
|
||||
|
||||
|
||||
g_main_loop_run (meta_main_loop);
|
||||
|
||||
meta_finalize ();
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -75,6 +75,7 @@ main (int argc, char **argv)
|
||||
g_printerr ("mutter: %s\n", error->message);
|
||||
exit (1);
|
||||
}
|
||||
g_option_context_free (ctx);
|
||||
|
||||
if (plugin)
|
||||
meta_plugin_manager_load (plugin);
|
||||
|
||||
280
src/core/place.c
280
src/core/place.c
@@ -2,12 +2,12 @@
|
||||
|
||||
/* Mutter window placement */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2002, 2003 Red Hat, Inc.
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -17,7 +17,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -57,11 +57,11 @@ northwestcmp (gconstpointer a, gconstpointer b)
|
||||
ay = a_frame.y;
|
||||
bx = b_frame.x;
|
||||
by = b_frame.y;
|
||||
|
||||
|
||||
/* probably there's a fast good-enough-guess we could use here. */
|
||||
from_origin_a = sqrt (ax * ax + ay * ay);
|
||||
from_origin_b = sqrt (bx * bx + by * by);
|
||||
|
||||
|
||||
if (from_origin_a < from_origin_b)
|
||||
return -1;
|
||||
else if (from_origin_a > from_origin_b)
|
||||
@@ -82,40 +82,31 @@ find_next_cascade (MetaWindow *window,
|
||||
GList *tmp;
|
||||
GList *sorted;
|
||||
int cascade_x, cascade_y;
|
||||
MetaRectangle titlebar_rect;
|
||||
int x_threshold, y_threshold;
|
||||
MetaRectangle frame_rect;
|
||||
int window_width, window_height;
|
||||
int cascade_stage;
|
||||
MetaRectangle work_area;
|
||||
int current;
|
||||
|
||||
|
||||
sorted = g_list_copy (windows);
|
||||
sorted = g_list_sort (sorted, northwestcmp);
|
||||
|
||||
/* This is a "fuzzy" cascade algorithm.
|
||||
/* This is a "fuzzy" cascade algorithm.
|
||||
* For each window in the list, we find where we'd cascade a
|
||||
* new window after it. If a window is already nearly at that
|
||||
* position, we move on.
|
||||
*/
|
||||
|
||||
|
||||
/* arbitrary-ish threshold, honors user attempts to
|
||||
* manually cascade.
|
||||
*/
|
||||
#define CASCADE_FUZZ 15
|
||||
if (window->frame)
|
||||
{
|
||||
MetaFrameBorders borders;
|
||||
meta_window_get_titlebar_rect (window, &titlebar_rect);
|
||||
x_threshold = MAX (titlebar_rect.x, CASCADE_FUZZ);
|
||||
y_threshold = MAX (titlebar_rect.y, CASCADE_FUZZ);
|
||||
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
x_threshold = MAX (borders.visible.left, CASCADE_FUZZ);
|
||||
y_threshold = MAX (borders.visible.top, CASCADE_FUZZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
x_threshold = CASCADE_FUZZ;
|
||||
y_threshold = CASCADE_FUZZ;
|
||||
}
|
||||
|
||||
/* Find furthest-SE origin of all workspaces.
|
||||
* cascade_x, cascade_y are the target position
|
||||
* of NW corner of window frame.
|
||||
@@ -126,13 +117,13 @@ find_next_cascade (MetaWindow *window,
|
||||
|
||||
cascade_x = MAX (0, work_area.x);
|
||||
cascade_y = MAX (0, work_area.y);
|
||||
|
||||
|
||||
/* Find first cascade position that's not used. */
|
||||
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
window_width = frame_rect.width;
|
||||
window_height = frame_rect.height;
|
||||
|
||||
|
||||
cascade_stage = 0;
|
||||
tmp = sorted;
|
||||
while (tmp != NULL)
|
||||
@@ -140,25 +131,23 @@ find_next_cascade (MetaWindow *window,
|
||||
MetaWindow *w;
|
||||
MetaRectangle w_frame_rect;
|
||||
int wx, wy;
|
||||
|
||||
|
||||
w = tmp->data;
|
||||
|
||||
/* we want frame position, not window position */
|
||||
meta_window_get_frame_rect (w, &w_frame_rect);
|
||||
wx = w_frame_rect.x;
|
||||
wy = w_frame_rect.y;
|
||||
|
||||
|
||||
if (ABS (wx - cascade_x) < x_threshold &&
|
||||
ABS (wy - cascade_y) < y_threshold)
|
||||
{
|
||||
/* This window is "in the way", move to next cascade
|
||||
* point. The new window frame should go at the origin
|
||||
* of the client window we're stacking above.
|
||||
*/
|
||||
meta_window_get_position (w, &wx, &wy);
|
||||
cascade_x = wx;
|
||||
cascade_y = wy;
|
||||
|
||||
meta_window_get_titlebar_rect (w, &titlebar_rect);
|
||||
|
||||
/* Cascade the window evenly by the titlebar height; this isn't a typo. */
|
||||
cascade_x = wx + titlebar_rect.height;
|
||||
cascade_y = wy + titlebar_rect.height;
|
||||
|
||||
/* If we go off the screen, start over with a new cascade */
|
||||
if (((cascade_x + window_width) >
|
||||
(work_area.x + work_area.width)) ||
|
||||
@@ -167,11 +156,11 @@ find_next_cascade (MetaWindow *window,
|
||||
{
|
||||
cascade_x = MAX (0, work_area.x);
|
||||
cascade_y = MAX (0, work_area.y);
|
||||
|
||||
|
||||
#define CASCADE_INTERVAL 50 /* space between top-left corners of cascades */
|
||||
cascade_stage += 1;
|
||||
cascade_x += CASCADE_INTERVAL * cascade_stage;
|
||||
|
||||
|
||||
/* start over with a new cascade translated to the right, unless
|
||||
* we are out of space
|
||||
*/
|
||||
@@ -193,14 +182,14 @@ find_next_cascade (MetaWindow *window,
|
||||
{
|
||||
/* Keep searching for a further-down-the-diagonal window. */
|
||||
}
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
/* cascade_x and cascade_y will match the last window in the list
|
||||
* that was "in the way" (in the approximate cascade diagonal)
|
||||
*/
|
||||
|
||||
|
||||
g_list_free (sorted);
|
||||
|
||||
*new_x = cascade_x;
|
||||
@@ -376,12 +365,12 @@ rectangle_overlaps_some_window (MetaRectangle *rect,
|
||||
{
|
||||
GList *tmp;
|
||||
MetaRectangle dest;
|
||||
|
||||
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *other = tmp->data;
|
||||
MetaRectangle other_rect;
|
||||
MetaRectangle other_rect;
|
||||
|
||||
switch (other->type)
|
||||
{
|
||||
@@ -405,12 +394,12 @@ rectangle_overlaps_some_window (MetaRectangle *rect,
|
||||
case META_WINDOW_TOOLBAR:
|
||||
case META_WINDOW_MENU:
|
||||
meta_window_get_frame_rect (other, &other_rect);
|
||||
|
||||
|
||||
if (meta_rectangle_intersect (rect, &other_rect, &dest))
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
@@ -503,20 +492,20 @@ find_first_fit (MetaWindow *window,
|
||||
* the bottom of each existing window, and then to the right
|
||||
* of each existing window, aligned with the left/top of the
|
||||
* existing window in each of those cases.
|
||||
*/
|
||||
*/
|
||||
int retval;
|
||||
GList *below_sorted;
|
||||
GList *right_sorted;
|
||||
GList *tmp;
|
||||
MetaRectangle rect;
|
||||
MetaRectangle work_area;
|
||||
|
||||
|
||||
retval = FALSE;
|
||||
|
||||
/* Below each window */
|
||||
below_sorted = g_list_copy (windows);
|
||||
below_sorted = g_list_sort (below_sorted, leftmost_cmp);
|
||||
below_sorted = g_list_sort (below_sorted, topmost_cmp);
|
||||
below_sorted = g_list_sort (below_sorted, topmost_cmp);
|
||||
|
||||
/* To the right of each window */
|
||||
right_sorted = g_list_copy (windows);
|
||||
@@ -526,85 +515,84 @@ find_first_fit (MetaWindow *window,
|
||||
meta_window_get_frame_rect (window, &rect);
|
||||
|
||||
#ifdef WITH_VERBOSE_MODE
|
||||
{
|
||||
char monitor_location_string[RECT_LENGTH];
|
||||
meta_rectangle_to_string (&window->screen->monitor_infos[monitor].rect,
|
||||
monitor_location_string);
|
||||
meta_topic (META_DEBUG_XINERAMA,
|
||||
"Natural monitor is %s\n",
|
||||
monitor_location_string);
|
||||
}
|
||||
{
|
||||
char monitor_location_string[RECT_LENGTH];
|
||||
meta_rectangle_to_string (&window->screen->monitor_infos[monitor].rect,
|
||||
monitor_location_string);
|
||||
meta_topic (META_DEBUG_XINERAMA,
|
||||
"Natural monitor is %s\n",
|
||||
monitor_location_string);
|
||||
}
|
||||
#endif
|
||||
|
||||
meta_window_get_work_area_for_monitor (window, monitor, &work_area);
|
||||
meta_window_get_work_area_for_monitor (window, monitor, &work_area);
|
||||
|
||||
center_tile_rect_in_area (&rect, &work_area);
|
||||
center_tile_rect_in_area (&rect, &work_area);
|
||||
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, windows))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, windows))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
|
||||
/* try below each window */
|
||||
tmp = below_sorted;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle frame_rect;
|
||||
retval = TRUE;
|
||||
|
||||
meta_window_get_frame_rect (w, &frame_rect);
|
||||
|
||||
rect.x = frame_rect.x;
|
||||
rect.y = frame_rect.y + frame_rect.height;
|
||||
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, below_sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
/* try below each window */
|
||||
tmp = below_sorted;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle frame_rect;
|
||||
|
||||
/* try to the right of each window */
|
||||
tmp = right_sorted;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle frame_rect;
|
||||
|
||||
meta_window_get_frame_rect (w, &frame_rect);
|
||||
|
||||
rect.x = frame_rect.x + frame_rect.width;
|
||||
rect.y = frame_rect.y;
|
||||
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, right_sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
meta_window_get_frame_rect (w, &frame_rect);
|
||||
|
||||
rect.x = frame_rect.x;
|
||||
rect.y = frame_rect.y + frame_rect.height;
|
||||
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, below_sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
/* try to the right of each window */
|
||||
tmp = right_sorted;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle frame_rect;
|
||||
|
||||
meta_window_get_frame_rect (w, &frame_rect);
|
||||
|
||||
rect.x = frame_rect.x + frame_rect.width;
|
||||
rect.y = frame_rect.y;
|
||||
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, right_sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
g_list_free (below_sorted);
|
||||
g_list_free (right_sorted);
|
||||
return retval;
|
||||
@@ -617,13 +605,11 @@ meta_window_place (MetaWindow *window,
|
||||
int *new_x,
|
||||
int *new_y)
|
||||
{
|
||||
GList *windows;
|
||||
GList *windows = NULL;
|
||||
const MetaMonitorInfo *xi;
|
||||
|
||||
meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc);
|
||||
|
||||
windows = NULL;
|
||||
|
||||
switch (window->type)
|
||||
{
|
||||
/* Run placement algorithm on these. */
|
||||
@@ -632,7 +618,7 @@ meta_window_place (MetaWindow *window,
|
||||
case META_WINDOW_MODAL_DIALOG:
|
||||
case META_WINDOW_SPLASHSCREEN:
|
||||
break;
|
||||
|
||||
|
||||
/* Assume the app knows best how to place these, no placement
|
||||
* algorithm ever (other than "leave them as-is")
|
||||
*/
|
||||
@@ -649,7 +635,7 @@ meta_window_place (MetaWindow *window,
|
||||
case META_WINDOW_COMBO:
|
||||
case META_WINDOW_DND:
|
||||
case META_WINDOW_OVERRIDE_OTHER:
|
||||
goto done_no_constraints;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (meta_prefs_get_disable_workarounds ())
|
||||
@@ -675,7 +661,7 @@ meta_window_place (MetaWindow *window,
|
||||
case META_WINDOW_MODAL_DIALOG:
|
||||
case META_WINDOW_SPLASHSCREEN:
|
||||
break;
|
||||
|
||||
|
||||
/* Assume the app knows best how to place these. */
|
||||
case META_WINDOW_DESKTOP:
|
||||
case META_WINDOW_DOCK:
|
||||
@@ -694,7 +680,7 @@ meta_window_place (MetaWindow *window,
|
||||
{
|
||||
meta_topic (META_DEBUG_PLACEMENT,
|
||||
"Not placing non-normal non-dialog window with PPosition set\n");
|
||||
goto done_no_constraints;
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -702,14 +688,14 @@ meta_window_place (MetaWindow *window,
|
||||
else
|
||||
{
|
||||
/* workarounds enabled */
|
||||
|
||||
|
||||
if ((window->size_hints.flags & PPosition) ||
|
||||
(window->size_hints.flags & USPosition))
|
||||
{
|
||||
meta_topic (META_DEBUG_PLACEMENT,
|
||||
"Not placing window with PPosition or USPosition set\n");
|
||||
avoid_being_obscured_as_second_modal_dialog (window, &x, &y);
|
||||
goto done_no_constraints;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -739,17 +725,17 @@ meta_window_place (MetaWindow *window,
|
||||
|
||||
meta_topic (META_DEBUG_PLACEMENT, "Centered window %s over transient parent\n",
|
||||
window->desc);
|
||||
|
||||
|
||||
avoid_being_obscured_as_second_modal_dialog (window, &x, &y);
|
||||
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* FIXME UTILITY with transient set should be stacked up
|
||||
* on the sides of the parent window or something.
|
||||
*/
|
||||
|
||||
|
||||
if (window_place_centered (window))
|
||||
{
|
||||
/* Center on current monitor */
|
||||
@@ -769,13 +755,13 @@ meta_window_place (MetaWindow *window,
|
||||
|
||||
x += xi->rect.x;
|
||||
y += xi->rect.y;
|
||||
|
||||
|
||||
meta_topic (META_DEBUG_PLACEMENT, "Centered window %s on screen %d monitor %d\n",
|
||||
window->desc, window->screen->number, xi->number);
|
||||
|
||||
goto done_check_denied_focus;
|
||||
}
|
||||
|
||||
|
||||
/* Find windows that matter (not minimized, on same workspace
|
||||
* as placed window, may be shaded - if shaded we pretend it isn't
|
||||
* for placement purposes)
|
||||
@@ -783,7 +769,7 @@ meta_window_place (MetaWindow *window,
|
||||
{
|
||||
GSList *all_windows;
|
||||
GSList *tmp;
|
||||
|
||||
|
||||
all_windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
|
||||
|
||||
tmp = all_windows;
|
||||
@@ -804,19 +790,10 @@ meta_window_place (MetaWindow *window,
|
||||
|
||||
/* Warning, this is a round trip! */
|
||||
xi = meta_screen_get_current_monitor_info (window->screen);
|
||||
|
||||
/* "Origin" placement algorithm */
|
||||
x = xi->rect.x;
|
||||
y = xi->rect.y;
|
||||
|
||||
if (find_first_fit (window, windows,
|
||||
xi->number,
|
||||
x, y, &x, &y))
|
||||
goto done_check_denied_focus;
|
||||
|
||||
/* Maximize windows if they are too big for their work area (bit of
|
||||
* a hack here). Assume undecorated windows probably don't intend to
|
||||
* be maximized.
|
||||
* be maximized.
|
||||
*/
|
||||
if (window->has_maximize_func && window->decorated &&
|
||||
!window->fullscreen)
|
||||
@@ -826,9 +803,9 @@ meta_window_place (MetaWindow *window,
|
||||
|
||||
meta_window_get_work_area_for_monitor (window,
|
||||
xi->number,
|
||||
&workarea);
|
||||
&workarea);
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
|
||||
|
||||
/* If the window is bigger than the screen, then automaximize. Do NOT
|
||||
* auto-maximize the directions independently. See #419810.
|
||||
*/
|
||||
@@ -839,11 +816,17 @@ meta_window_place (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
/* If no placement has been done, revert to cascade to avoid
|
||||
* fully overlapping window (e.g. starting multiple terminals)
|
||||
* */
|
||||
if (x == xi->rect.x && y == xi->rect.y)
|
||||
find_next_cascade (window, windows, x, y, &x, &y);
|
||||
/* "Origin" placement algorithm */
|
||||
x = xi->rect.x;
|
||||
y = xi->rect.y;
|
||||
|
||||
if (find_first_fit (window, windows,
|
||||
xi->number,
|
||||
x, y, &x, &y))
|
||||
goto done_check_denied_focus;
|
||||
|
||||
/* No good fit? Fall back to cascading... */
|
||||
find_next_cascade (window, windows, x, y, &x, &y);
|
||||
|
||||
done_check_denied_focus:
|
||||
/* If the window is being denied focus and isn't a transient of the
|
||||
@@ -886,11 +869,10 @@ meta_window_place (MetaWindow *window,
|
||||
if (!found_fit)
|
||||
find_most_freespace (window, focus_window, x, y, &x, &y);
|
||||
}
|
||||
|
||||
|
||||
done:
|
||||
g_list_free (windows);
|
||||
|
||||
done_no_constraints:
|
||||
if (windows)
|
||||
g_list_free (windows);
|
||||
|
||||
*new_x = x;
|
||||
*new_y = y;
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
/* Mutter window placement */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
174
src/core/prefs.c
174
src/core/prefs.c
@@ -1,6 +1,6 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington, Copyright (C) 2002 Red Hat Inc.
|
||||
* Copyright (C) 2006 Elijah Newren
|
||||
* Copyright (C) 2008 Thomas Thurman
|
||||
@@ -15,7 +15,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -55,6 +55,7 @@
|
||||
#define KEY_GNOME_CURSOR_THEME "cursor-theme"
|
||||
#define KEY_GNOME_CURSOR_SIZE "cursor-size"
|
||||
#define KEY_XKB_OPTIONS "xkb-options"
|
||||
#define KEY_XSETTINGS_OVERRIDES "overrides"
|
||||
|
||||
#define KEY_OVERLAY_KEY "overlay-key"
|
||||
#define KEY_WORKSPACES_ONLY_ON_PRIMARY "workspaces-only-on-primary"
|
||||
@@ -65,6 +66,7 @@
|
||||
#define SCHEMA_MUTTER "org.gnome.mutter"
|
||||
#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 SETTINGS(s) g_hash_table_lookup (settings_schemas, (s))
|
||||
|
||||
@@ -104,6 +106,7 @@ static gboolean edge_tiling = FALSE;
|
||||
static gboolean force_fullscreen = TRUE;
|
||||
static gboolean ignore_request_hide_titlebar = FALSE;
|
||||
static gboolean auto_maximize = TRUE;
|
||||
static gboolean show_fallback_app_menu = FALSE;
|
||||
|
||||
static GDesktopVisualBellType visual_bell_type = G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH;
|
||||
static MetaButtonLayout button_layout;
|
||||
@@ -129,6 +132,10 @@ static void bindings_changed (GSettings *settings,
|
||||
gchar *key,
|
||||
gpointer data);
|
||||
|
||||
static void xsettings_overrides_changed (GSettings *settings,
|
||||
gchar *key,
|
||||
gpointer data);
|
||||
|
||||
static void queue_changed (MetaPreference pref);
|
||||
|
||||
static void maybe_give_disable_workarounds_warning (void);
|
||||
@@ -173,7 +180,7 @@ typedef struct
|
||||
|
||||
/**
|
||||
* MetaStringPreference:
|
||||
* @handler: (allow-none): A handler. Many of the string preferences
|
||||
* @handler: (nullable): A handler. Many of the string preferences
|
||||
* aren't stored as strings and need parsing; others of them have
|
||||
* default values which can't be solved in the general case. If you
|
||||
* include a function pointer here, it will be called instead of writing
|
||||
@@ -185,7 +192,7 @@ typedef struct
|
||||
* in particular the @result (out) parameter as returned by
|
||||
* g_settings_get_mapped() will be ignored in all cases.
|
||||
* This may be %NULL. If it is, see "target", below.
|
||||
* @target: (allow-none): Where to write the incoming string.
|
||||
* @target: (nullable): Where to write the incoming string.
|
||||
* This must be %NULL if the handler is non-%NULL.
|
||||
* If the incoming string is %NULL, no change will be made.
|
||||
*/
|
||||
@@ -615,7 +622,7 @@ handle_preference_init_int (void)
|
||||
{
|
||||
MetaIntPreference *cursor = preferences_int;
|
||||
|
||||
|
||||
|
||||
while (cursor->base.key != NULL)
|
||||
{
|
||||
if (cursor->target)
|
||||
@@ -671,7 +678,7 @@ handle_preference_update_bool (GSettings *settings,
|
||||
* store the current value away.
|
||||
*/
|
||||
old_value = *((gboolean *) cursor->target);
|
||||
|
||||
|
||||
/* Now look it up... */
|
||||
*((gboolean *) cursor->target) =
|
||||
g_settings_get_boolean (SETTINGS (cursor->base.schema), key);
|
||||
@@ -802,7 +809,7 @@ handle_preference_update_int (GSettings *settings,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Listeners. */
|
||||
/****************************************************************************/
|
||||
@@ -851,7 +858,7 @@ meta_prefs_remove_listener (MetaPrefsChangedFunc func,
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
@@ -866,9 +873,9 @@ emit_changed (MetaPreference pref)
|
||||
|
||||
meta_topic (META_DEBUG_PREFS, "Notifying listeners that pref %s changed\n",
|
||||
meta_preference_to_string (pref));
|
||||
|
||||
|
||||
copy = g_list_copy (listeners);
|
||||
|
||||
|
||||
tmp = copy;
|
||||
|
||||
while (tmp != NULL)
|
||||
@@ -890,24 +897,24 @@ changed_idle_handler (gpointer data)
|
||||
GList *copy;
|
||||
|
||||
changed_idle = 0;
|
||||
|
||||
|
||||
copy = g_list_copy (changes); /* reentrancy paranoia */
|
||||
|
||||
g_list_free (changes);
|
||||
changes = NULL;
|
||||
|
||||
|
||||
tmp = copy;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaPreference pref = GPOINTER_TO_INT (tmp->data);
|
||||
|
||||
emit_changed (pref);
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
g_list_free (copy);
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -915,7 +922,7 @@ static void
|
||||
queue_changed (MetaPreference pref)
|
||||
{
|
||||
meta_topic (META_DEBUG_PREFS, "Queueing change of pref %s\n",
|
||||
meta_preference_to_string (pref));
|
||||
meta_preference_to_string (pref));
|
||||
|
||||
if (g_list_find (changes, GINT_TO_POINTER (pref)) == NULL)
|
||||
changes = g_list_prepend (changes, GINT_TO_POINTER (pref));
|
||||
@@ -931,11 +938,29 @@ queue_changed (MetaPreference pref)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Initialisation. */
|
||||
/****************************************************************************/
|
||||
|
||||
static GSettings *
|
||||
get_xsettings_settings (void)
|
||||
{
|
||||
GSettings *settings = NULL;
|
||||
GSettingsSchema *schema;
|
||||
|
||||
schema = g_settings_schema_source_lookup (g_settings_schema_source_get_default (),
|
||||
SCHEMA_XSETTINGS, FALSE);
|
||||
|
||||
if (schema)
|
||||
{
|
||||
settings = g_settings_new_full (schema, NULL, NULL);
|
||||
g_settings_schema_unref (schema);
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
void
|
||||
meta_prefs_init (void)
|
||||
{
|
||||
@@ -965,6 +990,16 @@ meta_prefs_init (void)
|
||||
G_CALLBACK (settings_changed), NULL);
|
||||
g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INTERFACE), settings);
|
||||
|
||||
settings = get_xsettings_settings ();
|
||||
if (settings)
|
||||
{
|
||||
g_signal_connect (settings, "changed::" KEY_XSETTINGS_OVERRIDES,
|
||||
G_CALLBACK (xsettings_overrides_changed), NULL);
|
||||
g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_XSETTINGS), settings);
|
||||
|
||||
xsettings_overrides_changed (settings, KEY_XSETTINGS_OVERRIDES, NULL);
|
||||
}
|
||||
|
||||
settings = g_settings_new (SCHEMA_INPUT_SOURCES);
|
||||
g_signal_connect (settings, "changed::" KEY_XKB_OPTIONS,
|
||||
G_CALLBACK (settings_changed), NULL);
|
||||
@@ -1117,7 +1152,7 @@ meta_prefs_override_preference_schema (const char *key, const char *schema)
|
||||
do_override (overridden->key, overridden->new_schema);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Updates. */
|
||||
/****************************************************************************/
|
||||
@@ -1184,6 +1219,38 @@ bindings_changed (GSettings *settings,
|
||||
g_strfreev (strokes);
|
||||
}
|
||||
|
||||
/* The fallback app menu should be enabled if either we are not
|
||||
* showing the app menu (e.g. when using the default plugin) or
|
||||
* with a corresponding XSettings override; we ignore the former
|
||||
* and assume that we always show the app menu, not least
|
||||
* because we rely on the compositor implementation to display
|
||||
* the fallback ...
|
||||
*/
|
||||
static void
|
||||
xsettings_overrides_changed (GSettings *settings,
|
||||
gchar *key,
|
||||
gpointer data)
|
||||
{
|
||||
GVariant *value;
|
||||
GVariantDict overrides;
|
||||
int shell_shows_app_menu = 1;
|
||||
|
||||
if (!g_settings_get_boolean (settings, "active"))
|
||||
goto out;
|
||||
|
||||
value = g_settings_get_value (settings, KEY_XSETTINGS_OVERRIDES);
|
||||
|
||||
g_variant_dict_init (&overrides, value);
|
||||
g_variant_unref (value);
|
||||
|
||||
g_variant_dict_lookup (&overrides,
|
||||
"Gtk/ShellShowsAppMenu", "i", &shell_shows_app_menu);
|
||||
g_variant_dict_clear (&overrides);
|
||||
|
||||
out:
|
||||
show_fallback_app_menu = !shell_shows_app_menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* maybe_give_disable_workaround_warning:
|
||||
*
|
||||
@@ -1194,7 +1261,7 @@ static void
|
||||
maybe_give_disable_workarounds_warning (void)
|
||||
{
|
||||
static gboolean first_disable = TRUE;
|
||||
|
||||
|
||||
if (first_disable && disable_workarounds)
|
||||
{
|
||||
first_disable = FALSE;
|
||||
@@ -1243,6 +1310,12 @@ meta_prefs_get_raise_on_click (void)
|
||||
return raise_on_click || focus_mode == G_DESKTOP_FOCUS_MODE_CLICK;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_prefs_get_show_fallback_app_menu (void)
|
||||
{
|
||||
return show_fallback_app_menu;
|
||||
}
|
||||
|
||||
const char*
|
||||
meta_prefs_get_theme (void)
|
||||
{
|
||||
@@ -1261,7 +1334,7 @@ meta_prefs_get_cursor_size (void)
|
||||
return cursor_size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Handlers for string preferences. */
|
||||
/****************************************************************************/
|
||||
@@ -1345,7 +1418,7 @@ mouse_button_mods_handler (GVariant *value,
|
||||
{
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Failed to parse new GSettings value\n");
|
||||
|
||||
|
||||
meta_warning ("\"%s\" found in configuration database is "
|
||||
"not a valid value for mouse button modifier\n",
|
||||
string_value);
|
||||
@@ -1369,7 +1442,7 @@ mouse_button_mods_handler (GVariant *value,
|
||||
static gboolean
|
||||
button_layout_equal (const MetaButtonLayout *a,
|
||||
const MetaButtonLayout *b)
|
||||
{
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
@@ -1398,6 +1471,8 @@ button_function_from_string (const char *str)
|
||||
{
|
||||
if (strcmp (str, "menu") == 0)
|
||||
return META_BUTTON_FUNCTION_MENU;
|
||||
else if (strcmp (str, "appmenu") == 0)
|
||||
return META_BUTTON_FUNCTION_APPMENU;
|
||||
else if (strcmp (str, "minimize") == 0)
|
||||
return META_BUTTON_FUNCTION_MINIMIZE;
|
||||
else if (strcmp (str, "maximize") == 0)
|
||||
@@ -1410,7 +1485,7 @@ button_function_from_string (const char *str)
|
||||
return META_BUTTON_FUNCTION_ABOVE;
|
||||
else if (strcmp (str, "stick") == 0)
|
||||
return META_BUTTON_FUNCTION_STICK;
|
||||
else
|
||||
else
|
||||
/* don't know; give up */
|
||||
return META_BUTTON_FUNCTION_LAST;
|
||||
}
|
||||
@@ -1535,7 +1610,7 @@ button_layout_handler (GVariant *value,
|
||||
new_layout.right_buttons_has_spacer[i] = FALSE;
|
||||
++i;
|
||||
}
|
||||
|
||||
|
||||
buttons = g_strsplit (sides[1], ",", -1);
|
||||
i = 0;
|
||||
b = 0;
|
||||
@@ -1571,7 +1646,7 @@ button_layout_handler (GVariant *value,
|
||||
buttons[b]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
++b;
|
||||
}
|
||||
|
||||
@@ -1585,13 +1660,13 @@ 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;
|
||||
|
||||
|
||||
for (i = 0; new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
@@ -1606,7 +1681,7 @@ button_layout_handler (GVariant *value,
|
||||
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++)
|
||||
{
|
||||
@@ -1751,7 +1826,7 @@ meta_preference_to_string (MetaPreference pref)
|
||||
|
||||
case META_PREF_RAISE_ON_CLICK:
|
||||
return "RAISE_ON_CLICK";
|
||||
|
||||
|
||||
case META_PREF_THEME:
|
||||
return "THEME";
|
||||
|
||||
@@ -1778,7 +1853,7 @@ meta_preference_to_string (MetaPreference pref)
|
||||
|
||||
case META_PREF_AUTO_RAISE:
|
||||
return "AUTO_RAISE";
|
||||
|
||||
|
||||
case META_PREF_AUTO_RAISE_DELAY:
|
||||
return "AUTO_RAISE_DELAY";
|
||||
|
||||
@@ -2021,7 +2096,7 @@ meta_prefs_change_workspace_name (int num,
|
||||
{
|
||||
GVariantBuilder builder;
|
||||
int n_workspace_names, i;
|
||||
|
||||
|
||||
g_return_if_fail (num >= 0);
|
||||
|
||||
meta_topic (META_DEBUG_PREFS,
|
||||
@@ -2181,7 +2256,7 @@ meta_prefs_get_keybindings ()
|
||||
return g_hash_table_get_values (key_bindings);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
meta_prefs_get_overlay_binding (MetaKeyCombo *combo)
|
||||
{
|
||||
*combo = overlay_key_combo;
|
||||
@@ -2262,43 +2337,6 @@ meta_prefs_get_keybinding_action (const char *name)
|
||||
: META_KEYBINDING_ACTION_NONE;
|
||||
}
|
||||
|
||||
/* This is used by the menu system to decide what key binding
|
||||
* to display next to an option. We return the first non-disabled
|
||||
* binding, if any.
|
||||
*/
|
||||
void
|
||||
meta_prefs_get_window_binding (const char *name,
|
||||
unsigned int *keysym,
|
||||
MetaVirtualModifier *modifiers)
|
||||
{
|
||||
MetaKeyPref *pref = g_hash_table_lookup (key_bindings, name);
|
||||
|
||||
if (pref->per_window)
|
||||
{
|
||||
GSList *s = pref->combos;
|
||||
|
||||
while (s)
|
||||
{
|
||||
MetaKeyCombo *c = s->data;
|
||||
|
||||
if (c->keysym != 0 || c->modifiers != 0)
|
||||
{
|
||||
*keysym = c->keysym;
|
||||
*modifiers = c->modifiers;
|
||||
return;
|
||||
}
|
||||
|
||||
s = s->next;
|
||||
}
|
||||
|
||||
/* Not found; return the disabled value */
|
||||
*keysym = *modifiers = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
gint
|
||||
meta_prefs_get_mouse_button_resize (void)
|
||||
{
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
* which the rest of the world is allowed to use.)
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -23,7 +23,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -73,7 +73,7 @@ struct _MetaScreen
|
||||
* any actual clients
|
||||
*/
|
||||
Window no_focus_window;
|
||||
|
||||
|
||||
GList *workspaces;
|
||||
|
||||
MetaStack *stack;
|
||||
@@ -110,11 +110,11 @@ struct _MetaScreen
|
||||
MetaScreenCorner starting_corner;
|
||||
guint vertical_workspaces : 1;
|
||||
guint workspace_layout_overridden : 1;
|
||||
|
||||
|
||||
guint keys_grabbed : 1;
|
||||
|
||||
|
||||
int closing;
|
||||
|
||||
|
||||
/* Instead of unmapping withdrawn windows we can leave them mapped
|
||||
* and restack them below a guard window. When using a compositor
|
||||
* this allows us to provide live previews of unmapped windows */
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001, 2002 Havoc Pennington
|
||||
* Copyright (C) 2002, 2003 Red Hat Inc.
|
||||
* Some ICCCM manager selection code derived from fvwm2,
|
||||
* Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -17,7 +17,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "x11/window-x11.h"
|
||||
#include "x11/xprops.h"
|
||||
|
||||
static char* get_screen_name (MetaDisplay *display,
|
||||
@@ -267,7 +268,7 @@ set_wm_check_hint (MetaScreen *screen)
|
||||
unsigned long data[1];
|
||||
|
||||
g_return_val_if_fail (screen->display->leader_window != None, 0);
|
||||
|
||||
|
||||
data[0] = screen->display->leader_window;
|
||||
|
||||
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||
@@ -281,7 +282,7 @@ set_wm_check_hint (MetaScreen *screen)
|
||||
static void
|
||||
unset_wm_check_hint (MetaScreen *screen)
|
||||
{
|
||||
XDeleteProperty (screen->display->xdisplay, screen->xroot,
|
||||
XDeleteProperty (screen->display->xdisplay, screen->xroot,
|
||||
screen->display->atom__NET_SUPPORTING_WM_CHECK);
|
||||
}
|
||||
|
||||
@@ -296,6 +297,7 @@ set_supported_hint (MetaScreen *screen)
|
||||
#undef EWMH_ATOMS_ONLY
|
||||
|
||||
screen->display->atom__GTK_FRAME_EXTENTS,
|
||||
screen->display->atom__GTK_SHOW_WINDOW_MENU,
|
||||
};
|
||||
|
||||
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||
@@ -303,7 +305,7 @@ set_supported_hint (MetaScreen *screen)
|
||||
XA_ATOM,
|
||||
32, PropModeReplace,
|
||||
(guchar*) atoms, G_N_ELEMENTS(atoms));
|
||||
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
@@ -327,12 +329,12 @@ set_wm_icon_size_hint (MetaScreen *screen)
|
||||
vals[4] = 0;
|
||||
vals[5] = 0;
|
||||
#undef LEGACY_ICON_SIZE
|
||||
|
||||
|
||||
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||
screen->display->atom_WM_ICON_SIZE,
|
||||
XA_CARDINAL,
|
||||
32, PropModeReplace, (guchar*) vals, N_VALS);
|
||||
|
||||
|
||||
return Success;
|
||||
#undef N_VALS
|
||||
}
|
||||
@@ -411,7 +413,7 @@ reload_monitor_infos (MetaScreen *screen)
|
||||
MetaWorkspace *space = tmp->data;
|
||||
|
||||
meta_workspace_invalidate_work_area (space);
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
@@ -506,16 +508,16 @@ meta_screen_new (MetaDisplay *display,
|
||||
guint32 manager_timestamp;
|
||||
gulong current_workspace;
|
||||
MetaMonitorManager *manager;
|
||||
|
||||
|
||||
replace_current_wm = meta_get_replace_current_wm ();
|
||||
|
||||
|
||||
/* Only display->name, display->xdisplay, and display->error_traps
|
||||
* can really be used in this function, since normally screens are
|
||||
* created from the MetaDisplay constructor
|
||||
*/
|
||||
|
||||
|
||||
xdisplay = display->xdisplay;
|
||||
|
||||
|
||||
meta_verbose ("Trying screen %d on display '%s'\n",
|
||||
number, display->name);
|
||||
|
||||
@@ -532,14 +534,14 @@ meta_screen_new (MetaDisplay *display,
|
||||
}
|
||||
|
||||
sprintf (buf, "WM_S%d", number);
|
||||
wm_sn_atom = XInternAtom (xdisplay, buf, False);
|
||||
|
||||
wm_sn_atom = XInternAtom (xdisplay, buf, False);
|
||||
|
||||
current_wm_sn_owner = XGetSelectionOwner (xdisplay, wm_sn_atom);
|
||||
|
||||
if (current_wm_sn_owner != None)
|
||||
{
|
||||
XSetWindowAttributes attrs;
|
||||
|
||||
|
||||
if (!replace_current_wm)
|
||||
{
|
||||
meta_warning (_("Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current window manager.\n"),
|
||||
@@ -563,7 +565,7 @@ meta_screen_new (MetaDisplay *display,
|
||||
new_wm_sn_owner = meta_create_offscreen_window (xdisplay, xroot, NoEventMask);
|
||||
|
||||
manager_timestamp = timestamp;
|
||||
|
||||
|
||||
XSetSelectionOwner (xdisplay, wm_sn_atom, new_wm_sn_owner,
|
||||
manager_timestamp);
|
||||
|
||||
@@ -573,14 +575,14 @@ meta_screen_new (MetaDisplay *display,
|
||||
number, display->name);
|
||||
|
||||
XDestroyWindow (xdisplay, new_wm_sn_owner);
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
/* Send client message indicating that we are now the WM */
|
||||
XClientMessageEvent ev;
|
||||
|
||||
|
||||
ev.type = ClientMessage;
|
||||
ev.window = xroot;
|
||||
ev.message_type = display->atom_MANAGER;
|
||||
@@ -597,7 +599,7 @@ meta_screen_new (MetaDisplay *display,
|
||||
XEvent event;
|
||||
|
||||
/* We sort of block infinitely here which is probably lame. */
|
||||
|
||||
|
||||
meta_verbose ("Waiting for old window manager to exit\n");
|
||||
do
|
||||
{
|
||||
@@ -606,7 +608,7 @@ meta_screen_new (MetaDisplay *display,
|
||||
}
|
||||
while (event.type != DestroyNotify);
|
||||
}
|
||||
|
||||
|
||||
/* select our root window events */
|
||||
meta_error_trap_push (display);
|
||||
|
||||
@@ -651,13 +653,13 @@ meta_screen_new (MetaDisplay *display,
|
||||
number, display->name);
|
||||
|
||||
XDestroyWindow (xdisplay, new_wm_sn_owner);
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
screen = g_object_new (META_TYPE_SCREEN, NULL);
|
||||
screen->closing = 0;
|
||||
|
||||
|
||||
screen->display = display;
|
||||
screen->number = number;
|
||||
screen->screen_name = get_screen_name (display, number);
|
||||
@@ -681,8 +683,8 @@ meta_screen_new (MetaDisplay *display,
|
||||
screen->wm_sn_atom = wm_sn_atom;
|
||||
screen->wm_sn_timestamp = manager_timestamp;
|
||||
|
||||
screen->wm_cm_selection_window = meta_create_offscreen_window (xdisplay,
|
||||
xroot,
|
||||
screen->wm_cm_selection_window = meta_create_offscreen_window (xdisplay,
|
||||
xroot,
|
||||
NoEventMask);
|
||||
screen->work_area_later = 0;
|
||||
screen->check_fullscreen_later = 0;
|
||||
@@ -699,18 +701,18 @@ meta_screen_new (MetaDisplay *display,
|
||||
|
||||
meta_screen_set_cursor (screen, META_CURSOR_DEFAULT);
|
||||
|
||||
/* Handle creating a no_focus_window for this screen */
|
||||
/* Handle creating a no_focus_window for this screen */
|
||||
screen->no_focus_window =
|
||||
meta_create_offscreen_window (display->xdisplay,
|
||||
screen->xroot,
|
||||
FocusChangeMask|KeyPressMask|KeyReleaseMask);
|
||||
XMapWindow (display->xdisplay, screen->no_focus_window);
|
||||
/* Done with no_focus_window stuff */
|
||||
|
||||
|
||||
set_wm_icon_size_hint (screen);
|
||||
|
||||
|
||||
set_supported_hint (screen);
|
||||
|
||||
|
||||
set_wm_check_hint (screen);
|
||||
|
||||
set_desktop_viewport_hint (screen);
|
||||
@@ -729,13 +731,13 @@ meta_screen_new (MetaDisplay *display,
|
||||
(int) current_workspace);
|
||||
else
|
||||
meta_verbose ("No _NET_CURRENT_DESKTOP present\n");
|
||||
|
||||
|
||||
/* Screens must have at least one workspace at all times,
|
||||
* so create that required workspace.
|
||||
*/
|
||||
meta_workspace_activate (meta_workspace_new (screen), timestamp);
|
||||
update_num_workspaces (screen, timestamp);
|
||||
|
||||
|
||||
set_workspace_names (screen);
|
||||
|
||||
screen->keys_grabbed = FALSE;
|
||||
@@ -765,10 +767,10 @@ meta_screen_new (MetaDisplay *display,
|
||||
/* Switch to the _NET_CURRENT_DESKTOP workspace */
|
||||
{
|
||||
MetaWorkspace *space;
|
||||
|
||||
|
||||
space = meta_screen_get_workspace_by_index (screen,
|
||||
current_workspace);
|
||||
|
||||
|
||||
if (space != NULL)
|
||||
meta_workspace_activate (space, timestamp);
|
||||
}
|
||||
@@ -788,15 +790,15 @@ meta_screen_free (MetaScreen *screen,
|
||||
display = screen->display;
|
||||
|
||||
screen->closing += 1;
|
||||
|
||||
|
||||
meta_display_grab (display);
|
||||
|
||||
meta_compositor_unmanage (screen->display->compositor);
|
||||
|
||||
|
||||
meta_display_unmanage_windows_for_screen (display, screen, timestamp);
|
||||
|
||||
|
||||
meta_prefs_remove_listener (prefs_changed_callback, screen);
|
||||
|
||||
|
||||
meta_screen_ungrab_keys (screen);
|
||||
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
@@ -816,7 +818,7 @@ meta_screen_free (MetaScreen *screen,
|
||||
screen->sn_context = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
meta_ui_free (screen->ui);
|
||||
|
||||
meta_stack_free (screen->stack);
|
||||
@@ -832,7 +834,7 @@ meta_screen_free (MetaScreen *screen,
|
||||
|
||||
XDestroyWindow (screen->display->xdisplay,
|
||||
screen->wm_sn_selection_window);
|
||||
|
||||
|
||||
if (screen->work_area_later != 0)
|
||||
meta_later_remove (screen->work_area_later);
|
||||
if (screen->check_fullscreen_later != 0)
|
||||
@@ -887,7 +889,7 @@ prefs_changed_callback (MetaPreference pref,
|
||||
gpointer data)
|
||||
{
|
||||
MetaScreen *screen = data;
|
||||
|
||||
|
||||
if ((pref == META_PREF_NUM_WORKSPACES ||
|
||||
pref == META_PREF_DYNAMIC_WORKSPACES) &&
|
||||
!meta_prefs_get_dynamic_workspaces ())
|
||||
@@ -895,7 +897,7 @@ prefs_changed_callback (MetaPreference pref,
|
||||
/* GSettings doesn't provide timestamps, but luckily update_num_workspaces
|
||||
* often doesn't need it...
|
||||
*/
|
||||
guint32 timestamp =
|
||||
guint32 timestamp =
|
||||
meta_display_get_current_time_roundtrip (screen->display);
|
||||
update_num_workspaces (screen, timestamp);
|
||||
}
|
||||
@@ -917,7 +919,7 @@ get_screen_name (MetaDisplay *display,
|
||||
char *p;
|
||||
char *dname;
|
||||
char *scr;
|
||||
|
||||
|
||||
/* DisplayString gives us a sort of canonical display,
|
||||
* vs. the user-entered name from XDisplayName()
|
||||
*/
|
||||
@@ -932,7 +934,7 @@ get_screen_name (MetaDisplay *display,
|
||||
if (p)
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
|
||||
scr = g_strdup_printf ("%s.%d", dname, number);
|
||||
|
||||
g_free (dname);
|
||||
@@ -955,7 +957,7 @@ static void
|
||||
listify_func (gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
GSList **listp;
|
||||
|
||||
|
||||
listp = data;
|
||||
|
||||
*listp = g_slist_prepend (*listp, value);
|
||||
@@ -981,14 +983,14 @@ meta_screen_foreach_window (MetaScreen *screen,
|
||||
/* 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);
|
||||
|
||||
|
||||
winlist = g_slist_sort (winlist, ptrcmp);
|
||||
|
||||
|
||||
tmp = winlist;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
@@ -1005,7 +1007,7 @@ meta_screen_foreach_window (MetaScreen *screen,
|
||||
!window->override_redirect)
|
||||
(* func) (screen, window, data);
|
||||
}
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
g_slist_free (winlist);
|
||||
@@ -1039,7 +1041,7 @@ meta_screen_get_workspace_by_index (MetaScreen *screen,
|
||||
/* should be robust, idx is maybe from an app */
|
||||
if (idx < 0)
|
||||
return NULL;
|
||||
|
||||
|
||||
i = 0;
|
||||
tmp = screen->workspaces;
|
||||
while (tmp != NULL)
|
||||
@@ -1258,7 +1260,7 @@ update_num_workspaces (MetaScreen *screen,
|
||||
GList *extras;
|
||||
MetaWorkspace *last_remaining;
|
||||
gboolean need_change_space;
|
||||
|
||||
|
||||
if (meta_prefs_get_dynamic_workspaces ())
|
||||
{
|
||||
int n_items;
|
||||
@@ -1301,14 +1303,14 @@ update_num_workspaces (MetaScreen *screen,
|
||||
extras = g_list_prepend (extras, w);
|
||||
else
|
||||
last_remaining = w;
|
||||
|
||||
|
||||
++i;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
old_num = i;
|
||||
|
||||
g_assert (last_remaining);
|
||||
|
||||
|
||||
/* Get rid of the extra workspaces by moving all their windows
|
||||
* to last_remaining, then activating last_remaining if
|
||||
* one of the removed workspaces was active. This will be a bit
|
||||
@@ -1321,11 +1323,11 @@ update_num_workspaces (MetaScreen *screen,
|
||||
{
|
||||
MetaWorkspace *w = tmp->data;
|
||||
|
||||
meta_workspace_relocate_windows (w, last_remaining);
|
||||
meta_workspace_relocate_windows (w, last_remaining);
|
||||
|
||||
if (w == screen->active_workspace)
|
||||
need_change_space = TRUE;
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
@@ -1551,7 +1553,7 @@ meta_screen_get_monitor_for_window (MetaScreen *screen,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaRectangle window_rect;
|
||||
|
||||
|
||||
meta_window_get_frame_rect (window, &window_rect);
|
||||
|
||||
return meta_screen_get_monitor_for_rect (screen, &window_rect);
|
||||
@@ -1565,7 +1567,7 @@ meta_screen_get_monitor_index_for_rect (MetaScreen *screen,
|
||||
return monitor->number;
|
||||
}
|
||||
|
||||
const MetaMonitorInfo*
|
||||
const MetaMonitorInfo*
|
||||
meta_screen_get_monitor_neighbor (MetaScreen *screen,
|
||||
int which_monitor,
|
||||
MetaScreenDirection direction)
|
||||
@@ -1578,23 +1580,23 @@ meta_screen_get_monitor_neighbor (MetaScreen *screen,
|
||||
{
|
||||
current = screen->monitor_infos + i;
|
||||
|
||||
if ((direction == META_SCREEN_RIGHT &&
|
||||
if ((direction == META_SCREEN_RIGHT &&
|
||||
current->rect.x == input->rect.x + input->rect.width &&
|
||||
meta_rectangle_vert_overlap(¤t->rect, &input->rect)) ||
|
||||
(direction == META_SCREEN_LEFT &&
|
||||
(direction == META_SCREEN_LEFT &&
|
||||
input->rect.x == current->rect.x + current->rect.width &&
|
||||
meta_rectangle_vert_overlap(¤t->rect, &input->rect)) ||
|
||||
(direction == META_SCREEN_UP &&
|
||||
(direction == META_SCREEN_UP &&
|
||||
input->rect.y == current->rect.y + current->rect.height &&
|
||||
meta_rectangle_horiz_overlap(¤t->rect, &input->rect)) ||
|
||||
(direction == META_SCREEN_DOWN &&
|
||||
(direction == META_SCREEN_DOWN &&
|
||||
current->rect.y == input->rect.y + input->rect.height &&
|
||||
meta_rectangle_horiz_overlap(¤t->rect, &input->rect)))
|
||||
{
|
||||
return current;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1634,7 +1636,7 @@ meta_screen_get_natural_monitor_list (MetaScreen *screen,
|
||||
|
||||
while (!g_queue_is_empty (monitor_queue))
|
||||
{
|
||||
current = (const MetaMonitorInfo*)
|
||||
current = (const MetaMonitorInfo*)
|
||||
g_queue_pop_head (monitor_queue);
|
||||
|
||||
(*monitors_list)[cur++] = current->number;
|
||||
@@ -1775,10 +1777,10 @@ meta_screen_get_current_monitor (MetaScreen *screen)
|
||||
|
||||
if (screen->n_monitor_infos == 1)
|
||||
return 0;
|
||||
|
||||
|
||||
/* Sadly, we have to do it this way. Yuck.
|
||||
*/
|
||||
|
||||
|
||||
if (screen->display->monitor_cache_invalidated)
|
||||
{
|
||||
int x, y;
|
||||
@@ -1858,7 +1860,7 @@ meta_screen_update_workspace_layout (MetaScreen *screen)
|
||||
|
||||
if (screen->workspace_layout_overridden)
|
||||
return;
|
||||
|
||||
|
||||
list = NULL;
|
||||
n_items = 0;
|
||||
|
||||
@@ -1870,7 +1872,7 @@ meta_screen_update_workspace_layout (MetaScreen *screen)
|
||||
if (n_items == 3 || n_items == 4)
|
||||
{
|
||||
int cols, rows;
|
||||
|
||||
|
||||
switch (list[0])
|
||||
{
|
||||
case _NET_WM_ORIENTATION_HORZ:
|
||||
@@ -1897,7 +1899,7 @@ meta_screen_update_workspace_layout (MetaScreen *screen)
|
||||
screen->rows_of_workspaces = rows;
|
||||
else
|
||||
screen->rows_of_workspaces = -1;
|
||||
|
||||
|
||||
if (cols > 0)
|
||||
screen->columns_of_workspaces = cols;
|
||||
else
|
||||
@@ -2007,10 +2009,10 @@ set_workspace_names (MetaScreen *screen)
|
||||
strlen (name) + 1);
|
||||
else
|
||||
g_string_append_len (flattened, "", 1);
|
||||
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
|
||||
meta_error_trap_push (screen->display);
|
||||
XChangeProperty (screen->display->xdisplay,
|
||||
screen->xroot,
|
||||
@@ -2019,7 +2021,7 @@ set_workspace_names (MetaScreen *screen)
|
||||
8, PropModeReplace,
|
||||
(unsigned char *)flattened->str, flattened->len);
|
||||
meta_error_trap_pop (screen->display);
|
||||
|
||||
|
||||
g_string_free (flattened, TRUE);
|
||||
}
|
||||
|
||||
@@ -2033,7 +2035,7 @@ meta_screen_update_workspace_names (MetaScreen *screen)
|
||||
/* this updates names in prefs when the root window property changes,
|
||||
* iff the new property contents don't match what's already in prefs
|
||||
*/
|
||||
|
||||
|
||||
names = NULL;
|
||||
n_names = 0;
|
||||
if (!meta_prop_get_utf8_list (screen->display,
|
||||
@@ -2053,10 +2055,10 @@ meta_screen_update_workspace_names (MetaScreen *screen)
|
||||
"Setting workspace %d name to \"%s\" due to _NET_DESKTOP_NAMES change\n",
|
||||
i, names[i] ? names[i] : "null");
|
||||
meta_prefs_change_workspace_name (i, names[i]);
|
||||
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
|
||||
g_strfreev (names);
|
||||
}
|
||||
|
||||
@@ -2073,7 +2075,7 @@ meta_create_offscreen_window (Display *xdisplay,
|
||||
*/
|
||||
attrs.override_redirect = True;
|
||||
attrs.event_mask = valuemask;
|
||||
|
||||
|
||||
return XCreateWindow (xdisplay,
|
||||
parent,
|
||||
-100, -100, 1, 1,
|
||||
@@ -2092,12 +2094,12 @@ set_work_area_hint (MetaScreen *screen)
|
||||
GList *tmp_list;
|
||||
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)
|
||||
{
|
||||
MetaWorkspace *workspace = tmp_list->data;
|
||||
@@ -2112,10 +2114,10 @@ set_work_area_hint (MetaScreen *screen)
|
||||
|
||||
tmp += 4;
|
||||
}
|
||||
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
|
||||
meta_error_trap_push (screen->display);
|
||||
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||
screen->display->atom__NET_WORKAREA,
|
||||
@@ -2132,11 +2134,11 @@ set_work_area_later_func (MetaScreen *screen)
|
||||
{
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
"Running work area hint computation function\n");
|
||||
|
||||
|
||||
screen->work_area_later = 0;
|
||||
|
||||
|
||||
set_work_area_hint (screen);
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -2188,7 +2190,7 @@ meta_screen_calc_workspace_layout (MetaScreen *screen,
|
||||
int *grid;
|
||||
int i, r, c;
|
||||
int current_row, current_col;
|
||||
|
||||
|
||||
rows = screen->rows_of_workspaces;
|
||||
cols = screen->columns_of_workspaces;
|
||||
if (rows <= 0 && cols <= 0)
|
||||
@@ -2206,58 +2208,58 @@ meta_screen_calc_workspace_layout (MetaScreen *screen,
|
||||
cols = 1;
|
||||
|
||||
g_assert (rows != 0 && cols != 0);
|
||||
|
||||
|
||||
grid_area = rows * cols;
|
||||
|
||||
|
||||
meta_verbose ("Getting layout rows = %d cols = %d current = %d "
|
||||
"num_spaces = %d vertical = %s corner = %s\n",
|
||||
rows, cols, current_space, num_workspaces,
|
||||
screen->vertical_workspaces ? "(true)" : "(false)",
|
||||
meta_screen_corner_to_string (screen->starting_corner));
|
||||
|
||||
/* ok, we want to setup the distances in the workspace array to go
|
||||
* in each direction. Remember, there are many ways that a workspace
|
||||
* array can be setup.
|
||||
* see http://www.freedesktop.org/standards/wm-spec/1.2/html/x109.html
|
||||
* and look at the _NET_DESKTOP_LAYOUT section for details.
|
||||
|
||||
/* ok, we want to setup the distances in the workspace array to go
|
||||
* in each direction. Remember, there are many ways that a workspace
|
||||
* array can be setup.
|
||||
* see http://www.freedesktop.org/standards/wm-spec/1.2/html/x109.html
|
||||
* and look at the _NET_DESKTOP_LAYOUT section for details.
|
||||
* For instance:
|
||||
*/
|
||||
/* starting_corner = META_SCREEN_TOPLEFT
|
||||
/* starting_corner = META_SCREEN_TOPLEFT
|
||||
* vertical_workspaces = 0 vertical_workspaces=1
|
||||
* 1234 1357
|
||||
* 5678 2468
|
||||
*
|
||||
* starting_corner = META_SCREEN_TOPRIGHT
|
||||
* 1234 1357
|
||||
* 5678 2468
|
||||
*
|
||||
* starting_corner = META_SCREEN_TOPRIGHT
|
||||
* vertical_workspaces = 0 vertical_workspaces=1
|
||||
* 4321 7531
|
||||
* 8765 8642
|
||||
*
|
||||
* starting_corner = META_SCREEN_BOTTOMLEFT
|
||||
* 4321 7531
|
||||
* 8765 8642
|
||||
*
|
||||
* starting_corner = META_SCREEN_BOTTOMLEFT
|
||||
* vertical_workspaces = 0 vertical_workspaces=1
|
||||
* 5678 2468
|
||||
* 1234 1357
|
||||
*
|
||||
* starting_corner = META_SCREEN_BOTTOMRIGHT
|
||||
* 5678 2468
|
||||
* 1234 1357
|
||||
*
|
||||
* starting_corner = META_SCREEN_BOTTOMRIGHT
|
||||
* vertical_workspaces = 0 vertical_workspaces=1
|
||||
* 8765 8642
|
||||
* 4321 7531
|
||||
* 8765 8642
|
||||
* 4321 7531
|
||||
*
|
||||
*/
|
||||
/* keep in mind that we could have a ragged layout, e.g. the "8"
|
||||
* in the above grids could be missing
|
||||
*/
|
||||
|
||||
|
||||
|
||||
grid = g_new (int, grid_area);
|
||||
|
||||
current_row = -1;
|
||||
current_col = -1;
|
||||
i = 0;
|
||||
|
||||
switch (screen->starting_corner)
|
||||
|
||||
switch (screen->starting_corner)
|
||||
{
|
||||
case META_SCREEN_TOPLEFT:
|
||||
if (screen->vertical_workspaces)
|
||||
if (screen->vertical_workspaces)
|
||||
{
|
||||
c = 0;
|
||||
while (c < cols)
|
||||
@@ -2289,7 +2291,7 @@ meta_screen_calc_workspace_layout (MetaScreen *screen,
|
||||
}
|
||||
break;
|
||||
case META_SCREEN_TOPRIGHT:
|
||||
if (screen->vertical_workspaces)
|
||||
if (screen->vertical_workspaces)
|
||||
{
|
||||
c = cols - 1;
|
||||
while (c >= 0)
|
||||
@@ -2321,7 +2323,7 @@ meta_screen_calc_workspace_layout (MetaScreen *screen,
|
||||
}
|
||||
break;
|
||||
case META_SCREEN_BOTTOMLEFT:
|
||||
if (screen->vertical_workspaces)
|
||||
if (screen->vertical_workspaces)
|
||||
{
|
||||
c = 0;
|
||||
while (c < cols)
|
||||
@@ -2353,7 +2355,7 @@ meta_screen_calc_workspace_layout (MetaScreen *screen,
|
||||
}
|
||||
break;
|
||||
case META_SCREEN_BOTTOMRIGHT:
|
||||
if (screen->vertical_workspaces)
|
||||
if (screen->vertical_workspaces)
|
||||
{
|
||||
c = cols - 1;
|
||||
while (c >= 0)
|
||||
@@ -2384,12 +2386,12 @@ meta_screen_calc_workspace_layout (MetaScreen *screen,
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i != grid_area)
|
||||
meta_bug ("did not fill in the whole workspace grid in %s (%d filled)\n",
|
||||
G_STRFUNC, i);
|
||||
|
||||
|
||||
current_row = 0;
|
||||
current_col = 0;
|
||||
r = 0;
|
||||
@@ -2525,7 +2527,7 @@ meta_screen_update_showing_desktop_hint (MetaScreen *screen)
|
||||
unsigned long data[1];
|
||||
|
||||
data[0] = screen->active_workspace->showing_desktop ? 1 : 0;
|
||||
|
||||
|
||||
meta_error_trap_push (screen->display);
|
||||
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||
screen->display->atom__NET_SHOWING_DESKTOP,
|
||||
@@ -2553,7 +2555,7 @@ queue_windows_showing (MetaScreen *screen)
|
||||
|
||||
if (w->screen == screen)
|
||||
meta_window_queue (w, META_QUEUE_CALC_SHOWING);
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
@@ -2568,32 +2570,32 @@ meta_screen_minimize_all_on_active_workspace_except (MetaScreen *screen,
|
||||
GList *tmp;
|
||||
|
||||
windows = screen->active_workspace->windows;
|
||||
|
||||
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
|
||||
|
||||
if (w->screen == screen &&
|
||||
w->has_minimize_func &&
|
||||
w != keep)
|
||||
meta_window_minimize (w);
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_show_desktop (MetaScreen *screen,
|
||||
meta_screen_show_desktop (MetaScreen *screen,
|
||||
guint32 timestamp)
|
||||
{
|
||||
GList *windows;
|
||||
|
||||
if (screen->active_workspace->showing_desktop)
|
||||
return;
|
||||
|
||||
|
||||
screen->active_workspace->showing_desktop = TRUE;
|
||||
|
||||
|
||||
queue_windows_showing (screen);
|
||||
|
||||
/* Focus the most recently used META_WINDOW_DESKTOP window, if there is one;
|
||||
@@ -2603,18 +2605,18 @@ meta_screen_show_desktop (MetaScreen *screen,
|
||||
while (windows != NULL)
|
||||
{
|
||||
MetaWindow *w = windows->data;
|
||||
|
||||
if (w->screen == screen &&
|
||||
|
||||
if (w->screen == screen &&
|
||||
w->type == META_WINDOW_DESKTOP)
|
||||
{
|
||||
meta_window_focus (w, timestamp);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
windows = windows->next;
|
||||
}
|
||||
|
||||
|
||||
|
||||
meta_screen_update_showing_desktop_hint (screen);
|
||||
}
|
||||
|
||||
@@ -2685,7 +2687,7 @@ remove_sequence (MetaScreen *screen,
|
||||
meta_topic (META_DEBUG_STARTUP,
|
||||
"Removing sequence %s\n",
|
||||
sn_startup_sequence_get_id (sequence));
|
||||
|
||||
|
||||
screen->startup_sequences = g_slist_remove (screen->startup_sequences,
|
||||
sequence);
|
||||
|
||||
@@ -2722,7 +2724,7 @@ collect_timed_out_foreach (void *element,
|
||||
SnStartupSequence *sequence = element;
|
||||
long tv_sec, tv_usec;
|
||||
double elapsed;
|
||||
|
||||
|
||||
sn_startup_sequence_get_last_active_time (sequence, &tv_sec, &tv_usec);
|
||||
|
||||
elapsed =
|
||||
@@ -2733,7 +2735,7 @@ collect_timed_out_foreach (void *element,
|
||||
"Sequence used %g seconds vs. %g max: %s\n",
|
||||
elapsed, (double) STARTUP_TIMEOUT,
|
||||
sn_startup_sequence_get_id (sequence));
|
||||
|
||||
|
||||
if (elapsed > STARTUP_TIMEOUT)
|
||||
ctod->list = g_slist_prepend (ctod->list, sequence);
|
||||
}
|
||||
@@ -2744,7 +2746,7 @@ startup_sequence_timeout (void *data)
|
||||
MetaScreen *screen = data;
|
||||
CollectTimedOutData ctod;
|
||||
GSList *tmp;
|
||||
|
||||
|
||||
ctod.list = NULL;
|
||||
g_get_current_time (&ctod.now);
|
||||
g_slist_foreach (screen->startup_sequences,
|
||||
@@ -2759,14 +2761,14 @@ startup_sequence_timeout (void *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);
|
||||
|
||||
|
||||
if (screen->startup_sequences != NULL)
|
||||
{
|
||||
return TRUE;
|
||||
@@ -2785,7 +2787,7 @@ meta_screen_sn_event (SnMonitorEvent *event,
|
||||
{
|
||||
MetaScreen *screen;
|
||||
SnStartupSequence *sequence;
|
||||
|
||||
|
||||
screen = user_data;
|
||||
|
||||
sequence = sn_monitor_event_get_startup_sequence (event);
|
||||
@@ -2799,7 +2801,7 @@ meta_screen_sn_event (SnMonitorEvent *event,
|
||||
const char *wmclass;
|
||||
|
||||
wmclass = sn_startup_sequence_get_wmclass (sequence);
|
||||
|
||||
|
||||
meta_topic (META_DEBUG_STARTUP,
|
||||
"Received startup initiated for %s wmclass %s\n",
|
||||
sn_startup_sequence_get_id (sequence),
|
||||
@@ -2865,7 +2867,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
const char *startup_id;
|
||||
GSList *tmp;
|
||||
SnStartupSequence *sequence;
|
||||
|
||||
|
||||
/* Does the window have a startup ID stored? */
|
||||
startup_id = meta_window_get_startup_id (window);
|
||||
|
||||
@@ -2873,7 +2875,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
"Applying startup props to %s id \"%s\"\n",
|
||||
window->desc,
|
||||
startup_id ? startup_id : "(none)");
|
||||
|
||||
|
||||
sequence = NULL;
|
||||
if (startup_id == NULL)
|
||||
{
|
||||
@@ -2904,11 +2906,11 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
"Ending legacy sequence %s due to window %s\n",
|
||||
sn_startup_sequence_get_id (sequence),
|
||||
window->desc);
|
||||
|
||||
|
||||
sn_startup_sequence_complete (sequence);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
@@ -2916,7 +2918,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
/* Still no startup ID? Bail. */
|
||||
if (startup_id == NULL)
|
||||
return FALSE;
|
||||
|
||||
|
||||
/* We might get this far and not know the sequence ID (if the window
|
||||
* already had a startup ID stored), so let's look for one if we don't
|
||||
* already know it.
|
||||
@@ -2927,15 +2929,15 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
while (tmp != NULL)
|
||||
{
|
||||
const char *id;
|
||||
|
||||
|
||||
id = sn_startup_sequence_get_id (tmp->data);
|
||||
|
||||
|
||||
if (strcmp (id, startup_id) == 0)
|
||||
{
|
||||
sequence = tmp->data;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
@@ -2943,7 +2945,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
if (sequence != NULL)
|
||||
{
|
||||
gboolean changed_something = FALSE;
|
||||
|
||||
|
||||
meta_topic (META_DEBUG_STARTUP,
|
||||
"Found startup sequence for window %s ID \"%s\"\n",
|
||||
window->desc, startup_id);
|
||||
@@ -2956,7 +2958,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
meta_topic (META_DEBUG_STARTUP,
|
||||
"Setting initial window workspace to %d based on startup info\n",
|
||||
space);
|
||||
|
||||
|
||||
window->initial_workspace_set = TRUE;
|
||||
window->initial_workspace = space;
|
||||
changed_something = TRUE;
|
||||
@@ -2969,7 +2971,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
meta_topic (META_DEBUG_STARTUP,
|
||||
"Setting initial window timestamp to %u based on startup info\n",
|
||||
timestamp);
|
||||
|
||||
|
||||
window->initial_timestamp_set = TRUE;
|
||||
window->initial_timestamp = timestamp;
|
||||
changed_something = TRUE;
|
||||
@@ -2983,7 +2985,7 @@ meta_screen_apply_startup_properties (MetaScreen *screen,
|
||||
"Did not find startup sequence for window %s ID \"%s\"\n",
|
||||
window->desc, startup_id);
|
||||
}
|
||||
|
||||
|
||||
#endif /* HAVE_STARTUP_NOTIFICATION */
|
||||
|
||||
return FALSE;
|
||||
@@ -2998,10 +3000,10 @@ meta_screen_get_screen_number (MetaScreen *screen)
|
||||
/**
|
||||
* meta_screen_get_display:
|
||||
* @screen: A #MetaScreen
|
||||
*
|
||||
*
|
||||
* Retrieve the display associated with screen.
|
||||
*
|
||||
* Returns: (transfer none): Display
|
||||
* Returns: (transfer none): Display
|
||||
*/
|
||||
MetaDisplay *
|
||||
meta_screen_get_display (MetaScreen *screen)
|
||||
@@ -3028,7 +3030,7 @@ meta_screen_get_xroot (MetaScreen *screen)
|
||||
*
|
||||
* Retrieve the size of the screen.
|
||||
*/
|
||||
void
|
||||
void
|
||||
meta_screen_get_size (MetaScreen *screen,
|
||||
int *width,
|
||||
int *height)
|
||||
@@ -3052,7 +3054,7 @@ meta_screen_set_cm_selection (MetaScreen *screen)
|
||||
g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
|
||||
meta_verbose ("Setting selection: %s\n", selection);
|
||||
a = XInternAtom (screen->display->xdisplay, selection, FALSE);
|
||||
XSetSelectionOwner (screen->display->xdisplay, a,
|
||||
XSetSelectionOwner (screen->display->xdisplay, a,
|
||||
screen->wm_cm_selection_window, screen->wm_cm_timestamp);
|
||||
}
|
||||
|
||||
@@ -3141,11 +3143,11 @@ meta_screen_set_active_workspace_hint (MetaScreen *screen)
|
||||
*/
|
||||
if (screen->closing > 0)
|
||||
return;
|
||||
|
||||
|
||||
data[0] = meta_workspace_index (screen->active_workspace);
|
||||
|
||||
meta_verbose ("Setting _NET_CURRENT_DESKTOP to %lu\n", data[0]);
|
||||
|
||||
|
||||
meta_error_trap_push (screen->display);
|
||||
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||
screen->display->atom__NET_CURRENT_DESKTOP,
|
||||
|
||||
@@ -541,6 +541,8 @@ static void
|
||||
stack_tracker_apply_prediction (MetaStackTracker *tracker,
|
||||
MetaStackOp *op)
|
||||
{
|
||||
gboolean free_at_end = FALSE;
|
||||
|
||||
/* If this is a wayland operation then it's implicitly verified so
|
||||
* we can apply it immediately so long as it doesn't depend on any
|
||||
* unverified X operations...
|
||||
@@ -550,6 +552,8 @@ stack_tracker_apply_prediction (MetaStackTracker *tracker,
|
||||
{
|
||||
if (meta_stack_op_apply (op, tracker->verified_stack))
|
||||
meta_stack_tracker_queue_sync_stack (tracker);
|
||||
|
||||
free_at_end = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -561,6 +565,9 @@ stack_tracker_apply_prediction (MetaStackTracker *tracker,
|
||||
meta_stack_op_apply (op, tracker->predicted_stack))
|
||||
meta_stack_tracker_queue_sync_stack (tracker);
|
||||
|
||||
if (free_at_end)
|
||||
meta_stack_op_free (op);
|
||||
|
||||
meta_stack_tracker_dump (tracker);
|
||||
}
|
||||
|
||||
@@ -895,7 +902,10 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
|
||||
requery_xserver_stack (tracker);
|
||||
|
||||
for (l = tracker->unverified_predictions->head; l; l = l->next)
|
||||
meta_stack_op_apply (l->data, tracker->verified_stack);
|
||||
{
|
||||
meta_stack_op_apply (l->data, tracker->verified_stack);
|
||||
meta_stack_op_free (l->data);
|
||||
}
|
||||
g_queue_clear (tracker->unverified_predictions);
|
||||
|
||||
j = 0;
|
||||
@@ -921,7 +931,7 @@ resync_verified_stack_with_xserver_stack (MetaStackTracker *tracker)
|
||||
MetaStackWindow new;
|
||||
MetaStackWindow *expected;
|
||||
int expected_index;
|
||||
|
||||
|
||||
/* If the current window corresponds to a window that's not
|
||||
* in xserver_stack any more then the least disruptive thing
|
||||
* we can do is to simply remove it and take another look at
|
||||
|
||||
192
src/core/stack.c
192
src/core/stack.c
@@ -5,12 +5,12 @@
|
||||
* @short_description: Which windows cover which other windows
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2002, 2003 Red Hat, Inc.
|
||||
* Copyright (C) 2004 Rob Adams
|
||||
* Copyright (C) 2004, 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -20,7 +20,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -67,7 +67,7 @@ MetaStack*
|
||||
meta_stack_new (MetaScreen *screen)
|
||||
{
|
||||
MetaStack *stack;
|
||||
|
||||
|
||||
stack = g_new (MetaStack, 1);
|
||||
|
||||
stack->screen = screen;
|
||||
@@ -85,7 +85,7 @@ meta_stack_new (MetaScreen *screen)
|
||||
stack->need_resort = FALSE;
|
||||
stack->need_relayer = FALSE;
|
||||
stack->need_constrain = FALSE;
|
||||
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ meta_stack_free (MetaStack *stack)
|
||||
|
||||
if (stack->last_all_root_children_stacked)
|
||||
free_last_all_root_children_stacked_cache (stack);
|
||||
|
||||
|
||||
g_free (stack);
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ meta_stack_add (MetaStack *stack,
|
||||
|
||||
if (window->stack_position >= 0)
|
||||
meta_bug ("Window %s had stack position already\n", window->desc);
|
||||
|
||||
|
||||
stack->added = g_list_prepend (stack->added, window);
|
||||
|
||||
window->stack_position = stack->n_positions;
|
||||
@@ -127,7 +127,7 @@ meta_stack_add (MetaStack *stack,
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"Window %s has stack_position initialized to %d\n",
|
||||
window->desc, window->stack_position);
|
||||
|
||||
|
||||
stack_sync_to_xserver (stack);
|
||||
meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
|
||||
}
|
||||
@@ -148,7 +148,7 @@ meta_stack_remove (MetaStack *stack,
|
||||
meta_window_set_stack_position_no_sync (window,
|
||||
stack->n_positions - 1);
|
||||
window->stack_position = -1;
|
||||
stack->n_positions -= 1;
|
||||
stack->n_positions -= 1;
|
||||
|
||||
/* We don't know if it's been moved from "added" to "stack" yet */
|
||||
stack->added = g_list_remove (stack->added, window);
|
||||
@@ -163,7 +163,7 @@ meta_stack_remove (MetaStack *stack,
|
||||
if (window->frame)
|
||||
stack->removed = g_list_prepend (stack->removed,
|
||||
GUINT_TO_POINTER (window->frame->xwindow));
|
||||
|
||||
|
||||
stack_sync_to_xserver (stack);
|
||||
meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
|
||||
}
|
||||
@@ -173,7 +173,7 @@ meta_stack_update_layer (MetaStack *stack,
|
||||
MetaWindow *window)
|
||||
{
|
||||
stack->need_relayer = TRUE;
|
||||
|
||||
|
||||
stack_sync_to_xserver (stack);
|
||||
meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
|
||||
}
|
||||
@@ -183,7 +183,7 @@ meta_stack_update_transient (MetaStack *stack,
|
||||
MetaWindow *window)
|
||||
{
|
||||
stack->need_constrain = TRUE;
|
||||
|
||||
|
||||
stack_sync_to_xserver (stack);
|
||||
meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
|
||||
}
|
||||
@@ -240,7 +240,7 @@ meta_stack_lower (MetaStack *stack,
|
||||
return;
|
||||
|
||||
meta_window_set_stack_position_no_sync (window, min_stack_position);
|
||||
|
||||
|
||||
stack_sync_to_xserver (stack);
|
||||
meta_stack_update_window_tile_matches (stack, window->screen->active_workspace);
|
||||
}
|
||||
@@ -255,7 +255,7 @@ void
|
||||
meta_stack_thaw (MetaStack *stack)
|
||||
{
|
||||
g_return_if_fail (stack->freeze_count > 0);
|
||||
|
||||
|
||||
stack->freeze_count -= 1;
|
||||
stack_sync_to_xserver (stack);
|
||||
meta_stack_update_window_tile_matches (stack, NULL);
|
||||
@@ -333,7 +333,7 @@ get_standalone_layer (MetaWindow *window)
|
||||
case META_WINDOW_OVERRIDE_OTHER:
|
||||
layer = META_LAYER_OVERRIDE_REDIRECT;
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
meta_window_foreach_transient (window,
|
||||
is_focused_foreach,
|
||||
&focused_transient);
|
||||
@@ -369,16 +369,16 @@ get_maximum_layer_in_group (MetaWindow *window)
|
||||
GSList *tmp;
|
||||
MetaStackLayer max;
|
||||
MetaStackLayer layer;
|
||||
|
||||
|
||||
max = META_LAYER_DESKTOP;
|
||||
|
||||
|
||||
group = meta_window_get_group (window);
|
||||
|
||||
if (group != NULL)
|
||||
members = meta_group_list_windows (group);
|
||||
else
|
||||
members = NULL;
|
||||
|
||||
|
||||
tmp = members;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
@@ -390,12 +390,12 @@ get_maximum_layer_in_group (MetaWindow *window)
|
||||
if (layer > max)
|
||||
max = layer;
|
||||
}
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
g_slist_free (members);
|
||||
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ compute_layer (MetaWindow *window)
|
||||
MetaStackLayer old_layer = window->layer;
|
||||
|
||||
window->layer = get_standalone_layer (window);
|
||||
|
||||
|
||||
/* We can only do promotion-due-to-group for dialogs and other
|
||||
* transients, or weird stuff happens like the desktop window and
|
||||
* nautilus windows getting in the same layer, or all gnome-terminal
|
||||
@@ -422,11 +422,11 @@ compute_layer (MetaWindow *window)
|
||||
* and a dialog transient for the normal window; you don't want the dialog
|
||||
* above the dock if it wouldn't normally be.
|
||||
*/
|
||||
|
||||
|
||||
MetaStackLayer group_max;
|
||||
|
||||
|
||||
group_max = get_maximum_layer_in_group (window);
|
||||
|
||||
|
||||
if (group_max > window->layer)
|
||||
{
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
@@ -467,10 +467,10 @@ compare_window_position (void *a,
|
||||
else
|
||||
return 0; /* not reached */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Stacking constraints
|
||||
*
|
||||
*
|
||||
* Assume constraints of the form "AB" meaning "window A must be
|
||||
* below window B"
|
||||
*
|
||||
@@ -487,14 +487,14 @@ compare_window_position (void *a,
|
||||
* apply BC: ABC
|
||||
*
|
||||
* but apply constraints in the wrong order and it breaks:
|
||||
*
|
||||
*
|
||||
* start: BCA
|
||||
* apply BC: BCA
|
||||
* apply AB: CAB
|
||||
*
|
||||
* We make a directed graph of the constraints by linking
|
||||
* from "above windows" to "below windows as follows:
|
||||
*
|
||||
*
|
||||
* AB -> BC -> CD
|
||||
* \
|
||||
* CE
|
||||
@@ -519,7 +519,7 @@ struct Constraint
|
||||
|
||||
/* used to create the graph. */
|
||||
GSList *next_nodes;
|
||||
|
||||
|
||||
/* constraint has been applied, used
|
||||
* to detect cycles.
|
||||
*/
|
||||
@@ -547,7 +547,7 @@ add_constraint (Constraint **constraints,
|
||||
Constraint *c;
|
||||
|
||||
g_assert (above->screen == below->screen);
|
||||
|
||||
|
||||
/* check if constraint is a duplicate */
|
||||
c = constraints[below->stack_position];
|
||||
while (c != NULL)
|
||||
@@ -574,7 +574,7 @@ create_constraints (Constraint **constraints,
|
||||
GList *windows)
|
||||
{
|
||||
GList *tmp;
|
||||
|
||||
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
@@ -587,7 +587,7 @@ create_constraints (Constraint **constraints,
|
||||
tmp = tmp->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (WINDOW_TRANSIENT_FOR_WHOLE_GROUP (w))
|
||||
{
|
||||
GSList *group_windows;
|
||||
@@ -600,9 +600,9 @@ create_constraints (Constraint **constraints,
|
||||
group_windows = meta_group_list_windows (group);
|
||||
else
|
||||
group_windows = NULL;
|
||||
|
||||
|
||||
tmp2 = group_windows;
|
||||
|
||||
|
||||
while (tmp2 != NULL)
|
||||
{
|
||||
MetaWindow *group_window = tmp2->data;
|
||||
@@ -614,7 +614,7 @@ create_constraints (Constraint **constraints,
|
||||
tmp2 = tmp2->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* old way of doing it */
|
||||
if (!(meta_window_is_ancestor_of_transient (w, group_window)) &&
|
||||
@@ -630,7 +630,7 @@ create_constraints (Constraint **constraints,
|
||||
w->desc, group_window->desc);
|
||||
add_constraint (constraints, w, group_window);
|
||||
}
|
||||
|
||||
|
||||
tmp2 = tmp2->next;
|
||||
}
|
||||
|
||||
@@ -640,7 +640,7 @@ create_constraints (Constraint **constraints,
|
||||
!w->transient_parent_is_root_window)
|
||||
{
|
||||
MetaWindow *parent;
|
||||
|
||||
|
||||
parent =
|
||||
meta_display_lookup_x_window (w->display, w->xtransient_for);
|
||||
|
||||
@@ -652,7 +652,7 @@ create_constraints (Constraint **constraints,
|
||||
add_constraint (constraints, w, parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
@@ -671,12 +671,12 @@ graph_constraints (Constraint **constraints,
|
||||
/* If we have "A below B" and "B below C" then AB -> BC so we
|
||||
* add BC to next_nodes in AB.
|
||||
*/
|
||||
|
||||
|
||||
c = constraints[i];
|
||||
while (c != NULL)
|
||||
{
|
||||
Constraint *n;
|
||||
|
||||
|
||||
g_assert (c->below->stack_position == i);
|
||||
|
||||
/* Constraints where ->above is below are our
|
||||
@@ -689,10 +689,10 @@ graph_constraints (Constraint **constraints,
|
||||
n);
|
||||
/* c is a previous node of n */
|
||||
n->has_prev = TRUE;
|
||||
|
||||
|
||||
n = n->next;
|
||||
}
|
||||
|
||||
|
||||
c = c->next;
|
||||
}
|
||||
|
||||
@@ -710,16 +710,16 @@ free_constraints (Constraint **constraints,
|
||||
while (i < n_constraints)
|
||||
{
|
||||
Constraint *c;
|
||||
|
||||
|
||||
c = constraints[i];
|
||||
while (c != NULL)
|
||||
{
|
||||
Constraint *next = c->next;
|
||||
|
||||
|
||||
g_slist_free (c->next_nodes);
|
||||
|
||||
g_free (c);
|
||||
|
||||
|
||||
c = next;
|
||||
}
|
||||
|
||||
@@ -730,7 +730,7 @@ free_constraints (Constraint **constraints,
|
||||
static void
|
||||
ensure_above (MetaWindow *above,
|
||||
MetaWindow *below)
|
||||
{
|
||||
{
|
||||
if (WINDOW_HAS_TRANSIENT_TYPE(above) &&
|
||||
above->layer < below->layer)
|
||||
{
|
||||
@@ -758,10 +758,10 @@ traverse_constraint (Constraint *c)
|
||||
|
||||
if (c->applied)
|
||||
return;
|
||||
|
||||
|
||||
ensure_above (c->above, c->below);
|
||||
c->applied = TRUE;
|
||||
|
||||
|
||||
tmp = c->next_nodes;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
@@ -785,13 +785,13 @@ apply_constraints (Constraint **constraints,
|
||||
while (i < n_constraints)
|
||||
{
|
||||
Constraint *c;
|
||||
|
||||
|
||||
c = constraints[i];
|
||||
while (c != NULL)
|
||||
{
|
||||
if (!c->has_prev)
|
||||
heads = g_slist_prepend (heads, c);
|
||||
|
||||
|
||||
c = c->next;
|
||||
}
|
||||
|
||||
@@ -805,7 +805,7 @@ apply_constraints (Constraint **constraints,
|
||||
Constraint *c = tmp->data;
|
||||
|
||||
traverse_constraint (c);
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
@@ -826,7 +826,7 @@ stack_do_window_deletions (MetaStack *stack)
|
||||
*/
|
||||
GList *tmp;
|
||||
int i;
|
||||
|
||||
|
||||
tmp = stack->removed;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
@@ -840,7 +840,7 @@ stack_do_window_deletions (MetaStack *stack)
|
||||
while (i > 0)
|
||||
{
|
||||
--i;
|
||||
|
||||
|
||||
/* there's no guarantee we'll actually find windows to
|
||||
* remove, e.g. the same xwindow could have been
|
||||
* added/removed before we ever synced, and we put
|
||||
@@ -877,34 +877,34 @@ stack_do_window_additions (MetaStack *stack)
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"Adding %d windows to sorted list\n",
|
||||
n_added);
|
||||
|
||||
|
||||
old_size = stack->xwindows->len;
|
||||
g_array_set_size (stack->xwindows, old_size + n_added);
|
||||
|
||||
|
||||
end = &g_array_index (stack->xwindows, Window, old_size);
|
||||
|
||||
/* stack->added has the most recent additions at the
|
||||
* front of the list, so we need to reverse it
|
||||
*/
|
||||
stack->added = g_list_reverse (stack->added);
|
||||
|
||||
|
||||
i = 0;
|
||||
tmp = stack->added;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w;
|
||||
|
||||
|
||||
w = tmp->data;
|
||||
|
||||
|
||||
end[i] = w->xwindow;
|
||||
|
||||
/* add to the main list */
|
||||
stack->sorted = g_list_prepend (stack->sorted, w);
|
||||
|
||||
|
||||
++i;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
|
||||
stack->need_resort = TRUE; /* may not be needed as we add to top */
|
||||
stack->need_constrain = TRUE;
|
||||
stack->need_relayer = TRUE;
|
||||
@@ -923,13 +923,13 @@ static void
|
||||
stack_do_relayer (MetaStack *stack)
|
||||
{
|
||||
GList *tmp;
|
||||
|
||||
|
||||
if (!stack->need_relayer)
|
||||
return;
|
||||
|
||||
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"Recomputing layers\n");
|
||||
|
||||
|
||||
tmp = stack->sorted;
|
||||
|
||||
while (tmp != NULL)
|
||||
@@ -954,7 +954,7 @@ stack_do_relayer (MetaStack *stack)
|
||||
* not layer
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
@@ -973,7 +973,7 @@ stack_do_constrain (MetaStack *stack)
|
||||
Constraint **constraints;
|
||||
|
||||
/* It'd be nice if this were all faster, probably */
|
||||
|
||||
|
||||
if (!stack->need_constrain)
|
||||
return;
|
||||
|
||||
@@ -988,10 +988,10 @@ stack_do_constrain (MetaStack *stack)
|
||||
graph_constraints (constraints, stack->n_positions);
|
||||
|
||||
apply_constraints (constraints, stack->n_positions);
|
||||
|
||||
|
||||
free_constraints (constraints, stack->n_positions);
|
||||
g_free (constraints);
|
||||
|
||||
|
||||
stack->need_constrain = FALSE;
|
||||
}
|
||||
|
||||
@@ -1005,10 +1005,10 @@ stack_do_resort (MetaStack *stack)
|
||||
{
|
||||
if (!stack->need_resort)
|
||||
return;
|
||||
|
||||
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"Sorting stack list\n");
|
||||
|
||||
|
||||
stack->sorted = g_list_sort (stack->sorted,
|
||||
(GCompareFunc) compare_window_position);
|
||||
|
||||
@@ -1248,12 +1248,12 @@ stack_sync_to_xserver (MetaStack *stack)
|
||||
GArray *x11_hidden_stack_windows;
|
||||
int n_override_redirect = 0;
|
||||
MetaStackWindow guard_stack_window;
|
||||
|
||||
|
||||
/* Bail out if frozen */
|
||||
if (stack->freeze_count > 0)
|
||||
return;
|
||||
|
||||
meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n");
|
||||
|
||||
meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n");
|
||||
|
||||
stack_ensure_sorted (stack);
|
||||
|
||||
@@ -1284,7 +1284,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
||||
MetaStackWindow stack_window;
|
||||
|
||||
stack_window.any.type = w->client_type;
|
||||
|
||||
|
||||
meta_topic (META_DEBUG_STACK, "%u:%d - %s ",
|
||||
w->layer, w->stack_position, w->desc);
|
||||
|
||||
@@ -1293,7 +1293,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
||||
n_override_redirect++;
|
||||
else
|
||||
g_array_prepend_val (x11_stacked, w->xwindow);
|
||||
|
||||
|
||||
if (w->frame)
|
||||
top_level_window = w->frame->xwindow;
|
||||
else
|
||||
@@ -1336,12 +1336,12 @@ stack_sync_to_xserver (MetaStack *stack)
|
||||
if (x11_stacked->len != stack->xwindows->len - n_override_redirect)
|
||||
meta_bug ("%u windows stacked, %u windows exist in stack\n",
|
||||
x11_stacked->len, stack->xwindows->len);
|
||||
|
||||
|
||||
/* Sync to server */
|
||||
|
||||
meta_topic (META_DEBUG_STACK, "Restacking %u windows\n",
|
||||
all_root_children_stacked->len);
|
||||
|
||||
|
||||
meta_error_trap_push (stack->screen->display);
|
||||
|
||||
if (stack->last_all_root_children_stacked == NULL)
|
||||
@@ -1425,7 +1425,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
||||
/* In this case we have an X window that we need to
|
||||
* put below a wayland window and this is the
|
||||
* topmost X window. */
|
||||
|
||||
|
||||
/* In X terms (because this is the topmost X window)
|
||||
* we want to
|
||||
* raise_window_relative_to_managed_windows() to
|
||||
@@ -1452,7 +1452,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
||||
* *newp, then we fail to restack *newp; but on
|
||||
* unmanaging last_xwindow, we'll fix it up.
|
||||
*/
|
||||
|
||||
|
||||
meta_topic (META_DEBUG_STACK, "Placing window 0x%lx below 0x%lx\n",
|
||||
newp->any.type == META_WINDOW_CLIENT_TYPE_X11 ? newp->x11.xwindow : 0,
|
||||
last_xwindow);
|
||||
@@ -1572,7 +1572,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
||||
* get removed from the stacking list when we unmanage it
|
||||
* and we'll fix stacking at that time.
|
||||
*/
|
||||
|
||||
|
||||
/* Sync _NET_CLIENT_LIST and _NET_CLIENT_LIST_STACKING */
|
||||
|
||||
XChangeProperty (stack->screen->display->xdisplay,
|
||||
@@ -1633,9 +1633,9 @@ meta_stack_get_above (MetaStack *stack,
|
||||
{
|
||||
GList *link;
|
||||
MetaWindow *above;
|
||||
|
||||
|
||||
stack_ensure_sorted (stack);
|
||||
|
||||
|
||||
link = g_list_find (stack->sorted, window);
|
||||
if (link == NULL)
|
||||
return NULL;
|
||||
@@ -1658,7 +1658,7 @@ meta_stack_get_below (MetaStack *stack,
|
||||
{
|
||||
GList *link;
|
||||
MetaWindow *below;
|
||||
|
||||
|
||||
stack_ensure_sorted (stack);
|
||||
|
||||
link = g_list_find (stack->sorted, window);
|
||||
@@ -1667,7 +1667,7 @@ meta_stack_get_below (MetaStack *stack,
|
||||
return NULL;
|
||||
if (link->next == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
below = link->next->data;
|
||||
|
||||
if (only_within_layer &&
|
||||
@@ -1801,22 +1801,22 @@ meta_stack_list_windows (MetaStack *stack,
|
||||
{
|
||||
GList *workspace_windows = NULL;
|
||||
GList *link;
|
||||
|
||||
|
||||
stack_ensure_sorted (stack); /* do adds/removes */
|
||||
|
||||
|
||||
link = stack->sorted;
|
||||
|
||||
|
||||
while (link)
|
||||
{
|
||||
MetaWindow *window = link->data;
|
||||
|
||||
|
||||
if (window &&
|
||||
(workspace == NULL || meta_window_located_on_workspace (window, workspace)))
|
||||
{
|
||||
workspace_windows = g_list_prepend (workspace_windows,
|
||||
window);
|
||||
}
|
||||
|
||||
|
||||
link = link->next;
|
||||
}
|
||||
|
||||
@@ -1833,7 +1833,7 @@ meta_stack_windows_cmp (MetaStack *stack,
|
||||
/* -1 means a below b */
|
||||
|
||||
stack_ensure_sorted (stack); /* update constraints, layers */
|
||||
|
||||
|
||||
if (window_a->layer < window_b->layer)
|
||||
return -1;
|
||||
else if (window_a->layer > window_b->layer)
|
||||
@@ -1883,7 +1883,7 @@ compare_pointers (gconstpointer a,
|
||||
return 1;
|
||||
else if (a < b)
|
||||
return -1;
|
||||
else
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1921,7 +1921,7 @@ meta_stack_set_positions (MetaStack *stack,
|
||||
|
||||
/* Make sure any adds or removes aren't in limbo -- is this needed? */
|
||||
stack_ensure_sorted (stack);
|
||||
|
||||
|
||||
if (!lists_contain_same_windows (windows, stack->sorted))
|
||||
{
|
||||
meta_warning ("This list of windows has somehow changed; not resetting "
|
||||
@@ -1934,7 +1934,7 @@ meta_stack_set_positions (MetaStack *stack,
|
||||
|
||||
stack->need_resort = TRUE;
|
||||
stack->need_constrain = TRUE;
|
||||
|
||||
|
||||
i = 0;
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
@@ -1943,7 +1943,7 @@ meta_stack_set_positions (MetaStack *stack,
|
||||
w->stack_position = i++;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"Reset the stack positions of (nearly) all windows\n");
|
||||
|
||||
@@ -1957,7 +1957,7 @@ meta_window_set_stack_position_no_sync (MetaWindow *window,
|
||||
{
|
||||
int low, high, delta;
|
||||
GList *tmp;
|
||||
|
||||
|
||||
g_return_if_fail (window->screen->stack != NULL);
|
||||
g_return_if_fail (window->stack_position >= 0);
|
||||
g_return_if_fail (position >= 0);
|
||||
@@ -1972,7 +1972,7 @@ meta_window_set_stack_position_no_sync (MetaWindow *window,
|
||||
|
||||
window->screen->stack->need_resort = TRUE;
|
||||
window->screen->stack->need_constrain = TRUE;
|
||||
|
||||
|
||||
if (position < window->stack_position)
|
||||
{
|
||||
low = position;
|
||||
@@ -1997,7 +1997,7 @@ meta_window_set_stack_position_no_sync (MetaWindow *window,
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
|
||||
window->stack_position = position;
|
||||
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -13,7 +13,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -26,7 +26,7 @@
|
||||
* @short_description: Which windows cover which other windows
|
||||
*
|
||||
* There are two factors that determine window position.
|
||||
*
|
||||
*
|
||||
* One is window->stack_position, which is a unique integer
|
||||
* indicating how windows are ordered with respect to one
|
||||
* another. The ordering here transcends layers; it isn't changed
|
||||
@@ -34,7 +34,7 @@
|
||||
* windows from one layer to another, while preserving the relative
|
||||
* order of the moved windows. Also, it allows us to restore
|
||||
* the stacking order from a saved session.
|
||||
*
|
||||
*
|
||||
* However when actually stacking windows on the screen, the
|
||||
* layer overrides the stack_position; windows are first sorted
|
||||
* by layer, then by stack_position within each layer.
|
||||
@@ -82,7 +82,7 @@ struct _MetaStack
|
||||
* The order of the elements in this list is not important.
|
||||
*/
|
||||
GList *removed;
|
||||
|
||||
|
||||
/**
|
||||
* If this is zero, the local stack oughtn't to be brought up to date with
|
||||
* the X server's stack, because it is in the middle of being updated.
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
/* Mutter box operation testing program */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -363,7 +363,7 @@ test_merge_regions ()
|
||||
* uniformly distributed location of center of struts (within screen)
|
||||
* merge all regions that are possible
|
||||
* print stats on problem setup
|
||||
* number of (non-completely-occluded?) struts
|
||||
* number of (non-completely-occluded?) struts
|
||||
* percentage of screen covered
|
||||
* length of resulting non-minimal spanning set
|
||||
* length of resulting minimal spanning set
|
||||
@@ -508,11 +508,11 @@ test_merge_regions ()
|
||||
compare = compare->next;
|
||||
}
|
||||
|
||||
printf (" Num rectangles contained in others : %d\n",
|
||||
printf (" Num rectangles contained in others : %d\n",
|
||||
num_contains);
|
||||
printf (" Num rectangles partially contained in others: %d\n",
|
||||
printf (" Num rectangles partially contained in others: %d\n",
|
||||
num_part_contains);
|
||||
printf (" Num rectangles adjacent to others : %d\n",
|
||||
printf (" Num rectangles adjacent to others : %d\n",
|
||||
num_adjacent);
|
||||
printf (" Num rectangles merged with others : %d\n",
|
||||
num_merged);
|
||||
@@ -583,9 +583,9 @@ test_regions_okay ()
|
||||
GList* region;
|
||||
GList* tmp;
|
||||
|
||||
/*************************************************************/
|
||||
/*************************************************************/
|
||||
/* Make sure test region 0 has the right spanning rectangles */
|
||||
/*************************************************************/
|
||||
/*************************************************************/
|
||||
region = get_screen_region (0);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_meta_rect (0, 0, 1600, 1200));
|
||||
@@ -593,9 +593,9 @@ test_regions_okay ()
|
||||
meta_rectangle_free_list_and_elements (tmp);
|
||||
meta_rectangle_free_list_and_elements (region);
|
||||
|
||||
/*************************************************************/
|
||||
/*************************************************************/
|
||||
/* Make sure test region 1 has the right spanning rectangles */
|
||||
/*************************************************************/
|
||||
/*************************************************************/
|
||||
region = get_screen_region (1);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_meta_rect (0, 20, 400, 1180));
|
||||
@@ -606,7 +606,7 @@ test_regions_okay ()
|
||||
|
||||
/*************************************************************/
|
||||
/* Make sure test region 2 has the right spanning rectangles */
|
||||
/*************************************************************/
|
||||
/*************************************************************/
|
||||
region = get_screen_region (2);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 300, 1180));
|
||||
@@ -620,7 +620,7 @@ test_regions_okay ()
|
||||
|
||||
/*************************************************************/
|
||||
/* Make sure test region 3 has the right spanning rectangles */
|
||||
/*************************************************************/
|
||||
/*************************************************************/
|
||||
region = get_screen_region (3);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_meta_rect ( 380, 675, 420, 525)); /* 220500 */
|
||||
@@ -646,7 +646,7 @@ test_regions_okay ()
|
||||
|
||||
/*************************************************************/
|
||||
/* Make sure test region 4 has the right spanning rectangles */
|
||||
/*************************************************************/
|
||||
/*************************************************************/
|
||||
region = get_screen_region (4);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_meta_rect ( 800, 20, 800, 1180));
|
||||
@@ -656,7 +656,7 @@ test_regions_okay ()
|
||||
|
||||
/*************************************************************/
|
||||
/* Make sure test region 5 has the right spanning rectangles */
|
||||
/*************************************************************/
|
||||
/*************************************************************/
|
||||
printf ("The next test intentionally causes a warning, "
|
||||
"but it can be ignored.\n");
|
||||
region = get_screen_region (5);
|
||||
@@ -1020,9 +1020,9 @@ test_find_onscreen_edges ()
|
||||
int top = META_DIRECTION_TOP;
|
||||
int bottom = META_DIRECTION_BOTTOM;
|
||||
|
||||
/*************************************************/
|
||||
/*************************************************/
|
||||
/* Make sure test region 0 has the correct edges */
|
||||
/*************************************************/
|
||||
/*************************************************/
|
||||
edges = get_screen_edges (0);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 1600, 0, bottom));
|
||||
@@ -1033,9 +1033,9 @@ test_find_onscreen_edges ()
|
||||
meta_rectangle_free_list_and_elements (tmp);
|
||||
meta_rectangle_free_list_and_elements (edges);
|
||||
|
||||
/*************************************************/
|
||||
/*************************************************/
|
||||
/* Make sure test region 1 has the correct edges */
|
||||
/*************************************************/
|
||||
/*************************************************/
|
||||
edges = get_screen_edges (1);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 400, 0, bottom));
|
||||
@@ -1048,9 +1048,9 @@ test_find_onscreen_edges ()
|
||||
meta_rectangle_free_list_and_elements (tmp);
|
||||
meta_rectangle_free_list_and_elements (edges);
|
||||
|
||||
/*************************************************/
|
||||
/*************************************************/
|
||||
/* Make sure test region 2 has the correct edges */
|
||||
/*************************************************/
|
||||
/*************************************************/
|
||||
edges = get_screen_edges (2);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_screen_edge (1200, 1200, 400, 0, bottom));
|
||||
@@ -1069,9 +1069,9 @@ test_find_onscreen_edges ()
|
||||
meta_rectangle_free_list_and_elements (tmp);
|
||||
meta_rectangle_free_list_and_elements (edges);
|
||||
|
||||
/*************************************************/
|
||||
/*************************************************/
|
||||
/* Make sure test region 3 has the correct edges */
|
||||
/*************************************************/
|
||||
/*************************************************/
|
||||
edges = get_screen_edges (3);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_screen_edge (1200, 1200, 400, 0, bottom));
|
||||
@@ -1096,7 +1096,7 @@ test_find_onscreen_edges ()
|
||||
char big_buffer1[(EDGE_LENGTH+2)*FUDGE], big_buffer2[(EDGE_LENGTH+2)*FUDGE];
|
||||
meta_rectangle_edge_list_to_string (edges, "\n ", big_buffer1);
|
||||
meta_rectangle_edge_list_to_string (tmp, "\n ", big_buffer2);
|
||||
printf("Generated edge list:\n %s\nComparison edges list:\n %s\n",
|
||||
printf("Generated edge list:\n %s\nComparison edges list:\n %s\n",
|
||||
big_buffer1, big_buffer2);
|
||||
#endif
|
||||
|
||||
@@ -1104,9 +1104,9 @@ test_find_onscreen_edges ()
|
||||
meta_rectangle_free_list_and_elements (tmp);
|
||||
meta_rectangle_free_list_and_elements (edges);
|
||||
|
||||
/*************************************************/
|
||||
/*************************************************/
|
||||
/* Make sure test region 4 has the correct edges */
|
||||
/*************************************************/
|
||||
/*************************************************/
|
||||
edges = get_screen_edges (4);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_screen_edge ( 800, 1200, 800, 0, bottom));
|
||||
@@ -1117,18 +1117,18 @@ test_find_onscreen_edges ()
|
||||
meta_rectangle_free_list_and_elements (tmp);
|
||||
meta_rectangle_free_list_and_elements (edges);
|
||||
|
||||
/*************************************************/
|
||||
/*************************************************/
|
||||
/* Make sure test region 5 has the correct edges */
|
||||
/*************************************************/
|
||||
/*************************************************/
|
||||
edges = get_screen_edges (5);
|
||||
tmp = NULL;
|
||||
verify_edge_lists_are_equal (edges, tmp);
|
||||
meta_rectangle_free_list_and_elements (tmp);
|
||||
meta_rectangle_free_list_and_elements (edges);
|
||||
|
||||
/*************************************************/
|
||||
/*************************************************/
|
||||
/* Make sure test region 6 has the correct edges */
|
||||
/*************************************************/
|
||||
/*************************************************/
|
||||
edges = get_screen_edges (6);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_screen_edge ( 0, 1200, 1600, 0, bottom));
|
||||
@@ -1153,18 +1153,18 @@ test_find_nonintersected_monitor_edges ()
|
||||
int top = META_DIRECTION_TOP;
|
||||
int bottom = META_DIRECTION_BOTTOM;
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/* Make sure test monitor set 0 for with region 0 has the correct edges */
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
edges = get_monitor_edges (0, 0);
|
||||
tmp = NULL;
|
||||
verify_edge_lists_are_equal (edges, tmp);
|
||||
meta_rectangle_free_list_and_elements (tmp);
|
||||
meta_rectangle_free_list_and_elements (edges);
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/* Make sure test monitor set 2 for with region 1 has the correct edges */
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
edges = get_monitor_edges (2, 1);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_monitor_edge ( 0, 600, 1600, 0, bottom));
|
||||
@@ -1173,9 +1173,9 @@ test_find_nonintersected_monitor_edges ()
|
||||
meta_rectangle_free_list_and_elements (tmp);
|
||||
meta_rectangle_free_list_and_elements (edges);
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/* Make sure test monitor set 1 for with region 2 has the correct edges */
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
edges = get_monitor_edges (1, 2);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_monitor_edge ( 800, 20, 0, 1080, right));
|
||||
@@ -1185,16 +1185,16 @@ test_find_nonintersected_monitor_edges ()
|
||||
char big_buffer1[(EDGE_LENGTH+2)*FUDGE], big_buffer2[(EDGE_LENGTH+2)*FUDGE];
|
||||
meta_rectangle_edge_list_to_string (edges, "\n ", big_buffer1);
|
||||
meta_rectangle_edge_list_to_string (tmp, "\n ", big_buffer2);
|
||||
printf("Generated edge list:\n %s\nComparison edges list:\n %s\n",
|
||||
printf("Generated edge list:\n %s\nComparison edges list:\n %s\n",
|
||||
big_buffer1, big_buffer2);
|
||||
#endif
|
||||
verify_edge_lists_are_equal (edges, tmp);
|
||||
meta_rectangle_free_list_and_elements (tmp);
|
||||
meta_rectangle_free_list_and_elements (edges);
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/* Make sure test monitor set 3 for with region 3 has the correct edges */
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
edges = get_monitor_edges (3, 3);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_monitor_edge ( 900, 600, 700, 0, bottom));
|
||||
@@ -1207,9 +1207,9 @@ test_find_nonintersected_monitor_edges ()
|
||||
meta_rectangle_free_list_and_elements (tmp);
|
||||
meta_rectangle_free_list_and_elements (edges);
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/* Make sure test monitor set 3 for with region 4 has the correct edges */
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
edges = get_monitor_edges (3, 4);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_monitor_edge ( 800, 600, 800, 0, bottom));
|
||||
@@ -1219,9 +1219,9 @@ test_find_nonintersected_monitor_edges ()
|
||||
meta_rectangle_free_list_and_elements (tmp);
|
||||
meta_rectangle_free_list_and_elements (edges);
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/* Make sure test monitor set 3 for with region 5has the correct edges */
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
edges = get_monitor_edges (3, 5);
|
||||
tmp = NULL;
|
||||
verify_edge_lists_are_equal (edges, tmp);
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
/* Mutter utilities */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -15,7 +15,7 @@
|
||||
* 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
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -13,7 +13,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -67,7 +67,7 @@ ensure_logfile (void)
|
||||
char *tmpl;
|
||||
int fd;
|
||||
GError *err;
|
||||
|
||||
|
||||
tmpl = g_strdup_printf ("mutter-%d-debug-log-XXXXXX",
|
||||
(int) getpid ());
|
||||
|
||||
@@ -77,7 +77,7 @@ ensure_logfile (void)
|
||||
&err);
|
||||
|
||||
g_free (tmpl);
|
||||
|
||||
|
||||
if (err != NULL)
|
||||
{
|
||||
meta_warning ("Failed to open debug log: %s\n",
|
||||
@@ -85,9 +85,9 @@ ensure_logfile (void)
|
||||
g_error_free (err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
logfile = fdopen (fd, "w");
|
||||
|
||||
|
||||
if (logfile == NULL)
|
||||
{
|
||||
meta_warning ("Failed to fdopen() log file %s: %s\n",
|
||||
@@ -98,7 +98,7 @@ ensure_logfile (void)
|
||||
{
|
||||
g_printerr ("Opened log file %s\n", filename);
|
||||
}
|
||||
|
||||
|
||||
g_free (filename);
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,7 @@ meta_set_verbose (gboolean setting)
|
||||
#ifndef WITH_VERBOSE_MODE
|
||||
if (setting)
|
||||
meta_fatal (_("Mutter was compiled without support for verbose mode\n"));
|
||||
#else
|
||||
#else
|
||||
if (setting)
|
||||
ensure_logfile ();
|
||||
#endif
|
||||
@@ -225,7 +225,7 @@ utf8_fputs (const char *str,
|
||||
{
|
||||
char *l;
|
||||
int retval;
|
||||
|
||||
|
||||
l = g_locale_from_utf8 (str, -1, NULL, NULL, NULL);
|
||||
|
||||
if (l == NULL)
|
||||
@@ -259,24 +259,24 @@ meta_debug_spew_real (const char *format, ...)
|
||||
va_list args;
|
||||
gchar *str;
|
||||
FILE *out;
|
||||
|
||||
|
||||
g_return_if_fail (format != NULL);
|
||||
|
||||
if (!is_debugging)
|
||||
return;
|
||||
|
||||
|
||||
va_start (args, format);
|
||||
str = g_strdup_vprintf (format, args);
|
||||
va_end (args);
|
||||
|
||||
out = logfile ? logfile : stderr;
|
||||
|
||||
|
||||
if (no_prefix == 0)
|
||||
utf8_fputs ("Window manager: ", out);
|
||||
utf8_fputs (str, out);
|
||||
|
||||
fflush (out);
|
||||
|
||||
|
||||
g_free (str);
|
||||
}
|
||||
#endif /* WITH_VERBOSE_MODE */
|
||||
@@ -381,11 +381,11 @@ meta_topic_real_valist (MetaDebugTopic topic,
|
||||
++sync_count;
|
||||
fprintf (out, "%d: ", sync_count);
|
||||
}
|
||||
|
||||
|
||||
utf8_fputs (str, out);
|
||||
|
||||
|
||||
fflush (out);
|
||||
|
||||
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
@@ -410,7 +410,7 @@ meta_bug (const char *format, ...)
|
||||
FILE *out;
|
||||
|
||||
g_return_if_fail (format != NULL);
|
||||
|
||||
|
||||
va_start (args, format);
|
||||
str = g_strdup_vprintf (format, args);
|
||||
va_end (args);
|
||||
@@ -426,9 +426,9 @@ meta_bug (const char *format, ...)
|
||||
utf8_fputs (str, out);
|
||||
|
||||
fflush (out);
|
||||
|
||||
|
||||
g_free (str);
|
||||
|
||||
|
||||
/* stop us in a debugger */
|
||||
abort ();
|
||||
}
|
||||
@@ -439,9 +439,9 @@ meta_warning (const char *format, ...)
|
||||
va_list args;
|
||||
gchar *str;
|
||||
FILE *out;
|
||||
|
||||
|
||||
g_return_if_fail (format != NULL);
|
||||
|
||||
|
||||
va_start (args, format);
|
||||
str = g_strdup_vprintf (format, args);
|
||||
va_end (args);
|
||||
@@ -457,7 +457,7 @@ meta_warning (const char *format, ...)
|
||||
utf8_fputs (str, out);
|
||||
|
||||
fflush (out);
|
||||
|
||||
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
@@ -467,9 +467,9 @@ meta_fatal (const char *format, ...)
|
||||
va_list args;
|
||||
gchar *str;
|
||||
FILE *out;
|
||||
|
||||
|
||||
g_return_if_fail (format != NULL);
|
||||
|
||||
|
||||
va_start (args, format);
|
||||
str = g_strdup_vprintf (format, args);
|
||||
va_end (args);
|
||||
@@ -485,7 +485,7 @@ meta_fatal (const char *format, ...)
|
||||
utf8_fputs (str, out);
|
||||
|
||||
fflush (out);
|
||||
|
||||
|
||||
g_free (str);
|
||||
|
||||
meta_exit (META_EXIT_ERROR);
|
||||
@@ -508,7 +508,7 @@ meta_pop_no_msg_prefix (void)
|
||||
void
|
||||
meta_exit (MetaExitCode code)
|
||||
{
|
||||
|
||||
|
||||
exit (code);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
* which the rest of the world is allowed to use.)
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2002 Red Hat, Inc.
|
||||
* Copyright (C) 2003, 2004 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -24,7 +24,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -74,11 +74,10 @@ typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
META_IS_CONFIGURE_REQUEST = 1 << 0,
|
||||
META_DO_GRAVITY_ADJUST = 1 << 1,
|
||||
META_IS_USER_ACTION = 1 << 2,
|
||||
META_IS_MOVE_ACTION = 1 << 3,
|
||||
META_IS_RESIZE_ACTION = 1 << 4,
|
||||
META_IS_WAYLAND_RESIZE = 1 << 5
|
||||
META_IS_USER_ACTION = 1 << 1,
|
||||
META_IS_MOVE_ACTION = 1 << 2,
|
||||
META_IS_RESIZE_ACTION = 1 << 3,
|
||||
META_IS_WAYLAND_RESIZE = 1 << 4,
|
||||
} MetaMoveResizeFlags;
|
||||
|
||||
typedef enum
|
||||
@@ -91,7 +90,7 @@ typedef enum
|
||||
struct _MetaWindow
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
|
||||
MetaDisplay *display;
|
||||
MetaScreen *screen;
|
||||
const MetaMonitorInfo *monitor;
|
||||
@@ -135,18 +134,18 @@ struct _MetaWindow
|
||||
|
||||
int hide_titlebar_when_maximized;
|
||||
int net_wm_pid;
|
||||
|
||||
|
||||
Window xtransient_for;
|
||||
Window xgroup_leader;
|
||||
Window xclient_leader;
|
||||
MetaWindow *transient_for;
|
||||
|
||||
/* Initial workspace property */
|
||||
int initial_workspace;
|
||||
|
||||
int initial_workspace;
|
||||
|
||||
/* Initial timestamp property */
|
||||
guint32 initial_timestamp;
|
||||
|
||||
guint32 initial_timestamp;
|
||||
|
||||
/* Whether this is an override redirect window or not */
|
||||
guint override_redirect : 1;
|
||||
|
||||
@@ -185,7 +184,7 @@ struct _MetaWindow
|
||||
* these monitors. If not, this is the single monitor which the window's
|
||||
* origin is on. */
|
||||
gint fullscreen_monitors[4];
|
||||
|
||||
|
||||
/* Whether we're trying to constrain the window to be fully onscreen */
|
||||
guint require_fully_onscreen : 1;
|
||||
|
||||
@@ -214,7 +213,7 @@ struct _MetaWindow
|
||||
* see also unmaps_pending
|
||||
*/
|
||||
guint mapped : 1;
|
||||
|
||||
|
||||
/* Whether window has been hidden from view by lowering it to the bottom
|
||||
* of window stack.
|
||||
*/
|
||||
@@ -248,23 +247,23 @@ struct _MetaWindow
|
||||
|
||||
/* whether an initial workspace was explicitly set */
|
||||
guint initial_workspace_set : 1;
|
||||
|
||||
|
||||
/* whether an initial timestamp was explicitly set */
|
||||
guint initial_timestamp_set : 1;
|
||||
|
||||
|
||||
/* whether net_wm_user_time has been set yet */
|
||||
guint net_wm_user_time_set : 1;
|
||||
|
||||
/* whether net_wm_icon_geometry has been set */
|
||||
guint icon_geometry_set : 1;
|
||||
|
||||
|
||||
/* These are the flags from WM_PROTOCOLS */
|
||||
guint take_focus : 1;
|
||||
guint delete_window : 1;
|
||||
guint can_ping : 1;
|
||||
/* Globally active / No input */
|
||||
guint input : 1;
|
||||
|
||||
|
||||
/* MWM hints about features of window */
|
||||
guint mwm_decorated : 1;
|
||||
guint mwm_border_only : 1;
|
||||
@@ -273,7 +272,7 @@ struct _MetaWindow
|
||||
guint mwm_has_maximize_func : 1;
|
||||
guint mwm_has_move_func : 1;
|
||||
guint mwm_has_resize_func : 1;
|
||||
|
||||
|
||||
/* Computed features of window */
|
||||
guint decorated : 1;
|
||||
guint border_only : 1;
|
||||
@@ -296,16 +295,13 @@ struct _MetaWindow
|
||||
|
||||
/* EWHH demands attention flag */
|
||||
guint wm_state_demands_attention : 1;
|
||||
|
||||
|
||||
/* TRUE iff window == window->display->focus_window */
|
||||
guint has_focus : 1;
|
||||
|
||||
/* Have we placed this window? */
|
||||
guint placed : 1;
|
||||
|
||||
/* Must we force_save_user_window_placement? */
|
||||
guint force_save_user_rect : 1;
|
||||
|
||||
/* Is this not a transient of the focus window which is being denied focus? */
|
||||
guint denied_focus_and_not_transient : 1;
|
||||
|
||||
@@ -317,15 +313,15 @@ struct _MetaWindow
|
||||
|
||||
/* Are we in meta_window_new()? */
|
||||
guint constructing : 1;
|
||||
|
||||
|
||||
/* Are we in the various queues? (Bitfield: see META_WINDOW_IS_IN_QUEUE) */
|
||||
guint is_in_queues : NUMBER_OF_QUEUES;
|
||||
|
||||
|
||||
/* Used by keybindings.c */
|
||||
guint keys_grabbed : 1; /* normal keybindings grabbed */
|
||||
guint grab_on_frame : 1; /* grabs are on the frame */
|
||||
guint all_keys_grabbed : 1; /* AnyKey grabbed */
|
||||
|
||||
|
||||
/* Set if the reason for unmanaging the window is that
|
||||
* it was withdrawn
|
||||
*/
|
||||
@@ -338,7 +334,7 @@ struct _MetaWindow
|
||||
|
||||
/* 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;
|
||||
|
||||
@@ -361,7 +357,8 @@ struct _MetaWindow
|
||||
/* if non-NULL, the bounds of the window frame */
|
||||
cairo_region_t *frame_bounds;
|
||||
|
||||
/* if non-NULL, the bounding shape region of the window */
|
||||
/* if non-NULL, the bounding shape region of the window. Relative to
|
||||
* the server-side client window. */
|
||||
cairo_region_t *shape_region;
|
||||
|
||||
/* if non-NULL, the opaque region _NET_WM_OPAQUE_REGION */
|
||||
@@ -387,7 +384,7 @@ struct _MetaWindow
|
||||
guint sync_request_timeout_id;
|
||||
/* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
|
||||
XSyncAlarm sync_request_alarm;
|
||||
|
||||
|
||||
/* Number of UnmapNotify that are caused by us, if
|
||||
* we get UnmapNotify with none pending then the client
|
||||
* is withdrawing the window.
|
||||
@@ -403,51 +400,40 @@ struct _MetaWindow
|
||||
|
||||
/* window that gets updated net_wm_user_time values */
|
||||
Window user_time_window;
|
||||
|
||||
/* The size we set the window to last (i.e. what we believe
|
||||
* to be its actual size on the server). The x, y are
|
||||
* the actual server-side x,y so are relative to the frame
|
||||
* (meaning that they just hold the frame width and height)
|
||||
* or the root window (meaning they specify the location
|
||||
* of the top left of the inner window) as appropriate.
|
||||
*/
|
||||
MetaRectangle rect;
|
||||
|
||||
gboolean has_custom_frame_extents;
|
||||
GtkBorder custom_frame_extents;
|
||||
|
||||
/* The geometry to restore when we unmaximize. The position is in
|
||||
* root window coords, even if there's a frame, which contrasts with
|
||||
* window->rect above. Note that this gives the position and size
|
||||
* of the client window (i.e. ignoring the frame).
|
||||
*/
|
||||
/* The rectangles here are in "frame rect" coordinates. See the
|
||||
* comment at the top of meta_window_move_resize_internal() for more
|
||||
* information. */
|
||||
|
||||
/* The current window geometry of the window. */
|
||||
MetaRectangle rect;
|
||||
|
||||
/* The geometry to restore when we unmaximize. */
|
||||
MetaRectangle saved_rect;
|
||||
|
||||
/* This is the geometry the window had after the last user-initiated
|
||||
* move/resize operations. We use this whenever we are moving the
|
||||
* implicitly (for example, if we move to avoid a panel, we can snap
|
||||
* back to this position if the panel moves again). Note that this
|
||||
* gives the position and size of the client window (i.e. ignoring
|
||||
* the frame).
|
||||
*
|
||||
* Position always in root coords, unlike window->rect.
|
||||
/* This is the geometry the window will have if no constraints have
|
||||
* applied. We use this whenever we are moving implicitly (for example,
|
||||
* if we move to avoid a panel, we can snap back to this position if
|
||||
* the panel moves again).
|
||||
*/
|
||||
MetaRectangle user_rect;
|
||||
|
||||
MetaRectangle unconstrained_rect;
|
||||
|
||||
/* Cached net_wm_icon_geometry */
|
||||
MetaRectangle icon_geometry;
|
||||
|
||||
/* Requested geometry */
|
||||
int border_width;
|
||||
/* x/y/w/h here get filled with ConfigureRequest values */
|
||||
XSizeHints size_hints;
|
||||
|
||||
/* Managed by stack.c */
|
||||
MetaStackLayer layer;
|
||||
int stack_position; /* see comment in stack.h */
|
||||
|
||||
/* Current dialog open for this window */
|
||||
|
||||
/* Managed by delete.c */
|
||||
int dialog_pid;
|
||||
guint is_alive : 1;
|
||||
|
||||
/* maintained by group.c */
|
||||
MetaGroup *group;
|
||||
@@ -481,9 +467,10 @@ struct _MetaWindowClass
|
||||
MetaGrabOp op);
|
||||
void (*grab_op_ended) (MetaWindow *window,
|
||||
MetaGrabOp op);
|
||||
void (*current_workspace_changed) (MetaWindow *window);
|
||||
void (*move_resize_internal) (MetaWindow *window,
|
||||
int gravity,
|
||||
MetaRectangle requested_rect,
|
||||
MetaRectangle unconstrained_rect,
|
||||
MetaRectangle constrained_rect,
|
||||
MetaMoveResizeFlags flags,
|
||||
MetaMoveResizeResultFlags *result);
|
||||
@@ -527,13 +514,6 @@ MetaWindow * _meta_window_shared_new (MetaDisplay *display,
|
||||
MetaCompEffect effect,
|
||||
XWindowAttributes *attrs);
|
||||
|
||||
MetaWindow * meta_window_x11_new (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
gboolean must_be_viewable,
|
||||
MetaCompEffect effect);
|
||||
MetaWindow * meta_window_wayland_new (MetaDisplay *display,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
void meta_window_unmanage (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
void meta_window_calc_showing (MetaWindow *window);
|
||||
@@ -543,11 +523,6 @@ void meta_window_tile (MetaWindow *window);
|
||||
void meta_window_maximize_internal (MetaWindow *window,
|
||||
MetaMaximizeFlags directions,
|
||||
MetaRectangle *saved_rect);
|
||||
void meta_window_unmaximize_with_gravity (MetaWindow *window,
|
||||
MetaMaximizeFlags directions,
|
||||
int new_width,
|
||||
int new_height,
|
||||
int gravity);
|
||||
|
||||
void meta_window_make_fullscreen_internal (MetaWindow *window);
|
||||
void meta_window_update_fullscreen_monitors (MetaWindow *window,
|
||||
@@ -556,27 +531,12 @@ void meta_window_update_fullscreen_monitors (MetaWindow *window,
|
||||
unsigned long left,
|
||||
unsigned long right);
|
||||
|
||||
void meta_window_resize_frame_with_gravity (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int w,
|
||||
int h,
|
||||
int gravity);
|
||||
|
||||
/* args to move are window pos, not frame pos */
|
||||
void meta_window_move (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int root_x_nw,
|
||||
int root_y_nw);
|
||||
void meta_window_resize (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int w,
|
||||
int h);
|
||||
void meta_window_move_resize (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int root_x_nw,
|
||||
int root_y_nw,
|
||||
int w,
|
||||
int h);
|
||||
void meta_window_resize_with_gravity (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int w,
|
||||
int h,
|
||||
int gravity);
|
||||
void meta_window_change_workspace (MetaWindow *window,
|
||||
MetaWorkspace *workspace);
|
||||
|
||||
@@ -585,17 +545,6 @@ gboolean meta_window_should_be_showing (MetaWindow *window);
|
||||
|
||||
void meta_window_update_struts (MetaWindow *window);
|
||||
|
||||
/* this gets root coords */
|
||||
void meta_window_get_position (MetaWindow *window,
|
||||
int *x,
|
||||
int *y);
|
||||
|
||||
/* Gets root coords for x, y, width & height of client window; uses
|
||||
* meta_window_get_position for x & y.
|
||||
*/
|
||||
void meta_window_get_client_root_coords (MetaWindow *window,
|
||||
MetaRectangle *rect);
|
||||
|
||||
/* gets position we need to set to stay in current position,
|
||||
* assuming position will be gravity-compensated. i.e.
|
||||
* this is the position a client would send in a configure
|
||||
@@ -608,7 +557,7 @@ void meta_window_get_gravity_position (MetaWindow *window,
|
||||
/* Get geometry for saving in the session; x/y are gravity
|
||||
* position, and w/h are in resize inc above the base size.
|
||||
*/
|
||||
void meta_window_get_geometry (MetaWindow *window,
|
||||
void meta_window_get_session_geometry (MetaWindow *window,
|
||||
int *x,
|
||||
int *y,
|
||||
int *width,
|
||||
@@ -619,15 +568,12 @@ void meta_window_update_unfocused_button_grabs (MetaWindow *window);
|
||||
void meta_window_set_focused_internal (MetaWindow *window,
|
||||
gboolean focused);
|
||||
|
||||
void meta_window_set_current_workspace_hint (MetaWindow *window);
|
||||
void meta_window_current_workspace_changed (MetaWindow *window);
|
||||
|
||||
unsigned long meta_window_get_net_wm_desktop (MetaWindow *window);
|
||||
|
||||
void meta_window_show_menu (MetaWindow *window,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp);
|
||||
void meta_window_show_menu (MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
gboolean meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
||||
const ClutterEvent *event);
|
||||
@@ -677,9 +623,6 @@ void meta_window_update_icon_now (MetaWindow *window);
|
||||
void meta_window_update_for_monitors_changed (MetaWindow *window);
|
||||
void meta_window_update_on_all_workspaces (MetaWindow *window);
|
||||
|
||||
void meta_window_propagate_focus_appearance (MetaWindow *window,
|
||||
gboolean focused);
|
||||
|
||||
gboolean meta_window_should_attach_to_parent (MetaWindow *window);
|
||||
gboolean meta_window_can_tile_side_by_side (MetaWindow *window);
|
||||
|
||||
@@ -713,6 +656,10 @@ void meta_window_handle_enter (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
guint root_x,
|
||||
guint root_y);
|
||||
void meta_window_handle_leave (MetaWindow *window);
|
||||
|
||||
gboolean meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
const ClutterEvent *event);
|
||||
|
||||
void meta_window_set_surface_mapped (MetaWindow *window,
|
||||
gboolean surface_mapped);
|
||||
@@ -721,6 +668,8 @@ Window meta_window_get_toplevel_xwindow (MetaWindow *window);
|
||||
|
||||
void meta_window_get_client_area_rect (const MetaWindow *window,
|
||||
cairo_rectangle_int_t *rect);
|
||||
void meta_window_get_titlebar_rect (MetaWindow *window,
|
||||
MetaRectangle *titlebar_rect);
|
||||
|
||||
void meta_window_activate_full (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
@@ -742,13 +691,11 @@ void meta_window_update_resize (MetaWindow *window,
|
||||
void meta_window_move_resize_internal (MetaWindow *window,
|
||||
MetaMoveResizeFlags flags,
|
||||
int gravity,
|
||||
int root_x_nw,
|
||||
int root_y_nw,
|
||||
int w,
|
||||
int h);
|
||||
void meta_window_save_user_window_placement (MetaWindow *window);
|
||||
MetaRectangle frame_rect);
|
||||
|
||||
void meta_window_grab_op_began (MetaWindow *window, MetaGrabOp op);
|
||||
void meta_window_grab_op_ended (MetaWindow *window, MetaGrabOp op);
|
||||
|
||||
void meta_window_set_alive (MetaWindow *window, gboolean is_alive);
|
||||
|
||||
#endif
|
||||
|
||||
1564
src/core/window.c
1564
src/core/window.c
File diff suppressed because it is too large
Load Diff
@@ -10,10 +10,10 @@
|
||||
* are unmapped.
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2004, 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -23,7 +23,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -38,7 +38,7 @@ struct _MetaWorkspace
|
||||
{
|
||||
GObject parent_instance;
|
||||
MetaScreen *screen;
|
||||
|
||||
|
||||
GList *windows;
|
||||
|
||||
/* The "MRU list", or "most recently used" list, is a list of
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004, 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -197,7 +197,7 @@ meta_workspace_new (MetaScreen *screen)
|
||||
workspace->all_struts = NULL;
|
||||
|
||||
workspace->showing_desktop = FALSE;
|
||||
|
||||
|
||||
return workspace;
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ workspace_free_all_struts (MetaWorkspace *workspace)
|
||||
{
|
||||
if (workspace->all_struts == NULL)
|
||||
return;
|
||||
|
||||
|
||||
g_slist_foreach (workspace->all_struts, free_this, NULL);
|
||||
g_slist_free (workspace->all_struts);
|
||||
workspace->all_struts = NULL;
|
||||
@@ -236,7 +236,7 @@ workspace_free_builtin_struts (MetaWorkspace *workspace)
|
||||
{
|
||||
if (workspace->builtin_struts == NULL)
|
||||
return;
|
||||
|
||||
|
||||
g_slist_foreach (workspace->builtin_struts, free_this, NULL);
|
||||
g_slist_free (workspace->builtin_struts);
|
||||
workspace->builtin_struts = NULL;
|
||||
@@ -254,7 +254,7 @@ meta_workspace_remove (MetaWorkspace *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)
|
||||
{
|
||||
@@ -272,10 +272,10 @@ meta_workspace_remove (MetaWorkspace *workspace)
|
||||
g_assert (workspace->windows == NULL);
|
||||
|
||||
screen = workspace->screen;
|
||||
|
||||
|
||||
workspace->screen->workspaces =
|
||||
g_list_remove (workspace->screen->workspaces, workspace);
|
||||
|
||||
|
||||
g_free (workspace->work_area_monitor);
|
||||
|
||||
g_list_free (workspace->mru_list);
|
||||
@@ -313,11 +313,11 @@ 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->on_all_workspaces)
|
||||
{
|
||||
if (window->workspace == NULL)
|
||||
{
|
||||
@@ -342,8 +342,8 @@ meta_workspace_add_window (MetaWorkspace *workspace,
|
||||
|
||||
window->workspace = workspace;
|
||||
|
||||
meta_window_set_current_workspace_hint (window);
|
||||
|
||||
meta_window_current_workspace_changed (window);
|
||||
|
||||
if (window->struts)
|
||||
{
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
@@ -371,10 +371,10 @@ meta_workspace_remove_window (MetaWorkspace *workspace,
|
||||
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
|
||||
* from the MRU list unless this causes it to be removed from all
|
||||
* workspaces
|
||||
*/
|
||||
if (window->on_all_workspaces)
|
||||
if (window->on_all_workspaces)
|
||||
{
|
||||
GList* tmp = window->screen->workspaces;
|
||||
while (tmp)
|
||||
@@ -391,8 +391,8 @@ meta_workspace_remove_window (MetaWorkspace *workspace,
|
||||
g_assert (g_list_find (workspace->mru_list, window) == NULL);
|
||||
}
|
||||
|
||||
meta_window_set_current_workspace_hint (window);
|
||||
|
||||
meta_window_current_workspace_changed (window);
|
||||
|
||||
if (window->struts)
|
||||
{
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
@@ -416,12 +416,12 @@ meta_workspace_relocate_windows (MetaWorkspace *workspace,
|
||||
{
|
||||
GList *tmp;
|
||||
GList *copy;
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -429,12 +429,12 @@ meta_workspace_relocate_windows (MetaWorkspace *workspace,
|
||||
|
||||
meta_workspace_remove_window (workspace, window);
|
||||
meta_workspace_add_window (new_home, window);
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
g_list_free (copy);
|
||||
|
||||
|
||||
g_assert (workspace->windows == NULL);
|
||||
}
|
||||
|
||||
@@ -547,10 +547,10 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
||||
MetaWorkspaceLayout layout1, layout2;
|
||||
gint num_workspaces, current_space, new_space;
|
||||
MetaMotionDirection direction;
|
||||
|
||||
|
||||
meta_verbose ("Activating workspace %d\n",
|
||||
meta_workspace_index (workspace));
|
||||
|
||||
|
||||
if (workspace->screen->active_workspace == workspace)
|
||||
return;
|
||||
|
||||
@@ -582,7 +582,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
||||
if (workspace->screen->display->grab_op == META_GRAB_OP_MOVING ||
|
||||
workspace->screen->display->grab_op == META_GRAB_OP_KEYBOARD_MOVING)
|
||||
move_window = workspace->screen->display->grab_window;
|
||||
|
||||
|
||||
if (move_window != NULL)
|
||||
{
|
||||
if (move_window->on_all_workspaces)
|
||||
@@ -718,7 +718,7 @@ meta_workspace_update_window_hints (MetaWorkspace *workspace)
|
||||
{
|
||||
MetaWindow *win = l->data;
|
||||
|
||||
meta_window_set_current_workspace_hint (win);
|
||||
meta_window_current_workspace_changed (win);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
@@ -739,7 +739,7 @@ meta_workspace_list_windows (MetaWorkspace *workspace)
|
||||
GSList *display_windows;
|
||||
GSList *tmp;
|
||||
GList *workspace_windows;
|
||||
|
||||
|
||||
display_windows = meta_display_list_windows (workspace->screen->display,
|
||||
META_LIST_DEFAULT);
|
||||
|
||||
@@ -767,7 +767,7 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
|
||||
GList *tmp;
|
||||
GList *windows;
|
||||
int i;
|
||||
|
||||
|
||||
if (workspace->work_areas_invalid)
|
||||
{
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
@@ -787,7 +787,7 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
|
||||
|
||||
g_free (workspace->work_area_monitor);
|
||||
workspace->work_area_monitor = NULL;
|
||||
|
||||
|
||||
workspace_free_all_struts (workspace);
|
||||
|
||||
for (i = 0; i < workspace->screen->n_monitor_infos; i++)
|
||||
@@ -800,7 +800,7 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
|
||||
workspace->screen_region = NULL;
|
||||
workspace->screen_edges = NULL;
|
||||
workspace->monitor_edges = NULL;
|
||||
|
||||
|
||||
workspace->work_areas_invalid = TRUE;
|
||||
|
||||
/* redo the size/position constraints on all windows */
|
||||
@@ -811,7 +811,7 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
|
||||
MetaWindow *w = tmp->data;
|
||||
|
||||
meta_window_queue (w, META_QUEUE_MOVE_RESIZE);
|
||||
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
@@ -876,7 +876,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
|
||||
|
||||
/* STEP 2: Get the maximal/spanning rects for the onscreen and
|
||||
* on-single-monitor regions
|
||||
*/
|
||||
*/
|
||||
g_assert (workspace->monitor_region == NULL);
|
||||
g_assert (workspace->screen_region == NULL);
|
||||
|
||||
@@ -948,7 +948,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
|
||||
workspace->work_area_screen.x,
|
||||
workspace->work_area_screen.y,
|
||||
workspace->work_area_screen.width,
|
||||
workspace->work_area_screen.height);
|
||||
workspace->work_area_screen.height);
|
||||
|
||||
/* Now find the work areas for each monitor */
|
||||
g_free (workspace->work_area_monitor);
|
||||
@@ -983,7 +983,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
|
||||
|
||||
/* STEP 4: Make sure the screen_region is nonempty (separate from step 2
|
||||
* since it relies on step 3).
|
||||
*/
|
||||
*/
|
||||
if (workspace->screen_region == NULL)
|
||||
{
|
||||
MetaRectangle *nonempty_region;
|
||||
@@ -1070,7 +1070,7 @@ meta_workspace_get_work_area_for_monitor (MetaWorkspace *workspace,
|
||||
|
||||
ensure_work_areas_validated (workspace);
|
||||
g_assert (which_monitor < workspace->screen->n_monitor_infos);
|
||||
|
||||
|
||||
*area = workspace->work_area_monitor[which_monitor];
|
||||
}
|
||||
|
||||
@@ -1086,7 +1086,7 @@ meta_workspace_get_work_area_all_monitors (MetaWorkspace *workspace,
|
||||
MetaRectangle *area)
|
||||
{
|
||||
ensure_work_areas_validated (workspace);
|
||||
|
||||
|
||||
*area = workspace->work_area_screen;
|
||||
}
|
||||
|
||||
@@ -1151,7 +1151,7 @@ MetaWorkspace*
|
||||
meta_workspace_get_neighbor (MetaWorkspace *workspace,
|
||||
MetaMotionDirection direction)
|
||||
{
|
||||
MetaWorkspaceLayout layout;
|
||||
MetaWorkspaceLayout layout;
|
||||
int i, current_space, num_workspaces;
|
||||
gboolean ltr;
|
||||
|
||||
@@ -1162,10 +1162,10 @@ 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;
|
||||
|
||||
switch (direction)
|
||||
switch (direction)
|
||||
{
|
||||
case META_MOTION_LEFT:
|
||||
layout.current_col -= ltr ? 1 : -1;
|
||||
@@ -1199,12 +1199,12 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace,
|
||||
if (i >= num_workspaces)
|
||||
meta_bug ("calc_workspace_layout left an invalid (too-high) workspace number %d in the grid\n",
|
||||
i);
|
||||
|
||||
|
||||
meta_verbose ("Neighbor workspace is %d at row %d col %d\n",
|
||||
i, layout.current_row, layout.current_col);
|
||||
|
||||
meta_screen_free_workspace_layout (&layout);
|
||||
|
||||
|
||||
return meta_screen_get_workspace_by_index (workspace->screen, i);
|
||||
}
|
||||
|
||||
@@ -1258,7 +1258,7 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
|
||||
}
|
||||
|
||||
if (workspace->screen->display->autoraise_window != window &&
|
||||
meta_prefs_get_auto_raise ())
|
||||
meta_prefs_get_auto_raise ())
|
||||
{
|
||||
meta_display_queue_autoraise_callback (workspace->screen->display,
|
||||
window);
|
||||
@@ -1303,7 +1303,7 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Focusing MRU window\n");
|
||||
|
||||
/* First, check to see if we need to focus an ancestor of a window */
|
||||
/* First, check to see if we need to focus an ancestor of a window */
|
||||
if (not_this_one)
|
||||
{
|
||||
MetaWindow *ancestor;
|
||||
@@ -1314,9 +1314,9 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
|
||||
meta_window_showing_on_its_workspace (ancestor))
|
||||
{
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Focusing %s, ancestor of %s\n",
|
||||
"Focusing %s, ancestor of %s\n",
|
||||
ancestor->desc, not_this_one->desc);
|
||||
|
||||
|
||||
meta_window_focus (ancestor, timestamp);
|
||||
|
||||
/* Also raise the window if in click-to-focus */
|
||||
@@ -1335,7 +1335,7 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
|
||||
{
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Focusing workspace MRU window %s\n", window->desc);
|
||||
|
||||
|
||||
meta_window_focus (window, timestamp);
|
||||
|
||||
/* Also raise the window if in click-to-focus */
|
||||
|
||||
@@ -62,6 +62,7 @@ item(_GTK_WINDOW_OBJECT_PATH)
|
||||
item(_GTK_APP_MENU_OBJECT_PATH)
|
||||
item(_GTK_MENUBAR_OBJECT_PATH)
|
||||
item(_GTK_FRAME_EXTENTS)
|
||||
item(_GTK_SHOW_WINDOW_MENU)
|
||||
item(_GNOME_WM_KEYBINDINGS)
|
||||
item(_GNOME_PANEL_ACTION)
|
||||
item(_GNOME_PANEL_ACTION_MAIN_MENU)
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
/* Simple box operations */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2005, 2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
* PLEASE KEEP IN SYNC WITH GSETTINGS SCHEMAS!
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -17,7 +17,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -49,6 +49,7 @@ typedef struct _MetaResizePopup MetaResizePopup;
|
||||
* MetaFrameFlags:
|
||||
* @META_FRAME_ALLOWS_DELETE: frame allows delete
|
||||
* @META_FRAME_ALLOWS_MENU: frame allows menu
|
||||
* @META_FRAME_ALLOWS_APPMENU: frame allows (fallback) app menu
|
||||
* @META_FRAME_ALLOWS_MINIMIZE: frame allows minimize
|
||||
* @META_FRAME_ALLOWS_MAXIMIZE: frame allows maximize
|
||||
* @META_FRAME_ALLOWS_VERTICAL_RESIZE: frame allows vertical resize
|
||||
@@ -69,78 +70,24 @@ typedef enum
|
||||
{
|
||||
META_FRAME_ALLOWS_DELETE = 1 << 0,
|
||||
META_FRAME_ALLOWS_MENU = 1 << 1,
|
||||
META_FRAME_ALLOWS_MINIMIZE = 1 << 2,
|
||||
META_FRAME_ALLOWS_MAXIMIZE = 1 << 3,
|
||||
META_FRAME_ALLOWS_VERTICAL_RESIZE = 1 << 4,
|
||||
META_FRAME_ALLOWS_HORIZONTAL_RESIZE = 1 << 5,
|
||||
META_FRAME_HAS_FOCUS = 1 << 6,
|
||||
META_FRAME_SHADED = 1 << 7,
|
||||
META_FRAME_STUCK = 1 << 8,
|
||||
META_FRAME_MAXIMIZED = 1 << 9,
|
||||
META_FRAME_ALLOWS_SHADE = 1 << 10,
|
||||
META_FRAME_ALLOWS_MOVE = 1 << 11,
|
||||
META_FRAME_FULLSCREEN = 1 << 12,
|
||||
META_FRAME_IS_FLASHING = 1 << 13,
|
||||
META_FRAME_ABOVE = 1 << 14,
|
||||
META_FRAME_TILED_LEFT = 1 << 15,
|
||||
META_FRAME_TILED_RIGHT = 1 << 16
|
||||
META_FRAME_ALLOWS_APPMENU = 1 << 2,
|
||||
META_FRAME_ALLOWS_MINIMIZE = 1 << 3,
|
||||
META_FRAME_ALLOWS_MAXIMIZE = 1 << 4,
|
||||
META_FRAME_ALLOWS_VERTICAL_RESIZE = 1 << 5,
|
||||
META_FRAME_ALLOWS_HORIZONTAL_RESIZE = 1 << 6,
|
||||
META_FRAME_HAS_FOCUS = 1 << 7,
|
||||
META_FRAME_SHADED = 1 << 8,
|
||||
META_FRAME_STUCK = 1 << 9,
|
||||
META_FRAME_MAXIMIZED = 1 << 10,
|
||||
META_FRAME_ALLOWS_SHADE = 1 << 11,
|
||||
META_FRAME_ALLOWS_MOVE = 1 << 12,
|
||||
META_FRAME_FULLSCREEN = 1 << 13,
|
||||
META_FRAME_IS_FLASHING = 1 << 14,
|
||||
META_FRAME_ABOVE = 1 << 15,
|
||||
META_FRAME_TILED_LEFT = 1 << 16,
|
||||
META_FRAME_TILED_RIGHT = 1 << 17
|
||||
} MetaFrameFlags;
|
||||
|
||||
/**
|
||||
* MetaMenuOp:
|
||||
* @META_MENU_OP_NONE: No menu operation
|
||||
* @META_MENU_OP_DELETE: Menu operation delete
|
||||
* @META_MENU_OP_MINIMIZE: Menu operation minimize
|
||||
* @META_MENU_OP_UNMAXIMIZE: Menu operation unmaximize
|
||||
* @META_MENU_OP_MAXIMIZE: Menu operation maximize
|
||||
* @META_MENU_OP_UNSHADE: Menu operation unshade
|
||||
* @META_MENU_OP_SHADE: Menu operation shade
|
||||
* @META_MENU_OP_UNSTICK: Menu operation unstick
|
||||
* @META_MENU_OP_STICK: Menu operation stick
|
||||
* @META_MENU_OP_WORKSPACES: Menu operation workspaces
|
||||
* @META_MENU_OP_MOVE: Menu operation move
|
||||
* @META_MENU_OP_RESIZE: Menu operation resize
|
||||
* @META_MENU_OP_ABOVE: Menu operation above
|
||||
* @META_MENU_OP_UNABOVE: Menu operation unabove
|
||||
* @META_MENU_OP_MOVE_LEFT: Menu operation left
|
||||
* @META_MENU_OP_MOVE_RIGHT: Menu operation right
|
||||
* @META_MENU_OP_MOVE_UP: Menu operation up
|
||||
* @META_MENU_OP_MOVE_DOWN: Menu operation down
|
||||
* @META_MENU_OP_RECOVER: Menu operation recover
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
META_MENU_OP_NONE = 0,
|
||||
META_MENU_OP_DELETE = 1 << 0,
|
||||
META_MENU_OP_MINIMIZE = 1 << 1,
|
||||
META_MENU_OP_UNMAXIMIZE = 1 << 2,
|
||||
META_MENU_OP_MAXIMIZE = 1 << 3,
|
||||
META_MENU_OP_UNSHADE = 1 << 4,
|
||||
META_MENU_OP_SHADE = 1 << 5,
|
||||
META_MENU_OP_UNSTICK = 1 << 6,
|
||||
META_MENU_OP_STICK = 1 << 7,
|
||||
META_MENU_OP_WORKSPACES = 1 << 8,
|
||||
META_MENU_OP_MOVE = 1 << 9,
|
||||
META_MENU_OP_RESIZE = 1 << 10,
|
||||
META_MENU_OP_ABOVE = 1 << 11,
|
||||
META_MENU_OP_UNABOVE = 1 << 12,
|
||||
META_MENU_OP_MOVE_LEFT = 1 << 13,
|
||||
META_MENU_OP_MOVE_RIGHT = 1 << 14,
|
||||
META_MENU_OP_MOVE_UP = 1 << 15,
|
||||
META_MENU_OP_MOVE_DOWN = 1 << 16,
|
||||
META_MENU_OP_RECOVER = 1 << 17
|
||||
} MetaMenuOp;
|
||||
|
||||
typedef struct _MetaWindowMenu MetaWindowMenu;
|
||||
|
||||
typedef void (* MetaWindowMenuFunc) (MetaWindowMenu *menu,
|
||||
Display *xdisplay,
|
||||
Window client_xwindow,
|
||||
guint32 timestamp,
|
||||
MetaMenuOp op,
|
||||
int workspace,
|
||||
gpointer user_data);
|
||||
|
||||
/**
|
||||
* MetaGrabOp:
|
||||
* @META_GRAB_OP_NONE: None
|
||||
@@ -226,6 +173,7 @@ typedef enum
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
META_CURSOR_NONE = 0,
|
||||
META_CURSOR_DEFAULT,
|
||||
META_CURSOR_NORTH_RESIZE,
|
||||
META_CURSOR_SOUTH_RESIZE,
|
||||
@@ -290,7 +238,7 @@ typedef enum
|
||||
*/
|
||||
META_VIRTUAL_SHIFT_MASK = 1 << 5,
|
||||
META_VIRTUAL_CONTROL_MASK = 1 << 6,
|
||||
META_VIRTUAL_ALT_MASK = 1 << 7,
|
||||
META_VIRTUAL_ALT_MASK = 1 << 7,
|
||||
META_VIRTUAL_META_MASK = 1 << 8,
|
||||
META_VIRTUAL_SUPER_MASK = 1 << 9,
|
||||
META_VIRTUAL_HYPER_MASK = 1 << 10,
|
||||
@@ -413,6 +361,7 @@ typedef enum
|
||||
META_BUTTON_FUNCTION_UNSHADE,
|
||||
META_BUTTON_FUNCTION_UNABOVE,
|
||||
META_BUTTON_FUNCTION_UNSTICK,
|
||||
META_BUTTON_FUNCTION_APPMENU,
|
||||
META_BUTTON_FUNCTION_LAST
|
||||
} MetaButtonFunction;
|
||||
|
||||
@@ -421,10 +370,10 @@ typedef enum
|
||||
/* Keep array size in sync with MAX_BUTTONS_PER_CORNER */
|
||||
/**
|
||||
* MetaButtonLayout:
|
||||
* @left_buttons: (array fixed-size=10):
|
||||
* @right_buttons: (array fixed-size=10):
|
||||
* @left_buttons_has_spacer: (array fixed-size=10):
|
||||
* @right_buttons_has_spacer: (array fixed-size=10):
|
||||
* @left_buttons: (array fixed-size=11):
|
||||
* @right_buttons: (array fixed-size=11):
|
||||
* @left_buttons_has_spacer: (array fixed-size=11):
|
||||
* @right_buttons_has_spacer: (array fixed-size=11):
|
||||
*/
|
||||
typedef struct _MetaButtonLayout MetaButtonLayout;
|
||||
struct _MetaButtonLayout
|
||||
@@ -438,6 +387,19 @@ struct _MetaButtonLayout
|
||||
gboolean right_buttons_has_spacer[MAX_BUTTONS_PER_CORNER];
|
||||
};
|
||||
|
||||
/**
|
||||
* MetaWindowMenuType:
|
||||
* @META_WINDOW_MENU_WM: the window manager menu
|
||||
* @META_WINDOW_MENU_APP: the (fallback) app menu
|
||||
*
|
||||
* Menu the compositor should display for a given window
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
META_WINDOW_MENU_WM,
|
||||
META_WINDOW_MENU_APP
|
||||
} MetaWindowMenuType;
|
||||
|
||||
/**
|
||||
* MetaFrameBorders:
|
||||
* @visible: inner visible portion of frame border
|
||||
|
||||
@@ -122,5 +122,10 @@ void meta_compositor_show_tile_preview (MetaCompositor *compositor,
|
||||
MetaRectangle *tile_rect,
|
||||
int tile_monitor_number);
|
||||
void meta_compositor_hide_tile_preview (MetaCompositor *compositor);
|
||||
void meta_compositor_show_window_menu (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
#endif /* META_COMPOSITOR_H */
|
||||
|
||||
@@ -75,6 +75,7 @@ Display *meta_display_get_xdisplay (MetaDisplay *display);
|
||||
MetaCompositor *meta_display_get_compositor (MetaDisplay *display);
|
||||
|
||||
gboolean meta_display_has_shape (MetaDisplay *display);
|
||||
gboolean meta_display_has_sync (MetaDisplay *display);
|
||||
|
||||
MetaWindow *meta_display_get_focus_window (MetaDisplay *display);
|
||||
|
||||
@@ -83,6 +84,7 @@ gboolean meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
|
||||
|
||||
int meta_display_get_damage_event_base (MetaDisplay *display);
|
||||
int meta_display_get_shape_event_base (MetaDisplay *display);
|
||||
int meta_display_get_sync_event_base (MetaDisplay *display);
|
||||
|
||||
gboolean meta_display_xserver_time_is_before (MetaDisplay *display,
|
||||
guint32 time1,
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
/* Mutter X error handling */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
/* Mutter gradient rendering */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington, 99% copied from wrlib in
|
||||
* WindowMaker, Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -15,7 +15,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
/* Mutter window groups */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2002 Red Hat Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -14,7 +14,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
/* Mutter main */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@@ -164,6 +164,12 @@ struct _MetaPluginClass
|
||||
int tile_monitor_number);
|
||||
void (*hide_tile_preview) (MetaPlugin *plugin);
|
||||
|
||||
void (*show_window_menu) (MetaPlugin *plugin,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
/**
|
||||
* MetaPluginClass::kill_window_effects:
|
||||
* @actor: a #MetaWindowActor
|
||||
|
||||
181
src/meta/prefs.h
181
src/meta/prefs.h
@@ -2,10 +2,10 @@
|
||||
|
||||
/* Mutter preferences */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -15,7 +15,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -141,6 +141,7 @@ gboolean meta_prefs_get_gnome_animations (void);
|
||||
gboolean meta_prefs_get_edge_tiling (void);
|
||||
gboolean meta_prefs_get_auto_maximize (void);
|
||||
gboolean meta_prefs_get_center_new_windows (void);
|
||||
gboolean meta_prefs_get_show_fallback_app_menu (void);
|
||||
|
||||
void meta_prefs_get_button_layout (MetaButtonLayout *button_layout);
|
||||
|
||||
@@ -171,95 +172,95 @@ void meta_prefs_set_ignore_request_hide_titlebar (gboolean whether);
|
||||
|
||||
/**
|
||||
* MetaKeyBindingAction:
|
||||
* @META_KEYBINDING_ACTION_NONE: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_1: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_2: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_3: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_4: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_5: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_6: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_7: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_8: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_9: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_10: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_11: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_12: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_LEFT: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_RIGHT: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_UP: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_DOWN: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_LAST: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_APPLICATIONS: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_GROUP: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_WINDOWS: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_PANELS: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD: FILLME
|
||||
* @META_KEYBINDING_ACTION_CYCLE_GROUP: FILLME
|
||||
* @META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD: FILLME
|
||||
* @META_KEYBINDING_ACTION_CYCLE_WINDOWS: FILLME
|
||||
* @META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD: FILLME
|
||||
* @META_KEYBINDING_ACTION_CYCLE_PANELS: FILLME
|
||||
* @META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD: FILLME
|
||||
* @META_KEYBINDING_ACTION_SHOW_DESKTOP: FILLME
|
||||
* @META_KEYBINDING_ACTION_PANEL_MAIN_MENU: FILLME
|
||||
* @META_KEYBINDING_ACTION_PANEL_RUN_DIALOG: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_RECORDING: FILLME
|
||||
* @META_KEYBINDING_ACTION_SET_SPEW_MARK: FILLME
|
||||
* @META_KEYBINDING_ACTION_ACTIVATE_WINDOW_MENU: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_FULLSCREEN: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_MAXIMIZED: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_TILED_LEFT: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_TILED_RIGHT: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_ABOVE: FILLME
|
||||
* @META_KEYBINDING_ACTION_MAXIMIZE: FILLME
|
||||
* @META_KEYBINDING_ACTION_UNMAXIMIZE: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_SHADED: FILLME
|
||||
* @META_KEYBINDING_ACTION_MINIMIZE: FILLME
|
||||
* @META_KEYBINDING_ACTION_CLOSE: FILLME
|
||||
* @META_KEYBINDING_ACTION_BEGIN_MOVE: FILLME
|
||||
* @META_KEYBINDING_ACTION_BEGIN_RESIZE: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_ON_ALL_WORKSPACES: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_1: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_2: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_3: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_4: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_5: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_6: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_7: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_8: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_9: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_10: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_11: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_12: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LEFT: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_RIGHT: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_UP: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_DOWN: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LAST: FILLME
|
||||
* @META_KEYBINDING_ACTION_NONE: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_1: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_2: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_3: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_4: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_5: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_6: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_7: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_8: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_9: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_10: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_11: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_12: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_LEFT: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_RIGHT: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_UP: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_DOWN: FILLME
|
||||
* @META_KEYBINDING_ACTION_WORKSPACE_LAST: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_APPLICATIONS: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_GROUP: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_WINDOWS: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_PANELS: FILLME
|
||||
* @META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD: FILLME
|
||||
* @META_KEYBINDING_ACTION_CYCLE_GROUP: FILLME
|
||||
* @META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD: FILLME
|
||||
* @META_KEYBINDING_ACTION_CYCLE_WINDOWS: FILLME
|
||||
* @META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD: FILLME
|
||||
* @META_KEYBINDING_ACTION_CYCLE_PANELS: FILLME
|
||||
* @META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD: FILLME
|
||||
* @META_KEYBINDING_ACTION_SHOW_DESKTOP: FILLME
|
||||
* @META_KEYBINDING_ACTION_PANEL_MAIN_MENU: FILLME
|
||||
* @META_KEYBINDING_ACTION_PANEL_RUN_DIALOG: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_RECORDING: FILLME
|
||||
* @META_KEYBINDING_ACTION_SET_SPEW_MARK: FILLME
|
||||
* @META_KEYBINDING_ACTION_ACTIVATE_WINDOW_MENU: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_FULLSCREEN: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_MAXIMIZED: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_TILED_LEFT: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_TILED_RIGHT: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_ABOVE: FILLME
|
||||
* @META_KEYBINDING_ACTION_MAXIMIZE: FILLME
|
||||
* @META_KEYBINDING_ACTION_UNMAXIMIZE: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_SHADED: FILLME
|
||||
* @META_KEYBINDING_ACTION_MINIMIZE: FILLME
|
||||
* @META_KEYBINDING_ACTION_CLOSE: FILLME
|
||||
* @META_KEYBINDING_ACTION_BEGIN_MOVE: FILLME
|
||||
* @META_KEYBINDING_ACTION_BEGIN_RESIZE: FILLME
|
||||
* @META_KEYBINDING_ACTION_TOGGLE_ON_ALL_WORKSPACES: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_1: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_2: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_3: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_4: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_5: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_6: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_7: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_8: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_9: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_10: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_11: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_12: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LEFT: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_RIGHT: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_UP: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_DOWN: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LAST: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_LEFT: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_RIGHT: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_UP: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_DOWN: FILLME
|
||||
* @META_KEYBINDING_ACTION_RAISE_OR_LOWER: FILLME
|
||||
* @META_KEYBINDING_ACTION_RAISE: FILLME
|
||||
* @META_KEYBINDING_ACTION_LOWER: FILLME
|
||||
* @META_KEYBINDING_ACTION_MAXIMIZE_VERTICALLY: FILLME
|
||||
* @META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_NW: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_NE: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_SW: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_SE: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_N: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_S: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_E: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_W: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_CENTER: FILLME
|
||||
* @META_KEYBINDING_ACTION_OVERLAY_KEY: FILLME
|
||||
* @META_KEYBINDING_ACTION_ALWAYS_ON_TOP: FILLME
|
||||
* @META_KEYBINDING_ACTION_LAST: FILLME
|
||||
* @META_KEYBINDING_ACTION_RAISE_OR_LOWER: FILLME
|
||||
* @META_KEYBINDING_ACTION_RAISE: FILLME
|
||||
* @META_KEYBINDING_ACTION_LOWER: FILLME
|
||||
* @META_KEYBINDING_ACTION_MAXIMIZE_VERTICALLY: FILLME
|
||||
* @META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_NW: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_NE: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_SW: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_CORNER_SE: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_N: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_S: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_E: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_SIDE_W: FILLME
|
||||
* @META_KEYBINDING_ACTION_MOVE_TO_CENTER: FILLME
|
||||
* @META_KEYBINDING_ACTION_OVERLAY_KEY: FILLME
|
||||
* @META_KEYBINDING_ACTION_ALWAYS_ON_TOP: FILLME
|
||||
* @META_KEYBINDING_ACTION_LAST: FILLME
|
||||
*/
|
||||
/* XXX FIXME This should be x-macroed, but isn't yet because it would be
|
||||
* difficult (or perhaps impossible) to add the suffixes using the current
|
||||
@@ -399,10 +400,6 @@ GType meta_key_binding_get_type (void);
|
||||
|
||||
MetaKeyBindingAction meta_prefs_get_keybinding_action (const char *name);
|
||||
|
||||
void meta_prefs_get_window_binding (const char *name,
|
||||
unsigned int *keysym,
|
||||
MetaVirtualModifier *modifiers);
|
||||
|
||||
gboolean meta_prefs_get_visual_bell (void);
|
||||
gboolean meta_prefs_bell_is_audible (void);
|
||||
GDesktopVisualBellType meta_prefs_get_visual_bell_type (void);
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
/* Metacity Theme Rendering */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -14,7 +14,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
/* Mutter utilities */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -15,7 +15,7 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user