Compare commits
91 Commits
3.13.2
...
wip/gestur
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3ed80495e0 | ||
![]() |
f13c86d651 | ||
![]() |
be2ca66735 | ||
![]() |
2df807549e | ||
![]() |
66cdb1bb71 | ||
![]() |
8030a2972e | ||
![]() |
ba086dea8c | ||
![]() |
6a02d7dfa3 | ||
![]() |
c5db56da5c | ||
![]() |
b5c605df5e | ||
![]() |
4ad2865cce | ||
![]() |
b9687d1a72 | ||
![]() |
66d18fcc55 | ||
![]() |
321cd5d85f | ||
![]() |
ae91de5d03 | ||
![]() |
7247b8d81b | ||
![]() |
97f2de37e1 | ||
![]() |
967b6c33df | ||
![]() |
00c7a27732 | ||
![]() |
048ba353c4 | ||
![]() |
555e2f6de2 | ||
![]() |
ff8d5281f0 | ||
![]() |
4f9b994e73 | ||
![]() |
b8b0dc5c78 | ||
![]() |
d0cafab836 | ||
![]() |
24d7c5ebe3 | ||
![]() |
dc6decefb5 | ||
![]() |
25d7e48077 | ||
![]() |
b0b8f37240 | ||
![]() |
188e4e1b92 | ||
![]() |
9d5273bb15 | ||
![]() |
3c0fae74f1 | ||
![]() |
86dae6d4c7 | ||
![]() |
d06600aeb0 | ||
![]() |
895a3d1f39 | ||
![]() |
381ef5c683 | ||
![]() |
62097897be | ||
![]() |
2d2c47ba49 | ||
![]() |
89cdfc9194 | ||
![]() |
ad60ea9e0e | ||
![]() |
a7350475e8 | ||
![]() |
f3d7c9cff9 | ||
![]() |
906cbeed61 | ||
![]() |
0fccb0fc86 | ||
![]() |
8100cefd4c | ||
![]() |
d7e99a3f86 | ||
![]() |
6af944fe2c | ||
![]() |
12fc394b92 | ||
![]() |
53814fefc1 | ||
![]() |
e87a01c80b | ||
![]() |
21d7c1a850 | ||
![]() |
e33c58297d | ||
![]() |
5350120db4 | ||
![]() |
0997cf7fee | ||
![]() |
af3aae7295 | ||
![]() |
98e219da4b | ||
![]() |
fba022cc06 | ||
![]() |
3f6c6f1dd9 | ||
![]() |
ebc2e7221b | ||
![]() |
7cb30ced23 | ||
![]() |
7b449ac56c | ||
![]() |
724953101d | ||
![]() |
8734477d52 | ||
![]() |
ec8ba4b5f9 | ||
![]() |
2250865eb6 | ||
![]() |
847a3bbee3 | ||
![]() |
410a002ddd | ||
![]() |
8766db2593 | ||
![]() |
e362227514 | ||
![]() |
da311f266d | ||
![]() |
f5a4e996a8 | ||
![]() |
a7f083897f | ||
![]() |
e2105dc721 | ||
![]() |
b64548ee1f | ||
![]() |
53425fa721 | ||
![]() |
048f035d30 | ||
![]() |
b32c837df9 | ||
![]() |
dd03a76d51 | ||
![]() |
806a666950 | ||
![]() |
b240a5e819 | ||
![]() |
fe823b3553 | ||
![]() |
d380d30ef4 | ||
![]() |
1fe5b3e7d5 | ||
![]() |
a8df208a5c | ||
![]() |
f3f3c94831 | ||
![]() |
6e06648f7a | ||
![]() |
afb41f715b | ||
![]() |
19d26dde92 | ||
![]() |
4acb902423 | ||
![]() |
626516d12e | ||
![]() |
1c94df2553 |
35
.cvsignore
35
.cvsignore
@@ -1,35 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
confdefs.h
|
||||
config.cache
|
||||
config.guess
|
||||
config.h
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
configure.scan
|
||||
libtool
|
||||
ltconfig
|
||||
ltmain.sh
|
||||
stamp-h
|
||||
stamp-h.in
|
||||
stamp-h1
|
||||
stamp.h
|
||||
version.h
|
||||
config.h.in
|
||||
install-sh
|
||||
missing
|
||||
mkinstalldirs
|
||||
INSTALL
|
||||
intl
|
||||
ABOUT-NLS
|
||||
COPYING
|
||||
intltool-*
|
||||
metacity.spec
|
||||
autom4te.cache
|
||||
compile
|
||||
depcomp
|
||||
omf.make
|
||||
xmldocs.make
|
21
.gitignore
vendored
21
.gitignore
vendored
@@ -3,6 +3,7 @@ Makefile.in
|
||||
Makefile.in.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
build-aux
|
||||
compile
|
||||
config.guess
|
||||
config.h
|
||||
@@ -19,11 +20,11 @@ libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
.deps
|
||||
src/50-mutter-navigation.xml
|
||||
src/50-mutter-system.xml
|
||||
src/50-mutter-windows.xml
|
||||
src/mutter.desktop
|
||||
src/mutter-wayland.desktop
|
||||
50-mutter-navigation.xml
|
||||
50-mutter-system.xml
|
||||
50-mutter-windows.xml
|
||||
mutter.desktop
|
||||
mutter-wayland.desktop
|
||||
*.o
|
||||
*.a
|
||||
*.lo
|
||||
@@ -32,10 +33,6 @@ src/mutter-wayland.desktop
|
||||
*.swp
|
||||
*.gir
|
||||
*.typelib
|
||||
tidy-enum-types.[ch]
|
||||
tidy-marshal.[ch]
|
||||
stamp-tidy-enum-types.h
|
||||
stamp-tidy-marshal.h
|
||||
stamp-h1
|
||||
*.gmo
|
||||
*.make
|
||||
@@ -44,8 +41,6 @@ stamp-it
|
||||
.intltool-merge-cache
|
||||
POTFILES
|
||||
po/*.pot
|
||||
50-metacity-desktop-key.xml
|
||||
50-metacity-key.xml
|
||||
libmutter.pc
|
||||
mutter
|
||||
org.gnome.mutter.gschema.valid
|
||||
@@ -66,9 +61,6 @@ test-focus
|
||||
test-gravity
|
||||
test-resizing
|
||||
test-size-hints
|
||||
# We can't say just "wm-tester" here or it will ignore the directory
|
||||
# rather than the binary
|
||||
src/wm-tester/wm-tester
|
||||
INSTALL
|
||||
mkinstalldirs
|
||||
src/mutter-enum-types.[ch]
|
||||
@@ -84,6 +76,7 @@ src/xdg-shell-protocol.c
|
||||
src/xdg-shell-server-protocol.h
|
||||
src/xserver-protocol.c
|
||||
src/xserver-server-protocol.h
|
||||
src/meta/meta-version.h
|
||||
doc/reference/*.args
|
||||
doc/reference/*.bak
|
||||
doc/reference/*.hierarchy
|
||||
|
11
Makefile.am
11
Makefile.am
@@ -1,10 +1,13 @@
|
||||
|
||||
SUBDIRS=src po doc
|
||||
SUBDIRS = data src po doc
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||
|
||||
DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache
|
||||
DISTCLEANFILES = \
|
||||
intltool-extract \
|
||||
intltool-merge \
|
||||
intltool-update \
|
||||
po/stamp-it \
|
||||
po/.intltool-merge-cache
|
||||
|
||||
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||
|
13
NEWS
13
NEWS
@@ -1,3 +1,16 @@
|
||||
3.13.3
|
||||
======
|
||||
* Improve behavior of window buttons with compositor menus [Florian; #731058]
|
||||
* Implement touch support on wayland [Carlos; #724442]
|
||||
* Update window shadows [Nikita; #731866]
|
||||
* Keep windows on the preferred output [Florian; #731760]
|
||||
* Misc bug fixes [Jonas, Florian, Jasper; #729601, #730681, #731353, #731332,
|
||||
#730527, #662962]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Nikita Churaev, Carlos Garnacho, Florian Müllner,
|
||||
Jasper St. Pierre, Rico Tzschichholz
|
||||
|
||||
3.13.2
|
||||
======
|
||||
* Add basic HiDPI support on wayland [Adel; #728902]
|
||||
|
@@ -5,7 +5,7 @@ srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
PKG_NAME="mutter"
|
||||
REQUIRED_AUTOMAKE_VERSION=1.10
|
||||
REQUIRED_AUTOMAKE_VERSION=1.11
|
||||
|
||||
(test -f $srcdir/configure.ac \
|
||||
&& test -d $srcdir/src) || {
|
||||
|
57
configure.ac
57
configure.ac
@@ -1,9 +1,8 @@
|
||||
AC_PREREQ(2.50)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_PREREQ(2.62)
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [13])
|
||||
m4_define([mutter_micro_version], [2])
|
||||
m4_define([mutter_micro_version], [3])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
@@ -14,6 +13,7 @@ AC_INIT([mutter], [mutter_version],
|
||||
[http://bugzilla.gnome.org/enter_bug.cgi?product=mutter])
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_SRCDIR(src/core/display.c)
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
|
||||
@@ -40,12 +40,14 @@ GETTEXT_PACKAGE=mutter
|
||||
AC_SUBST(GETTEXT_PACKAGE)
|
||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[Name of default gettext domain])
|
||||
|
||||
IT_PROG_INTLTOOL([0.34.90])
|
||||
LT_PREREQ([2.2.6])
|
||||
LT_INIT([disable-static])
|
||||
IT_PROG_INTLTOOL([0.41])
|
||||
AC_PROG_CC
|
||||
AC_ISC_POSIX
|
||||
AC_PROG_CC_C_O
|
||||
AC_PROG_INSTALL
|
||||
AC_HEADER_STDC
|
||||
AC_LIBTOOL_WIN32_DLL
|
||||
AM_PROG_LIBTOOL
|
||||
PKG_PROG_PKG_CONFIG([0.21])
|
||||
|
||||
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
|
||||
AM_PATH_GLIB_2_0()
|
||||
@@ -75,8 +77,13 @@ MUTTER_PC_MODULES="
|
||||
cairo >= 1.10.0
|
||||
gsettings-desktop-schemas >= 3.7.3
|
||||
xcomposite >= 0.2 xfixes xext xdamage xi >= 1.6.0
|
||||
xcursor
|
||||
$CLUTTER_PACKAGE >= 1.17.5
|
||||
clutter-wayland-1.0
|
||||
clutter-wayland-compositor-1.0
|
||||
clutter-egl-1.0
|
||||
cogl-1.0 >= 1.17.1
|
||||
wayland-server >= 1.4.93
|
||||
upower-glib >= 0.99.0
|
||||
gnome-desktop-3.0
|
||||
"
|
||||
@@ -107,26 +114,12 @@ AC_ARG_WITH(libcanberra,
|
||||
[disable the use of libcanberra for playing sounds]),,
|
||||
with_libcanberra=auto)
|
||||
|
||||
AC_ARG_ENABLE(xsync,
|
||||
AC_HELP_STRING([--disable-xsync],
|
||||
[disable mutter's use of the XSync extension]),,
|
||||
enable_xsync=auto)
|
||||
|
||||
AC_ARG_ENABLE(shape,
|
||||
AC_HELP_STRING([--disable-shape],
|
||||
[disable mutter's use of the shaped window extension]),,
|
||||
enable_shape=auto)
|
||||
|
||||
AC_ARG_WITH([xwayland-path],
|
||||
[AS_HELP_STRING([--with-xwayland-path], [Absolute path for an X Wayland server])],
|
||||
[XWAYLAND_PATH="$withval"],
|
||||
[XWAYLAND_PATH="$bindir/Xwayland"])
|
||||
|
||||
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)
|
||||
|
||||
# Unconditionally use this dir to avoid a circular dep with gnomecc
|
||||
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
|
||||
@@ -191,17 +184,20 @@ if test x$found_introspection != xno; then
|
||||
AC_SUBST(META_GIR)
|
||||
fi
|
||||
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES xcursor"
|
||||
|
||||
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
|
||||
AS_IF([test "x$WAYLAND_SCANNER" = "xno"],
|
||||
AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols]))
|
||||
AC_SUBST([WAYLAND_SCANNER])
|
||||
AC_SUBST(XWAYLAND_PATH)
|
||||
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES clutter-wayland-1.0 clutter-wayland-compositor-1.0 clutter-egl-1.0 wayland-server >= 1.4.93 libdrm libsystemd"
|
||||
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]))
|
||||
|
||||
@@ -293,17 +289,6 @@ fi
|
||||
|
||||
AM_CONDITIONAL(HAVE_SM, test "$found_sm" = "yes")
|
||||
|
||||
HOST_ALIAS=$host_alias
|
||||
AC_SUBST(HOST_ALIAS)
|
||||
|
||||
AC_PATH_PROG(GDK_PIXBUF_CSOURCE, gdk-pixbuf-csource, no)
|
||||
|
||||
if test x"$GDK_PIXBUF_CSOURCE" = xno; then
|
||||
AC_MSG_ERROR([gdk-pixbuf-csource executable not found in your path - should be installed with GTK])
|
||||
fi
|
||||
|
||||
AC_SUBST(GDK_PIXBUF_CSOURCE)
|
||||
|
||||
AC_PATH_PROG(ZENITY, zenity, no)
|
||||
if test x"$ZENITY" = xno; then
|
||||
AC_MSG_ERROR([zenity not found in your path - needed for dialogs])
|
||||
@@ -386,6 +371,7 @@ changequote([,])dnl
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
data/Makefile
|
||||
doc/Makefile
|
||||
doc/man/Makefile
|
||||
doc/reference/Makefile
|
||||
@@ -393,6 +379,7 @@ doc/reference/meta-docs.sgml
|
||||
src/Makefile
|
||||
src/libmutter.pc
|
||||
src/compositor/plugins/Makefile
|
||||
src/meta/meta-version.h
|
||||
po/Makefile.in
|
||||
])
|
||||
|
||||
|
@@ -1,3 +1,36 @@
|
||||
defaultcursordir = $(datadir)/mutter/cursors
|
||||
desktopfiles_in_files = \
|
||||
mutter.desktop.in \
|
||||
mutter-wayland.desktop.in
|
||||
desktopfilesdir = $(datadir)/applications
|
||||
desktopfiles_DATA = $(desktopfiles_in_files:.desktop.in=.desktop)
|
||||
|
||||
dist_defaultcursor_DATA = left_ptr.png
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
||||
xml_in_files = \
|
||||
50-mutter-navigation.xml.in \
|
||||
50-mutter-system.xml.in \
|
||||
50-mutter-windows.xml.in
|
||||
xmldir = $(GNOME_KEYBINDINGS_KEYSDIR)
|
||||
xml_DATA = $(xml_in_files:.xml.in=.xml)
|
||||
|
||||
gschema_in_files = \
|
||||
org.gnome.mutter.gschema.xml.in \
|
||||
org.gnome.mutter.wayland.gschema.xml.in
|
||||
gsettings_SCHEMAS = $(gschema_in_files:.xml.in=.xml)
|
||||
|
||||
@INTLTOOL_XML_NOMERGE_RULE@
|
||||
@GSETTINGS_RULES@
|
||||
|
||||
convertdir = $(datadir)/GConf/gsettings
|
||||
convert_DATA = mutter-schemas.convert
|
||||
|
||||
CLEANFILES = \
|
||||
$(desktopfiles_DATA) \
|
||||
$(gsettings_SCHEMAS) \
|
||||
$(xml_DATA)
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(convert_DATA) \
|
||||
$(desktopfiles_in_files) \
|
||||
$(gschema_in_files) \
|
||||
$(xml_in_files)
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -555,7 +555,7 @@ meta_window_is_monitor_sized
|
||||
meta_window_is_override_redirect
|
||||
meta_window_is_skip_taskbar
|
||||
meta_window_get_rect
|
||||
meta_window_get_input_rect
|
||||
meta_window_get_buffer_rect
|
||||
meta_window_get_frame_rect
|
||||
meta_window_get_outer_rect
|
||||
meta_window_client_rect_to_frame_rect
|
||||
|
@@ -1,8 +1,11 @@
|
||||
# List of source files containing translatable strings.
|
||||
# Please keep this file sorted alphabetically.
|
||||
src/50-mutter-navigation.xml.in
|
||||
src/50-mutter-system.xml.in
|
||||
src/50-mutter-windows.xml.in
|
||||
data/50-mutter-navigation.xml.in
|
||||
data/50-mutter-system.xml.in
|
||||
data/50-mutter-windows.xml.in
|
||||
data/mutter.desktop.in
|
||||
data/org.gnome.mutter.gschema.xml.in
|
||||
data/org.gnome.mutter.wayland.gschema.xml.in
|
||||
src/backends/meta-monitor-manager.c
|
||||
src/compositor/compositor.c
|
||||
src/compositor/meta-background.c
|
||||
@@ -18,9 +21,6 @@ src/core/prefs.c
|
||||
src/core/screen.c
|
||||
src/core/util.c
|
||||
src/core/window.c
|
||||
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/resizepopup.c
|
||||
src/ui/theme.c
|
||||
|
@@ -1,2 +1 @@
|
||||
src/metacity.schemas.in
|
||||
src/mutter-wayland.desktop.in
|
||||
data/mutter-wayland.desktop.in
|
||||
|
106
src/Makefile.am
106
src/Makefile.am
@@ -5,37 +5,35 @@ lib_LTLIBRARIES = libmutter.la
|
||||
|
||||
SUBDIRS=compositor/plugins
|
||||
|
||||
INCLUDES= \
|
||||
AM_CPPFLAGS = \
|
||||
-DCLUTTER_ENABLE_COMPOSITOR_API \
|
||||
-DCLUTTER_ENABLE_EXPERIMENTAL_API \
|
||||
-DCOGL_ENABLE_EXPERIMENTAL_API \
|
||||
-DCOGL_ENABLE_EXPERIMENTAL_2_0_API \
|
||||
$(MUTTER_CFLAGS) \
|
||||
$(MUTTER_NATIVE_BACKEND_CFLAGS) \
|
||||
-I$(builddir) \
|
||||
-I$(srcdir) \
|
||||
-I$(srcdir)/backends \
|
||||
-I$(srcdir)/core \
|
||||
-I$(srcdir)/ui \
|
||||
-I$(srcdir)/compositor \
|
||||
-DMUTTER_LIBEXECDIR=\"$(libexecdir)\" \
|
||||
-DHOST_ALIAS=\"@HOST_ALIAS@\" \
|
||||
-DMUTTER_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" \
|
||||
-DMUTTER_LOCALEDIR=\"$(localedir)\" \
|
||||
-DMUTTER_PKGDATADIR=\"$(pkgdatadir)\" \
|
||||
-DMUTTER_DATADIR=\"$(datadir)\" \
|
||||
-DG_LOG_DOMAIN=\"mutter\" \
|
||||
-DSN_API_NOT_YET_FROZEN=1 \
|
||||
-DMUTTER_MAJOR_VERSION=$(MUTTER_MAJOR_VERSION) \
|
||||
-DMUTTER_MINOR_VERSION=$(MUTTER_MINOR_VERSION) \
|
||||
-DMUTTER_MICRO_VERSION=$(MUTTER_MICRO_VERSION) \
|
||||
-DMUTTER_PLUGIN_API_VERSION=$(MUTTER_PLUGIN_API_VERSION) \
|
||||
-DMUTTER_PKGLIBDIR=\"$(pkglibdir)\" \
|
||||
-DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\" \
|
||||
-DMUTTER_PLUGIN_DIR=\"$(MUTTER_PLUGIN_DIR)\" \
|
||||
-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \
|
||||
-DXWAYLAND_PATH='"@XWAYLAND_PATH@"'
|
||||
-DXWAYLAND_PATH=\"$(XWAYLAND_PATH)\"
|
||||
|
||||
mutter_built_sources = \
|
||||
$(dbus_idle_built_sources) \
|
||||
$(dbus_display_config_built_sources) \
|
||||
$(dbus_login1_built_sources) \
|
||||
meta/meta-version.h \
|
||||
mutter-enum-types.h \
|
||||
mutter-enum-types.c \
|
||||
gtk-shell-protocol.c \
|
||||
@@ -71,18 +69,6 @@ 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/native/dbus-utils.c \
|
||||
backends/native/dbus-utils.h \
|
||||
backends/x11/meta-backend-x11.c \
|
||||
backends/x11/meta-backend-x11.h \
|
||||
backends/x11/meta-cursor-renderer-x11.c \
|
||||
@@ -166,6 +152,8 @@ libmutter_la_SOURCES = \
|
||||
core/frame.h \
|
||||
ui/gradient.c \
|
||||
meta/gradient.h \
|
||||
core/gesture-tracker.c \
|
||||
core/gesture-tracker-private.h \
|
||||
core/keybindings.c \
|
||||
core/keybindings-private.h \
|
||||
core/main.c \
|
||||
@@ -205,6 +193,8 @@ libmutter_la_SOURCES = \
|
||||
x11/iconcache.h \
|
||||
x11/async-getprop.c \
|
||||
x11/async-getprop.h \
|
||||
x11/events.c \
|
||||
x11/events.h \
|
||||
x11/group-private.h \
|
||||
x11/group-props.c \
|
||||
x11/group-props.h \
|
||||
@@ -234,6 +224,8 @@ libmutter_la_SOURCES = \
|
||||
wayland/meta-wayland-pointer.h \
|
||||
wayland/meta-wayland-seat.c \
|
||||
wayland/meta-wayland-seat.h \
|
||||
wayland/meta-wayland-touch.c \
|
||||
wayland/meta-wayland-touch.h \
|
||||
wayland/meta-wayland-surface.c \
|
||||
wayland/meta-wayland-surface.h \
|
||||
wayland/meta-wayland-types.h \
|
||||
@@ -243,15 +235,31 @@ 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
|
||||
libmutterinclude_base_headers = \
|
||||
libmutterinclude_headers = \
|
||||
meta/barrier.h \
|
||||
meta/boxes.h \
|
||||
meta/common.h \
|
||||
@@ -280,6 +288,13 @@ libmutterinclude_base_headers = \
|
||||
meta/window.h \
|
||||
meta/workspace.h
|
||||
|
||||
libmutterinclude_built_headers = \
|
||||
meta/meta-version.h
|
||||
|
||||
libmutterinclude_base_headers = \
|
||||
$(libmutterinclude_headers) \
|
||||
$(libmutterinclude_built_headers)
|
||||
|
||||
# Excluded from scanning for introspection but installed
|
||||
# atomnames.h: macros cause problems for scanning process
|
||||
libmutterinclude_extra_headers = \
|
||||
@@ -288,9 +303,12 @@ libmutterinclude_extra_headers = \
|
||||
libmutterincludedir = $(includedir)/mutter/meta
|
||||
|
||||
libmutterinclude_HEADERS = \
|
||||
$(libmutterinclude_base_headers) \
|
||||
$(libmutterinclude_headers) \
|
||||
$(libmutterinclude_extra_headers)
|
||||
|
||||
nodist_libmutterinclude_HEADERS = \
|
||||
$(libmutterinclude_built_headers)
|
||||
|
||||
bin_PROGRAMS=mutter
|
||||
|
||||
mutter_SOURCES = core/mutter.c
|
||||
@@ -319,7 +337,7 @@ INTROSPECTION_GIRS = Meta-$(api_version).gir
|
||||
Meta-$(api_version).gir: libmutter.la
|
||||
@META_GIR@_INCLUDES = GObject-2.0 GDesktopEnums-3.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0 Cogl-1.0
|
||||
@META_GIR@_EXPORT_PACKAGES = libmutter
|
||||
@META_GIR@_CFLAGS = $(INCLUDES)
|
||||
@META_GIR@_CFLAGS = $(AM_CPPFLAGS)
|
||||
@META_GIR@_LIBS = libmutter.la
|
||||
@META_GIR@_FILES = \
|
||||
mutter-enum-types.h \
|
||||
@@ -339,53 +357,19 @@ testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
testgradient_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
||||
desktopfilesdir=$(datadir)/applications
|
||||
desktopfiles_in_files=mutter.desktop.in
|
||||
desktopfiles_files=$(desktopfiles_in_files:.desktop.in=.desktop)
|
||||
desktopfiles_DATA = $(desktopfiles_files)
|
||||
|
||||
xmldir = @GNOME_KEYBINDINGS_KEYSDIR@
|
||||
xml_in_files = \
|
||||
50-mutter-navigation.xml.in \
|
||||
50-mutter-system.xml.in \
|
||||
50-mutter-windows.xml.in
|
||||
xml_DATA = $(xml_in_files:.xml.in=.xml)
|
||||
|
||||
dbus_idle_built_sources = meta-dbus-idle-monitor.c meta-dbus-idle-monitor.h
|
||||
|
||||
gsettings_SCHEMAS = org.gnome.mutter.gschema.xml org.gnome.mutter.wayland.gschema.xml
|
||||
@INTLTOOL_XML_NOMERGE_RULE@
|
||||
@GSETTINGS_RULES@
|
||||
|
||||
convertdir = $(datadir)/GConf/gsettings
|
||||
convert_DATA = mutter-schemas.convert
|
||||
|
||||
CLEANFILES = \
|
||||
mutter.desktop \
|
||||
mutter-wm.desktop \
|
||||
org.gnome.mutter.gschema.xml \
|
||||
org.gnome.mutter.wayland.gschema.xml \
|
||||
$(xml_DATA) \
|
||||
$(mutter_built_sources) \
|
||||
$(libmutterinclude_built_headers) \
|
||||
$(typelib_DATA) \
|
||||
$(gir_DATA)
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
|
||||
pkgconfig_DATA = libmutter.pc
|
||||
|
||||
EXTRA_DIST=$(desktopfiles_files) \
|
||||
$(wmproperties_files) \
|
||||
$(IMAGES) \
|
||||
$(desktopfiles_in_files) \
|
||||
$(wmproperties_in_files) \
|
||||
$(xml_in_files) \
|
||||
EXTRA_DIST = \
|
||||
$(wayland_protocols) \
|
||||
org.gnome.mutter.gschema.xml.in \
|
||||
org.gnome.mutter.wayland.gschema.xml.in \
|
||||
mutter-schemas.convert \
|
||||
libmutter.pc.in \
|
||||
mutter-enum-types.h.in \
|
||||
mutter-enum-types.c.in \
|
||||
|
@@ -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;
|
||||
|
||||
@@ -100,14 +103,6 @@ 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)
|
||||
{
|
||||
@@ -119,7 +114,6 @@ 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
|
||||
@@ -214,7 +208,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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -174,6 +174,20 @@ meta_backend_native_create_cursor_renderer (MetaBackend *backend)
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER_NATIVE, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_native_warp_pointer (MetaBackend *backend,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
ClutterInputDevice *device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
|
||||
|
||||
/* XXX */
|
||||
guint32 time_ = 0;
|
||||
|
||||
clutter_evdev_warp_pointer (device, time_, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_native_class_init (MetaBackendNativeClass *klass)
|
||||
{
|
||||
@@ -183,6 +197,8 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
|
||||
backend_class->create_idle_monitor = meta_backend_native_create_idle_monitor;
|
||||
backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager;
|
||||
backend_class->create_cursor_renderer = meta_backend_native_create_cursor_renderer;
|
||||
|
||||
backend_class->warp_pointer = meta_backend_native_warp_pointer;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -51,6 +51,7 @@ struct _MetaBackendX11Private
|
||||
int xinput_opcode;
|
||||
int xinput_event_base;
|
||||
int xinput_error_base;
|
||||
Time latest_evtime;
|
||||
};
|
||||
typedef struct _MetaBackendX11Private MetaBackendX11Private;
|
||||
|
||||
@@ -71,6 +72,7 @@ static void
|
||||
translate_device_event (MetaBackendX11 *x11,
|
||||
XIDeviceEvent *device_event)
|
||||
{
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
Window stage_window = meta_backend_x11_get_xwindow (x11);
|
||||
|
||||
if (device_event->event != stage_window)
|
||||
@@ -88,6 +90,21 @@ translate_device_event (MetaBackendX11 *x11,
|
||||
device_event->event_x = device_event->root_x;
|
||||
device_event->event_y = device_event->root_y;
|
||||
}
|
||||
|
||||
if (!device_event->send_event && device_event->time != CurrentTime)
|
||||
{
|
||||
if (device_event->time < priv->latest_evtime)
|
||||
{
|
||||
/* Emulated pointer events received after XIRejectTouch is received
|
||||
* on a passive touch grab will contain older timestamps, update those
|
||||
* so we dont get InvalidTime at grabs.
|
||||
*/
|
||||
device_event->time = priv->latest_evtime;
|
||||
}
|
||||
|
||||
/* Update the internal latest evtime, for any possible later use */
|
||||
priv->latest_evtime = device_event->time;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clutter makes the assumption that there is only one X window
|
||||
@@ -117,6 +134,9 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
|
||||
case XI_ButtonRelease:
|
||||
case XI_KeyPress:
|
||||
case XI_KeyRelease:
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchUpdate:
|
||||
case XI_TouchEnd:
|
||||
translate_device_event (x11, (XIDeviceEvent *) input_event);
|
||||
break;
|
||||
default:
|
||||
@@ -142,17 +162,14 @@ handle_host_xevent (MetaBackend *backend,
|
||||
MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend);
|
||||
if (META_IS_MONITOR_MANAGER_XRANDR (manager) &&
|
||||
meta_monitor_manager_xrandr_handle_xevent (META_MONITOR_MANAGER_XRANDR (manager), event))
|
||||
{
|
||||
bypass_clutter = TRUE;
|
||||
goto out;
|
||||
}
|
||||
bypass_clutter = TRUE;
|
||||
}
|
||||
|
||||
maybe_spoof_event_as_stage_event (x11, event);
|
||||
|
||||
out:
|
||||
if (!bypass_clutter)
|
||||
clutter_x11_handle_event (event);
|
||||
{
|
||||
maybe_spoof_event_as_stage_event (x11, event);
|
||||
clutter_x11_handle_event (event);
|
||||
}
|
||||
|
||||
XFreeEventData (priv->xdisplay, &event->xcookie);
|
||||
}
|
||||
@@ -313,6 +330,9 @@ meta_backend_x11_grab_device (MetaBackend *backend,
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
int ret;
|
||||
|
||||
if (timestamp != CurrentTime)
|
||||
timestamp = MAX (timestamp, priv->latest_evtime);
|
||||
|
||||
XISetMask (mask.mask, XI_ButtonPress);
|
||||
XISetMask (mask.mask, XI_ButtonRelease);
|
||||
XISetMask (mask.mask, XI_Enter);
|
||||
|
@@ -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
|
||||
|
@@ -385,6 +385,10 @@ meta_begin_modal_for_plugin (MetaCompositor *compositor,
|
||||
display->grab_have_pointer = TRUE;
|
||||
display->grab_have_keyboard = TRUE;
|
||||
|
||||
g_signal_emit_by_name (display, "grab-op-begin",
|
||||
meta_plugin_get_screen (plugin),
|
||||
display->grab_window, display->grab_op);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
|
||||
@@ -401,6 +405,10 @@ meta_end_modal_for_plugin (MetaCompositor *compositor,
|
||||
|
||||
g_return_if_fail (is_modal (display));
|
||||
|
||||
g_signal_emit_by_name (display, "grab-op-end",
|
||||
meta_plugin_get_screen (plugin),
|
||||
display->grab_window, display->grab_op);
|
||||
|
||||
display->grab_op = META_GRAB_OP_NONE;
|
||||
display->grab_window = NULL;
|
||||
display->grab_have_pointer = FALSE;
|
||||
@@ -595,7 +603,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.
|
||||
@@ -691,12 +699,11 @@ meta_compositor_remove_window (MetaCompositor *compositor,
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_set_updates_frozen (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
gboolean updates_frozen)
|
||||
meta_compositor_sync_updates_frozen (MetaCompositor *compositor,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
meta_window_actor_set_updates_frozen (window_actor, updates_frozen);
|
||||
meta_window_actor_sync_updates_frozen (window_actor);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1366,3 +1373,12 @@ meta_compositor_show_window_menu (MetaCompositor *compositor,
|
||||
{
|
||||
meta_plugin_manager_show_window_menu (compositor->plugin_mgr, window, menu, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_show_window_menu_for_rect (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
meta_plugin_manager_show_window_menu_for_rect (compositor->plugin_mgr, window, menu, rect);
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include <meta/meta-plugin.h>
|
||||
#include <meta/meta-version.h>
|
||||
#include "meta-module.h"
|
||||
|
||||
#include <gmodule.h>
|
||||
@@ -68,7 +69,7 @@ meta_module_load (GTypeModule *gmodule)
|
||||
(gpointer *)(void *)®ister_type) &&
|
||||
info && register_type)
|
||||
{
|
||||
if (info->version_api != MUTTER_PLUGIN_API_VERSION)
|
||||
if (info->version_api != META_PLUGIN_API_VERSION)
|
||||
g_warning ("Plugin API mismatch for [%s]", priv->path);
|
||||
else
|
||||
{
|
||||
|
@@ -374,3 +374,20 @@ meta_plugin_manager_show_window_menu (MetaPluginManager *plugin_mgr,
|
||||
if (klass->show_window_menu)
|
||||
klass->show_window_menu (plugin, window, menu, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_plugin_manager_show_window_menu_for_rect (MetaPluginManager *plugin_mgr,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
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_for_rect)
|
||||
klass->show_window_menu_for_rect (plugin, window, menu, rect);
|
||||
}
|
||||
|
@@ -87,5 +87,10 @@ void meta_plugin_manager_show_window_menu (MetaPluginManager *mgr,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
void meta_plugin_manager_show_window_menu_for_rect (MetaPluginManager *mgr,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
MetaRectangle *rect);
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -121,17 +121,17 @@ static guint signals[LAST_SIGNAL] = { 0 };
|
||||
/* The first element in this array also defines the default parameters
|
||||
* for newly created classes */
|
||||
MetaShadowClassInfo default_shadow_classes[] = {
|
||||
{ "normal", { 6, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "dialog", { 6, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "modal_dialog", { 6, -1, 0, 1, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "normal", { 3, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "dialog", { 3, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "modal_dialog", { 3, -1, 0, 1, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "utility", { 3, -1, 0, 1, 128 }, { 3, -1, 0, 1, 32 } },
|
||||
{ "border", { 6, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "menu", { 6, -1, 0, 3, 128 }, { 3, -1, 0, 0, 32 } },
|
||||
{ "border", { 3, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "menu", { 3, -1, 0, 3, 128 }, { 3, -1, 0, 0, 32 } },
|
||||
|
||||
{ "popup-menu", { 1, -1, 0, 1, 128 }, { 1, -1, 0, 1, 128 } },
|
||||
{ "popup-menu", { 1, 0, 0, 1, 128 }, { 1, -1, 0, 1, 128 } },
|
||||
|
||||
{ "dropdown-menu", { 1, 10, 0, 1, 128 }, { 1, 10, 0, 1, 128 } },
|
||||
{ "attached", { 1, -1, 0, 1, 128 }, { 1, -1, 0, 1, 128 } }
|
||||
{ "attached", { 1, 0, 0, 1, 128 }, { 1, -1, 0, 1, 128 } }
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaShadowFactory, meta_shadow_factory, G_TYPE_OBJECT);
|
||||
@@ -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
|
||||
@@ -496,7 +496,12 @@ get_box_filter_size (int radius)
|
||||
static int
|
||||
get_shadow_spread (int radius)
|
||||
{
|
||||
int d = get_box_filter_size (radius);
|
||||
int d;
|
||||
|
||||
if (radius == 0)
|
||||
return 0;
|
||||
|
||||
d = get_box_filter_size (radius);
|
||||
|
||||
if (d % 2 == 1)
|
||||
return 3 * (d / 2);
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include "window-private.h"
|
||||
#include "meta-shaped-texture-private.h"
|
||||
#include "meta-cullable.h"
|
||||
#include "x11/window-x11.h"
|
||||
|
||||
struct _MetaSurfaceActorX11Private
|
||||
{
|
||||
@@ -143,7 +144,7 @@ update_pixmap (MetaSurfaceActorX11 *self)
|
||||
if (priv->pixmap == None)
|
||||
{
|
||||
Pixmap new_pixmap;
|
||||
Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
|
||||
Window xwindow = meta_window_x11_get_toplevel_xwindow (priv->window);
|
||||
|
||||
meta_error_trap_push (display);
|
||||
new_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow);
|
||||
@@ -312,7 +313,7 @@ sync_unredirected (MetaSurfaceActorX11 *self)
|
||||
MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
|
||||
MetaDisplay *display = priv->display;
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
|
||||
Window xwindow = meta_window_x11_get_toplevel_xwindow (priv->window);
|
||||
|
||||
meta_error_trap_push (display);
|
||||
|
||||
@@ -404,7 +405,7 @@ create_damage (MetaSurfaceActorX11 *self)
|
||||
{
|
||||
MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
|
||||
Display *xdisplay = meta_display_get_xdisplay (priv->display);
|
||||
Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
|
||||
Window xwindow = meta_window_x11_get_toplevel_xwindow (priv->window);
|
||||
|
||||
priv->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox);
|
||||
}
|
||||
|
@@ -51,8 +51,7 @@ void meta_window_actor_update_shape (MetaWindowActor *self);
|
||||
void meta_window_actor_update_opacity (MetaWindowActor *self);
|
||||
void meta_window_actor_mapped (MetaWindowActor *self);
|
||||
void meta_window_actor_unmapped (MetaWindowActor *self);
|
||||
void meta_window_actor_set_updates_frozen (MetaWindowActor *self,
|
||||
gboolean updates_frozen);
|
||||
void meta_window_actor_sync_updates_frozen (MetaWindowActor *self);
|
||||
void meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
|
||||
gboolean no_delay_frame);
|
||||
|
||||
|
@@ -746,9 +746,11 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Add shadows to override redirect windows (e.g., Gtk menus).
|
||||
* Add shadows to override redirect windows on X11 unless the toolkit
|
||||
* indicates that it is handling shadows itself (e.g., Gtk menus).
|
||||
*/
|
||||
if (priv->window->override_redirect)
|
||||
if (priv->window->override_redirect &&
|
||||
!priv->window->has_custom_frame_extents)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
@@ -1150,7 +1152,7 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaRectangle window_rect;
|
||||
|
||||
meta_window_get_input_rect (priv->window, &window_rect);
|
||||
meta_window_get_buffer_rect (priv->window, &window_rect);
|
||||
|
||||
/* When running as a Wayland compositor we catch size changes when new
|
||||
* buffers are attached */
|
||||
@@ -1324,7 +1326,7 @@ meta_window_actor_new (MetaWindow *window)
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (priv->window));
|
||||
meta_window_actor_sync_updates_frozen (self);
|
||||
|
||||
/* If a window doesn't start off with updates frozen, we should
|
||||
* we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn.
|
||||
@@ -2020,7 +2022,7 @@ meta_window_actor_update_opacity (MetaWindowActor *self)
|
||||
clutter_actor_set_opacity (CLUTTER_ACTOR (priv->surface), window->opacity);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
meta_window_actor_set_updates_frozen (MetaWindowActor *self,
|
||||
gboolean updates_frozen)
|
||||
{
|
||||
@@ -2037,3 +2039,12 @@ meta_window_actor_set_updates_frozen (MetaWindowActor *self,
|
||||
meta_window_actor_thaw (self);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_sync_updates_frozen (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaWindow *window = priv->window;
|
||||
|
||||
meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (window));
|
||||
}
|
||||
|
@@ -1,12 +1,22 @@
|
||||
|
||||
pkglibdir=@MUTTER_PLUGIN_DIR@
|
||||
pkglibdir = $(MUTTER_PLUGIN_DIR)
|
||||
|
||||
INCLUDES=@MUTTER_CFLAGS@ -I $(top_srcdir)/src -DMUTTER_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\" -DMUTTER_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" -DMUTTER_PKGDATADIR=\"$(pkgdatadir)\" -DMUTTER_DATADIR=\"$(datadir)\" -DG_LOG_DOMAIN=\"mutter\" -DSN_API_NOT_YET_FROZEN=1 -DMUTTER_MAJOR_VERSION=$(MUTTER_MAJOR_VERSION) -DMUTTER_MINOR_VERSION=$(MUTTER_MINOR_VERSION) -DMUTTER_MICRO_VERSION=$(MUTTER_MICRO_VERSION) -DMUTTER_PLUGIN_API_VERSION=$(MUTTER_PLUGIN_API_VERSION) -DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\"
|
||||
AM_CPPFLAGS = \
|
||||
$(MUTTER_CFLAGS) \
|
||||
-I$(top_builddir)/src \
|
||||
-I$(top_srcdir)/src \
|
||||
-DMUTTER_LIBEXECDIR=\"$(libexecdir)\" \
|
||||
-DMUTTER_LOCALEDIR=\"$(localedir)\" \
|
||||
-DMUTTER_PKGDATADIR=\"$(pkgdatadir)\" \
|
||||
-DMUTTER_DATADIR=\"$(datadir)\" \
|
||||
-DG_LOG_DOMAIN=\"mutter\" \
|
||||
-DSN_API_NOT_YET_FROZEN=1 \
|
||||
-DMUTTER_PLUGIN_DIR=\"$(MUTTER_PLUGIN_DIR)\"
|
||||
|
||||
default_la_CFLAGS = -fPIC
|
||||
default_la_SOURCES = default.c
|
||||
default_la_LDFLAGS = -module -avoid-version -no-undefined
|
||||
default_la_LIBADD = @CLUTTER_LIBS@
|
||||
default_la_LIBADD = $(CLUTTER_LIBS)
|
||||
|
||||
pkglib_LTLIBRARIES = default.la
|
||||
|
||||
|
@@ -546,6 +546,26 @@ compare_rect_areas (gconstpointer a, gconstpointer b)
|
||||
return b_area - a_area; /* positive ret value denotes b > a, ... */
|
||||
}
|
||||
|
||||
/* ... and another helper for get_minimal_spanning_set_for_region()... */
|
||||
static gboolean
|
||||
check_strut_align (MetaStrut *strut, const MetaRectangle *rect)
|
||||
{
|
||||
/* Check whether @strut actually aligns to the side of @rect it claims */
|
||||
switch (strut->side)
|
||||
{
|
||||
case META_SIDE_TOP:
|
||||
return BOX_TOP (strut->rect) <= BOX_TOP (*rect);
|
||||
case META_SIDE_BOTTOM:
|
||||
return BOX_BOTTOM (strut->rect) >= BOX_BOTTOM (*rect);
|
||||
case META_SIDE_LEFT:
|
||||
return BOX_LEFT (strut->rect) <= BOX_LEFT (*rect);
|
||||
case META_SIDE_RIGHT:
|
||||
return BOX_RIGHT (strut->rect) >= BOX_RIGHT (*rect);
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_rectangle_get_minimal_spanning_set_for_region:
|
||||
* @basic_rect: Input rectangle
|
||||
@@ -630,7 +650,8 @@ meta_rectangle_get_minimal_spanning_set_for_region (
|
||||
for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next)
|
||||
{
|
||||
GList *rect_iter;
|
||||
MetaRectangle *strut_rect = &((MetaStrut*)strut_iter->data)->rect;
|
||||
MetaStrut *strut = (MetaStrut*)strut_iter->data;
|
||||
MetaRectangle *strut_rect = &strut->rect;
|
||||
|
||||
tmp_list = ret;
|
||||
ret = NULL;
|
||||
@@ -638,7 +659,9 @@ meta_rectangle_get_minimal_spanning_set_for_region (
|
||||
while (rect_iter)
|
||||
{
|
||||
MetaRectangle *rect = (MetaRectangle*) rect_iter->data;
|
||||
if (!meta_rectangle_overlap (rect, strut_rect))
|
||||
|
||||
if (!meta_rectangle_overlap (strut_rect, rect) ||
|
||||
!check_strut_align (strut, basic_rect))
|
||||
ret = g_list_prepend (ret, rect);
|
||||
else
|
||||
{
|
||||
|
@@ -404,31 +404,6 @@ setup_constraint_info (ConstraintInfo *info,
|
||||
meta_workspace_get_onmonitor_region (cur_workspace,
|
||||
monitor_info->number);
|
||||
|
||||
/* Workaround braindead legacy apps that don't know how to
|
||||
* fullscreen themselves properly - don't get fooled by
|
||||
* windows which hide their titlebar when maximized or which are
|
||||
* client decorated; that's not the same as fullscreen, even
|
||||
* if there are no struts making the workarea smaller than
|
||||
* the monitor.
|
||||
*/
|
||||
if (meta_prefs_get_force_fullscreen() &&
|
||||
window->client_type != META_WINDOW_CLIENT_TYPE_WAYLAND &&
|
||||
!window->hide_titlebar_when_maximized &&
|
||||
(window->decorated || !meta_window_is_client_decorated (window)) &&
|
||||
meta_rectangle_equal (new, &monitor_info->rect) &&
|
||||
window->has_fullscreen_func &&
|
||||
!window->fullscreen)
|
||||
{
|
||||
/*
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
*/
|
||||
meta_warning (
|
||||
"Treating resize request of legacy application %s as a "
|
||||
"fullscreen request\n",
|
||||
window->desc);
|
||||
meta_window_make_fullscreen_internal (window);
|
||||
}
|
||||
|
||||
/* Log all this information for debugging */
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Setting up constraint info:\n"
|
||||
@@ -613,7 +588,7 @@ update_onscreen_requirements (MetaWindow *window,
|
||||
window->require_fully_onscreen =
|
||||
meta_rectangle_contained_in_region (info->usable_screen_region,
|
||||
&info->current);
|
||||
if (old ^ window->require_fully_onscreen)
|
||||
if (old != window->require_fully_onscreen)
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"require_fully_onscreen for %s toggled to %s\n",
|
||||
window->desc,
|
||||
@@ -626,7 +601,7 @@ update_onscreen_requirements (MetaWindow *window,
|
||||
window->require_on_single_monitor =
|
||||
meta_rectangle_contained_in_region (info->usable_monitor_region,
|
||||
&info->current);
|
||||
if (old ^ window->require_on_single_monitor)
|
||||
if (old != window->require_on_single_monitor)
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"require_on_single_monitor for %s toggled to %s\n",
|
||||
window->desc,
|
||||
@@ -645,7 +620,7 @@ update_onscreen_requirements (MetaWindow *window,
|
||||
window->require_titlebar_visible =
|
||||
meta_rectangle_overlaps_with_region (info->usable_screen_region,
|
||||
&titlebar_rect);
|
||||
if (old ^ window->require_titlebar_visible)
|
||||
if (old != window->require_titlebar_visible)
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"require_titlebar_visible for %s toggled to %s\n",
|
||||
window->desc,
|
||||
|
@@ -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.
|
||||
*
|
||||
@@ -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);
|
||||
|
||||
@@ -103,10 +108,10 @@ meta_core_get (Display *xdisplay,
|
||||
if (!*((gboolean*)answer)) goto out; /* see above */
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_WIDTH:
|
||||
*((gint*)answer) = window->rect.width;
|
||||
*((gint*)answer) = priv->client_rect.width;
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_HEIGHT:
|
||||
*((gint*)answer) = window->rect.height;
|
||||
*((gint*)answer) = priv->client_rect.height;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_FLAGS:
|
||||
*((MetaFrameFlags*)answer) = meta_frame_get_flags (window->frame);
|
||||
@@ -120,11 +125,8 @@ meta_core_get (Display *xdisplay,
|
||||
case META_CORE_GET_ICON:
|
||||
*((GdkPixbuf**)answer) = window->icon;
|
||||
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;
|
||||
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;
|
||||
@@ -390,6 +392,22 @@ meta_core_show_window_menu (Display *xdisplay,
|
||||
meta_window_show_menu (window, menu, root_x, root_y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_show_window_menu_for_rect (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
MetaWindowMenuType menu,
|
||||
MetaRectangle *rect,
|
||||
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_for_rect (window, menu, rect);
|
||||
}
|
||||
|
||||
const char*
|
||||
meta_core_get_workspace_name_with_index (Display *xdisplay,
|
||||
Window xroot,
|
||||
|
@@ -26,6 +26,7 @@
|
||||
/* Don't include core headers here */
|
||||
#include <gdk/gdkx.h>
|
||||
#include <meta/common.h>
|
||||
#include <meta/boxes.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -37,8 +38,7 @@ typedef enum
|
||||
META_CORE_GET_FRAME_TYPE,
|
||||
META_CORE_GET_MINI_ICON,
|
||||
META_CORE_GET_ICON,
|
||||
META_CORE_GET_FRAME_WIDTH,
|
||||
META_CORE_GET_FRAME_HEIGHT,
|
||||
META_CORE_GET_FRAME_RECT,
|
||||
META_CORE_GET_THEME_VARIANT,
|
||||
} MetaCoreGetType;
|
||||
|
||||
@@ -139,6 +139,12 @@ void meta_core_show_window_menu (Display *xdisplay,
|
||||
int root_y,
|
||||
guint32 timestamp);
|
||||
|
||||
void meta_core_show_window_menu_for_rect (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
MetaWindowMenuType menu,
|
||||
MetaRectangle *rect,
|
||||
guint32 timestamp);
|
||||
|
||||
gboolean meta_core_begin_grab_op (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
MetaGrabOp op,
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include <meta/boxes.h>
|
||||
#include <meta/display.h>
|
||||
#include "keybindings-private.h"
|
||||
#include "gesture-tracker-private.h"
|
||||
#include <meta/prefs.h>
|
||||
#include <meta/barrier.h>
|
||||
#include <clutter/clutter.h>
|
||||
@@ -181,7 +182,6 @@ struct _MetaDisplay
|
||||
/* current window operation */
|
||||
MetaGrabOp grab_op;
|
||||
MetaWindow *grab_window;
|
||||
Window grab_xwindow;
|
||||
int grab_button;
|
||||
int grab_anchor_root_x;
|
||||
int grab_anchor_root_y;
|
||||
@@ -254,6 +254,8 @@ struct _MetaDisplay
|
||||
/* Managed by compositor.c */
|
||||
MetaCompositor *compositor;
|
||||
|
||||
MetaGestureTracker *gesture_tracker;
|
||||
|
||||
int composite_event_base;
|
||||
int composite_error_base;
|
||||
int composite_major_version;
|
||||
@@ -443,4 +445,6 @@ void meta_display_sanity_check_timestamps (MetaDisplay *display,
|
||||
gboolean meta_display_timestamp_too_old (MetaDisplay *display,
|
||||
guint32 *timestamp);
|
||||
|
||||
MetaGestureTracker * meta_display_get_gesture_tracker (MetaDisplay *display);
|
||||
|
||||
#endif
|
||||
|
@@ -51,6 +51,8 @@
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include "meta-backend.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
#include "compositor-private.h"
|
||||
|
||||
#ifdef HAVE_RANDR
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
@@ -146,6 +148,11 @@ static void update_window_grab_modifiers (MetaDisplay *display);
|
||||
static void prefs_changed_callback (MetaPreference pref,
|
||||
void *data);
|
||||
|
||||
static void meta_display_grab_window_touch (MetaDisplay *display,
|
||||
Window xwindow);
|
||||
static void meta_display_ungrab_window_touch (MetaDisplay *display,
|
||||
Window xwindow);
|
||||
|
||||
static void
|
||||
meta_display_get_property(GObject *object,
|
||||
guint prop_id,
|
||||
@@ -413,6 +420,28 @@ meta_set_gnome_wm_keybindings (const char *wm_keybindings)
|
||||
gnome_wm_keybindings = wm_keybindings;
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_tracker_state_changed (MetaGestureTracker *tracker,
|
||||
ClutterEventSequence *sequence,
|
||||
MetaSequenceState state,
|
||||
MetaDisplay *display)
|
||||
{
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
int event_mode;
|
||||
|
||||
if (state == META_SEQUENCE_ACCEPTED)
|
||||
event_mode = XIAcceptTouch;
|
||||
else if (state == META_SEQUENCE_REJECTED)
|
||||
event_mode = XIRejectTouch;
|
||||
else
|
||||
return;
|
||||
|
||||
XIAllowTouchEvents (meta_backend_x11_get_xdisplay (backend),
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
clutter_x11_event_sequence_get_touch_detail (sequence),
|
||||
DefaultRootWindow (display->xdisplay), event_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_open:
|
||||
*
|
||||
@@ -805,8 +834,16 @@ meta_display_open (void)
|
||||
|
||||
enable_compositor (the_display);
|
||||
|
||||
meta_screen_init_workspaces (screen);
|
||||
meta_screen_create_guard_window (screen);
|
||||
|
||||
/* Set up touch support */
|
||||
the_display->gesture_tracker = meta_gesture_tracker_new (0);
|
||||
g_signal_connect (the_display->gesture_tracker, "state-changed",
|
||||
G_CALLBACK (gesture_tracker_state_changed), the_display);
|
||||
meta_display_grab_window_touch (the_display,
|
||||
DefaultRootWindow (the_display->xdisplay));
|
||||
|
||||
/* We know that if mutter is running as a Wayland compositor,
|
||||
* we start out with no windows.
|
||||
*/
|
||||
@@ -976,6 +1013,10 @@ meta_display_close (MetaDisplay *display,
|
||||
|
||||
meta_display_remove_autoraise_callback (display);
|
||||
|
||||
meta_display_ungrab_window_touch (display,
|
||||
DefaultRootWindow (display->xdisplay));
|
||||
g_clear_object (&display->gesture_tracker);
|
||||
|
||||
if (display->focus_timeout_id)
|
||||
g_source_remove (display->focus_timeout_id);
|
||||
display->focus_timeout_id = 0;
|
||||
@@ -1343,23 +1384,7 @@ window_raise_with_delay_callback (void *data)
|
||||
*/
|
||||
if (meta_stack_get_top (window->screen->stack) != window)
|
||||
{
|
||||
int x, y, root_x, root_y;
|
||||
Window root, child;
|
||||
MetaRectangle frame_rect;
|
||||
unsigned int mask;
|
||||
gboolean same_screen;
|
||||
gboolean point_in_window;
|
||||
|
||||
meta_error_trap_push (window->display);
|
||||
same_screen = XQueryPointer (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
&root, &child,
|
||||
&root_x, &root_y, &x, &y, &mask);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
point_in_window = POINT_IN_RECT (root_x, root_y, frame_rect);
|
||||
if (same_screen && point_in_window)
|
||||
if (meta_window_has_pointer (window))
|
||||
meta_window_raise (window);
|
||||
else
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
@@ -1367,7 +1392,7 @@ window_raise_with_delay_callback (void *data)
|
||||
window->desc);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1696,15 +1721,15 @@ meta_display_update_cursor (MetaDisplay *display)
|
||||
}
|
||||
|
||||
static MetaWindow *
|
||||
get_toplevel_transient_for (MetaWindow *window)
|
||||
get_first_freefloating_window (MetaWindow *window)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
MetaWindow *parent = meta_window_get_transient_for (window);
|
||||
if (parent == NULL)
|
||||
return window;
|
||||
window = parent;
|
||||
}
|
||||
while (meta_window_is_attached_dialog (window))
|
||||
window = meta_window_get_transient_for (window);
|
||||
|
||||
/* Attached dialogs should always have a non-NULL transient-for */
|
||||
g_assert (window != NULL);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -1752,11 +1777,11 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
|
||||
grab_window = window;
|
||||
|
||||
/* If window is a modal dialog attached to its parent,
|
||||
* grab the parent instead for moving.
|
||||
/* If we're trying to move a window, move the first
|
||||
* non-attached dialog instead.
|
||||
*/
|
||||
if (meta_window_is_attached_dialog (window) && meta_grab_op_is_moving (op))
|
||||
grab_window = get_toplevel_transient_for (window);
|
||||
if (meta_grab_op_is_moving (op))
|
||||
grab_window = get_first_freefloating_window (window);
|
||||
|
||||
g_assert (grab_window != NULL);
|
||||
g_assert (op != META_GRAB_OP_NONE);
|
||||
@@ -1826,8 +1851,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 ())
|
||||
@@ -2070,6 +2095,35 @@ meta_display_ungrab_window_buttons (MetaDisplay *display,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_display_grab_window_touch (MetaDisplay *display,
|
||||
Window xwindow)
|
||||
{
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { META_VIRTUAL_CORE_POINTER_ID, sizeof (mask_bits), mask_bits };
|
||||
XIGrabModifiers mods = { XIAnyModifier, 0 };
|
||||
|
||||
XISetMask (mask.mask, XI_TouchBegin);
|
||||
XISetMask (mask.mask, XI_TouchUpdate);
|
||||
XISetMask (mask.mask, XI_TouchEnd);
|
||||
|
||||
XIGrabTouchBegin (meta_backend_x11_get_xdisplay (backend),
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
xwindow, False, &mask, 1, &mods);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_display_ungrab_window_touch (MetaDisplay *display,
|
||||
Window xwindow)
|
||||
{
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
XIGrabModifiers mods = { XIAnyModifier, 0 };
|
||||
|
||||
XIUngrabTouchBegin (meta_backend_x11_get_xdisplay (backend),
|
||||
META_VIRTUAL_CORE_POINTER_ID, xwindow, 1, &mods);
|
||||
}
|
||||
|
||||
/* Grab buttons we only grab while unfocused in click-to-focus mode */
|
||||
#define MAX_FOCUS_BUTTON 4
|
||||
void
|
||||
@@ -2525,21 +2579,19 @@ mru_cmp (gconstpointer a,
|
||||
* meta_display_get_tab_list:
|
||||
* @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.
|
||||
* If @workspace is not %NULL, the list only conains windows that are on
|
||||
* @workspace or have the demands-attention hint set; otherwise it contains
|
||||
* all windows on @screen.
|
||||
* all windows.
|
||||
*
|
||||
* Returns: (transfer container) (element-type Meta.Window): List of windows
|
||||
*/
|
||||
GList*
|
||||
meta_display_get_tab_list (MetaDisplay *display,
|
||||
MetaTabList type,
|
||||
MetaScreen *screen,
|
||||
MetaWorkspace *workspace)
|
||||
{
|
||||
GList *tab_list = NULL;
|
||||
@@ -2595,7 +2647,7 @@ meta_display_get_tab_list (MetaDisplay *display,
|
||||
* @display: a #MetaDisplay
|
||||
* @type: type of tab list
|
||||
* @workspace: origin workspace
|
||||
* @window: (allow-none): starting window
|
||||
* @window: (nullable): starting window
|
||||
* @backward: If %TRUE, look for the previous window.
|
||||
*
|
||||
* Determine the next window that should be displayed for Alt-TAB
|
||||
@@ -2614,7 +2666,7 @@ meta_display_get_tab_next (MetaDisplay *display,
|
||||
gboolean skip;
|
||||
GList *tab_list;
|
||||
MetaWindow *ret;
|
||||
tab_list = meta_display_get_tab_list (display, type, NULL, workspace);
|
||||
tab_list = meta_display_get_tab_list (display, type, workspace);
|
||||
|
||||
if (tab_list == NULL)
|
||||
return NULL;
|
||||
@@ -3169,3 +3221,9 @@ meta_display_create_x_cursor (MetaDisplay *display,
|
||||
{
|
||||
return meta_cursor_create_x_cursor (display->xdisplay, cursor);
|
||||
}
|
||||
|
||||
MetaGestureTracker *
|
||||
meta_display_get_gesture_tracker (MetaDisplay *display)
|
||||
{
|
||||
return display->gesture_tracker;
|
||||
}
|
||||
|
@@ -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,8 +1226,8 @@ 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);
|
||||
proposed_outer_width = *new_width;
|
||||
proposed_outer_height = *new_height;
|
||||
meta_rectangle_resize_with_gravity (&old_outer,
|
||||
&new_outer,
|
||||
gravity,
|
||||
@@ -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",
|
||||
|
@@ -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,
|
||||
|
1853
src/core/events.c
1853
src/core/events.c
File diff suppressed because it is too large
Load Diff
@@ -29,4 +29,3 @@ void meta_display_init_events (MetaDisplay *display);
|
||||
void meta_display_free_events (MetaDisplay *display);
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -109,6 +109,19 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
XChangeWindowAttributes (window->display->xdisplay,
|
||||
frame->xwindow, CWEventMask, &attrs);
|
||||
|
||||
{
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
|
||||
XISetMask (mask.mask, XI_ButtonPress);
|
||||
XISetMask (mask.mask, XI_ButtonRelease);
|
||||
XISetMask (mask.mask, XI_Motion);
|
||||
XISetMask (mask.mask, XI_Enter);
|
||||
XISetMask (mask.mask, XI_Leave);
|
||||
|
||||
XISelectEvents (window->display->xdisplay, frame->xwindow, &mask, 1);
|
||||
}
|
||||
|
||||
meta_display_register_x_window (window->display, &frame->xwindow, window);
|
||||
|
||||
meta_error_trap_push (window->display);
|
||||
@@ -121,9 +134,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,8 +142,8 @@ 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);
|
||||
|
||||
@@ -202,7 +212,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.
|
||||
*/
|
||||
|
83
src/core/gesture-tracker-private.h
Normal file
83
src/core/gesture-tracker-private.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/**
|
||||
* \file gesture-tracker-private.h Manages gestures on windows/desktop
|
||||
*
|
||||
* Forwards touch events to clutter actors, and accepts/rejects touch sequences
|
||||
* based on the outcome of those.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef META_GESTURE_TRACKER_PRIVATE_H
|
||||
#define META_GESTURE_TRACKER_PRIVATE_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <meta/window.h>
|
||||
|
||||
#define META_TYPE_GESTURE_TRACKER (meta_gesture_tracker_get_type ())
|
||||
#define META_GESTURE_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_GESTURE_TRACKER, MetaGestureTracker))
|
||||
#define META_GESTURE_TRACKER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_GESTURE_TRACKER, MetaGestureTrackerClass))
|
||||
#define META_IS_GESTURE_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_GESTURE_TRACKER))
|
||||
#define META_IS_GESTURE_TRACKER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_GESTURE_TRACKER))
|
||||
#define META_GESTURE_TRACKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_GESTURE_TRACKER, MetaGestureTrackerClass))
|
||||
|
||||
typedef struct _MetaGestureTracker MetaGestureTracker;
|
||||
typedef struct _MetaGestureTrackerClass MetaGestureTrackerClass;
|
||||
|
||||
typedef enum {
|
||||
META_SEQUENCE_NONE,
|
||||
META_SEQUENCE_ACCEPTED,
|
||||
META_SEQUENCE_REJECTED,
|
||||
META_SEQUENCE_PENDING_END
|
||||
} MetaSequenceState;
|
||||
|
||||
struct _MetaGestureTracker
|
||||
{
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
struct _MetaGestureTrackerClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* state_changed) (MetaGestureTracker *tracker,
|
||||
ClutterEventSequence *sequence,
|
||||
MetaSequenceState state);
|
||||
};
|
||||
|
||||
GType meta_gesture_tracker_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MetaGestureTracker * meta_gesture_tracker_new (guint autodeny_timeout);
|
||||
|
||||
gboolean meta_gesture_tracker_handle_event (MetaGestureTracker *tracker,
|
||||
const ClutterEvent *event);
|
||||
gboolean meta_gesture_tracker_set_sequence_state (MetaGestureTracker *tracker,
|
||||
ClutterEventSequence *sequence,
|
||||
MetaSequenceState state);
|
||||
MetaSequenceState meta_gesture_tracker_get_sequence_state (MetaGestureTracker *tracker,
|
||||
ClutterEventSequence *sequence);
|
||||
gboolean meta_gesture_tracker_consumes_event (MetaGestureTracker *tracker,
|
||||
const ClutterEvent *event);
|
||||
|
||||
#endif /* META_GESTURE_TRACKER_PRIVATE_H */
|
555
src/core/gesture-tracker.c
Normal file
555
src/core/gesture-tracker.c
Normal file
@@ -0,0 +1,555 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gesture-tracker-private.h"
|
||||
#include "meta-surface-actor.h"
|
||||
|
||||
#define DISTANCE_THRESHOLD 30
|
||||
|
||||
typedef struct _MetaGestureTrackerPrivate MetaGestureTrackerPrivate;
|
||||
typedef struct _GestureActionData GestureActionData;
|
||||
typedef struct _MetaSequenceInfo MetaSequenceInfo;
|
||||
|
||||
struct _MetaSequenceInfo
|
||||
{
|
||||
MetaGestureTracker *tracker;
|
||||
ClutterEventSequence *sequence;
|
||||
MetaSequenceState state;
|
||||
guint autodeny_timeout_id;
|
||||
gfloat start_x;
|
||||
gfloat start_y;
|
||||
};
|
||||
|
||||
struct _GestureActionData
|
||||
{
|
||||
ClutterGestureAction *gesture;
|
||||
MetaSequenceState state;
|
||||
guint gesture_begin_id;
|
||||
guint gesture_end_id;
|
||||
guint gesture_cancel_id;
|
||||
};
|
||||
|
||||
struct _MetaGestureTrackerPrivate
|
||||
{
|
||||
GHashTable *sequences; /* Hashtable of ClutterEventSequence->MetaSequenceInfo */
|
||||
|
||||
MetaSequenceState stage_state;
|
||||
GArray *stage_gestures; /* Array of GestureActionData */
|
||||
GList *listeners; /* List of ClutterGestureAction */
|
||||
guint autodeny_timeout;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_AUTODENY_TIMEOUT = 1
|
||||
};
|
||||
|
||||
enum {
|
||||
STATE_CHANGED,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
#define DEFAULT_AUTODENY_TIMEOUT 150
|
||||
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
|
||||
static void meta_gesture_tracker_untrack_stage (MetaGestureTracker *tracker);
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaGestureTracker, meta_gesture_tracker, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
meta_gesture_tracker_finalize (GObject *object)
|
||||
{
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
|
||||
priv = meta_gesture_tracker_get_instance_private (META_GESTURE_TRACKER (object));
|
||||
|
||||
g_hash_table_destroy (priv->sequences);
|
||||
g_array_free (priv->stage_gestures, TRUE);
|
||||
g_list_free (priv->listeners);
|
||||
|
||||
G_OBJECT_CLASS (meta_gesture_tracker_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_gesture_tracker_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
|
||||
priv = meta_gesture_tracker_get_instance_private (META_GESTURE_TRACKER (object));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_AUTODENY_TIMEOUT:
|
||||
priv->autodeny_timeout = g_value_get_uint (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_gesture_tracker_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
|
||||
priv = meta_gesture_tracker_get_instance_private (META_GESTURE_TRACKER (object));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_AUTODENY_TIMEOUT:
|
||||
g_value_set_uint (value, priv->autodeny_timeout);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_gesture_tracker_class_init (MetaGestureTrackerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_gesture_tracker_finalize;
|
||||
object_class->set_property = meta_gesture_tracker_set_property;
|
||||
object_class->get_property = meta_gesture_tracker_get_property;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_AUTODENY_TIMEOUT,
|
||||
g_param_spec_uint ("autodeny-timeout",
|
||||
"Auto-deny timeout",
|
||||
"Auto-deny timeout",
|
||||
0, G_MAXUINT, 0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
signals[STATE_CHANGED] =
|
||||
g_signal_new ("state-changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (MetaGestureTrackerClass, state_changed),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
autodeny_sequence (gpointer user_data)
|
||||
{
|
||||
MetaSequenceInfo *info = user_data;
|
||||
|
||||
/* Deny the sequence automatically after the given timeout */
|
||||
if (info->state == META_SEQUENCE_NONE)
|
||||
meta_gesture_tracker_set_sequence_state (info->tracker, info->sequence,
|
||||
META_SEQUENCE_REJECTED);
|
||||
|
||||
info->autodeny_timeout_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static MetaSequenceInfo *
|
||||
meta_sequence_info_new (MetaGestureTracker *tracker,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
MetaSequenceInfo *info;
|
||||
guint ms;
|
||||
|
||||
priv = meta_gesture_tracker_get_instance_private (tracker);
|
||||
ms = (priv->autodeny_timeout) ?
|
||||
priv->autodeny_timeout : DEFAULT_AUTODENY_TIMEOUT;
|
||||
|
||||
info = g_slice_new0 (MetaSequenceInfo);
|
||||
info->tracker = tracker;
|
||||
info->sequence = event->touch.sequence;
|
||||
info->state = META_SEQUENCE_NONE;
|
||||
info->autodeny_timeout_id = g_timeout_add (ms, autodeny_sequence, info);
|
||||
|
||||
clutter_event_get_coords (event, &info->start_x, &info->start_y);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sequence_info_free (MetaSequenceInfo *info)
|
||||
{
|
||||
if (info->autodeny_timeout_id)
|
||||
g_source_remove (info->autodeny_timeout_id);
|
||||
|
||||
if (info->state == META_SEQUENCE_NONE)
|
||||
meta_gesture_tracker_set_sequence_state (info->tracker, info->sequence,
|
||||
META_SEQUENCE_REJECTED);
|
||||
g_slice_free (MetaSequenceInfo, info);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
state_is_applicable (MetaSequenceState prev_state,
|
||||
MetaSequenceState state)
|
||||
{
|
||||
if (prev_state == META_SEQUENCE_PENDING_END)
|
||||
return FALSE;
|
||||
|
||||
/* Don't allow reverting to none */
|
||||
if (state == META_SEQUENCE_NONE)
|
||||
return FALSE;
|
||||
|
||||
/* PENDING_END state is final */
|
||||
if (prev_state == META_SEQUENCE_PENDING_END)
|
||||
return FALSE;
|
||||
|
||||
/* Sequences must be accepted/denied before PENDING_END */
|
||||
if (prev_state == META_SEQUENCE_NONE &&
|
||||
state == META_SEQUENCE_PENDING_END)
|
||||
return FALSE;
|
||||
|
||||
/* Make sequences stick to their accepted/denied state */
|
||||
if (state != META_SEQUENCE_PENDING_END &&
|
||||
prev_state != META_SEQUENCE_NONE)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_gesture_tracker_set_state (MetaGestureTracker *tracker,
|
||||
MetaSequenceState state)
|
||||
{
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
ClutterEventSequence *sequence;
|
||||
GHashTableIter iter;
|
||||
|
||||
priv = meta_gesture_tracker_get_instance_private (tracker);
|
||||
|
||||
if (priv->stage_state != state &&
|
||||
!state_is_applicable (priv->stage_state, state))
|
||||
return FALSE;
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->sequences);
|
||||
priv->stage_state = state;
|
||||
|
||||
while (g_hash_table_iter_next (&iter, (gpointer*) &sequence, NULL))
|
||||
meta_gesture_tracker_set_sequence_state (tracker, sequence, state);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gesture_begin_cb (ClutterGestureAction *gesture,
|
||||
ClutterActor *actor,
|
||||
MetaGestureTracker *tracker)
|
||||
{
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
|
||||
priv = meta_gesture_tracker_get_instance_private (tracker);
|
||||
|
||||
if (!g_list_find (priv->listeners, gesture) &&
|
||||
meta_gesture_tracker_set_state (tracker, META_SEQUENCE_ACCEPTED))
|
||||
priv->listeners = g_list_prepend (priv->listeners, gesture);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_end_cb (ClutterGestureAction *gesture,
|
||||
ClutterActor *actor,
|
||||
MetaGestureTracker *tracker)
|
||||
{
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
|
||||
priv = meta_gesture_tracker_get_instance_private (tracker);
|
||||
priv->listeners = g_list_remove (priv->listeners, gesture);
|
||||
|
||||
if (!priv->listeners)
|
||||
meta_gesture_tracker_untrack_stage (tracker);
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_cancel_cb (ClutterGestureAction *gesture,
|
||||
ClutterActor *actor,
|
||||
MetaGestureTracker *tracker)
|
||||
{
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
|
||||
priv = meta_gesture_tracker_get_instance_private (tracker);
|
||||
|
||||
if (g_list_find (priv->listeners, gesture))
|
||||
{
|
||||
priv->listeners = g_list_remove (priv->listeners, gesture);
|
||||
|
||||
if (!priv->listeners)
|
||||
meta_gesture_tracker_set_state (tracker, META_SEQUENCE_PENDING_END);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cancel_and_unref_gesture_cb (ClutterGestureAction *action)
|
||||
{
|
||||
clutter_gesture_action_cancel (action);
|
||||
g_object_unref (action);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_gesture_data (GestureActionData *data)
|
||||
{
|
||||
g_signal_handler_disconnect (data->gesture, data->gesture_begin_id);
|
||||
g_signal_handler_disconnect (data->gesture, data->gesture_end_id);
|
||||
g_signal_handler_disconnect (data->gesture, data->gesture_cancel_id);
|
||||
|
||||
/* Defer cancellation to an idle, as it may happen within event handling */
|
||||
g_idle_add ((GSourceFunc) cancel_and_unref_gesture_cb, data->gesture);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_gesture_tracker_init (MetaGestureTracker *tracker)
|
||||
{
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
|
||||
priv = meta_gesture_tracker_get_instance_private (tracker);
|
||||
priv->sequences = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) meta_sequence_info_free);
|
||||
priv->stage_gestures = g_array_new (FALSE, FALSE, sizeof (GestureActionData));
|
||||
g_array_set_clear_func (priv->stage_gestures, (GDestroyNotify) clear_gesture_data);
|
||||
}
|
||||
|
||||
MetaGestureTracker *
|
||||
meta_gesture_tracker_new (guint autodeny_timeout)
|
||||
{
|
||||
return g_object_new (META_TYPE_GESTURE_TRACKER,
|
||||
"autodeny-timeout", autodeny_timeout,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_gesture_tracker_track_stage (MetaGestureTracker *tracker,
|
||||
ClutterActor *stage)
|
||||
{
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
GList *actions, *l;
|
||||
|
||||
priv = meta_gesture_tracker_get_instance_private (tracker);
|
||||
actions = clutter_actor_get_actions (stage);
|
||||
|
||||
for (l = actions; l; l = l->next)
|
||||
{
|
||||
GestureActionData data;
|
||||
|
||||
if (!CLUTTER_IS_GESTURE_ACTION (l->data))
|
||||
continue;
|
||||
|
||||
data.gesture = g_object_ref (l->data);
|
||||
data.state = META_SEQUENCE_NONE;
|
||||
data.gesture_begin_id =
|
||||
g_signal_connect (data.gesture, "gesture-begin",
|
||||
G_CALLBACK (gesture_begin_cb), tracker);
|
||||
data.gesture_end_id =
|
||||
g_signal_connect (data.gesture, "gesture-end",
|
||||
G_CALLBACK (gesture_end_cb), tracker);
|
||||
data.gesture_cancel_id =
|
||||
g_signal_connect (data.gesture, "gesture-cancel",
|
||||
G_CALLBACK (gesture_cancel_cb), tracker);
|
||||
g_array_append_val (priv->stage_gestures, data);
|
||||
}
|
||||
|
||||
g_list_free (actions);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_gesture_tracker_untrack_stage (MetaGestureTracker *tracker)
|
||||
{
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
|
||||
priv = meta_gesture_tracker_get_instance_private (tracker);
|
||||
priv->stage_state = META_SEQUENCE_NONE;
|
||||
|
||||
g_hash_table_remove_all (priv->sequences);
|
||||
|
||||
if (priv->stage_gestures->len > 0)
|
||||
g_array_remove_range (priv->stage_gestures, 0, priv->stage_gestures->len);
|
||||
|
||||
g_list_free (priv->listeners);
|
||||
priv->listeners = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_gesture_tracker_handle_event (MetaGestureTracker *tracker,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
ClutterEventSequence *sequence;
|
||||
MetaSequenceInfo *info;
|
||||
ClutterActor *stage;
|
||||
gfloat x, y;
|
||||
|
||||
sequence = clutter_event_get_event_sequence (event);
|
||||
|
||||
if (!sequence)
|
||||
return FALSE;
|
||||
|
||||
priv = meta_gesture_tracker_get_instance_private (tracker);
|
||||
stage = CLUTTER_ACTOR (clutter_event_get_stage (event));
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_TOUCH_BEGIN:
|
||||
if (g_hash_table_size (priv->sequences) == 0)
|
||||
meta_gesture_tracker_track_stage (tracker, stage);
|
||||
|
||||
info = meta_sequence_info_new (tracker, event);
|
||||
g_hash_table_insert (priv->sequences, sequence, info);
|
||||
|
||||
if (priv->stage_gestures->len == 0)
|
||||
{
|
||||
/* If no gestures are attached, reject the sequence right away */
|
||||
meta_gesture_tracker_set_sequence_state (tracker, sequence,
|
||||
META_SEQUENCE_REJECTED);
|
||||
}
|
||||
else if (priv->stage_state != META_SEQUENCE_NONE)
|
||||
{
|
||||
/* Make the sequence state match the general state */
|
||||
meta_gesture_tracker_set_sequence_state (tracker, sequence,
|
||||
priv->stage_state);
|
||||
}
|
||||
break;
|
||||
case CLUTTER_TOUCH_END:
|
||||
info = g_hash_table_lookup (priv->sequences, sequence);
|
||||
|
||||
if (!info)
|
||||
return FALSE;
|
||||
|
||||
/* If nothing was done yet about the sequence, reject it so X11
|
||||
* clients may see it
|
||||
*/
|
||||
if (info->state == META_SEQUENCE_NONE)
|
||||
meta_gesture_tracker_set_sequence_state (tracker, sequence,
|
||||
META_SEQUENCE_REJECTED);
|
||||
|
||||
g_hash_table_remove (priv->sequences, sequence);
|
||||
|
||||
if (g_hash_table_size (priv->sequences) == 0)
|
||||
meta_gesture_tracker_untrack_stage (tracker);
|
||||
break;
|
||||
case CLUTTER_TOUCH_UPDATE:
|
||||
info = g_hash_table_lookup (priv->sequences, sequence);
|
||||
|
||||
if (!info)
|
||||
return FALSE;
|
||||
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
|
||||
if (info->state == META_SEQUENCE_NONE &&
|
||||
(ABS (info->start_x - x) > DISTANCE_THRESHOLD ||
|
||||
ABS (info->start_y - y) > DISTANCE_THRESHOLD))
|
||||
meta_gesture_tracker_set_sequence_state (tracker, sequence,
|
||||
META_SEQUENCE_REJECTED);
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_gesture_tracker_set_sequence_state (MetaGestureTracker *tracker,
|
||||
ClutterEventSequence *sequence,
|
||||
MetaSequenceState state)
|
||||
{
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
MetaSequenceInfo *info;
|
||||
|
||||
g_return_val_if_fail (META_IS_GESTURE_TRACKER (tracker), FALSE);
|
||||
|
||||
priv = meta_gesture_tracker_get_instance_private (tracker);
|
||||
info = g_hash_table_lookup (priv->sequences, sequence);
|
||||
|
||||
if (!info)
|
||||
return FALSE;
|
||||
else if (state == info->state)
|
||||
return TRUE;
|
||||
|
||||
if (!state_is_applicable (info->state, state))
|
||||
return FALSE;
|
||||
|
||||
/* Unset autodeny timeout */
|
||||
if (info->autodeny_timeout_id)
|
||||
{
|
||||
g_source_remove (info->autodeny_timeout_id);
|
||||
info->autodeny_timeout_id = 0;
|
||||
}
|
||||
|
||||
info->state = state;
|
||||
g_signal_emit (tracker, signals[STATE_CHANGED], 0, sequence, info->state);
|
||||
|
||||
/* If the sequence was denied, set immediately to PENDING_END after emission */
|
||||
if (state == META_SEQUENCE_REJECTED)
|
||||
{
|
||||
info->state = META_SEQUENCE_PENDING_END;
|
||||
g_signal_emit (tracker, signals[STATE_CHANGED], 0, sequence, info->state);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
MetaSequenceState
|
||||
meta_gesture_tracker_get_sequence_state (MetaGestureTracker *tracker,
|
||||
ClutterEventSequence *sequence)
|
||||
{
|
||||
MetaGestureTrackerPrivate *priv;
|
||||
MetaSequenceInfo *info;
|
||||
|
||||
g_return_val_if_fail (META_IS_GESTURE_TRACKER (tracker), META_SEQUENCE_PENDING_END);
|
||||
|
||||
priv = meta_gesture_tracker_get_instance_private (tracker);
|
||||
info = g_hash_table_lookup (priv->sequences, sequence);
|
||||
|
||||
if (!info)
|
||||
return META_SEQUENCE_PENDING_END;
|
||||
|
||||
return info->state;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_gesture_tracker_consumes_event (MetaGestureTracker *tracker,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
ClutterEventSequence *sequence;
|
||||
MetaSequenceState state;
|
||||
|
||||
g_return_val_if_fail (META_IS_GESTURE_TRACKER (tracker), FALSE);
|
||||
|
||||
sequence = clutter_event_get_event_sequence (event);
|
||||
|
||||
if (!sequence)
|
||||
return FALSE;
|
||||
|
||||
state = meta_gesture_tracker_get_sequence_state (tracker, sequence);
|
||||
|
||||
return (event->type != CLUTTER_TOUCH_END &&
|
||||
(state == META_SEQUENCE_REJECTED || state == META_SEQUENCE_PENDING_END));
|
||||
}
|
@@ -57,7 +57,11 @@
|
||||
|
||||
#include "wayland/meta-wayland.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "x11/window-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"
|
||||
@@ -1220,7 +1224,7 @@ meta_window_grab_keys (MetaWindow *window)
|
||||
}
|
||||
|
||||
meta_window_change_keygrabs (window,
|
||||
meta_window_get_toplevel_xwindow (window),
|
||||
meta_window_x11_get_toplevel_xwindow (window),
|
||||
TRUE);
|
||||
|
||||
window->keys_grabbed = TRUE;
|
||||
@@ -1434,7 +1438,7 @@ meta_window_grab_all_keys (MetaWindow *window,
|
||||
window->desc);
|
||||
meta_window_focus (window, timestamp);
|
||||
|
||||
grabwindow = meta_window_get_toplevel_xwindow (window);
|
||||
grabwindow = meta_window_x11_get_toplevel_xwindow (window);
|
||||
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Grabbing all keys on window %s\n", window->desc);
|
||||
@@ -1906,12 +1910,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;
|
||||
@@ -1927,6 +1931,7 @@ process_keyboard_move_grab (MetaDisplay *display,
|
||||
ClutterKeyEvent *event)
|
||||
{
|
||||
gboolean handled;
|
||||
MetaRectangle frame_rect;
|
||||
int x, y;
|
||||
int incr;
|
||||
gboolean smart_snap;
|
||||
@@ -1941,7 +1946,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;
|
||||
|
||||
@@ -1965,12 +1972,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
|
||||
@@ -2016,23 +2023,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);
|
||||
}
|
||||
|
||||
@@ -2166,6 +2168,7 @@ process_keyboard_resize_grab (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
ClutterKeyEvent *event)
|
||||
{
|
||||
MetaRectangle frame_rect;
|
||||
gboolean handled;
|
||||
int height_inc;
|
||||
int width_inc;
|
||||
@@ -2186,12 +2189,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;
|
||||
}
|
||||
@@ -2202,6 +2205,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;
|
||||
@@ -2359,18 +2366,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,
|
||||
@@ -2378,15 +2380,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);
|
||||
}
|
||||
@@ -3172,6 +3170,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,
|
||||
@@ -3189,11 +3188,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.
|
||||
*
|
||||
@@ -3481,7 +3481,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",
|
||||
@@ -3532,6 +3534,7 @@ init_builtin_key_bindings (MetaDisplay *display)
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 7);
|
||||
}
|
||||
#endif /* HAVE_NATIVE_BACKEND */
|
||||
|
||||
#undef REVERSES_AND_REVERSED
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
113
src/core/place.c
113
src/core/place.c
@@ -515,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;
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, windows))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
|
||||
retval = TRUE;
|
||||
retval = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* try below each window */
|
||||
tmp = below_sorted;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle frame_rect;
|
||||
/* try below each window */
|
||||
tmp = below_sorted;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle frame_rect;
|
||||
|
||||
meta_window_get_frame_rect (w, &frame_rect);
|
||||
meta_window_get_frame_rect (w, &frame_rect);
|
||||
|
||||
rect.x = frame_rect.x;
|
||||
rect.y = frame_rect.y + frame_rect.height;
|
||||
rect.x = frame_rect.x;
|
||||
rect.y = frame_rect.y + frame_rect.height;
|
||||
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, below_sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, below_sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
|
||||
retval = TRUE;
|
||||
retval = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
/* try to the right of each window */
|
||||
tmp = right_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);
|
||||
meta_window_get_frame_rect (w, &frame_rect);
|
||||
|
||||
rect.x = frame_rect.x + frame_rect.width;
|
||||
rect.y = frame_rect.y;
|
||||
rect.x = frame_rect.x + frame_rect.width;
|
||||
rect.y = frame_rect.y;
|
||||
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, right_sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
if (meta_rectangle_contains_rect (&work_area, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, right_sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
|
||||
retval = TRUE;
|
||||
retval = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
g_list_free (below_sorted);
|
||||
g_list_free (right_sorted);
|
||||
return retval;
|
||||
|
@@ -180,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
|
||||
@@ -192,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.
|
||||
*/
|
||||
@@ -1234,6 +1234,7 @@ xsettings_overrides_changed (GSettings *settings,
|
||||
GVariant *value;
|
||||
GVariantDict overrides;
|
||||
int shell_shows_app_menu = 1;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
if (!g_settings_get_boolean (settings, "active"))
|
||||
goto out;
|
||||
@@ -1247,8 +1248,13 @@ xsettings_overrides_changed (GSettings *settings,
|
||||
"Gtk/ShellShowsAppMenu", "i", &shell_shows_app_menu);
|
||||
g_variant_dict_clear (&overrides);
|
||||
|
||||
changed = (show_fallback_app_menu == !!shell_shows_app_menu);
|
||||
|
||||
out:
|
||||
show_fallback_app_menu = !shell_shows_app_menu;
|
||||
|
||||
if (changed)
|
||||
queue_changed (META_PREF_BUTTON_LAYOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -135,6 +135,7 @@ MetaScreen* meta_screen_new (MetaDisplay *displ
|
||||
guint32 timestamp);
|
||||
void meta_screen_free (MetaScreen *screen,
|
||||
guint32 timestamp);
|
||||
void meta_screen_init_workspaces (MetaScreen *screen);
|
||||
void meta_screen_manage_all_windows (MetaScreen *screen);
|
||||
void meta_screen_foreach_window (MetaScreen *screen,
|
||||
MetaScreenWindowFunc func,
|
||||
|
@@ -506,7 +506,6 @@ meta_screen_new (MetaDisplay *display,
|
||||
Atom wm_sn_atom;
|
||||
char buf[128];
|
||||
guint32 manager_timestamp;
|
||||
gulong current_workspace;
|
||||
MetaMonitorManager *manager;
|
||||
|
||||
replace_current_wm = meta_get_replace_current_wm ();
|
||||
@@ -721,24 +720,10 @@ meta_screen_new (MetaDisplay *display,
|
||||
|
||||
meta_screen_update_workspace_layout (screen);
|
||||
|
||||
/* Get current workspace */
|
||||
current_workspace = 0;
|
||||
if (meta_prop_get_cardinal (screen->display,
|
||||
screen->xroot,
|
||||
screen->display->atom__NET_CURRENT_DESKTOP,
|
||||
¤t_workspace))
|
||||
meta_verbose ("Read existing _NET_CURRENT_DESKTOP = %d\n",
|
||||
(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);
|
||||
meta_workspace_new (screen);
|
||||
|
||||
screen->keys_grabbed = FALSE;
|
||||
meta_screen_grab_keys (screen);
|
||||
@@ -764,23 +749,46 @@ meta_screen_new (MetaDisplay *display,
|
||||
screen->startup_sequence_timeout = 0;
|
||||
#endif
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
meta_verbose ("Added screen %d ('%s') root 0x%lx\n",
|
||||
screen->number, screen->screen_name, screen->xroot);
|
||||
|
||||
return screen;
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_init_workspaces (MetaScreen *screen)
|
||||
{
|
||||
MetaWorkspace *current_workspace;
|
||||
gulong current_workspace_index = 0;
|
||||
guint32 timestamp;
|
||||
|
||||
g_return_if_fail (META_IS_SCREEN (screen));
|
||||
|
||||
timestamp = screen->wm_sn_timestamp;
|
||||
|
||||
/* Get current workspace */
|
||||
if (meta_prop_get_cardinal (screen->display,
|
||||
screen->xroot,
|
||||
screen->display->atom__NET_CURRENT_DESKTOP,
|
||||
¤t_workspace_index))
|
||||
meta_verbose ("Read existing _NET_CURRENT_DESKTOP = %d\n",
|
||||
(int) current_workspace_index);
|
||||
else
|
||||
meta_verbose ("No _NET_CURRENT_DESKTOP present\n");
|
||||
|
||||
meta_workspace_activate (screen->workspaces->data, timestamp);
|
||||
update_num_workspaces (screen, timestamp);
|
||||
|
||||
set_workspace_names (screen);
|
||||
|
||||
/* Switch to the _NET_CURRENT_DESKTOP workspace */
|
||||
current_workspace = meta_screen_get_workspace_by_index (screen,
|
||||
current_workspace_index);
|
||||
|
||||
if (current_workspace != NULL)
|
||||
meta_workspace_activate (current_workspace, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_free (MetaScreen *screen,
|
||||
guint32 timestamp)
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include <stdio.h>
|
||||
#include <X11/Xutil.h> /* Just for the definition of the various gravities */
|
||||
#include <time.h> /* To initialize random seed */
|
||||
#include <math.h>
|
||||
|
||||
#define NUM_RANDOM_RUNS 10000
|
||||
|
||||
@@ -238,7 +239,7 @@ static GSList*
|
||||
get_strut_list (int which)
|
||||
{
|
||||
GSList *ans;
|
||||
MetaDirection wc = 0; /* wc == who cares? ;-) */
|
||||
MetaSide wc = 0; /* wc == who cares? ;-) */
|
||||
|
||||
ans = NULL;
|
||||
|
||||
@@ -248,32 +249,32 @@ get_strut_list (int which)
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, wc));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 400, 1160, 1600, 40, wc));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, META_SIDE_TOP));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 400, 1160, 1600, 40, META_SIDE_BOTTOM));
|
||||
break;
|
||||
case 2:
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, wc));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 800, 1100, 400, 100, wc));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 300, 1150, 150, 50, wc));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, META_SIDE_TOP));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 800, 1100, 400, 100, META_SIDE_BOTTOM));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 300, 1150, 150, 50, META_SIDE_BOTTOM));
|
||||
break;
|
||||
case 3:
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, wc));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 800, 1100, 400, 100, wc));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 300, 1150, 80, 50, wc));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, META_SIDE_TOP));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 800, 1100, 400, 100, META_SIDE_LEFT));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 300, 1150, 80, 50, META_SIDE_BOTTOM));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 700, 525, 200, 150, wc));
|
||||
break;
|
||||
case 4:
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 800, 1200, wc));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 800, 0, 1600, 20, wc));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 800, 1200, META_SIDE_LEFT));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 800, 0, 1600, 20, META_SIDE_TOP));
|
||||
break;
|
||||
case 5:
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 800, 0, 1600, 20, wc));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 800, 1200, wc));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 800, 10, 800, 1200, wc));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 800, 0, 1600, 20, META_SIDE_TOP));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 800, 1200, META_SIDE_LEFT));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 800, 10, 800, 1200, META_SIDE_RIGHT));
|
||||
break;
|
||||
case 6:
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 40, wc));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, wc));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 40, META_SIDE_TOP));
|
||||
ans = g_slist_prepend (ans, new_meta_strut ( 0, 0, 1600, 20, META_SIDE_TOP));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -623,15 +624,9 @@ test_regions_okay ()
|
||||
/*************************************************************/
|
||||
region = get_screen_region (3);
|
||||
tmp = NULL;
|
||||
tmp = g_list_prepend (tmp, new_meta_rect ( 380, 675, 420, 525)); /* 220500 */
|
||||
tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 300, 1180)); /* 354000 */
|
||||
tmp = g_list_prepend (tmp, new_meta_rect ( 380, 20, 320, 1180)); /* 377600 */
|
||||
tmp = g_list_prepend (tmp, new_meta_rect ( 0, 675, 800, 475)); /* 380000 */
|
||||
tmp = g_list_prepend (tmp, new_meta_rect (1200, 20, 400, 1180)); /* 472000 */
|
||||
tmp = g_list_prepend (tmp, new_meta_rect ( 0, 675, 1600, 425)); /* 680000 */
|
||||
tmp = g_list_prepend (tmp, new_meta_rect ( 900, 20, 700, 1080)); /* 756000 */
|
||||
tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 700, 1130)); /* 791000 */
|
||||
tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 1600, 505)); /* 808000 */
|
||||
tmp = g_list_prepend (tmp, new_meta_rect ( 380, 20, 1220, 1180)); /* 377600 */
|
||||
tmp = g_list_prepend (tmp, new_meta_rect ( 0, 20, 1600, 1130)); /* 791000 */
|
||||
#if 0
|
||||
printf ("Got to here...\n");
|
||||
char region_list[(RECT_LENGTH+2) * g_list_length (region)];
|
||||
@@ -1332,6 +1327,7 @@ test_gravity_resize ()
|
||||
printf ("%s passed.\n", G_STRFUNC);
|
||||
}
|
||||
|
||||
#define EPSILON 0.000000001
|
||||
static void
|
||||
test_find_closest_point_to_line ()
|
||||
{
|
||||
@@ -1346,7 +1342,7 @@ test_find_closest_point_to_line ()
|
||||
x2, y2,
|
||||
px, py,
|
||||
&rx, &ry);
|
||||
g_assert (rx == answer_x && ry == answer_y);
|
||||
g_assert (fabs (rx - answer_x) < EPSILON && fabs (ry - answer_y) < EPSILON);
|
||||
|
||||
/* Special test for x1 == x2, so that slop of line is infinite */
|
||||
x1 = 3.0; y1 = 49.0;
|
||||
@@ -1357,7 +1353,7 @@ test_find_closest_point_to_line ()
|
||||
x2, y2,
|
||||
px, py,
|
||||
&rx, &ry);
|
||||
g_assert (rx == answer_x && ry == answer_y);
|
||||
g_assert (fabs (rx - answer_x) < EPSILON && fabs (ry - answer_y) < EPSILON);
|
||||
|
||||
/* Special test for y1 == y2, so perp line has slope of infinity */
|
||||
x1 = 3.14; y1 = 7.0;
|
||||
@@ -1368,7 +1364,7 @@ test_find_closest_point_to_line ()
|
||||
x2, y2,
|
||||
px, py,
|
||||
&rx, &ry);
|
||||
g_assert (rx == answer_x && ry == answer_y);
|
||||
g_assert (fabs (rx - answer_x) < EPSILON && fabs (ry - answer_y) < EPSILON);
|
||||
|
||||
/* Test when we the point we want to be closest to is actually on the line */
|
||||
x1 = 3.0; y1 = 49.0;
|
||||
@@ -1379,7 +1375,7 @@ test_find_closest_point_to_line ()
|
||||
x2, y2,
|
||||
px, py,
|
||||
&rx, &ry);
|
||||
g_assert (rx == answer_x && ry == answer_y);
|
||||
g_assert (fabs (rx - answer_x) < EPSILON && fabs (ry - answer_y) < EPSILON);
|
||||
|
||||
printf ("%s passed.\n", G_STRFUNC);
|
||||
}
|
||||
|
@@ -166,6 +166,7 @@ struct _MetaWindow
|
||||
* that to toggle between normal/tiled or maximized/tiled states. */
|
||||
guint saved_maximize : 1;
|
||||
int tile_monitor_number;
|
||||
int preferred_output_id;
|
||||
|
||||
/* Whether we're shaded */
|
||||
guint shaded : 1;
|
||||
@@ -357,7 +358,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 */
|
||||
@@ -403,32 +405,32 @@ struct _MetaWindow
|
||||
gboolean has_custom_frame_extents;
|
||||
GtkBorder custom_frame_extents;
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
/* 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. 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 geometry to restore when we unmaximize. */
|
||||
MetaRectangle saved_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). 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.
|
||||
* the panel moves again).
|
||||
*/
|
||||
MetaRectangle unconstrained_rect;
|
||||
|
||||
|
||||
/* The rectangle of the "server-side" geometry of the buffer,
|
||||
* in root coordinates.
|
||||
*
|
||||
* For X11 windows, this matches XGetGeometry of the toplevel.
|
||||
*
|
||||
* For Wayland windows, this matches the buffer size and where
|
||||
* the surface actor is positioned. */
|
||||
MetaRectangle buffer_rect;
|
||||
|
||||
/* Cached net_wm_icon_geometry */
|
||||
MetaRectangle icon_geometry;
|
||||
|
||||
@@ -539,23 +541,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_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);
|
||||
|
||||
@@ -564,17 +555,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
|
||||
@@ -605,6 +585,10 @@ void meta_window_show_menu (MetaWindow *window,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
void meta_window_show_menu_for_rect (MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
MetaRectangle *rect);
|
||||
|
||||
gboolean meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
||||
const ClutterEvent *event);
|
||||
|
||||
@@ -694,8 +678,6 @@ gboolean meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
void meta_window_set_surface_mapped (MetaWindow *window,
|
||||
gboolean surface_mapped);
|
||||
|
||||
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,
|
||||
@@ -708,7 +690,8 @@ void meta_window_activate_full (MetaWindow *window,
|
||||
|
||||
gboolean meta_window_is_client_decorated (MetaWindow *window);
|
||||
|
||||
void meta_window_update_monitor (MetaWindow *window);
|
||||
void meta_window_update_monitor (MetaWindow *window,
|
||||
gboolean user_op);
|
||||
|
||||
void meta_window_set_urgent (MetaWindow *window,
|
||||
gboolean urgent);
|
||||
@@ -721,11 +704,13 @@ void meta_window_update_resize (MetaWindow *window,
|
||||
void meta_window_move_resize_internal (MetaWindow *window,
|
||||
MetaMoveResizeFlags flags,
|
||||
int gravity,
|
||||
MetaRectangle client_rect);
|
||||
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);
|
||||
|
||||
gboolean meta_window_has_pointer (MetaWindow *window);
|
||||
|
||||
#endif
|
||||
|
@@ -965,6 +965,7 @@ _meta_window_shared_new (MetaDisplay *display,
|
||||
window->compositor_private = NULL;
|
||||
|
||||
window->monitor = meta_screen_get_monitor_for_window (window->screen, window);
|
||||
window->preferred_output_id = window->monitor->output_id;
|
||||
|
||||
window->tile_match = NULL;
|
||||
|
||||
@@ -1044,9 +1045,6 @@ _meta_window_shared_new (MetaDisplay *display,
|
||||
if (window->attached)
|
||||
meta_window_recalc_features (window);
|
||||
|
||||
if (window->decorated)
|
||||
meta_window_ensure_frame (window);
|
||||
|
||||
if (window->type == META_WINDOW_DESKTOP ||
|
||||
window->type == META_WINDOW_DOCK)
|
||||
{
|
||||
@@ -1278,6 +1276,12 @@ meta_window_unmanage (MetaWindow *window,
|
||||
g_list_free (attached_children);
|
||||
}
|
||||
|
||||
/* Make sure to only show window on all workspaces if requested, to
|
||||
* not confuse other window managers that may take over
|
||||
*/
|
||||
if (window->screen->closing && meta_prefs_get_workspaces_only_on_primary ())
|
||||
meta_window_update_on_all_workspaces (window);
|
||||
|
||||
if (window->fullscreen)
|
||||
{
|
||||
MetaGroup *group;
|
||||
@@ -1393,9 +1397,6 @@ meta_window_unmanage (MetaWindow *window,
|
||||
|
||||
META_WINDOW_GET_CLASS (window)->unmanage (window);
|
||||
|
||||
if (window->frame)
|
||||
meta_window_destroy_frame (window);
|
||||
|
||||
meta_prefs_remove_listener (prefs_changed_callback, window);
|
||||
meta_screen_queue_check_fullscreen (window->screen);
|
||||
|
||||
@@ -1411,6 +1412,7 @@ should_be_on_all_workspaces (MetaWindow *window)
|
||||
window->on_all_workspaces_requested ||
|
||||
window->override_redirect ||
|
||||
(meta_prefs_get_workspaces_only_on_primary () &&
|
||||
!window->unmanaging &&
|
||||
!meta_window_is_on_primary_monitor (window));
|
||||
}
|
||||
|
||||
@@ -2654,15 +2656,11 @@ meta_window_save_rect (MetaWindow *window)
|
||||
{
|
||||
window->saved_rect.x = window->rect.x;
|
||||
window->saved_rect.width = window->rect.width;
|
||||
if (window->frame)
|
||||
window->saved_rect.x += window->frame->rect.x;
|
||||
}
|
||||
if (!window->maximized_vertically)
|
||||
{
|
||||
window->saved_rect.y = window->rect.y;
|
||||
window->saved_rect.height = window->rect.height;
|
||||
if (window->frame)
|
||||
window->saved_rect.y += window->frame->rect.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3016,12 +3014,12 @@ unmaximize_window_before_freeing (MetaWindow *window)
|
||||
* Moreover, it will need to know the unmaximized geometry,
|
||||
* therefore move_resize the window to saved_rect here
|
||||
* before closing it. */
|
||||
meta_window_move_resize (window,
|
||||
FALSE,
|
||||
window->saved_rect.x,
|
||||
window->saved_rect.y,
|
||||
window->saved_rect.width,
|
||||
window->saved_rect.height);
|
||||
meta_window_move_resize_frame (window,
|
||||
FALSE,
|
||||
window->saved_rect.x,
|
||||
window->saved_rect.y,
|
||||
window->saved_rect.width,
|
||||
window->saved_rect.height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3078,7 +3076,7 @@ meta_window_unmaximize_internal (MetaWindow *window,
|
||||
/* Unmaximize to the saved_rect position in the direction(s)
|
||||
* being unmaximized.
|
||||
*/
|
||||
meta_window_get_client_root_coords (window, &target_rect);
|
||||
target_rect = old_rect;
|
||||
|
||||
/* Avoid unmaximizing to "almost maximized" size when the previous size
|
||||
* is greater then 80% of the work area use MAX_UNMAXIMIZED_WINDOW_AREA of the work area as upper limit
|
||||
@@ -3115,7 +3113,9 @@ meta_window_unmaximize_internal (MetaWindow *window,
|
||||
/* Window's size hints may have changed while maximized, making
|
||||
* saved_rect invalid. #329152
|
||||
*/
|
||||
meta_window_frame_rect_to_client_rect (window, &target_rect, &target_rect);
|
||||
ensure_size_hints_satisfied (&target_rect, &window->size_hints);
|
||||
meta_window_client_rect_to_frame_rect (window, &target_rect, &target_rect);
|
||||
|
||||
meta_window_move_resize_internal (window,
|
||||
META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION,
|
||||
@@ -3176,7 +3176,6 @@ meta_window_unmaximize_with_gravity (MetaWindow *window,
|
||||
{
|
||||
MetaRectangle desired_rect;
|
||||
|
||||
meta_window_get_position (window, &desired_rect.x, &desired_rect.y);
|
||||
desired_rect.width = new_width;
|
||||
desired_rect.height = new_height;
|
||||
|
||||
@@ -3293,12 +3292,12 @@ meta_window_unmake_fullscreen (MetaWindow *window)
|
||||
meta_window_recalc_features (window);
|
||||
set_net_wm_state (window);
|
||||
|
||||
meta_window_move_resize (window,
|
||||
FALSE,
|
||||
target_rect.x,
|
||||
target_rect.y,
|
||||
target_rect.width,
|
||||
target_rect.height);
|
||||
meta_window_move_resize_frame (window,
|
||||
FALSE,
|
||||
target_rect.x,
|
||||
target_rect.y,
|
||||
target_rect.width,
|
||||
target_rect.height);
|
||||
|
||||
meta_window_update_layer (window);
|
||||
|
||||
@@ -3532,7 +3531,7 @@ maybe_move_attached_dialog (MetaWindow *window,
|
||||
{
|
||||
if (meta_window_is_attached_dialog (window))
|
||||
/* It ignores x,y for such a dialog */
|
||||
meta_window_move (window, FALSE, 0, 0);
|
||||
meta_window_move_frame (window, FALSE, 0, 0);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -3551,40 +3550,51 @@ meta_window_get_monitor (MetaWindow *window)
|
||||
return window->monitor->number;
|
||||
}
|
||||
|
||||
static MetaMonitorInfo *
|
||||
find_monitor_by_id (MetaWindow *window,
|
||||
guint id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < window->screen->n_monitor_infos; i++)
|
||||
{
|
||||
MetaMonitorInfo *info = &window->screen->monitor_infos[i];
|
||||
|
||||
if (info->output_id != 0 && info->output_id == id)
|
||||
return info;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This is called when the monitor setup has changed. The window->monitor
|
||||
* reference is still "valid", but refer to the previous monitor setup */
|
||||
void
|
||||
meta_window_update_for_monitors_changed (MetaWindow *window)
|
||||
{
|
||||
const MetaMonitorInfo *old, *new;
|
||||
int i;
|
||||
|
||||
if (window->type == META_WINDOW_DESKTOP)
|
||||
return;
|
||||
|
||||
if (window->override_redirect)
|
||||
{
|
||||
meta_window_update_monitor (window);
|
||||
meta_window_update_monitor (window, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
old = window->monitor;
|
||||
|
||||
/* Start on primary */
|
||||
new = &window->screen->monitor_infos[window->screen->primary_monitor_index];
|
||||
/* Try the preferred output first */
|
||||
new = find_monitor_by_id (window, window->preferred_output_id);
|
||||
|
||||
/* But, if we can find the old output on a new monitor, use that */
|
||||
for (i = 0; i < window->screen->n_monitor_infos; i++)
|
||||
{
|
||||
MetaMonitorInfo *info = &window->screen->monitor_infos[i];
|
||||
/* Otherwise, try to find the old output on a new monitor */
|
||||
if (!new)
|
||||
new = find_monitor_by_id (window, old->output_id);
|
||||
|
||||
if (info->output_id != 0 &&
|
||||
info->output_id == old->output_id)
|
||||
{
|
||||
new = info;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Fall back to primary if everything else failed */
|
||||
if (!new)
|
||||
new = &window->screen->monitor_infos[window->screen->primary_monitor_index];
|
||||
|
||||
if (window->tile_mode != META_TILE_NONE)
|
||||
window->tile_monitor_number = new->number;
|
||||
@@ -3602,7 +3612,8 @@ meta_window_update_for_monitors_changed (MetaWindow *window)
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_update_monitor (MetaWindow *window)
|
||||
meta_window_update_monitor (MetaWindow *window,
|
||||
gboolean user_op)
|
||||
{
|
||||
const MetaMonitorInfo *old;
|
||||
|
||||
@@ -3612,22 +3623,17 @@ meta_window_update_monitor (MetaWindow *window)
|
||||
{
|
||||
meta_window_update_on_all_workspaces (window);
|
||||
|
||||
/* If workspaces only on primary and we moved back to primary, ensure that the
|
||||
* window is now in that workspace. We do this because while the window is on a
|
||||
* non-primary monitor it is always visible, so it would be very jarring if it
|
||||
* disappeared when it crossed the monitor border.
|
||||
/* If workspaces only on primary and we moved back to primary due to a user action,
|
||||
* ensure that the window is now in that workspace. We do this because while
|
||||
* the window is on a non-primary monitor it is always visible, so it would be
|
||||
* very jarring if it disappeared when it crossed the monitor border.
|
||||
* The one time we want it to both change to the primary monitor and a non-active
|
||||
* workspace is when dropping the window on some other workspace thumbnail directly.
|
||||
* That should be handled by explicitly moving the window before changing the
|
||||
* workspace
|
||||
* Don't do this if old == NULL, because thats what happens when starting up, and
|
||||
* we don't want to move all windows around from a previous WM instance. Nor do
|
||||
* we want it when moving from one primary monitor to another (can happen during
|
||||
* screen reconfiguration.
|
||||
* workspace.
|
||||
*/
|
||||
if (meta_prefs_get_workspaces_only_on_primary () &&
|
||||
if (meta_prefs_get_workspaces_only_on_primary () && user_op &&
|
||||
meta_window_is_on_primary_monitor (window) &&
|
||||
old != NULL && !old->is_primary &&
|
||||
window->screen->active_workspace != window->workspace)
|
||||
meta_window_change_workspace (window, window->screen->active_workspace);
|
||||
|
||||
@@ -3638,6 +3644,7 @@ meta_window_update_monitor (MetaWindow *window)
|
||||
/* If we're changing monitors, we need to update the has_maximize_func flag,
|
||||
* as the working area has changed. */
|
||||
meta_window_recalc_features (window);
|
||||
meta_window_queue (window, META_QUEUE_CALC_SHOWING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3645,14 +3652,29 @@ void
|
||||
meta_window_move_resize_internal (MetaWindow *window,
|
||||
MetaMoveResizeFlags flags,
|
||||
int gravity,
|
||||
MetaRectangle client_rect)
|
||||
MetaRectangle frame_rect)
|
||||
{
|
||||
/* The rectangle here that's passed in is always the root position
|
||||
* of the client window. For undecorated or client-decorated windows,
|
||||
* this is the root position of the X11 window. For server-decorated
|
||||
* windows, this is the root position of the client area of the window.
|
||||
/* The rectangle here that's passed in *always* in "frame rect"
|
||||
* coordinates. That means the position of the frame's visible bounds,
|
||||
* with x and y being absolute (root window) coordinates.
|
||||
*
|
||||
* For an X11 framed window, the client window's server rectangle is
|
||||
* inset from this rectangle by the frame's visible borders, and the
|
||||
* frame window's server rectangle is outset by the invisible borders.
|
||||
*
|
||||
* For an X11 unframed window, the rectangle here directly matches
|
||||
* the server's rectangle, since the visible and invisible borders
|
||||
* are both 0.
|
||||
*
|
||||
* For an X11 CSD window, the client window's server rectangle is
|
||||
* outset from this rectagle by the client-specified frame extents.
|
||||
*
|
||||
* For a Wayland window, this rectangle can simply be sent directly
|
||||
* to the client.
|
||||
*/
|
||||
|
||||
gboolean did_placement;
|
||||
guint old_output_id;
|
||||
MetaRectangle unconstrained_rect;
|
||||
MetaRectangle constrained_rect;
|
||||
MetaMoveResizeResultFlags result = 0;
|
||||
@@ -3674,18 +3696,15 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
* resizing the old rectangle with the given gravity. */
|
||||
if ((flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION)) == META_IS_RESIZE_ACTION)
|
||||
{
|
||||
MetaRectangle old_rect;
|
||||
|
||||
meta_window_get_client_root_coords (window, &old_rect);
|
||||
meta_rectangle_resize_with_gravity (&old_rect,
|
||||
meta_rectangle_resize_with_gravity (&window->rect,
|
||||
&unconstrained_rect,
|
||||
gravity,
|
||||
client_rect.width,
|
||||
client_rect.height);
|
||||
frame_rect.width,
|
||||
frame_rect.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
unconstrained_rect = client_rect;
|
||||
unconstrained_rect = frame_rect;
|
||||
}
|
||||
|
||||
/* If this is only a move, then ignore the passed in size and
|
||||
@@ -3706,15 +3725,21 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
MetaRectangle old_rect;
|
||||
meta_window_get_frame_rect (window, &old_rect);
|
||||
|
||||
meta_window_client_rect_to_frame_rect (window, &constrained_rect, &constrained_rect);
|
||||
|
||||
meta_window_constrain (window,
|
||||
flags,
|
||||
gravity,
|
||||
&old_rect,
|
||||
&constrained_rect);
|
||||
}
|
||||
|
||||
meta_window_frame_rect_to_client_rect (window, &constrained_rect, &constrained_rect);
|
||||
/* If we did placement, then we need to save the position that the window
|
||||
* was placed at to make sure that meta_window_move_resize_now places the
|
||||
* window correctly.
|
||||
*/
|
||||
if (did_placement)
|
||||
{
|
||||
window->unconstrained_rect.x = constrained_rect.x;
|
||||
window->unconstrained_rect.y = constrained_rect.y;
|
||||
}
|
||||
|
||||
/* Do the protocol-specific move/resize logic */
|
||||
@@ -3734,13 +3759,13 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
did_placement);
|
||||
}
|
||||
|
||||
meta_window_update_monitor (window);
|
||||
old_output_id = window->monitor->output_id;
|
||||
|
||||
/* Invariants leaving this function are:
|
||||
* a) window->rect and frame->rect reflect the actual
|
||||
* server-side size/pos of window->xwindow and frame->xwindow
|
||||
* b) all constraints are obeyed by window->rect and frame->rect
|
||||
*/
|
||||
meta_window_update_monitor (window, flags & META_IS_USER_ACTION);
|
||||
|
||||
if (old_output_id != window->monitor->output_id &&
|
||||
flags & META_IS_MOVE_ACTION && flags & META_IS_USER_ACTION)
|
||||
window->preferred_output_id = window->monitor->output_id;
|
||||
|
||||
if ((result & META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED) && window->frame_bounds)
|
||||
{
|
||||
@@ -3754,33 +3779,6 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
window->screen->active_workspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_move:
|
||||
* @window: a #MetaWindow
|
||||
* @user_op: bool to indicate whether or not this is a user operation
|
||||
* @root_x_nw: desired x pos
|
||||
* @root_y_nw: desired y pos
|
||||
*
|
||||
* Moves the window to the desired location on window's assigned workspace.
|
||||
* NOTE: does NOT place according to the origin of the enclosing
|
||||
* frame/window-decoration, but according to the origin of the window,
|
||||
* itself.
|
||||
*/
|
||||
void
|
||||
meta_window_move (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int root_x_nw,
|
||||
int root_y_nw)
|
||||
{
|
||||
MetaMoveResizeFlags flags;
|
||||
MetaRectangle rect = { root_x_nw, root_y_nw, 0, 0 };
|
||||
|
||||
g_return_if_fail (!window->override_redirect);
|
||||
|
||||
flags = (user_op ? META_IS_USER_ACTION : 0) | META_IS_MOVE_ACTION;
|
||||
meta_window_move_resize_internal (window, flags, NorthWestGravity, rect);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_move_frame:
|
||||
* @window: a #MetaWindow
|
||||
@@ -3799,10 +3797,13 @@ meta_window_move_frame (MetaWindow *window,
|
||||
int root_x_nw,
|
||||
int root_y_nw)
|
||||
{
|
||||
MetaMoveResizeFlags flags;
|
||||
MetaRectangle rect = { root_x_nw, root_y_nw, 0, 0 };
|
||||
|
||||
meta_window_frame_rect_to_client_rect (window, &rect, &rect);
|
||||
meta_window_move (window, user_op, rect.x, rect.y);
|
||||
g_return_if_fail (!window->override_redirect);
|
||||
|
||||
flags = (user_op ? META_IS_USER_ACTION : 0) | META_IS_MOVE_ACTION;
|
||||
meta_window_move_resize_internal (window, flags, NorthWestGravity, rect);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3846,10 +3847,14 @@ meta_window_move_resize_frame (MetaWindow *window,
|
||||
int w,
|
||||
int h)
|
||||
{
|
||||
MetaMoveResizeFlags flags;
|
||||
MetaRectangle rect = { root_x_nw, root_y_nw, w, h };
|
||||
meta_window_frame_rect_to_client_rect (window, &rect, &rect);
|
||||
|
||||
meta_window_move_resize (window, user_op, rect.x, rect.y, rect.width, rect.height);
|
||||
g_return_if_fail (!window->override_redirect);
|
||||
|
||||
flags = (user_op ? META_IS_USER_ACTION : 0) | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
||||
|
||||
meta_window_move_resize_internal (window, flags, NorthWestGravity, rect);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3880,41 +3885,18 @@ meta_window_move_to_monitor (MetaWindow *window,
|
||||
window->tile_monitor_number = monitor;
|
||||
|
||||
meta_window_move_between_rects (window, &old_area, &new_area);
|
||||
window->preferred_output_id = window->monitor->output_id;
|
||||
|
||||
if (window->fullscreen || window->override_redirect)
|
||||
meta_screen_queue_check_fullscreen (window->screen);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_move_resize (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int root_x_nw,
|
||||
int root_y_nw,
|
||||
int w,
|
||||
int h)
|
||||
{
|
||||
MetaMoveResizeFlags flags;
|
||||
MetaRectangle rect;
|
||||
|
||||
g_return_if_fail (!window->override_redirect);
|
||||
|
||||
flags = (user_op ? META_IS_USER_ACTION : 0) |
|
||||
META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
||||
|
||||
rect.x = root_x_nw;
|
||||
rect.y = root_y_nw;
|
||||
rect.width = w;
|
||||
rect.height = h;
|
||||
|
||||
meta_window_move_resize_internal (window, flags, NorthWestGravity, rect);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_resize_with_gravity (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int w,
|
||||
int h,
|
||||
int gravity)
|
||||
meta_window_resize_frame_with_gravity (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
int w,
|
||||
int h,
|
||||
int gravity)
|
||||
{
|
||||
MetaMoveResizeFlags flags;
|
||||
MetaRectangle rect;
|
||||
@@ -3929,11 +3911,11 @@ meta_window_resize_with_gravity (MetaWindow *window,
|
||||
static void
|
||||
meta_window_move_resize_now (MetaWindow *window)
|
||||
{
|
||||
meta_window_move_resize (window, FALSE,
|
||||
window->unconstrained_rect.x,
|
||||
window->unconstrained_rect.y,
|
||||
window->unconstrained_rect.width,
|
||||
window->unconstrained_rect.height);
|
||||
meta_window_move_resize_frame (window, FALSE,
|
||||
window->unconstrained_rect.x,
|
||||
window->unconstrained_rect.y,
|
||||
window->unconstrained_rect.width,
|
||||
window->unconstrained_rect.height);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -3976,36 +3958,6 @@ idle_move_resize (gpointer data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_get_position (MetaWindow *window,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
if (window->frame)
|
||||
{
|
||||
if (x)
|
||||
*x = window->frame->rect.x + window->frame->child_x;
|
||||
if (y)
|
||||
*y = window->frame->rect.y + window->frame->child_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x)
|
||||
*x = window->rect.x;
|
||||
if (y)
|
||||
*y = window->rect.y;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_get_client_root_coords (MetaWindow *window,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
meta_window_get_position (window, &rect->x, &rect->y);
|
||||
rect->width = window->rect.width;
|
||||
rect->height = window->rect.height;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_get_gravity_position (MetaWindow *window,
|
||||
int gravity,
|
||||
@@ -4108,23 +4060,23 @@ meta_window_get_session_geometry (MetaWindow *window,
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_get_input_rect:
|
||||
* meta_window_get_buffer_rect:
|
||||
* @window: a #MetaWindow
|
||||
* @rect: (out): pointer to an allocated #MetaRectangle
|
||||
*
|
||||
* Gets the rectangle that bounds @window that is responsive to mouse events.
|
||||
* This includes decorations - the visible portion of its border - and (if
|
||||
* present) any invisible area that we make make responsive to mouse clicks in
|
||||
* order to allow convenient border dragging.
|
||||
* Gets the rectangle that the pixmap or buffer of @window occupies.
|
||||
*
|
||||
* For X11 windows, this is the server-side geometry of the toplevel
|
||||
* window.
|
||||
*
|
||||
* For Wayland windows, this is the bounding rectangle of the attached
|
||||
* buffer.
|
||||
*/
|
||||
void
|
||||
meta_window_get_input_rect (const MetaWindow *window,
|
||||
MetaRectangle *rect)
|
||||
meta_window_get_buffer_rect (const MetaWindow *window,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
if (window->frame)
|
||||
*rect = window->frame->rect;
|
||||
else
|
||||
*rect = window->rect;
|
||||
*rect = window->buffer_rect;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4234,30 +4186,7 @@ void
|
||||
meta_window_get_frame_rect (const MetaWindow *window,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
if (window->frame)
|
||||
{
|
||||
MetaFrameBorders borders;
|
||||
*rect = window->frame->rect;
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
|
||||
rect->x += borders.invisible.left;
|
||||
rect->y += borders.invisible.top;
|
||||
rect->width -= borders.invisible.left + borders.invisible.right;
|
||||
rect->height -= borders.invisible.top + borders.invisible.bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
*rect = window->rect;
|
||||
|
||||
if (window->has_custom_frame_extents)
|
||||
{
|
||||
const GtkBorder *extents = &window->custom_frame_extents;
|
||||
rect->x += extents->left;
|
||||
rect->y += extents->top;
|
||||
rect->width -= extents->left + extents->right;
|
||||
rect->height -= extents->top + extents->bottom;
|
||||
}
|
||||
}
|
||||
*rect = window->rect;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4292,22 +4221,18 @@ void
|
||||
meta_window_get_client_area_rect (const MetaWindow *window,
|
||||
cairo_rectangle_int_t *rect)
|
||||
{
|
||||
if (window->frame)
|
||||
{
|
||||
rect->x = window->frame->child_x;
|
||||
rect->y = window->frame->child_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect->x = 0;
|
||||
rect->y = 0;
|
||||
}
|
||||
MetaFrameBorders borders;
|
||||
|
||||
rect->width = window->rect.width;
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
|
||||
rect->x = borders.total.left;
|
||||
rect->y = borders.total.top;
|
||||
|
||||
rect->width = window->rect.width - borders.visible.left - borders.visible.right;
|
||||
if (window->shaded)
|
||||
rect->height = 0;
|
||||
else
|
||||
rect->height = window->rect.height;
|
||||
rect->height = window->rect.height - borders.visible.top - borders.visible.bottom;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4895,7 +4820,7 @@ meta_window_get_icon_geometry (MetaWindow *window,
|
||||
/**
|
||||
* meta_window_set_icon_geometry:
|
||||
* @window: a #MetaWindow
|
||||
* @rect: (allow-none): rectangle with the desired geometry or %NULL.
|
||||
* @rect: (nullable): rectangle with the desired geometry or %NULL.
|
||||
*
|
||||
* Sets or unsets the location of the icon corresponding to the window. If
|
||||
* set, the location should correspond to a dock, task bar or other user
|
||||
@@ -5347,6 +5272,15 @@ meta_window_show_menu (MetaWindow *window,
|
||||
meta_compositor_show_window_menu (window->display->compositor, window, menu, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_show_menu_for_rect (MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
g_return_if_fail (!window->override_redirect);
|
||||
meta_compositor_show_window_menu_for_rect (window->display->compositor, window, menu, rect);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_shove_titlebar_onscreen (MetaWindow *window)
|
||||
{
|
||||
@@ -5694,7 +5628,7 @@ update_move (MetaWindow *window,
|
||||
meta_screen_update_tile_preview (window->screen,
|
||||
window->tile_mode != META_TILE_NONE);
|
||||
|
||||
meta_window_get_client_root_coords (window, &old);
|
||||
meta_window_get_frame_rect (window, &old);
|
||||
|
||||
/* Don't allow movement in the maximized directions or while tiled */
|
||||
if (window->maximized_horizontally || META_WINDOW_TILED_SIDE_BY_SIDE (window))
|
||||
@@ -5704,15 +5638,13 @@ update_move (MetaWindow *window,
|
||||
|
||||
/* Do any edge resistance/snapping */
|
||||
meta_window_edge_resistance_for_move (window,
|
||||
old.x,
|
||||
old.y,
|
||||
&new_x,
|
||||
&new_y,
|
||||
update_move_timeout,
|
||||
snap,
|
||||
FALSE);
|
||||
|
||||
meta_window_move (window, TRUE, new_x, new_y);
|
||||
meta_window_move_frame (window, TRUE, new_x, new_y);
|
||||
}
|
||||
|
||||
/* When resizing a maximized window by using alt-middle-drag (resizing
|
||||
@@ -5998,7 +5930,7 @@ update_resize (MetaWindow *window,
|
||||
window->display->grab_resize_timeout_id = 0;
|
||||
}
|
||||
|
||||
old = window->rect; /* Don't actually care about x,y */
|
||||
meta_window_get_frame_rect (window, &old);
|
||||
|
||||
/* One sided resizing ought to actually be one-sided, despite the fact that
|
||||
* aspect ratio windows don't interact nicely with the above stuff. So,
|
||||
@@ -6026,8 +5958,6 @@ update_resize (MetaWindow *window,
|
||||
|
||||
/* Do any edge resistance/snapping */
|
||||
meta_window_edge_resistance_for_resize (window,
|
||||
old.width,
|
||||
old.height,
|
||||
&new_w,
|
||||
&new_h,
|
||||
gravity,
|
||||
@@ -6037,13 +5967,7 @@ update_resize (MetaWindow *window,
|
||||
|
||||
if (new_unmaximize == window->display->grab_resize_unmaximize)
|
||||
{
|
||||
/* We don't need to update unless the specified width and height
|
||||
* are actually different from what we had before.
|
||||
*/
|
||||
if (old.width != new_w || old.height != new_h)
|
||||
{
|
||||
meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
|
||||
}
|
||||
meta_window_resize_frame_with_gravity (window, TRUE, new_w, new_h, gravity);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -6582,8 +6506,8 @@ warp_grab_pointer (MetaWindow *window,
|
||||
display->grab_anchor_root_y = *y;
|
||||
display->grab_latest_motion_x = *x;
|
||||
display->grab_latest_motion_y = *y;
|
||||
meta_window_get_client_root_coords (window,
|
||||
&display->grab_anchor_window_pos);
|
||||
meta_window_get_frame_rect (window,
|
||||
&display->grab_anchor_window_pos);
|
||||
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
@@ -7396,7 +7320,7 @@ meta_window_get_frame_type (MetaWindow *window)
|
||||
*
|
||||
* Gets a region representing the outer bounds of the window's frame.
|
||||
*
|
||||
* Return value: (transfer none) (allow-none): a #cairo_region_t
|
||||
* Return value: (transfer none) (nullable): a #cairo_region_t
|
||||
* holding the outer bounds of the window, or %NULL if the window
|
||||
* doesn't have a frame.
|
||||
*/
|
||||
@@ -7441,7 +7365,7 @@ meta_window_is_attached_dialog (MetaWindow *window)
|
||||
* - there is no 3rd window stacked between both tiled windows that's
|
||||
* partially visible in the common edge.
|
||||
*
|
||||
* Return value: (transfer none) (allow-none): the matching tiled window or
|
||||
* Return value: (transfer none) (nullable): the matching tiled window or
|
||||
* %NULL if it doesn't exist.
|
||||
*/
|
||||
MetaWindow *
|
||||
@@ -7760,8 +7684,8 @@ window_has_pointer_x11 (MetaWindow *window)
|
||||
return meta_display_lookup_x_window (display, child) == window;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
window_has_pointer (MetaWindow *window)
|
||||
gboolean
|
||||
meta_window_has_pointer (MetaWindow *window)
|
||||
{
|
||||
if (meta_is_wayland_compositor ())
|
||||
return window_has_pointer_wayland (window);
|
||||
@@ -7790,10 +7714,10 @@ window_focus_on_pointer_rest_callback (gpointer data)
|
||||
{
|
||||
focus_data->pointer_x = root_x;
|
||||
focus_data->pointer_y = root_y;
|
||||
return TRUE;
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
if (!window_has_pointer (window))
|
||||
if (!meta_window_has_pointer (window))
|
||||
goto out;
|
||||
|
||||
timestamp = meta_display_get_current_time_roundtrip (display);
|
||||
@@ -7801,7 +7725,7 @@ window_focus_on_pointer_rest_callback (gpointer data)
|
||||
|
||||
out:
|
||||
display->focus_timeout_id = 0;
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
/* The interval, in milliseconds, we use in focus-follows-mouse
|
||||
@@ -7890,6 +7814,15 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
if (display->grab_op != META_GRAB_OP_NONE)
|
||||
return FALSE;
|
||||
|
||||
/* Some windows might not ask for input, in which case we might be here
|
||||
* because we selected for ButtonPress on the root window. In that case,
|
||||
* we have to take special care not to act for an override-redirect window.
|
||||
*
|
||||
* Consume the event in this case, though, since we don't want it passed
|
||||
* to the compositor or UI. */
|
||||
if (window->override_redirect)
|
||||
return TRUE;
|
||||
|
||||
/* 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
|
||||
@@ -8038,12 +7971,6 @@ meta_window_set_surface_mapped (MetaWindow *window,
|
||||
meta_window_queue (window, META_QUEUE_CALC_SHOWING);
|
||||
}
|
||||
|
||||
Window
|
||||
meta_window_get_toplevel_xwindow (MetaWindow *window)
|
||||
{
|
||||
return window->frame ? window->frame->xwindow : window->xwindow;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_set_custom_frame_extents (MetaWindow *window,
|
||||
GtkBorder *extents)
|
||||
|
@@ -1040,6 +1040,45 @@ void
|
||||
meta_workspace_set_builtin_struts (MetaWorkspace *workspace,
|
||||
GSList *struts)
|
||||
{
|
||||
MetaScreen *screen = workspace->screen;
|
||||
GSList *l;
|
||||
|
||||
for (l = struts; l; l = l->next)
|
||||
{
|
||||
MetaStrut *strut = l->data;
|
||||
int idx = meta_screen_get_monitor_index_for_rect (screen, &strut->rect);
|
||||
|
||||
switch (strut->side)
|
||||
{
|
||||
case META_SIDE_TOP:
|
||||
if (meta_screen_get_monitor_neighbor (screen, idx, META_SCREEN_UP))
|
||||
continue;
|
||||
|
||||
strut->rect.height += strut->rect.y;
|
||||
strut->rect.y = 0;
|
||||
break;
|
||||
case META_SIDE_BOTTOM:
|
||||
if (meta_screen_get_monitor_neighbor (screen, idx, META_SCREEN_DOWN))
|
||||
continue;
|
||||
|
||||
strut->rect.height = screen->rect.height - strut->rect.y;
|
||||
break;
|
||||
case META_SIDE_LEFT:
|
||||
if (meta_screen_get_monitor_neighbor (screen, idx, META_SCREEN_LEFT))
|
||||
continue;
|
||||
|
||||
strut->rect.width += strut->rect.x;
|
||||
strut->rect.x = 0;
|
||||
break;
|
||||
case META_SIDE_RIGHT:
|
||||
if (meta_screen_get_monitor_neighbor (screen, idx, META_SCREEN_RIGHT))
|
||||
continue;
|
||||
|
||||
strut->rect.width = screen->rect.width - strut->rect.x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reordering doesn't actually matter, so we don't catch all
|
||||
* no-impact changes, but this is just a (possibly unnecessary
|
||||
* anyways) optimization */
|
||||
|
@@ -5,14 +5,9 @@ includedir=@includedir@
|
||||
girdir=@libdir@/mutter
|
||||
typelibdir=@libdir@/mutter
|
||||
|
||||
mutter_major_version=@MUTTER_MAJOR_VERSION@
|
||||
mutter_minor_version=@MUTTER_MINOR_VERSION@
|
||||
mutter_micro_version=@MUTTER_MICRO_VERSION@
|
||||
mutter_plugin_api_version=@MUTTER_PLUGIN_API_VERSION@
|
||||
|
||||
Name: libmutter
|
||||
Description: Mutter window manager library
|
||||
Requires: gsettings-desktop-schemas gtk+-3.0 @CLUTTER_PACKAGE@ x11
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lmutter
|
||||
Cflags: -I${includedir}/mutter -DMUTTER_MAJOR_VERSION=${mutter_major_version} -DMUTTER_MINOR_VERSION=${mutter_minor_version} -DMUTTER_MICRO_VERSION=${mutter_micro_version} -DMUTTER_PLUGIN_API_VERSION=${mutter_plugin_api_version}
|
||||
Cflags: -I${includedir}/mutter
|
||||
|
@@ -43,8 +43,6 @@
|
||||
#define META_VIRTUAL_CORE_POINTER_ID 2
|
||||
#define META_VIRTUAL_CORE_KEYBOARD_ID 3
|
||||
|
||||
typedef struct _MetaResizePopup MetaResizePopup;
|
||||
|
||||
/**
|
||||
* MetaFrameFlags:
|
||||
* @META_FRAME_ALLOWS_DELETE: frame allows delete
|
||||
|
@@ -101,9 +101,8 @@ void meta_compositor_unmaximize_window (MetaCompositor *compositor,
|
||||
void meta_compositor_sync_window_geometry (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
gboolean did_placement);
|
||||
void meta_compositor_set_updates_frozen (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
gboolean updates_frozen);
|
||||
void meta_compositor_sync_updates_frozen (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
void meta_compositor_queue_frame_drawn (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
gboolean no_delay_frame);
|
||||
@@ -127,5 +126,9 @@ void meta_compositor_show_window_menu (MetaCompositor *compositor,
|
||||
MetaWindowMenuType menu,
|
||||
int x,
|
||||
int y);
|
||||
void meta_compositor_show_window_menu_for_rect (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
MetaRectangle *rect);
|
||||
|
||||
#endif /* META_COMPOSITOR_H */
|
||||
|
@@ -94,7 +94,6 @@ guint32 meta_display_get_current_time_roundtrip (MetaDisplay *display);
|
||||
|
||||
GList* meta_display_get_tab_list (MetaDisplay *display,
|
||||
MetaTabList type,
|
||||
MetaScreen *screen,
|
||||
MetaWorkspace *workspace);
|
||||
|
||||
MetaWindow* meta_display_get_tab_next (MetaDisplay *display,
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include <meta/types.h>
|
||||
#include <meta/compositor.h>
|
||||
#include <meta/compositor-mutter.h>
|
||||
#include <meta/meta-version.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
@@ -170,6 +171,11 @@ struct _MetaPluginClass
|
||||
int x,
|
||||
int y);
|
||||
|
||||
void (*show_window_menu_for_rect) (MetaPlugin *plugin,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
MetaRectangle *rect);
|
||||
|
||||
/**
|
||||
* MetaPluginClass::kill_window_effects:
|
||||
* @actor: a #MetaWindowActor
|
||||
@@ -294,10 +300,10 @@ struct _MetaPluginVersion
|
||||
#define META_PLUGIN_DECLARE(ObjectName, object_name) \
|
||||
G_MODULE_EXPORT MetaPluginVersion meta_plugin_version = \
|
||||
{ \
|
||||
MUTTER_MAJOR_VERSION, \
|
||||
MUTTER_MINOR_VERSION, \
|
||||
MUTTER_MICRO_VERSION, \
|
||||
MUTTER_PLUGIN_API_VERSION \
|
||||
META_MAJOR_VERSION, \
|
||||
META_MINOR_VERSION, \
|
||||
META_MICRO_VERSION, \
|
||||
META_PLUGIN_API_VERSION \
|
||||
}; \
|
||||
\
|
||||
static GType g_define_type_id = 0; \
|
||||
|
28
src/meta/meta-version.h.in
Normal file
28
src/meta/meta-version.h.in
Normal file
@@ -0,0 +1,28 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Rico Tzschichholz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef META_VERSION_H
|
||||
#define META_VERSION_H
|
||||
|
||||
#define META_MAJOR_VERSION @MUTTER_MAJOR_VERSION@
|
||||
#define META_MINOR_VERSION @MUTTER_MINOR_VERSION@
|
||||
#define META_MICRO_VERSION @MUTTER_MICRO_VERSION@
|
||||
#define META_PLUGIN_API_VERSION @MUTTER_PLUGIN_API_VERSION@
|
||||
|
||||
#endif
|
@@ -108,7 +108,7 @@ gboolean meta_window_appears_focused (MetaWindow *window);
|
||||
gboolean meta_window_is_shaded (MetaWindow *window);
|
||||
gboolean meta_window_is_override_redirect (MetaWindow *window);
|
||||
gboolean meta_window_is_skip_taskbar (MetaWindow *window);
|
||||
void meta_window_get_input_rect (const MetaWindow *window, MetaRectangle *rect);
|
||||
void meta_window_get_buffer_rect (const MetaWindow *window, MetaRectangle *rect);
|
||||
|
||||
void meta_window_get_frame_rect (const MetaWindow *window, MetaRectangle *rect);
|
||||
void meta_window_get_outer_rect (const MetaWindow *window, MetaRectangle *rect) G_GNUC_DEPRECATED;
|
||||
@@ -147,7 +147,6 @@ const char * meta_window_get_gtk_window_object_path (MetaWindow *window);
|
||||
const char * meta_window_get_gtk_app_menu_object_path (MetaWindow *window);
|
||||
const char * meta_window_get_gtk_menubar_object_path (MetaWindow *window);
|
||||
|
||||
void meta_window_move(MetaWindow *window, gboolean user_op, int root_x_nw, int root_y_nw);
|
||||
void meta_window_move_frame(MetaWindow *window, gboolean user_op, int root_x_nw, int root_y_nw);
|
||||
void meta_window_move_resize_frame (MetaWindow *window, gboolean user_op, int root_x_nw, int root_y_nw, int w, int h);
|
||||
void meta_window_move_to_monitor (MetaWindow *window, int monitor);
|
||||
|
221
src/ui/frames.c
221
src/ui/frames.c
@@ -224,8 +224,6 @@ meta_frames_init (MetaFrames *frames)
|
||||
|
||||
update_style_contexts (frames);
|
||||
|
||||
gtk_widget_set_double_buffered (GTK_WIDGET (frames), FALSE);
|
||||
|
||||
meta_prefs_add_listener (prefs_changed_callback, frames);
|
||||
}
|
||||
|
||||
@@ -1138,6 +1136,64 @@ meta_frame_right_click_event(MetaUIFrame *frame,
|
||||
return meta_frame_titlebar_event (frame, event, action);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_frames_try_grab_op (MetaFrames *frames,
|
||||
MetaUIFrame *frame,
|
||||
MetaGrabOp op,
|
||||
gdouble grab_x,
|
||||
gdouble grab_y,
|
||||
guint32 time)
|
||||
{
|
||||
Display *display;
|
||||
gboolean ret;
|
||||
|
||||
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
ret = meta_core_begin_grab_op (display,
|
||||
frame->xwindow,
|
||||
op,
|
||||
FALSE,
|
||||
TRUE,
|
||||
frame->grab_button,
|
||||
0,
|
||||
time,
|
||||
grab_x, grab_y);
|
||||
if (!ret)
|
||||
{
|
||||
frames->current_grab_op = op;
|
||||
frames->grab_frame = frame;
|
||||
frames->grab_x = grab_x;
|
||||
frames->grab_y = grab_y;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_frames_retry_grab_op (MetaFrames *frames,
|
||||
guint time)
|
||||
{
|
||||
Display *display;
|
||||
MetaGrabOp op;
|
||||
|
||||
if (frames->current_grab_op == META_GRAB_OP_NONE)
|
||||
return TRUE;
|
||||
|
||||
op = frames->current_grab_op;
|
||||
frames->current_grab_op = META_GRAB_OP_NONE;
|
||||
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
|
||||
return meta_core_begin_grab_op (display,
|
||||
frames->grab_frame->xwindow,
|
||||
op,
|
||||
FALSE,
|
||||
TRUE,
|
||||
frames->grab_frame->grab_button,
|
||||
0,
|
||||
time,
|
||||
frames->grab_x,
|
||||
frames->grab_y);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_frames_button_press_event (GtkWidget *widget,
|
||||
GdkEventButton *event)
|
||||
@@ -1192,6 +1248,8 @@ meta_frames_button_press_event (GtkWidget *widget,
|
||||
if (meta_core_get_grab_op (display) != META_GRAB_OP_NONE)
|
||||
return FALSE; /* already up to something */
|
||||
|
||||
frame->grab_button = event->button;
|
||||
|
||||
if (event->button == 1 &&
|
||||
(control == META_FRAME_CONTROL_MAXIMIZE ||
|
||||
control == META_FRAME_CONTROL_UNMAXIMIZE ||
|
||||
@@ -1218,30 +1276,36 @@ meta_frames_button_press_event (GtkWidget *widget,
|
||||
{
|
||||
MetaFrameGeometry fgeom;
|
||||
GdkRectangle *rect;
|
||||
MetaRectangle root_rect;
|
||||
MetaWindowMenuType menu;
|
||||
int dx, dy;
|
||||
int win_x, win_y;
|
||||
|
||||
meta_frames_calc_geometry (frames, frame, &fgeom);
|
||||
|
||||
rect = control_rect (control, &fgeom);
|
||||
|
||||
/* get delta to convert to root coords */
|
||||
dx = event->x_root - event->x;
|
||||
dy = event->y_root - event->y;
|
||||
/* convert to root coords */
|
||||
win_x = event->x_root - event->x;
|
||||
win_y = event->y_root - event->y;
|
||||
|
||||
/* Align to the right end of the menu rectangle if RTL */
|
||||
if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
|
||||
dx += rect->width;
|
||||
root_rect.x = win_x + rect->x;
|
||||
root_rect.y = win_y + rect->y;
|
||||
root_rect.width = rect->width;
|
||||
root_rect.height = rect->height;
|
||||
|
||||
menu = control == META_FRAME_CONTROL_MENU ? META_WINDOW_MENU_WM
|
||||
: META_WINDOW_MENU_APP;
|
||||
|
||||
meta_core_show_window_menu (display,
|
||||
frame->xwindow,
|
||||
menu,
|
||||
rect->x + dx,
|
||||
rect->y + rect->height + dy,
|
||||
event->time);
|
||||
/* if the compositor takes a grab for showing the menu, we will
|
||||
* get a LeaveNotify event we want to ignore, to keep the pressed
|
||||
* button state while the menu is open
|
||||
*/
|
||||
frame->maybe_ignore_leave_notify = TRUE;
|
||||
meta_core_show_window_menu_for_rect (display,
|
||||
frame->xwindow,
|
||||
menu,
|
||||
&root_rect,
|
||||
event->time);
|
||||
}
|
||||
}
|
||||
else if (event->button == 1 &&
|
||||
@@ -1289,16 +1353,9 @@ meta_frames_button_press_event (GtkWidget *widget,
|
||||
break;
|
||||
}
|
||||
|
||||
meta_core_begin_grab_op (display,
|
||||
frame->xwindow,
|
||||
op,
|
||||
TRUE,
|
||||
TRUE,
|
||||
event->button,
|
||||
0,
|
||||
event->time,
|
||||
event->x_root,
|
||||
event->y_root);
|
||||
meta_frames_try_grab_op (frames, frame, op,
|
||||
event->x_root, event->y_root,
|
||||
event->time);
|
||||
}
|
||||
else if (control == META_FRAME_CONTROL_TITLE &&
|
||||
event->button == 1)
|
||||
@@ -1311,16 +1368,10 @@ meta_frames_button_press_event (GtkWidget *widget,
|
||||
|
||||
if (flags & META_FRAME_ALLOWS_MOVE)
|
||||
{
|
||||
meta_core_begin_grab_op (display,
|
||||
frame->xwindow,
|
||||
meta_frames_try_grab_op (frames, frame,
|
||||
META_GRAB_OP_MOVING,
|
||||
TRUE,
|
||||
TRUE,
|
||||
event->button,
|
||||
0,
|
||||
event->time,
|
||||
event->x_root,
|
||||
event->y_root);
|
||||
event->x_root, event->y_root,
|
||||
event->time);
|
||||
}
|
||||
}
|
||||
else if (event->button == 2)
|
||||
@@ -1345,6 +1396,7 @@ meta_frames_button_release_event (GtkWidget *widget,
|
||||
|
||||
frames = META_FRAMES (widget);
|
||||
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
frames->current_grab_op = META_GRAB_OP_NONE;
|
||||
|
||||
frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
|
||||
if (frame == NULL)
|
||||
@@ -1506,7 +1558,8 @@ meta_frames_update_prelit_control (MetaFrames *frames,
|
||||
break;
|
||||
}
|
||||
|
||||
if (control == frame->prelit_control)
|
||||
if (control == frame->prelit_control &&
|
||||
frame->button_state == META_BUTTON_STATE_PRELIGHT)
|
||||
return;
|
||||
|
||||
/* Save the old control so we can unprelight it */
|
||||
@@ -1555,6 +1608,10 @@ meta_frames_motion_notify_event (GtkWidget *widget,
|
||||
meta_frames_update_prelit_control (frames, frame, control);
|
||||
}
|
||||
|
||||
if ((event->state & GDK_BUTTON1_MASK) &&
|
||||
frames->current_grab_op != META_GRAB_OP_NONE)
|
||||
meta_frames_retry_grab_op (frames, event->time);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1575,47 +1632,23 @@ meta_frames_destroy_event (GtkWidget *widget,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
setup_bg_cr (cairo_t *cr, GdkWindow *window, int x_offset, int y_offset)
|
||||
{
|
||||
GdkWindow *parent = gdk_window_get_parent (window);
|
||||
cairo_pattern_t *bg_pattern;
|
||||
|
||||
bg_pattern = gdk_window_get_background_pattern (window);
|
||||
if (bg_pattern == NULL && parent)
|
||||
{
|
||||
gint window_x, window_y;
|
||||
|
||||
gdk_window_get_position (window, &window_x, &window_y);
|
||||
setup_bg_cr (cr, parent, x_offset + window_x, y_offset + window_y);
|
||||
}
|
||||
else if (bg_pattern)
|
||||
{
|
||||
cairo_translate (cr, - x_offset, - y_offset);
|
||||
cairo_set_source (cr, bg_pattern);
|
||||
cairo_translate (cr, x_offset, y_offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clip_region_to_visible_frame_border (cairo_region_t *region,
|
||||
MetaUIFrame *frame)
|
||||
static cairo_region_t *
|
||||
get_visible_frame_border_region (MetaUIFrame *frame)
|
||||
{
|
||||
MetaRectangle frame_rect;
|
||||
cairo_rectangle_int_t area;
|
||||
cairo_region_t *frame_border;
|
||||
MetaFrameFlags flags;
|
||||
MetaFrameType type;
|
||||
MetaFrameBorders borders;
|
||||
Display *display;
|
||||
int frame_width, frame_height;
|
||||
|
||||
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
|
||||
meta_core_get (display, frame->xwindow,
|
||||
META_CORE_GET_FRAME_FLAGS, &flags,
|
||||
META_CORE_GET_FRAME_TYPE, &type,
|
||||
META_CORE_GET_FRAME_WIDTH, &frame_width,
|
||||
META_CORE_GET_FRAME_HEIGHT, &frame_height,
|
||||
META_CORE_GET_FRAME_RECT, &frame_rect,
|
||||
META_CORE_GET_END);
|
||||
|
||||
meta_theme_get_frame_borders (meta_theme_get_current (),
|
||||
@@ -1625,8 +1658,8 @@ clip_region_to_visible_frame_border (cairo_region_t *region,
|
||||
/* Visible frame rect */
|
||||
area.x = borders.invisible.left;
|
||||
area.y = borders.invisible.top;
|
||||
area.width = frame_width - borders.invisible.left - borders.invisible.right;
|
||||
area.height = frame_height - borders.invisible.top - borders.invisible.bottom;
|
||||
area.width = frame_rect.width;
|
||||
area.height = frame_rect.height;
|
||||
|
||||
frame_border = cairo_region_create_rectangle (&area);
|
||||
|
||||
@@ -1638,9 +1671,7 @@ clip_region_to_visible_frame_border (cairo_region_t *region,
|
||||
|
||||
/* Visible frame border */
|
||||
cairo_region_subtract_rectangle (frame_border, &area);
|
||||
cairo_region_intersect (region, frame_border);
|
||||
|
||||
cairo_region_destroy (frame_border);
|
||||
return frame_border;
|
||||
}
|
||||
|
||||
#define TAU (2*M_PI)
|
||||
@@ -1739,42 +1770,42 @@ meta_frames_get_mask (MetaFrames *frames,
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
/* XXX -- this is disgusting. Find a better approach here.
|
||||
* Use multiple widgets? */
|
||||
static MetaUIFrame *
|
||||
find_frame_to_draw (MetaFrames *frames,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
MetaUIFrame *frame;
|
||||
|
||||
g_hash_table_iter_init (&iter, frames->frames);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &frame, NULL))
|
||||
if (gtk_cairo_should_draw_window (cr, frame->window))
|
||||
return frame;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_frames_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
MetaUIFrame *frame;
|
||||
MetaFrames *frames;
|
||||
cairo_rectangle_int_t clip;
|
||||
cairo_region_t *region;
|
||||
cairo_surface_t *target;
|
||||
|
||||
frames = META_FRAMES (widget);
|
||||
target = cairo_get_target (cr);
|
||||
gdk_cairo_get_clip_rectangle (cr, &clip);
|
||||
|
||||
g_assert (cairo_surface_get_type (target) == CAIRO_SURFACE_TYPE_XLIB);
|
||||
frame = meta_frames_lookup_window (frames, cairo_xlib_surface_get_drawable (target));
|
||||
frame = find_frame_to_draw (frames, cr);
|
||||
if (frame == NULL)
|
||||
return FALSE;
|
||||
|
||||
region = cairo_region_create_rectangle (&clip);
|
||||
clip_region_to_visible_frame_border (region, frame);
|
||||
|
||||
if (cairo_region_is_empty (region))
|
||||
goto out;
|
||||
|
||||
region = get_visible_frame_border_region (frame);
|
||||
gdk_cairo_region (cr, region);
|
||||
cairo_clip (cr);
|
||||
|
||||
cairo_save (cr);
|
||||
setup_bg_cr (cr, frame->window, 0, 0);
|
||||
cairo_paint (cr);
|
||||
cairo_restore (cr);
|
||||
|
||||
meta_frames_paint (frames, frame, cr);
|
||||
|
||||
out:
|
||||
cairo_region_destroy (region);
|
||||
|
||||
return TRUE;
|
||||
@@ -1933,6 +1964,8 @@ meta_frames_enter_notify_event (GtkWidget *widget,
|
||||
if (frame == NULL)
|
||||
return FALSE;
|
||||
|
||||
frame->maybe_ignore_leave_notify = FALSE;
|
||||
|
||||
control = get_control (frames, frame, event->x, event->y);
|
||||
meta_frames_update_prelit_control (frames, frame, control);
|
||||
|
||||
@@ -1945,6 +1978,8 @@ meta_frames_leave_notify_event (GtkWidget *widget,
|
||||
{
|
||||
MetaUIFrame *frame;
|
||||
MetaFrames *frames;
|
||||
Display *display;
|
||||
MetaGrabOp grab_op;
|
||||
|
||||
frames = META_FRAMES (widget);
|
||||
|
||||
@@ -1952,6 +1987,18 @@ meta_frames_leave_notify_event (GtkWidget *widget,
|
||||
if (frame == NULL)
|
||||
return FALSE;
|
||||
|
||||
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
grab_op = meta_core_get_grab_op (display);
|
||||
|
||||
/* ignore the first LeaveNotify event after opening a window menu
|
||||
* if it is the result of a compositor grab
|
||||
*/
|
||||
frame->maybe_ignore_leave_notify = frame->maybe_ignore_leave_notify &&
|
||||
grab_op == META_GRAB_OP_COMPOSITOR;
|
||||
|
||||
if (frame->maybe_ignore_leave_notify)
|
||||
return FALSE;
|
||||
|
||||
meta_frames_update_prelit_control (frames, frame, META_FRAME_CONTROL_NONE);
|
||||
|
||||
return TRUE;
|
||||
|
@@ -80,6 +80,7 @@ struct _MetaUIFrame
|
||||
int text_height;
|
||||
char *title; /* NULL once we have a layout */
|
||||
guint shape_applied : 1;
|
||||
guint maybe_ignore_leave_notify : 1;
|
||||
|
||||
/* FIXME get rid of this, it can just be in the MetaFrames struct */
|
||||
MetaFrameControl prelit_control;
|
||||
@@ -99,6 +100,12 @@ struct _MetaFrames
|
||||
GtkStyleContext *normal_style;
|
||||
GHashTable *style_variants;
|
||||
|
||||
MetaGrabOp current_grab_op;
|
||||
MetaUIFrame *grab_frame;
|
||||
guint grab_button;
|
||||
gdouble grab_x;
|
||||
gdouble grab_y;
|
||||
|
||||
Window grab_xwindow;
|
||||
};
|
||||
|
||||
|
@@ -29,6 +29,8 @@
|
||||
#include <glib.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
typedef struct _MetaResizePopup MetaResizePopup;
|
||||
|
||||
MetaResizePopup* meta_ui_resize_popup_new (Display *display,
|
||||
int screen_number);
|
||||
void meta_ui_resize_popup_free (MetaResizePopup *popup);
|
||||
|
327
src/ui/theme.c
327
src/ui/theme.c
@@ -56,8 +56,6 @@
|
||||
((int)((color).green * 255) << 8) | \
|
||||
((int)((color).blue * 255))))
|
||||
|
||||
#define ALPHA_TO_UCHAR(d) ((unsigned char) ((d) * 255))
|
||||
|
||||
#define DEBUG_FILL_STRUCT(s) memset ((s), 0xef, sizeof (*(s)))
|
||||
#define CLAMP_UCHAR(v) ((guchar) (CLAMP (((int)v), (int)0, (int)255)))
|
||||
#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
|
||||
@@ -94,8 +92,8 @@ colorize_pixbuf (GdkPixbuf *orig,
|
||||
guchar *dest_pixels;
|
||||
|
||||
pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (orig), gdk_pixbuf_get_has_alpha (orig),
|
||||
gdk_pixbuf_get_bits_per_sample (orig),
|
||||
gdk_pixbuf_get_width (orig), gdk_pixbuf_get_height (orig));
|
||||
gdk_pixbuf_get_bits_per_sample (orig),
|
||||
gdk_pixbuf_get_width (orig), gdk_pixbuf_get_height (orig));
|
||||
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
@@ -795,19 +793,19 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
|
||||
&n_right, &fgeom->above_rect))
|
||||
continue;
|
||||
else if (strip_button (left_func_rects, left_bg_rects,
|
||||
&n_left, &fgeom->stick_rect))
|
||||
&n_left, &fgeom->stick_rect))
|
||||
continue;
|
||||
else if (strip_button (right_func_rects, right_bg_rects,
|
||||
&n_right, &fgeom->stick_rect))
|
||||
continue;
|
||||
else if (strip_button (left_func_rects, left_bg_rects,
|
||||
&n_left, &fgeom->shade_rect))
|
||||
&n_left, &fgeom->shade_rect))
|
||||
continue;
|
||||
else if (strip_button (right_func_rects, right_bg_rects,
|
||||
&n_right, &fgeom->shade_rect))
|
||||
continue;
|
||||
else if (strip_button (left_func_rects, left_bg_rects,
|
||||
&n_left, &fgeom->min_rect))
|
||||
&n_left, &fgeom->min_rect))
|
||||
continue;
|
||||
else if (strip_button (right_func_rects, right_bg_rects,
|
||||
&n_right, &fgeom->min_rect))
|
||||
@@ -926,12 +924,11 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout,
|
||||
rect->clickable.width = button_width;
|
||||
}
|
||||
|
||||
rect->clickable.y = 0;
|
||||
rect->clickable.height = button_height + button_y;
|
||||
}
|
||||
else
|
||||
g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable));
|
||||
|
||||
rect->clickable.y = 0;
|
||||
rect->clickable.height = button_height + button_y;
|
||||
}
|
||||
else
|
||||
g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable));
|
||||
|
||||
x = rect->visible.x + rect->visible.width + layout->button_border.right;
|
||||
if (left_buttons_has_spacer[i])
|
||||
@@ -1192,10 +1189,8 @@ meta_color_spec_new_from_string (const char *str,
|
||||
MetaColorSpec *spec;
|
||||
|
||||
spec = NULL;
|
||||
|
||||
if (str[0] == 'g' && str[1] == 't' && str[2] == 'k' && str[3] == ':' &&
|
||||
str[4] == 'c' && str[5] == 'u' && str[6] == 's' && str[7] == 't' &&
|
||||
str[8] == 'o' && str[9] == 'm')
|
||||
|
||||
if (strncmp (str, "gtk:custom", 10) == 0)
|
||||
{
|
||||
const char *color_name_start, *fallback_str_start, *end;
|
||||
char *color_name;
|
||||
@@ -1270,7 +1265,7 @@ meta_color_spec_new_from_string (const char *str,
|
||||
spec->data.gtkcustom.color_name = color_name;
|
||||
spec->data.gtkcustom.fallback = fallback;
|
||||
}
|
||||
else if (str[0] == 'g' && str[1] == 't' && str[2] == 'k' && str[3] == ':')
|
||||
else if (strncmp (str, "gtk:", 4) == 0)
|
||||
{
|
||||
/* GTK color */
|
||||
const char *bracket;
|
||||
@@ -1337,8 +1332,7 @@ meta_color_spec_new_from_string (const char *str,
|
||||
spec->data.gtk.component = component;
|
||||
g_assert (spec->data.gtk.component < META_GTK_COLOR_LAST);
|
||||
}
|
||||
else if (str[0] == 'b' && str[1] == 'l' && str[2] == 'e' && str[3] == 'n' &&
|
||||
str[4] == 'd' && str[5] == '/')
|
||||
else if (strncmp (str, "blend/", 6) == 0)
|
||||
{
|
||||
/* blend */
|
||||
char **split;
|
||||
@@ -1406,8 +1400,7 @@ meta_color_spec_new_from_string (const char *str,
|
||||
spec->data.blend.background = bg;
|
||||
spec->data.blend.foreground = fg;
|
||||
}
|
||||
else if (str[0] == 's' && str[1] == 'h' && str[2] == 'a' && str[3] == 'd' &&
|
||||
str[4] == 'e' && str[5] == '/')
|
||||
else if (strncmp (str, "shade/", 6) == 0)
|
||||
{
|
||||
/* shade */
|
||||
char **split;
|
||||
@@ -1704,20 +1697,12 @@ op_from_string (const char *p,
|
||||
return POS_OP_MOD;
|
||||
|
||||
case '`':
|
||||
if (p[0] == '`' &&
|
||||
p[1] == 'm' &&
|
||||
p[2] == 'a' &&
|
||||
p[3] == 'x' &&
|
||||
p[4] == '`')
|
||||
if (strncmp (p, "`max`", 5) == 0)
|
||||
{
|
||||
*len = 5;
|
||||
return POS_OP_MAX;
|
||||
}
|
||||
else if (p[0] == '`' &&
|
||||
p[1] == 'm' &&
|
||||
p[2] == 'i' &&
|
||||
p[3] == 'n' &&
|
||||
p[4] == '`')
|
||||
else if (strncmp (p, "`min`", 5) == 0)
|
||||
{
|
||||
*len = 5;
|
||||
return POS_OP_MIN;
|
||||
@@ -3067,7 +3052,7 @@ meta_draw_op_free (MetaDrawOp *op)
|
||||
g_object_unref (G_OBJECT (op->data.image.pixbuf));
|
||||
|
||||
if (op->data.image.colorize_spec)
|
||||
meta_color_spec_free (op->data.image.colorize_spec);
|
||||
meta_color_spec_free (op->data.image.colorize_spec);
|
||||
|
||||
if (op->data.image.colorize_cache_pixbuf)
|
||||
g_object_unref (G_OBJECT (op->data.image.colorize_cache_pixbuf));
|
||||
@@ -3418,32 +3403,6 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
|
||||
|
||||
switch (op->type)
|
||||
{
|
||||
case META_DRAW_LINE:
|
||||
break;
|
||||
|
||||
case META_DRAW_RECTANGLE:
|
||||
if (op->data.rectangle.filled)
|
||||
{
|
||||
GdkRGBA color;
|
||||
|
||||
meta_color_spec_render (op->data.rectangle.color_spec,
|
||||
context,
|
||||
&color);
|
||||
|
||||
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
|
||||
FALSE,
|
||||
8, width, height);
|
||||
|
||||
gdk_pixbuf_fill (pixbuf, GDK_COLOR_RGBA (color));
|
||||
}
|
||||
break;
|
||||
|
||||
case META_DRAW_ARC:
|
||||
break;
|
||||
|
||||
case META_DRAW_CLIP:
|
||||
break;
|
||||
|
||||
case META_DRAW_TINT:
|
||||
{
|
||||
GdkRGBA color;
|
||||
@@ -3502,12 +3461,11 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case META_DRAW_IMAGE:
|
||||
{
|
||||
if (op->data.image.colorize_spec)
|
||||
{
|
||||
GdkRGBA color;
|
||||
if (op->data.image.colorize_spec)
|
||||
{
|
||||
GdkRGBA color;
|
||||
|
||||
meta_color_spec_render (op->data.image.colorize_spec,
|
||||
context, &color);
|
||||
@@ -3535,24 +3493,18 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
|
||||
op->data.image.vertical_stripes,
|
||||
op->data.image.horizontal_stripes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pixbuf = scale_and_alpha_pixbuf (op->data.image.pixbuf,
|
||||
}
|
||||
else
|
||||
{
|
||||
pixbuf = scale_and_alpha_pixbuf (op->data.image.pixbuf,
|
||||
op->data.image.alpha_spec,
|
||||
op->data.image.fill_type,
|
||||
width, height,
|
||||
op->data.image.vertical_stripes,
|
||||
op->data.image.horizontal_stripes);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case META_DRAW_GTK_ARROW:
|
||||
case META_DRAW_GTK_BOX:
|
||||
case META_DRAW_GTK_VLINE:
|
||||
break;
|
||||
|
||||
case META_DRAW_ICON:
|
||||
if (info->mini_icon &&
|
||||
width <= gdk_pixbuf_get_width (info->mini_icon) &&
|
||||
@@ -3570,12 +3522,15 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
|
||||
FALSE, FALSE);
|
||||
break;
|
||||
|
||||
case META_DRAW_LINE:
|
||||
case META_DRAW_RECTANGLE:
|
||||
case META_DRAW_ARC:
|
||||
case META_DRAW_CLIP:
|
||||
case META_DRAW_GTK_ARROW:
|
||||
case META_DRAW_GTK_BOX:
|
||||
case META_DRAW_GTK_VLINE:
|
||||
case META_DRAW_TITLE:
|
||||
break;
|
||||
|
||||
case META_DRAW_OP_LIST:
|
||||
break;
|
||||
|
||||
case META_DRAW_TILE:
|
||||
break;
|
||||
}
|
||||
@@ -4046,8 +4001,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
|
||||
d_rect.height = parse_size_unchecked (op->data.op_list.height, env);
|
||||
|
||||
meta_draw_op_list_draw_with_style (op->data.op_list.op_list,
|
||||
style_gtk, cr, info,
|
||||
d_rect);
|
||||
style_gtk, cr, info, d_rect);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -4084,8 +4038,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
|
||||
while (tile.y < (ry + rheight))
|
||||
{
|
||||
meta_draw_op_list_draw_with_style (op->data.tile.op_list,
|
||||
style_gtk, cr, info,
|
||||
tile);
|
||||
style_gtk, cr, info, tile);
|
||||
|
||||
tile.y += tile.height;
|
||||
}
|
||||
@@ -6569,216 +6522,6 @@ hls_to_rgb (gdouble *h,
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* These are some functions I'm saving to use in optimizing
|
||||
* MetaDrawOpList, namely to pre-composite pixbufs on client side
|
||||
* prior to rendering to the server
|
||||
*/
|
||||
static void
|
||||
draw_bg_solid_composite (const MetaTextureSpec *bg,
|
||||
const MetaTextureSpec *fg,
|
||||
double alpha,
|
||||
GtkWidget *widget,
|
||||
GdkDrawable *drawable,
|
||||
const GdkRectangle *clip,
|
||||
MetaTextureDrawMode mode,
|
||||
double xalign,
|
||||
double yalign,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GdkRGBA bg_color;
|
||||
|
||||
g_assert (bg->type == META_TEXTURE_SOLID);
|
||||
g_assert (fg->type != META_TEXTURE_COMPOSITE);
|
||||
g_assert (fg->type != META_TEXTURE_SHAPE_LIST);
|
||||
|
||||
meta_color_spec_render (bg->data.solid.color_spec,
|
||||
widget,
|
||||
&bg_color);
|
||||
|
||||
switch (fg->type)
|
||||
{
|
||||
case META_TEXTURE_SOLID:
|
||||
{
|
||||
GdkRGBA fg_color;
|
||||
|
||||
meta_color_spec_render (fg->data.solid.color_spec,
|
||||
widget,
|
||||
&fg_color);
|
||||
|
||||
color_composite (&bg_color, &fg_color,
|
||||
alpha, &fg_color);
|
||||
|
||||
draw_color_rectangle (widget, drawable, &fg_color, clip,
|
||||
x, y, width, height);
|
||||
}
|
||||
break;
|
||||
|
||||
case META_TEXTURE_GRADIENT:
|
||||
/* FIXME I think we could just composite all the colors in
|
||||
* the gradient prior to generating the gradient?
|
||||
*/
|
||||
/* FALL THRU */
|
||||
case META_TEXTURE_IMAGE:
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkPixbuf *composited;
|
||||
|
||||
pixbuf = meta_texture_spec_render (fg, widget, mode, 255,
|
||||
width, height);
|
||||
|
||||
if (pixbuf == NULL)
|
||||
return;
|
||||
|
||||
composited = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
|
||||
gdk_pixbuf_get_has_alpha (pixbuf), 8,
|
||||
gdk_pixbuf_get_width (pixbuf),
|
||||
gdk_pixbuf_get_height (pixbuf));
|
||||
|
||||
if (composited == NULL)
|
||||
{
|
||||
g_object_unref (G_OBJECT (pixbuf));
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_pixbuf_composite_color (pixbuf,
|
||||
composited,
|
||||
0, 0,
|
||||
gdk_pixbuf_get_width (pixbuf),
|
||||
gdk_pixbuf_get_height (pixbuf),
|
||||
0.0, 0.0, /* offsets */
|
||||
1.0, 1.0, /* scale */
|
||||
GDK_INTERP_BILINEAR,
|
||||
255 * alpha,
|
||||
0, 0, /* check offsets */
|
||||
0, /* check size */
|
||||
GDK_COLOR_RGB (bg_color),
|
||||
GDK_COLOR_RGB (bg_color));
|
||||
|
||||
/* Need to draw background since pixbuf is not
|
||||
* necessarily covering the whole thing
|
||||
*/
|
||||
draw_color_rectangle (widget, drawable, &bg_color, clip,
|
||||
x, y, width, height);
|
||||
|
||||
render_pixbuf_aligned (drawable, clip, composited,
|
||||
xalign, yalign,
|
||||
x, y, width, height);
|
||||
|
||||
g_object_unref (G_OBJECT (pixbuf));
|
||||
g_object_unref (G_OBJECT (composited));
|
||||
}
|
||||
break;
|
||||
|
||||
case META_TEXTURE_BLANK:
|
||||
case META_TEXTURE_COMPOSITE:
|
||||
case META_TEXTURE_SHAPE_LIST:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_bg_gradient_composite (const MetaTextureSpec *bg,
|
||||
const MetaTextureSpec *fg,
|
||||
double alpha,
|
||||
GtkWidget *widget,
|
||||
GdkDrawable *drawable,
|
||||
const GdkRectangle *clip,
|
||||
MetaTextureDrawMode mode,
|
||||
double xalign,
|
||||
double yalign,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
g_assert (bg->type == META_TEXTURE_GRADIENT);
|
||||
g_assert (fg->type != META_TEXTURE_COMPOSITE);
|
||||
g_assert (fg->type != META_TEXTURE_SHAPE_LIST);
|
||||
|
||||
switch (fg->type)
|
||||
{
|
||||
case META_TEXTURE_SOLID:
|
||||
case META_TEXTURE_GRADIENT:
|
||||
case META_TEXTURE_IMAGE:
|
||||
{
|
||||
GdkPixbuf *bg_pixbuf;
|
||||
GdkPixbuf *fg_pixbuf;
|
||||
GdkPixbuf *composited;
|
||||
int fg_width, fg_height;
|
||||
|
||||
bg_pixbuf = meta_texture_spec_render (bg, widget, mode, 255,
|
||||
width, height);
|
||||
|
||||
if (bg_pixbuf == NULL)
|
||||
return;
|
||||
|
||||
fg_pixbuf = meta_texture_spec_render (fg, widget, mode, 255,
|
||||
width, height);
|
||||
|
||||
if (fg_pixbuf == NULL)
|
||||
{
|
||||
g_object_unref (G_OBJECT (bg_pixbuf));
|
||||
return;
|
||||
}
|
||||
|
||||
/* gradients always fill the entire target area */
|
||||
g_assert (gdk_pixbuf_get_width (bg_pixbuf) == width);
|
||||
g_assert (gdk_pixbuf_get_height (bg_pixbuf) == height);
|
||||
|
||||
composited = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
|
||||
gdk_pixbuf_get_has_alpha (bg_pixbuf), 8,
|
||||
gdk_pixbuf_get_width (bg_pixbuf),
|
||||
gdk_pixbuf_get_height (bg_pixbuf));
|
||||
|
||||
if (composited == NULL)
|
||||
{
|
||||
g_object_unref (G_OBJECT (bg_pixbuf));
|
||||
g_object_unref (G_OBJECT (fg_pixbuf));
|
||||
return;
|
||||
}
|
||||
|
||||
fg_width = gdk_pixbuf_get_width (fg_pixbuf);
|
||||
fg_height = gdk_pixbuf_get_height (fg_pixbuf);
|
||||
|
||||
/* If we wanted to be all cool we could deal with the
|
||||
* offsets and try to composite only in the clip rectangle,
|
||||
* but I just don't care enough to figure it out.
|
||||
*/
|
||||
|
||||
gdk_pixbuf_composite (fg_pixbuf,
|
||||
composited,
|
||||
x + (width - fg_width) * xalign,
|
||||
y + (height - fg_height) * yalign,
|
||||
gdk_pixbuf_get_width (fg_pixbuf),
|
||||
gdk_pixbuf_get_height (fg_pixbuf),
|
||||
0.0, 0.0, /* offsets */
|
||||
1.0, 1.0, /* scale */
|
||||
GDK_INTERP_BILINEAR,
|
||||
255 * alpha);
|
||||
|
||||
gdk_cairo_set_source_pixbuf (cr, composited, x, y);
|
||||
cairo_paint (cr);
|
||||
|
||||
g_object_unref (G_OBJECT (bg_pixbuf));
|
||||
g_object_unref (G_OBJECT (fg_pixbuf));
|
||||
g_object_unref (G_OBJECT (composited));
|
||||
}
|
||||
break;
|
||||
|
||||
case META_TEXTURE_BLANK:
|
||||
case META_TEXTURE_SHAPE_LIST:
|
||||
case META_TEXTURE_COMPOSITE:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* meta_theme_earliest_version_with_button:
|
||||
* @type: the button type
|
||||
|
37
src/ui/ui.c
37
src/ui/ui.c
@@ -26,6 +26,7 @@
|
||||
#include <meta/util.h>
|
||||
#include "core.h"
|
||||
#include "theme-private.h"
|
||||
#include "x11/events.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -119,7 +120,6 @@ maybe_redirect_mouse_event (XEvent *xevent)
|
||||
|
||||
switch (xev->evtype)
|
||||
{
|
||||
case XI_TouchBegin:
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
case XI_Motion:
|
||||
@@ -147,19 +147,11 @@ maybe_redirect_mouse_event (XEvent *xevent)
|
||||
gmanager = gdk_display_get_device_manager (gdisplay);
|
||||
gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID);
|
||||
|
||||
/* If GDK already thinks it has a grab, we better let it see events; this
|
||||
* is the menu-navigation case and events need to get sent to the appropriate
|
||||
* (client-side) subwindow for individual menu items.
|
||||
*/
|
||||
if (gdk_display_device_is_grabbed (gdisplay, gdevice))
|
||||
return FALSE;
|
||||
|
||||
switch (xev->evtype)
|
||||
{
|
||||
case XI_TouchBegin:
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
if (xev_d->evtype == XI_ButtonPress || xev_d->evtype == XI_TouchBegin)
|
||||
if (xev_d->evtype == XI_ButtonPress)
|
||||
{
|
||||
GtkSettings *settings = gtk_settings_get_default ();
|
||||
int double_click_time;
|
||||
@@ -171,10 +163,7 @@ maybe_redirect_mouse_event (XEvent *xevent)
|
||||
"gtk-double-click-distance", &double_click_distance,
|
||||
NULL);
|
||||
|
||||
if (xev->evtype == XI_TouchBegin)
|
||||
button = 1;
|
||||
else
|
||||
button = xev_d->detail;
|
||||
button = xev_d->detail;
|
||||
|
||||
if (button == ui->button_click_number &&
|
||||
xev_d->event == ui->button_click_window &&
|
||||
@@ -216,6 +205,12 @@ maybe_redirect_mouse_event (XEvent *xevent)
|
||||
gevent = gdk_event_new (GDK_MOTION_NOTIFY);
|
||||
gevent->motion.type = GDK_MOTION_NOTIFY;
|
||||
gevent->motion.window = g_object_ref (gdk_window);
|
||||
gevent->motion.time = xev_d->time;
|
||||
gevent->motion.x_root = xev_d->root_x;
|
||||
gevent->motion.y_root = xev_d->root_y;
|
||||
|
||||
if (XIMaskIsSet (xev_d->buttons.mask, 1))
|
||||
gevent->motion.state |= GDK_BUTTON1_MASK;
|
||||
break;
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
@@ -237,15 +232,11 @@ maybe_redirect_mouse_event (XEvent *xevent)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GdkFilterReturn
|
||||
ui_filter_func (GdkXEvent *xevent,
|
||||
GdkEvent *event,
|
||||
static void
|
||||
ui_filter_func (gpointer xevent,
|
||||
gpointer data)
|
||||
{
|
||||
if (maybe_redirect_mouse_event (xevent))
|
||||
return GDK_FILTER_REMOVE;
|
||||
else
|
||||
return GDK_FILTER_CONTINUE;
|
||||
maybe_redirect_mouse_event (xevent);
|
||||
}
|
||||
|
||||
MetaUI*
|
||||
@@ -271,7 +262,7 @@ meta_ui_new (Display *xdisplay,
|
||||
*/
|
||||
gtk_widget_show (GTK_WIDGET (ui->frames));
|
||||
|
||||
gdk_window_add_filter (NULL, ui_filter_func, NULL);
|
||||
meta_display_events_x11_add_func (ui_filter_func, NULL);
|
||||
|
||||
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", ui);
|
||||
|
||||
@@ -288,7 +279,7 @@ meta_ui_free (MetaUI *ui)
|
||||
gdisplay = gdk_x11_lookup_xdisplay (ui->xdisplay);
|
||||
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", NULL);
|
||||
|
||||
gdk_window_remove_filter (NULL, ui_filter_func, NULL);
|
||||
meta_display_events_x11_add_func (ui_filter_func, NULL);
|
||||
|
||||
g_free (ui);
|
||||
}
|
||||
|
@@ -200,8 +200,6 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer,
|
||||
|
||||
pointer->cursor_surface = NULL;
|
||||
pointer->cursor_surface_destroy_listener.notify = pointer_handle_cursor_surface_destroy;
|
||||
pointer->hotspot_x = 16;
|
||||
pointer->hotspot_y = 16;
|
||||
|
||||
pointer->default_grab.interface = &default_pointer_grab_interface;
|
||||
pointer->default_grab.pointer = pointer;
|
||||
@@ -383,9 +381,13 @@ handle_scroll_event (MetaWaylandPointer *pointer,
|
||||
case CLUTTER_SCROLL_SMOOTH:
|
||||
{
|
||||
double dx, dy;
|
||||
/* Clutter smooth scroll events are in discrete steps (1 step = 1.0 long
|
||||
* vector along one axis). To convert to smooth scroll events that are
|
||||
* in pointer motion event space, multiply the vector with the 10. */
|
||||
const double factor = 10.0;
|
||||
clutter_event_get_scroll_delta (event, &dx, &dy);
|
||||
x_value = wl_fixed_from_double (dx);
|
||||
y_value = wl_fixed_from_double (dy);
|
||||
x_value = wl_fixed_from_double (dx) * factor;
|
||||
y_value = wl_fixed_from_double (dy) * factor;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@@ -59,7 +59,10 @@ seat_get_touch (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t id)
|
||||
{
|
||||
/* Touch not supported */
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
|
||||
MetaWaylandTouch *touch = &seat->touch;
|
||||
|
||||
meta_wayland_touch_create_new_resource (touch, client, resource, id);
|
||||
}
|
||||
|
||||
static const struct wl_seat_interface seat_interface = {
|
||||
@@ -84,7 +87,8 @@ bind_seat (struct wl_client *client,
|
||||
|
||||
wl_seat_send_capabilities (resource,
|
||||
WL_SEAT_CAPABILITY_POINTER |
|
||||
WL_SEAT_CAPABILITY_KEYBOARD);
|
||||
WL_SEAT_CAPABILITY_KEYBOARD |
|
||||
WL_SEAT_CAPABILITY_TOUCH);
|
||||
|
||||
if (version >= WL_SEAT_NAME_SINCE_VERSION)
|
||||
wl_seat_send_name (resource, "seat0");
|
||||
@@ -101,6 +105,7 @@ meta_wayland_seat_new (struct wl_display *display)
|
||||
|
||||
meta_wayland_pointer_init (&seat->pointer, display);
|
||||
meta_wayland_keyboard_init (&seat->keyboard, display);
|
||||
meta_wayland_touch_init (&seat->touch, display);
|
||||
|
||||
seat->display = display;
|
||||
|
||||
@@ -120,6 +125,7 @@ meta_wayland_seat_free (MetaWaylandSeat *seat)
|
||||
{
|
||||
meta_wayland_pointer_release (&seat->pointer);
|
||||
meta_wayland_keyboard_release (&seat->keyboard);
|
||||
meta_wayland_touch_release (&seat->touch);
|
||||
|
||||
g_slice_free (MetaWaylandSeat, seat);
|
||||
}
|
||||
@@ -142,6 +148,12 @@ meta_wayland_seat_update (MetaWaylandSeat *seat,
|
||||
meta_wayland_keyboard_update (&seat->keyboard, (const ClutterKeyEvent *) event);
|
||||
break;
|
||||
|
||||
case CLUTTER_TOUCH_BEGIN:
|
||||
case CLUTTER_TOUCH_UPDATE:
|
||||
case CLUTTER_TOUCH_END:
|
||||
meta_wayland_touch_update (&seat->touch, event);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -163,6 +175,10 @@ meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
return meta_wayland_keyboard_handle_event (&seat->keyboard,
|
||||
(const ClutterKeyEvent *) event);
|
||||
case CLUTTER_TOUCH_BEGIN:
|
||||
case CLUTTER_TOUCH_UPDATE:
|
||||
case CLUTTER_TOUCH_END:
|
||||
return meta_wayland_touch_handle_event (&seat->touch, event);
|
||||
|
||||
default:
|
||||
break;
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "meta-wayland-types.h"
|
||||
#include "meta-wayland-keyboard.h"
|
||||
#include "meta-wayland-pointer.h"
|
||||
#include "meta-wayland-touch.h"
|
||||
|
||||
struct _MetaWaylandDataOffer
|
||||
{
|
||||
@@ -53,6 +54,7 @@ struct _MetaWaylandSeat
|
||||
struct wl_list data_device_resource_list;
|
||||
MetaWaylandPointer pointer;
|
||||
MetaWaylandKeyboard keyboard;
|
||||
MetaWaylandTouch touch;
|
||||
|
||||
struct wl_display *display;
|
||||
};
|
||||
|
@@ -1018,9 +1018,9 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
|
||||
}
|
||||
|
||||
window = meta_window_wayland_new (meta_get_display (), surface);
|
||||
meta_window_move (window, FALSE,
|
||||
parent_surf->window->rect.x + x,
|
||||
parent_surf->window->rect.y + y);
|
||||
meta_window_move_frame (window, FALSE,
|
||||
parent_surf->window->rect.x + x,
|
||||
parent_surf->window->rect.y + y);
|
||||
window->showing_for_first_time = FALSE;
|
||||
window->placed = TRUE;
|
||||
meta_window_set_transient_for (window, parent_surf->window);
|
||||
@@ -1212,9 +1212,9 @@ wl_shell_surface_set_transient (struct wl_client *client,
|
||||
wl_shell_surface_set_state (surface, SURFACE_STATE_TOPLEVEL);
|
||||
|
||||
meta_window_set_transient_for (surface->window, parent_surf->window);
|
||||
meta_window_move (surface->window, FALSE,
|
||||
parent_surf->window->rect.x + x,
|
||||
parent_surf->window->rect.y + y);
|
||||
meta_window_move_frame (surface->window, FALSE,
|
||||
parent_surf->window->rect.x + x,
|
||||
parent_surf->window->rect.y + y);
|
||||
surface->window->placed = TRUE;
|
||||
}
|
||||
|
||||
@@ -1247,9 +1247,9 @@ wl_shell_surface_set_popup (struct wl_client *client,
|
||||
wl_shell_surface_set_state (surface, SURFACE_STATE_TOPLEVEL);
|
||||
|
||||
meta_window_set_transient_for (surface->window, parent_surf->window);
|
||||
meta_window_move (surface->window, FALSE,
|
||||
parent_surf->window->rect.x + x,
|
||||
parent_surf->window->rect.y + y);
|
||||
meta_window_move_frame (surface->window, FALSE,
|
||||
parent_surf->window->rect.x + x,
|
||||
parent_surf->window->rect.y + y);
|
||||
surface->window->placed = TRUE;
|
||||
|
||||
meta_wayland_pointer_start_popup_grab (&seat->pointer, surface);
|
||||
@@ -1677,11 +1677,10 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
|
||||
}
|
||||
|
||||
pending_state_init (&surface->sub.pending);
|
||||
surface->sub.synchronous = TRUE;
|
||||
surface->sub.parent = parent;
|
||||
surface->sub.parent_destroy_listener.notify =
|
||||
surface_handle_parent_surface_destroyed;
|
||||
wl_resource_add_destroy_listener (parent->resource,
|
||||
&surface->sub.parent_destroy_listener);
|
||||
surface->sub.parent_destroy_listener.notify = surface_handle_parent_surface_destroyed;
|
||||
wl_resource_add_destroy_listener (parent->resource, &surface->sub.parent_destroy_listener);
|
||||
parent->subsurfaces = g_list_append (parent->subsurfaces, surface);
|
||||
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (parent->surface_actor),
|
||||
|
547
src/wayland/meta-wayland-touch.c
Normal file
547
src/wayland/meta-wayland-touch.c
Normal file
@@ -0,0 +1,547 @@
|
||||
/*
|
||||
* Wayland Support
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include <clutter/evdev/clutter-evdev.h>
|
||||
|
||||
#include "meta-surface-actor-wayland.h"
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
struct _MetaWaylandTouchSurface
|
||||
{
|
||||
MetaWaylandSurface *surface;
|
||||
MetaWaylandTouch *touch;
|
||||
struct wl_listener surface_destroy_listener;
|
||||
struct wl_list resource_list;
|
||||
gint touch_count;
|
||||
};
|
||||
|
||||
struct _MetaWaylandTouchInfo
|
||||
{
|
||||
MetaWaylandTouchSurface *touch_surface;
|
||||
guint32 slot_serial;
|
||||
gint32 slot;
|
||||
gfloat x;
|
||||
gfloat y;
|
||||
guint updated : 1;
|
||||
};
|
||||
|
||||
static void
|
||||
move_resources (struct wl_list *destination, struct wl_list *source)
|
||||
{
|
||||
wl_list_insert_list (destination, source);
|
||||
wl_list_init (source);
|
||||
}
|
||||
|
||||
static void
|
||||
move_resources_for_client (struct wl_list *destination,
|
||||
struct wl_list *source,
|
||||
struct wl_client *client)
|
||||
{
|
||||
struct wl_resource *resource, *tmp;
|
||||
wl_resource_for_each_safe (resource, tmp, source)
|
||||
{
|
||||
if (wl_resource_get_client (resource) == client)
|
||||
{
|
||||
wl_list_remove (wl_resource_get_link (resource));
|
||||
wl_list_insert (destination, wl_resource_get_link (resource));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
touch_surface_free (gpointer data)
|
||||
{
|
||||
MetaWaylandTouchSurface *touch_surface = data;
|
||||
MetaWaylandTouch *touch = touch_surface->touch;
|
||||
|
||||
move_resources (&touch->resource_list,
|
||||
&touch_surface->resource_list);
|
||||
wl_list_remove (&touch_surface->surface_destroy_listener.link);
|
||||
g_free (touch_surface);
|
||||
}
|
||||
|
||||
static MetaWaylandTouchSurface *
|
||||
touch_surface_increment_touch (MetaWaylandTouchSurface *surface)
|
||||
{
|
||||
surface->touch_count++;
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
touch_surface_decrement_touch (MetaWaylandTouchSurface *touch_surface)
|
||||
{
|
||||
touch_surface->touch_count--;
|
||||
|
||||
if (touch_surface->touch_count == 0)
|
||||
{
|
||||
/* Now that there are no touches on the surface, free the
|
||||
* MetaWaylandTouchSurface, the memory is actually owned by
|
||||
* the touch_surface->touch_surfaces hashtable, so remove the
|
||||
* item from there.
|
||||
*/
|
||||
MetaWaylandTouch *touch = touch_surface->touch;
|
||||
g_hash_table_remove (touch->touch_surfaces, touch_surface->surface);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
touch_handle_surface_destroy (struct wl_listener *listener, void *data)
|
||||
{
|
||||
MetaWaylandTouchSurface *touch_surface = wl_container_of (listener, touch_surface, surface_destroy_listener);
|
||||
MetaWaylandSurface *surface = touch_surface->surface;
|
||||
MetaWaylandTouch *touch = touch_surface->touch;
|
||||
MetaWaylandTouchInfo *touch_info;
|
||||
GHashTableIter iter;
|
||||
|
||||
g_hash_table_iter_init (&iter, touch->touches);
|
||||
|
||||
/* Destroy all touches on the surface, this indirectly drops touch_count
|
||||
* on the touch_surface to 0, also freeing touch_surface and removing
|
||||
* from the touch_surfaces hashtable.
|
||||
*/
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &touch_info))
|
||||
{
|
||||
if (touch_info->touch_surface == touch_surface)
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
|
||||
/* Ensure the surface no longer exists */
|
||||
g_assert (g_hash_table_remove (touch->touch_surfaces, surface) == FALSE);
|
||||
}
|
||||
|
||||
static MetaWaylandTouchSurface *
|
||||
touch_surface_get (MetaWaylandTouch *touch,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandTouchSurface *touch_surface;
|
||||
|
||||
touch_surface = g_hash_table_lookup (touch->touch_surfaces, surface);
|
||||
|
||||
if (touch_surface)
|
||||
return touch_surface_increment_touch (touch_surface);
|
||||
|
||||
/* Create a new one for this surface */
|
||||
touch_surface = g_new0 (MetaWaylandTouchSurface, 1);
|
||||
touch_surface->touch = touch;
|
||||
touch_surface->surface = surface;
|
||||
touch_surface->touch_count = 1;
|
||||
touch_surface->surface_destroy_listener.notify = touch_handle_surface_destroy;
|
||||
wl_resource_add_destroy_listener (touch_surface->surface->resource,
|
||||
&touch_surface->surface_destroy_listener);
|
||||
|
||||
wl_list_init (&touch_surface->resource_list);
|
||||
move_resources_for_client (&touch_surface->resource_list,
|
||||
&touch->resource_list,
|
||||
wl_resource_get_client (touch_surface->surface->resource));
|
||||
|
||||
g_hash_table_insert (touch->touch_surfaces, surface, touch_surface);
|
||||
|
||||
return touch_surface;
|
||||
}
|
||||
|
||||
static MetaWaylandTouchInfo *
|
||||
touch_get_info (MetaWaylandTouch *touch,
|
||||
ClutterEventSequence *sequence,
|
||||
gboolean create)
|
||||
{
|
||||
MetaWaylandTouchInfo *touch_info;
|
||||
|
||||
touch_info = g_hash_table_lookup (touch->touches, sequence);
|
||||
|
||||
if (!touch_info && create)
|
||||
{
|
||||
touch_info = g_new0 (MetaWaylandTouchInfo, 1);
|
||||
touch_info->slot = clutter_evdev_event_sequence_get_slot (sequence);
|
||||
g_hash_table_insert (touch->touches, sequence, touch_info);
|
||||
}
|
||||
|
||||
return touch_info;
|
||||
}
|
||||
|
||||
static void
|
||||
touch_get_relative_coordinates (MetaWaylandTouch *touch,
|
||||
MetaWaylandSurface *surface,
|
||||
const ClutterEvent *event,
|
||||
gfloat *x,
|
||||
gfloat *y)
|
||||
{
|
||||
gfloat event_x, event_y;
|
||||
|
||||
clutter_event_get_coords (event, &event_x, &event_y);
|
||||
|
||||
if (surface->surface_actor)
|
||||
{
|
||||
clutter_actor_transform_stage_point (CLUTTER_ACTOR (surface->surface_actor),
|
||||
event_x, event_y,
|
||||
&event_x, &event_y);
|
||||
}
|
||||
|
||||
*x = event_x;
|
||||
*y = event_y;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
meta_wayland_touch_update (MetaWaylandTouch *touch,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaWaylandTouchInfo *touch_info;
|
||||
ClutterEventSequence *sequence;
|
||||
|
||||
sequence = clutter_event_get_event_sequence (event);
|
||||
|
||||
if (event->type == CLUTTER_TOUCH_BEGIN)
|
||||
{
|
||||
MetaWaylandSurface *surface = NULL;
|
||||
ClutterActor *actor;
|
||||
|
||||
actor = clutter_event_get_source (event);
|
||||
|
||||
if (META_IS_SURFACE_ACTOR_WAYLAND (actor))
|
||||
surface = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (actor));
|
||||
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
touch_info = touch_get_info (touch, sequence, TRUE);
|
||||
touch_info->touch_surface = touch_surface_get (touch, surface);
|
||||
}
|
||||
else
|
||||
touch_info = touch_get_info (touch, sequence, FALSE);
|
||||
|
||||
if (!touch_info)
|
||||
return;
|
||||
|
||||
if (event->type == CLUTTER_TOUCH_BEGIN ||
|
||||
event->type == CLUTTER_TOUCH_END)
|
||||
{
|
||||
MetaWaylandSurface *surface = touch_info->touch_surface->surface;
|
||||
struct wl_client *client = wl_resource_get_client (surface->resource);
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
|
||||
touch_info->slot_serial = wl_display_next_serial (display);
|
||||
}
|
||||
|
||||
touch_get_relative_coordinates (touch, touch_info->touch_surface->surface,
|
||||
event, &touch_info->x, &touch_info->y);
|
||||
touch_info->updated = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_touch_begin (MetaWaylandTouch *touch,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaWaylandTouchInfo *touch_info;
|
||||
ClutterEventSequence *sequence;
|
||||
struct wl_resource *resource;
|
||||
struct wl_list *l;
|
||||
|
||||
sequence = clutter_event_get_event_sequence (event);
|
||||
touch_info = touch_get_info (touch, sequence, FALSE);
|
||||
|
||||
if (!touch_info)
|
||||
return;
|
||||
|
||||
l = &touch_info->touch_surface->resource_list;
|
||||
wl_resource_for_each(resource, l)
|
||||
{
|
||||
wl_touch_send_down (resource, touch_info->slot_serial,
|
||||
clutter_event_get_time (event),
|
||||
touch_info->touch_surface->surface->resource,
|
||||
touch_info->slot,
|
||||
wl_fixed_from_double (touch_info->x),
|
||||
wl_fixed_from_double (touch_info->y));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_touch_update (MetaWaylandTouch *touch,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaWaylandTouchInfo *touch_info;
|
||||
ClutterEventSequence *sequence;
|
||||
struct wl_resource *resource;
|
||||
struct wl_list *l;
|
||||
|
||||
sequence = clutter_event_get_event_sequence (event);
|
||||
touch_info = touch_get_info (touch, sequence, FALSE);
|
||||
|
||||
if (!touch_info)
|
||||
return;
|
||||
|
||||
l = &touch_info->touch_surface->resource_list;
|
||||
wl_resource_for_each(resource, l)
|
||||
{
|
||||
wl_touch_send_motion (resource,
|
||||
clutter_event_get_time (event),
|
||||
touch_info->slot,
|
||||
wl_fixed_from_double (touch_info->x),
|
||||
wl_fixed_from_double (touch_info->y));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_touch_end (MetaWaylandTouch *touch,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaWaylandTouchInfo *touch_info;
|
||||
ClutterEventSequence *sequence;
|
||||
struct wl_resource *resource;
|
||||
struct wl_list *l;
|
||||
|
||||
sequence = clutter_event_get_event_sequence (event);
|
||||
touch_info = touch_get_info (touch, sequence, FALSE);
|
||||
|
||||
if (!touch_info)
|
||||
return;
|
||||
|
||||
l = &touch_info->touch_surface->resource_list;
|
||||
wl_resource_for_each(resource, l)
|
||||
{
|
||||
wl_touch_send_up (resource, touch_info->slot_serial,
|
||||
clutter_event_get_time (event),
|
||||
touch_info->slot);
|
||||
}
|
||||
|
||||
g_hash_table_remove (touch->touches, sequence);
|
||||
}
|
||||
|
||||
static GList *
|
||||
touch_get_surfaces (MetaWaylandTouch *touch,
|
||||
gboolean only_updated)
|
||||
{
|
||||
MetaWaylandTouchInfo *touch_info;
|
||||
GList *surfaces = NULL;
|
||||
GHashTableIter iter;
|
||||
|
||||
g_hash_table_iter_init (&iter, touch->touches);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &touch_info))
|
||||
{
|
||||
if (only_updated && !touch_info->updated)
|
||||
continue;
|
||||
if (g_list_find (surfaces, touch_info->touch_surface))
|
||||
continue;
|
||||
|
||||
surfaces = g_list_prepend (surfaces, touch_info->touch_surface);
|
||||
touch_info->updated = FALSE;
|
||||
}
|
||||
|
||||
return g_list_reverse (surfaces);
|
||||
}
|
||||
|
||||
static void
|
||||
touch_send_frame_event (MetaWaylandTouch *touch)
|
||||
{
|
||||
GList *surfaces, *s;
|
||||
|
||||
surfaces = s = touch_get_surfaces (touch, TRUE);
|
||||
|
||||
for (s = surfaces; s; s = s->next)
|
||||
{
|
||||
MetaWaylandTouchSurface *touch_surface = s->data;
|
||||
struct wl_resource *resource;
|
||||
struct wl_list *l;
|
||||
|
||||
l = &touch_surface->resource_list;
|
||||
wl_resource_for_each(resource, l)
|
||||
{
|
||||
wl_touch_send_frame (resource);
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free (surfaces);
|
||||
}
|
||||
|
||||
static void
|
||||
check_send_frame_event (MetaWaylandTouch *touch,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
ClutterEventSequence *sequence;
|
||||
gint32 slot;
|
||||
|
||||
sequence = clutter_event_get_event_sequence (event);
|
||||
slot = clutter_evdev_event_sequence_get_slot (sequence);
|
||||
touch->frame_slots &= ~(1 << slot);
|
||||
|
||||
if (touch->frame_slots == 0)
|
||||
touch_send_frame_event (touch);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_touch_handle_event (MetaWaylandTouch *touch,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_TOUCH_BEGIN:
|
||||
handle_touch_begin (touch, event);
|
||||
break;
|
||||
|
||||
case CLUTTER_TOUCH_UPDATE:
|
||||
handle_touch_update (touch, event);
|
||||
break;
|
||||
|
||||
case CLUTTER_TOUCH_END:
|
||||
handle_touch_end (touch, event);
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
check_send_frame_event (touch, event);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
unbind_resource (struct wl_resource *resource)
|
||||
{
|
||||
wl_list_remove (wl_resource_get_link (resource));
|
||||
}
|
||||
|
||||
static void
|
||||
touch_release (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static const struct wl_touch_interface touch_interface = {
|
||||
touch_release,
|
||||
};
|
||||
|
||||
static void
|
||||
touch_info_free (MetaWaylandTouchInfo *touch_info)
|
||||
{
|
||||
touch_surface_decrement_touch (touch_info->touch_surface);
|
||||
g_free (touch_info);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
evdev_filter_func (struct libinput_event *event,
|
||||
gpointer data)
|
||||
{
|
||||
MetaWaylandTouch *touch = data;
|
||||
|
||||
switch (libinput_event_get_type (event))
|
||||
{
|
||||
case LIBINPUT_EVENT_TOUCH_DOWN:
|
||||
case LIBINPUT_EVENT_TOUCH_UP:
|
||||
case LIBINPUT_EVENT_TOUCH_MOTION: {
|
||||
struct libinput_event_touch *touch_event;
|
||||
int32_t slot;
|
||||
|
||||
touch_event = libinput_event_get_touch_event (event);
|
||||
slot = libinput_event_touch_get_slot (touch_event);
|
||||
|
||||
/* XXX: Could theoretically overflow, 64 slots should be
|
||||
* enough for most hw/usecases though.
|
||||
*/
|
||||
touch->frame_slots |= (1 << slot);
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TOUCH_CANCEL:
|
||||
/* Clutter translates this into individual CLUTTER_TOUCH_CANCEL events,
|
||||
* which are not so useful when sending a global signal as the protocol
|
||||
* requires.
|
||||
*/
|
||||
meta_wayland_touch_cancel (touch);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_touch_init (MetaWaylandTouch *touch,
|
||||
struct wl_display *display)
|
||||
{
|
||||
ClutterDeviceManager *manager;
|
||||
|
||||
memset (touch, 0, sizeof *touch);
|
||||
|
||||
touch->display = display;
|
||||
touch->touch_surfaces = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) touch_surface_free);
|
||||
touch->touches = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) touch_info_free);
|
||||
|
||||
wl_list_init (&touch->resource_list);
|
||||
|
||||
manager = clutter_device_manager_get_default ();
|
||||
touch->device = clutter_device_manager_get_core_device (manager, CLUTTER_TOUCHSCREEN_DEVICE);
|
||||
clutter_evdev_add_filter (evdev_filter_func, touch, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_touch_release (MetaWaylandTouch *touch)
|
||||
{
|
||||
clutter_evdev_remove_filter (evdev_filter_func, touch);
|
||||
g_hash_table_unref (touch->touch_surfaces);
|
||||
g_hash_table_unref (touch->touches);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_touch_create_new_resource (MetaWaylandTouch *touch,
|
||||
struct wl_client *client,
|
||||
struct wl_resource *seat_resource,
|
||||
uint32_t id)
|
||||
{
|
||||
struct wl_resource *cr;
|
||||
|
||||
cr = wl_resource_create (client, &wl_touch_interface,
|
||||
MIN (META_WL_TOUCH_VERSION, wl_resource_get_version (seat_resource)), id);
|
||||
wl_resource_set_implementation (cr, NULL, touch, unbind_resource);
|
||||
wl_list_insert (&touch->resource_list, wl_resource_get_link (cr));
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_touch_cancel (MetaWaylandTouch *touch)
|
||||
{
|
||||
GList *surfaces, *s;
|
||||
|
||||
surfaces = s = touch_get_surfaces (touch, FALSE);
|
||||
|
||||
while (s)
|
||||
{
|
||||
MetaWaylandTouchSurface *touch_surface = s->data;
|
||||
struct wl_resource *resource;
|
||||
struct wl_list *l;
|
||||
|
||||
l = &touch_surface->resource_list;
|
||||
wl_resource_for_each(resource, l)
|
||||
wl_touch_send_cancel (resource);
|
||||
}
|
||||
|
||||
g_hash_table_remove_all (touch->touches);
|
||||
g_list_free (surfaces);
|
||||
}
|
64
src/wayland/meta-wayland-touch.h
Normal file
64
src/wayland/meta-wayland-touch.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Wayland Support
|
||||
*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef META_WAYLAND_TOUCH_H
|
||||
#define META_WAYLAND_TOUCH_H
|
||||
|
||||
#include <wayland-server.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "meta-wayland-types.h"
|
||||
|
||||
typedef struct _MetaWaylandTouchSurface MetaWaylandTouchSurface;
|
||||
typedef struct _MetaWaylandTouchInfo MetaWaylandTouchInfo;
|
||||
|
||||
struct _MetaWaylandTouch
|
||||
{
|
||||
struct wl_display *display;
|
||||
struct wl_list resource_list;
|
||||
|
||||
GHashTable *touch_surfaces; /* HT of MetaWaylandSurface->MetaWaylandTouchSurface */
|
||||
GHashTable *touches; /* HT of sequence->MetaWaylandTouchInfo */
|
||||
|
||||
ClutterInputDevice *device;
|
||||
guint64 frame_slots;
|
||||
};
|
||||
|
||||
void meta_wayland_touch_init (MetaWaylandTouch *touch,
|
||||
struct wl_display *display);
|
||||
|
||||
void meta_wayland_touch_release (MetaWaylandTouch *touch);
|
||||
|
||||
void meta_wayland_touch_update (MetaWaylandTouch *touch,
|
||||
const ClutterEvent *event);
|
||||
|
||||
gboolean meta_wayland_touch_handle_event (MetaWaylandTouch *touch,
|
||||
const ClutterEvent *event);
|
||||
|
||||
void meta_wayland_touch_create_new_resource (MetaWaylandTouch *touch,
|
||||
struct wl_client *client,
|
||||
struct wl_resource *seat_resource,
|
||||
uint32_t id);
|
||||
void meta_wayland_touch_cancel (MetaWaylandTouch *touch);
|
||||
|
||||
|
||||
#endif /* META_WAYLAND_TOUCH_H */
|
@@ -29,6 +29,7 @@ typedef struct _MetaWaylandPointerGrabInterface MetaWaylandPointerGrabInterface;
|
||||
typedef struct _MetaWaylandKeyboard MetaWaylandKeyboard;
|
||||
typedef struct _MetaWaylandDataOffer MetaWaylandDataOffer;
|
||||
typedef struct _MetaWaylandDataSource MetaWaylandDataSource;
|
||||
typedef struct _MetaWaylandTouch MetaWaylandTouch;
|
||||
|
||||
typedef struct _MetaWaylandBuffer MetaWaylandBuffer;
|
||||
typedef struct _MetaWaylandBufferReference MetaWaylandBufferReference;
|
||||
|
@@ -51,7 +51,7 @@
|
||||
#define META_WL_SURFACE_VERSION 3 /* from wl_compositor */
|
||||
#define META_WL_POINTER_VERSION 3 /* from wl_seat */
|
||||
#define META_WL_KEYBOARD_VERSION 3 /* from wl_seat */
|
||||
#define META_WL_TOUCH_VERSION 0 /* from wl_seat; wl_touch not supported */
|
||||
#define META_WL_TOUCH_VERSION 3 /* from wl_seat */
|
||||
#define META_WL_REGION_VERSION 1 /* from wl_compositor */
|
||||
#define META_XDG_SURFACE_VERSION 1 /* from xdg_shell */
|
||||
#define META_XDG_POPUP_VERSION 1 /* from xdg_shell */
|
||||
|
@@ -361,6 +361,8 @@ meta_window_wayland_move_resize (MetaWindow *window,
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
window->buffer_rect = rect;
|
||||
|
||||
if (rect.width != window->rect.width || rect.height != window->rect.height)
|
||||
flags |= META_IS_RESIZE_ACTION;
|
||||
|
||||
|
1891
src/x11/events.c
Normal file
1891
src/x11/events.c
Normal file
File diff suppressed because it is too large
Load Diff
36
src/x11/events.h
Normal file
36
src/x11/events.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* -*- 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
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <meta/display.h>
|
||||
|
||||
#ifndef META_EVENTS_X11_H
|
||||
#define META_EVENTS_X11_H
|
||||
|
||||
void meta_display_init_events_x11 (MetaDisplay *display);
|
||||
void meta_display_free_events_x11 (MetaDisplay *display);
|
||||
|
||||
void meta_display_events_x11_add_func (GFunc func,
|
||||
gpointer user_data);
|
||||
void meta_display_events_x11_remove_func (GFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
#endif
|
@@ -20,11 +20,12 @@
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "window-private.h"
|
||||
|
||||
#ifndef META_WINDOW_X11_PRIVATE_H
|
||||
#define META_WINDOW_X11_PRIVATE_H
|
||||
|
||||
#include "window-private.h"
|
||||
#include "ui/resizepopup.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _MetaWindowX11Private MetaWindowX11Private;
|
||||
@@ -55,6 +56,10 @@ struct _MetaWindowX11Private
|
||||
int border_width;
|
||||
|
||||
MetaResizePopup *grab_resize_popup;
|
||||
|
||||
/* These are in server coordinates. If we have a frame, it's
|
||||
* relative to the frame. */
|
||||
MetaRectangle client_rect;
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -204,14 +204,16 @@ send_configure_notify (MetaWindow *window)
|
||||
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
|
||||
XEvent event;
|
||||
|
||||
g_assert (!window->override_redirect);
|
||||
|
||||
/* from twm */
|
||||
|
||||
event.type = ConfigureNotify;
|
||||
event.xconfigure.display = window->display->xdisplay;
|
||||
event.xconfigure.event = window->xwindow;
|
||||
event.xconfigure.window = window->xwindow;
|
||||
event.xconfigure.x = window->rect.x - priv->border_width;
|
||||
event.xconfigure.y = window->rect.y - priv->border_width;
|
||||
event.xconfigure.x = priv->client_rect.x - priv->border_width;
|
||||
event.xconfigure.y = priv->client_rect.y - priv->border_width;
|
||||
if (window->frame)
|
||||
{
|
||||
if (window->withdrawn)
|
||||
@@ -233,8 +235,8 @@ send_configure_notify (MetaWindow *window)
|
||||
event.xconfigure.y += window->frame->rect.y;
|
||||
}
|
||||
}
|
||||
event.xconfigure.width = window->rect.width;
|
||||
event.xconfigure.height = window->rect.height;
|
||||
event.xconfigure.width = priv->client_rect.width;
|
||||
event.xconfigure.height = priv->client_rect.height;
|
||||
event.xconfigure.border_width = priv->border_width; /* requested not actual */
|
||||
event.xconfigure.above = None; /* FIXME */
|
||||
event.xconfigure.override_redirect = False;
|
||||
@@ -492,6 +494,7 @@ meta_window_apply_session_info (MetaWindow *window,
|
||||
flags = META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
||||
|
||||
adjust_for_gravity (window, FALSE, gravity, &rect);
|
||||
meta_window_client_rect_to_frame_rect (window, &rect, &rect);
|
||||
meta_window_move_resize_internal (window, flags, gravity, rect);
|
||||
}
|
||||
}
|
||||
@@ -500,7 +503,6 @@ static void
|
||||
meta_window_x11_manage (MetaWindow *window)
|
||||
{
|
||||
MetaDisplay *display = window->display;
|
||||
MetaMoveResizeFlags flags;
|
||||
|
||||
meta_display_register_x_window (display, &window->xwindow, window);
|
||||
meta_window_x11_update_shape_region (window);
|
||||
@@ -518,6 +520,9 @@ meta_window_x11_manage (MetaWindow *window)
|
||||
|
||||
meta_window_x11_update_net_wm_type (window);
|
||||
|
||||
if (window->decorated)
|
||||
meta_window_ensure_frame (window);
|
||||
|
||||
/* Now try applying saved stuff from the session */
|
||||
{
|
||||
const MetaWindowSessionInfo *info;
|
||||
@@ -531,14 +536,26 @@ meta_window_x11_manage (MetaWindow *window)
|
||||
}
|
||||
}
|
||||
|
||||
/* Put our state back where it should be,
|
||||
* passing TRUE for is_configure_request, ICCCM says
|
||||
* initial map is handled same as configure request
|
||||
/* For override-redirect windows, save the client rect
|
||||
* directly. window->rect was assigned from the XWindowAttributes
|
||||
* in the main meta_window_shared_new.
|
||||
*
|
||||
* For normal windows, do a full ConfigureRequest based on the
|
||||
* window hints, as that's what the ICCCM says to do.
|
||||
*/
|
||||
flags = META_IS_CONFIGURE_REQUEST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
||||
if (!window->override_redirect)
|
||||
|
||||
if (window->override_redirect)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
|
||||
|
||||
priv->client_rect = window->rect;
|
||||
window->buffer_rect = window->rect;
|
||||
}
|
||||
else
|
||||
{
|
||||
MetaRectangle rect;
|
||||
MetaMoveResizeFlags flags;
|
||||
int gravity = window->size_hints.win_gravity;
|
||||
|
||||
rect.x = window->size_hints.x;
|
||||
@@ -546,7 +563,10 @@ meta_window_x11_manage (MetaWindow *window)
|
||||
rect.width = window->size_hints.width;
|
||||
rect.height = window->size_hints.height;
|
||||
|
||||
flags = META_IS_CONFIGURE_REQUEST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION;
|
||||
|
||||
adjust_for_gravity (window, TRUE, gravity, &rect);
|
||||
meta_window_client_rect_to_frame_rect (window, &rect, &rect);
|
||||
meta_window_move_resize_internal (window, flags, gravity, rect);
|
||||
}
|
||||
}
|
||||
@@ -633,17 +653,22 @@ meta_window_x11_unmanage (MetaWindow *window)
|
||||
if (META_DISPLAY_HAS_SHAPE (window->display))
|
||||
XShapeSelectInput (window->display->xdisplay, window->xwindow, NoEventMask);
|
||||
|
||||
/* The XReparentWindow call in meta_window_destroy_frame() moves the
|
||||
* window so we need to send a configure notify; see bug 399552. (We
|
||||
* also do this just in case a window got unmaximized.)
|
||||
*/
|
||||
send_configure_notify (window);
|
||||
|
||||
meta_window_ungrab_keys (window);
|
||||
meta_display_ungrab_window_buttons (window->display, window->xwindow);
|
||||
meta_display_ungrab_focus_window_button (window->display, window);
|
||||
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
if (window->frame)
|
||||
{
|
||||
/* The XReparentWindow call in meta_window_destroy_frame() moves the
|
||||
* window so we need to send a configure notify; see bug 399552. (We
|
||||
* also do this just in case a window got unmaximized.)
|
||||
*/
|
||||
send_configure_notify (window);
|
||||
|
||||
meta_window_destroy_frame (window);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -785,6 +810,22 @@ meta_window_x11_focus (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_get_client_root_coords (MetaWindow *window,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
|
||||
|
||||
*rect = priv->client_rect;
|
||||
|
||||
if (window->frame)
|
||||
{
|
||||
rect->x += window->frame->rect.x;
|
||||
rect->y += window->frame->rect.y;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_refresh_resize_popup (MetaWindow *window)
|
||||
{
|
||||
@@ -888,8 +929,7 @@ sync_request_timeout (gpointer data)
|
||||
* window updates
|
||||
*/
|
||||
window->sync_request_wait_serial = 0;
|
||||
meta_compositor_set_updates_frozen (window->display->compositor, window,
|
||||
meta_window_updates_are_frozen (window));
|
||||
meta_compositor_sync_updates_frozen (window->display->compositor, window);
|
||||
|
||||
if (window == window->display->grab_window &&
|
||||
meta_grab_op_is_resizing (window->display->grab_op))
|
||||
@@ -952,8 +992,7 @@ send_sync_request (MetaWindow *window)
|
||||
g_source_set_name_by_id (window->sync_request_timeout_id,
|
||||
"[mutter] sync_request_timeout");
|
||||
|
||||
meta_compositor_set_updates_frozen (window->display->compositor, window,
|
||||
meta_window_updates_are_frozen (window));
|
||||
meta_compositor_sync_updates_frozen (window->display->compositor, window);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
@@ -1003,9 +1042,7 @@ meta_window_x11_move_resize_internal (MetaWindow *window,
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
|
||||
MetaFrameBorders borders;
|
||||
int root_x_nw, root_y_nw;
|
||||
int w, h;
|
||||
int client_move_x, client_move_y;
|
||||
MetaRectangle client_rect;
|
||||
int size_dx, size_dy;
|
||||
XWindowChanges values;
|
||||
unsigned int mask;
|
||||
@@ -1021,32 +1058,22 @@ meta_window_x11_move_resize_internal (MetaWindow *window,
|
||||
|
||||
is_configure_request = (flags & META_IS_CONFIGURE_REQUEST) != 0;
|
||||
|
||||
/* meta_window_constrain() might have maximized the window after placement,
|
||||
* changing the borders.
|
||||
*/
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
|
||||
root_x_nw = constrained_rect.x;
|
||||
root_y_nw = constrained_rect.y;
|
||||
w = constrained_rect.width;
|
||||
h = constrained_rect.height;
|
||||
size_dx = constrained_rect.x - window->rect.width;
|
||||
size_dy = constrained_rect.y - window->rect.height;
|
||||
|
||||
size_dx = w - window->rect.width;
|
||||
size_dy = h - window->rect.height;
|
||||
|
||||
if (size_dx != 0 || size_dy != 0)
|
||||
need_resize_client = TRUE;
|
||||
|
||||
window->rect.width = w;
|
||||
window->rect.height = h;
|
||||
window->rect = constrained_rect;
|
||||
|
||||
if (window->frame)
|
||||
{
|
||||
int new_w, new_h;
|
||||
int new_x, new_y;
|
||||
|
||||
new_w = window->rect.width + borders.total.left + borders.total.right;
|
||||
/* Compute new frame size */
|
||||
new_w = window->rect.width + borders.invisible.left + borders.invisible.right;
|
||||
|
||||
new_h = borders.total.top + borders.total.bottom;
|
||||
new_h = borders.invisible.top + borders.invisible.bottom;
|
||||
if (!window->shaded)
|
||||
new_h += window->rect.height;
|
||||
|
||||
@@ -1058,19 +1085,9 @@ meta_window_x11_move_resize_internal (MetaWindow *window,
|
||||
window->frame->rect.height = new_h;
|
||||
}
|
||||
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Calculated frame size %dx%d\n",
|
||||
window->frame->rect.width,
|
||||
window->frame->rect.height);
|
||||
}
|
||||
|
||||
if (window->frame)
|
||||
{
|
||||
int new_x, new_y;
|
||||
|
||||
/* Compute new frame coords */
|
||||
new_x = root_x_nw - borders.total.left;
|
||||
new_y = root_y_nw - borders.total.top;
|
||||
new_x = window->rect.x - borders.invisible.left;
|
||||
new_y = window->rect.y - borders.invisible.top;
|
||||
|
||||
if (new_x != window->frame->rect.x ||
|
||||
new_y != window->frame->rect.y)
|
||||
@@ -1079,22 +1096,35 @@ meta_window_x11_move_resize_internal (MetaWindow *window,
|
||||
window->frame->rect.x = new_x;
|
||||
window->frame->rect.y = new_y;
|
||||
}
|
||||
|
||||
client_move_x = borders.total.left;
|
||||
client_move_y = borders.total.top;
|
||||
}
|
||||
else
|
||||
|
||||
/* Calculate the new client rect */
|
||||
meta_window_frame_rect_to_client_rect (window, &constrained_rect, &client_rect);
|
||||
|
||||
/* The above client_rect is in root window coordinates. The
|
||||
* values we need to pass to XConfigureWindow are in parent
|
||||
* coordinates, so if the window is in a frame, we need to
|
||||
* correct the x/y positions here. */
|
||||
if (window->frame)
|
||||
{
|
||||
client_move_x = root_x_nw;
|
||||
client_move_y = root_y_nw;
|
||||
client_rect.x = borders.total.left;
|
||||
client_rect.y = borders.total.top;
|
||||
}
|
||||
|
||||
if (client_move_x != window->rect.x ||
|
||||
client_move_y != window->rect.y)
|
||||
if (client_rect.x != priv->client_rect.x ||
|
||||
client_rect.y != priv->client_rect.y)
|
||||
{
|
||||
need_move_client = TRUE;
|
||||
window->rect.x = client_move_x;
|
||||
window->rect.y = client_move_y;
|
||||
priv->client_rect.x = client_rect.x;
|
||||
priv->client_rect.y = client_rect.y;
|
||||
}
|
||||
|
||||
if (client_rect.width != priv->client_rect.width ||
|
||||
client_rect.height != priv->client_rect.height)
|
||||
{
|
||||
need_resize_client = TRUE;
|
||||
priv->client_rect.width = client_rect.width;
|
||||
priv->client_rect.height = client_rect.height;
|
||||
}
|
||||
|
||||
/* If frame extents have changed, fill in other frame fields and
|
||||
@@ -1186,10 +1216,10 @@ meta_window_x11_move_resize_internal (MetaWindow *window,
|
||||
need_move_frame, need_resize_frame);
|
||||
|
||||
values.border_width = 0;
|
||||
values.x = client_move_x;
|
||||
values.y = client_move_y;
|
||||
values.width = window->rect.width;
|
||||
values.height = window->rect.height;
|
||||
values.x = client_rect.x;
|
||||
values.y = client_rect.y;
|
||||
values.width = client_rect.width;
|
||||
values.height = client_rect.height;
|
||||
|
||||
mask = 0;
|
||||
if (is_configure_request && priv->border_width != 0)
|
||||
@@ -1226,6 +1256,11 @@ meta_window_x11_move_resize_internal (MetaWindow *window,
|
||||
gravity,
|
||||
need_move_frame, need_resize_frame);
|
||||
|
||||
if (window->frame)
|
||||
window->buffer_rect = window->frame->rect;
|
||||
else
|
||||
window->buffer_rect = client_rect;
|
||||
|
||||
if (need_configure_notify)
|
||||
send_configure_notify (window);
|
||||
|
||||
@@ -1768,6 +1803,8 @@ void
|
||||
meta_window_x11_update_input_region (MetaWindow *window)
|
||||
{
|
||||
cairo_region_t *region = NULL;
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
|
||||
|
||||
/* Decorated windows don't have an input region, because
|
||||
we don't shape the frame to match the client windows
|
||||
@@ -1804,8 +1841,8 @@ meta_window_x11_update_input_region (MetaWindow *window)
|
||||
(n_rects == 1 &&
|
||||
(rects[0].x != 0 ||
|
||||
rects[0].y != 0 ||
|
||||
rects[0].width != window->rect.width ||
|
||||
rects[0].height != window->rect.height)))
|
||||
rects[0].width != priv->client_rect.width ||
|
||||
rects[0].height != priv->client_rect.height)))
|
||||
region = region_create_from_x_rectangles (rects, n_rects);
|
||||
|
||||
XFree (rects);
|
||||
@@ -1818,8 +1855,8 @@ meta_window_x11_update_input_region (MetaWindow *window)
|
||||
|
||||
client_area.x = 0;
|
||||
client_area.y = 0;
|
||||
client_area.width = window->rect.width;
|
||||
client_area.height = window->rect.height;
|
||||
client_area.width = priv->client_rect.width;
|
||||
client_area.height = priv->client_rect.height;
|
||||
|
||||
/* The shape we get back from the client may have coordinates
|
||||
* outside of the frame. The X SHAPE Extension requires that
|
||||
@@ -1850,6 +1887,8 @@ meta_window_set_shape_region (MetaWindow *window,
|
||||
void
|
||||
meta_window_x11_update_shape_region (MetaWindow *window)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
|
||||
cairo_region_t *region = NULL;
|
||||
|
||||
if (META_DISPLAY_HAS_SHAPE (window->display))
|
||||
@@ -1893,8 +1932,8 @@ meta_window_x11_update_shape_region (MetaWindow *window)
|
||||
|
||||
client_area.x = 0;
|
||||
client_area.y = 0;
|
||||
client_area.width = window->rect.width;
|
||||
client_area.height = window->rect.height;
|
||||
client_area.width = priv->client_rect.width;
|
||||
client_area.height = priv->client_rect.height;
|
||||
|
||||
/* The shape we get back from the client may have coordinates
|
||||
* outside of the frame. The X SHAPE Extension requires that
|
||||
@@ -2072,14 +2111,41 @@ meta_window_move_resize_request (MetaWindow *window,
|
||||
|
||||
if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION))
|
||||
{
|
||||
MetaRectangle rect;
|
||||
MetaRectangle rect, monitor_rect;
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
meta_screen_get_monitor_geometry (window->screen, window->monitor->number, &monitor_rect);
|
||||
|
||||
/* Workaround braindead legacy apps that don't know how to
|
||||
* fullscreen themselves properly - don't get fooled by
|
||||
* windows which hide their titlebar when maximized or which are
|
||||
* client decorated; that's not the same as fullscreen, even
|
||||
* if there are no struts making the workarea smaller than
|
||||
* the monitor.
|
||||
*/
|
||||
if (meta_prefs_get_force_fullscreen() &&
|
||||
!window->hide_titlebar_when_maximized &&
|
||||
(window->decorated || !meta_window_is_client_decorated (window)) &&
|
||||
meta_rectangle_equal (&rect, &monitor_rect) &&
|
||||
window->has_fullscreen_func &&
|
||||
!window->fullscreen)
|
||||
{
|
||||
/*
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
*/
|
||||
meta_warning (
|
||||
"Treating resize request of legacy application %s as a "
|
||||
"fullscreen request\n",
|
||||
window->desc);
|
||||
meta_window_make_fullscreen_internal (window);
|
||||
}
|
||||
|
||||
adjust_for_gravity (window, TRUE, gravity, &rect);
|
||||
meta_window_client_rect_to_frame_rect (window, &rect, &rect);
|
||||
meta_window_move_resize_internal (window, flags, gravity, rect);
|
||||
}
|
||||
}
|
||||
@@ -3146,7 +3212,7 @@ meta_window_x11_recalc_window_type (MetaWindow *window)
|
||||
*/
|
||||
if (window->override_redirect)
|
||||
{
|
||||
switch (window->type)
|
||||
switch (type)
|
||||
{
|
||||
/* Decorated types */
|
||||
case META_WINDOW_NORMAL:
|
||||
@@ -3191,6 +3257,9 @@ void
|
||||
meta_window_x11_configure_notify (MetaWindow *window,
|
||||
XConfigureEvent *event)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);
|
||||
|
||||
g_assert (window->override_redirect);
|
||||
g_assert (window->frame == NULL);
|
||||
|
||||
@@ -3198,7 +3267,11 @@ meta_window_x11_configure_notify (MetaWindow *window,
|
||||
window->rect.y = event->y;
|
||||
window->rect.width = event->width;
|
||||
window->rect.height = event->height;
|
||||
meta_window_update_monitor (window);
|
||||
|
||||
priv->client_rect = window->rect;
|
||||
window->buffer_rect = window->rect;
|
||||
|
||||
meta_window_update_monitor (window, FALSE);
|
||||
|
||||
/* Whether an override-redirect window is considered fullscreen depends
|
||||
* on its geometry.
|
||||
@@ -3380,8 +3453,7 @@ meta_window_x11_update_sync_request_counter (MetaWindow *window,
|
||||
}
|
||||
|
||||
window->sync_request_serial = new_counter_value;
|
||||
meta_compositor_set_updates_frozen (window->display->compositor, window,
|
||||
meta_window_updates_are_frozen (window));
|
||||
meta_compositor_sync_updates_frozen (window->display->compositor, window);
|
||||
|
||||
if (window == window->display->grab_window &&
|
||||
meta_grab_op_is_resizing (window->display->grab_op) &&
|
||||
@@ -3416,3 +3488,9 @@ meta_window_x11_update_sync_request_counter (MetaWindow *window,
|
||||
meta_compositor_queue_frame_drawn (window->display->compositor, window,
|
||||
no_delay_frame);
|
||||
}
|
||||
|
||||
Window
|
||||
meta_window_x11_get_toplevel_xwindow (MetaWindow *window)
|
||||
{
|
||||
return window->frame ? window->frame->xwindow : window->xwindow;
|
||||
}
|
||||
|
@@ -73,4 +73,6 @@ gboolean meta_window_x11_client_message (MetaWindow *window,
|
||||
void meta_window_x11_configure_notify (MetaWindow *window,
|
||||
XConfigureEvent *event);
|
||||
|
||||
Window meta_window_x11_get_toplevel_xwindow (MetaWindow *window);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user