Compare commits
59 Commits
wip/xtogls
...
3.13.3
Author | SHA1 | Date | |
---|---|---|---|
![]() |
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 |
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) || {
|
||||
|
56
configure.ac
56
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,15 +184,12 @@ 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"
|
||||
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
|
||||
|
||||
PKG_CHECK_MODULES(MUTTER_NATIVE_BACKEND, [libdrm libsystemd], [have_native_backend=yes], [have_native_backend=no])
|
||||
@@ -299,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])
|
||||
@@ -324,11 +303,6 @@ fi
|
||||
|
||||
GTK_DOC_CHECK([1.15], [--flavour no-tmpl])
|
||||
|
||||
AC_CHECK_DECL([GL_EXT_x11_sync_object],
|
||||
[],
|
||||
[AC_MSG_ERROR([GL_EXT_x11_sync_object definition not found, please update your GL headers])],
|
||||
[#include <GL/glx.h>])
|
||||
|
||||
#### Warnings (last since -Werror can disturb other tests)
|
||||
|
||||
# Stay command-line compatible with the gnome-common configure option. Here
|
||||
@@ -397,6 +371,7 @@ changequote([,])dnl
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
data/Makefile
|
||||
doc/Makefile
|
||||
doc/man/Makefile
|
||||
doc/reference/Makefile
|
||||
@@ -404,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
|
||||
|
@@ -5,38 +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 \
|
||||
@@ -118,8 +115,6 @@ libmutter_la_SOURCES = \
|
||||
compositor/meta-surface-actor-wayland.h \
|
||||
compositor/meta-stage.h \
|
||||
compositor/meta-stage.c \
|
||||
compositor/meta-sync-ring.c \
|
||||
compositor/meta-sync-ring.h \
|
||||
compositor/meta-texture-rectangle.c \
|
||||
compositor/meta-texture-rectangle.h \
|
||||
compositor/meta-texture-tower.c \
|
||||
@@ -196,6 +191,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 \
|
||||
@@ -225,6 +222,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 \
|
||||
@@ -258,7 +257,7 @@ 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 \
|
||||
@@ -287,6 +286,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 = \
|
||||
@@ -295,9 +301,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
|
||||
@@ -326,7 +335,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 \
|
||||
@@ -346,53 +355,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 \
|
||||
|
@@ -103,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)
|
||||
{
|
||||
@@ -122,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
|
||||
|
@@ -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
|
||||
|
@@ -15,8 +15,7 @@ struct _MetaCompositor
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
guint pre_paint_func_id;
|
||||
guint post_paint_func_id;
|
||||
guint repaint_func_id;
|
||||
|
||||
gint64 server_time_query_time;
|
||||
gint64 server_time_offset;
|
||||
@@ -39,9 +38,6 @@ struct _MetaCompositor
|
||||
gint switch_workspace_in_progress;
|
||||
|
||||
MetaPluginManager *plugin_mgr;
|
||||
|
||||
gboolean frame_has_updated_xsurfaces;
|
||||
gboolean have_x11_sync_object;
|
||||
};
|
||||
|
||||
/* Wait 2ms after vblank before starting to draw next frame */
|
||||
|
@@ -79,7 +79,6 @@
|
||||
#include "frame.h"
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
#include "meta-sync-ring.h"
|
||||
|
||||
#include "backends/meta-backend.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
@@ -137,11 +136,7 @@ meta_switch_workspace_completed (MetaCompositor *compositor)
|
||||
void
|
||||
meta_compositor_destroy (MetaCompositor *compositor)
|
||||
{
|
||||
clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
|
||||
clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
|
||||
|
||||
if (compositor->have_x11_sync_object)
|
||||
meta_sync_ring_destroy ();
|
||||
clutter_threads_remove_repaint_func (compositor->repaint_func_id);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -151,8 +146,6 @@ process_damage (MetaCompositor *compositor,
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
meta_window_actor_process_x11_damage (window_actor, event);
|
||||
|
||||
compositor->frame_has_updated_xsurfaces = TRUE;
|
||||
}
|
||||
|
||||
static Window
|
||||
@@ -576,8 +569,6 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
* contents until we show the stage.
|
||||
*/
|
||||
XMapWindow (xdisplay, compositor->output);
|
||||
|
||||
compositor->have_x11_sync_object = meta_sync_ring_init (display);
|
||||
}
|
||||
|
||||
redirect_windows (display->screen);
|
||||
@@ -700,12 +691,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
|
||||
@@ -789,10 +779,6 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
||||
if (!meta_is_wayland_compositor () && event->type == MapNotify)
|
||||
clutter_x11_handle_event (event);
|
||||
|
||||
if (compositor->have_x11_sync_object &&
|
||||
event->type == (compositor->display->xsync_event_base + XSyncAlarmNotify))
|
||||
meta_sync_ring_handle_event ((XSyncAlarmNotifyEvent *) event);
|
||||
|
||||
/* The above handling is basically just "observing" the events, so we return
|
||||
* FALSE to indicate that the event should not be filtered out; if we have
|
||||
* GTK+ windows in the same process, GTK+ needs the ConfigureNotify event, for example.
|
||||
@@ -1138,12 +1124,11 @@ frame_callback (CoglOnscreen *onscreen,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_pre_paint_func (gpointer data)
|
||||
static void
|
||||
pre_paint_windows (MetaCompositor *compositor)
|
||||
{
|
||||
GList *l;
|
||||
MetaWindowActor *top_window;
|
||||
MetaCompositor *compositor = data;
|
||||
|
||||
if (compositor->onscreen == NULL)
|
||||
{
|
||||
@@ -1155,7 +1140,7 @@ meta_pre_paint_func (gpointer data)
|
||||
}
|
||||
|
||||
if (compositor->windows == NULL)
|
||||
return TRUE;
|
||||
return;
|
||||
|
||||
top_window = g_list_last (compositor->windows)->data;
|
||||
|
||||
@@ -1167,53 +1152,13 @@ meta_pre_paint_func (gpointer data)
|
||||
|
||||
for (l = compositor->windows; l; l = l->next)
|
||||
meta_window_actor_pre_paint (l->data);
|
||||
|
||||
if (compositor->frame_has_updated_xsurfaces)
|
||||
{
|
||||
/* We need to make sure that any X drawing that happens before
|
||||
* the XDamageSubtract() for each window above is visible to
|
||||
* subsequent GL rendering; the standardized way to do this is
|
||||
* GL_EXT_X11_sync_object. Since this isn't implemented yet in
|
||||
* mesa, we also have a path that relies on the implementation
|
||||
* of the open source drivers.
|
||||
*
|
||||
* Anything else, we just hope for the best.
|
||||
*
|
||||
* Xorg and open source driver specifics:
|
||||
*
|
||||
* The X server makes sure to flush drawing to the kernel before
|
||||
* sending out damage events, but since we use
|
||||
* DamageReportBoundingBox there may be drawing between the last
|
||||
* damage event and the XDamageSubtract() that needs to be
|
||||
* flushed as well.
|
||||
*
|
||||
* Xorg always makes sure that drawing is flushed to the kernel
|
||||
* before writing events or responses to the client, so any
|
||||
* round trip request at this point is sufficient to flush the
|
||||
* GLX buffers.
|
||||
*/
|
||||
if (compositor->have_x11_sync_object)
|
||||
compositor->have_x11_sync_object = meta_sync_ring_insert_wait ();
|
||||
else
|
||||
XSync (compositor->display->xdisplay, False);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_post_paint_func (gpointer data)
|
||||
meta_repaint_func (gpointer data)
|
||||
{
|
||||
MetaCompositor *compositor = data;
|
||||
|
||||
if (compositor->frame_has_updated_xsurfaces)
|
||||
{
|
||||
if (compositor->have_x11_sync_object)
|
||||
compositor->have_x11_sync_object = meta_sync_ring_after_frame ();
|
||||
|
||||
compositor->frame_has_updated_xsurfaces = FALSE;
|
||||
}
|
||||
|
||||
pre_paint_windows (compositor);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1252,16 +1197,10 @@ meta_compositor_new (MetaDisplay *display)
|
||||
G_CALLBACK (on_shadow_factory_changed),
|
||||
compositor);
|
||||
|
||||
compositor->pre_paint_func_id =
|
||||
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_PRE_PAINT,
|
||||
meta_pre_paint_func,
|
||||
compositor,
|
||||
NULL);
|
||||
compositor->post_paint_func_id =
|
||||
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
|
||||
meta_post_paint_func,
|
||||
compositor,
|
||||
NULL);
|
||||
compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func,
|
||||
compositor,
|
||||
NULL);
|
||||
|
||||
return compositor;
|
||||
}
|
||||
|
||||
@@ -1426,3 +1365,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);
|
||||
@@ -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);
|
||||
@@ -238,6 +239,26 @@ meta_surface_actor_x11_pre_paint (MetaSurfaceActor *actor)
|
||||
XDamageSubtract (xdisplay, priv->damage, None, None);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
/* We need to make sure that any X drawing that happens before the
|
||||
* XDamageSubtract() above is visible to subsequent GL rendering;
|
||||
* the only standardized way to do this is EXT_x11_sync_object,
|
||||
* which isn't yet widely available. For now, we count on details
|
||||
* of Xorg and the open source drivers, and hope for the best
|
||||
* otherwise.
|
||||
*
|
||||
* Xorg and open source driver specifics:
|
||||
*
|
||||
* The X server makes sure to flush drawing to the kernel before
|
||||
* sending out damage events, but since we use DamageReportBoundingBox
|
||||
* there may be drawing between the last damage event and the
|
||||
* XDamageSubtract() that needs to be flushed as well.
|
||||
*
|
||||
* Xorg always makes sure that drawing is flushed to the kernel
|
||||
* before writing events or responses to the client, so any round trip
|
||||
* request at this point is sufficient to flush the GLX buffers.
|
||||
*/
|
||||
XSync (xdisplay, False);
|
||||
|
||||
priv->received_damage = FALSE;
|
||||
}
|
||||
|
||||
@@ -292,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);
|
||||
|
||||
@@ -384,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);
|
||||
}
|
||||
|
@@ -1,574 +0,0 @@
|
||||
/*
|
||||
* This is based on an original C++ implementation for compiz that
|
||||
* carries the following copyright notice:
|
||||
*
|
||||
*
|
||||
* Copyright © 2011 NVIDIA Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of NVIDIA
|
||||
* Corporation not be used in advertising or publicity pertaining to
|
||||
* distribution of the software without specific, written prior
|
||||
* permission. NVIDIA Corporation makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Authors: James Jones <jajones@nvidia.com>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include <meta/display.h>
|
||||
#include <meta/util.h>
|
||||
|
||||
#include "meta-sync-ring.h"
|
||||
|
||||
/* Theory of operation:
|
||||
*
|
||||
* We use a ring of NUM_SYNCS fence objects. On each frame we advance
|
||||
* to the next fence in the ring. For each fence we do:
|
||||
*
|
||||
* 1. fence is XSyncTriggerFence()'d and glWaitSync()'d
|
||||
* 2. NUM_SYNCS / 2 frames later, fence should be triggered
|
||||
* 3. fence is XSyncResetFence()'d
|
||||
* 4. NUM_SYNCS / 2 frames later, fence should be reset
|
||||
* 5. go back to 1 and re-use fence
|
||||
*
|
||||
* glClientWaitSync() and XAlarms are used in steps 2 and 4,
|
||||
* respectively, to double-check the expectections.
|
||||
*/
|
||||
|
||||
#define NUM_SYNCS 10
|
||||
#define MAX_SYNC_WAIT_TIME (1 * 1000 * 1000 * 1000) /* one sec */
|
||||
#define MAX_REBOOT_ATTEMPTS 2
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_SYNC_STATE_READY,
|
||||
META_SYNC_STATE_WAITING,
|
||||
META_SYNC_STATE_DONE,
|
||||
META_SYNC_STATE_RESET_PENDING,
|
||||
} MetaSyncState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Display *xdisplay;
|
||||
|
||||
XSyncFence xfence;
|
||||
GLsync glsync;
|
||||
|
||||
XSyncCounter xcounter;
|
||||
XSyncAlarm xalarm;
|
||||
XSyncValue next_counter_value;
|
||||
|
||||
MetaSyncState state;
|
||||
} MetaSync;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
GHashTable *alarm_to_sync;
|
||||
|
||||
MetaSync *syncs_array[NUM_SYNCS];
|
||||
guint current_sync_idx;
|
||||
MetaSync *current_sync;
|
||||
guint warmup_syncs;
|
||||
|
||||
guint reboots;
|
||||
} MetaSyncRing;
|
||||
|
||||
static MetaSyncRing meta_sync_ring = { 0 };
|
||||
|
||||
static XSyncValue SYNC_VALUE_ZERO;
|
||||
static XSyncValue SYNC_VALUE_ONE;
|
||||
|
||||
static void (*meta_gl_get_integerv) (GLenum pname,
|
||||
GLint *params);
|
||||
static const char* (*meta_gl_get_stringi) (GLenum name,
|
||||
GLuint index);
|
||||
static void (*meta_gl_delete_sync) (GLsync sync);
|
||||
static GLenum (*meta_gl_client_wait_sync) (GLsync sync,
|
||||
GLbitfield flags,
|
||||
GLuint64 timeout);
|
||||
static void (*meta_gl_wait_sync) (GLsync sync,
|
||||
GLbitfield flags,
|
||||
GLuint64 timeout);
|
||||
static GLsync (*meta_gl_import_sync) (GLenum external_sync_type,
|
||||
GLintptr external_sync,
|
||||
GLbitfield flags);
|
||||
|
||||
static GLenum (*meta_gl_get_error) (void);
|
||||
static GLboolean (*meta_gl_is_sync) (GLsync sync);
|
||||
|
||||
static MetaSyncRing *
|
||||
meta_sync_ring_get (void)
|
||||
{
|
||||
if (meta_sync_ring.reboots > MAX_REBOOT_ATTEMPTS)
|
||||
return NULL;
|
||||
|
||||
return &meta_sync_ring;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_gl_symbol (const char *name,
|
||||
void **func)
|
||||
{
|
||||
*func = cogl_get_proc_address (name);
|
||||
if (!*func)
|
||||
{
|
||||
meta_verbose ("MetaSyncRing: failed to resolve required GL symbol \"%s\"\n", name);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_gl_extensions (void)
|
||||
{
|
||||
int num_extensions, i;
|
||||
gboolean sync = FALSE;
|
||||
gboolean x11_sync_object = FALSE;
|
||||
|
||||
meta_gl_get_integerv (GL_NUM_EXTENSIONS, &num_extensions);
|
||||
|
||||
for (i = 0; i < num_extensions; ++i)
|
||||
{
|
||||
const char *ext = meta_gl_get_stringi (GL_EXTENSIONS, i);
|
||||
|
||||
if (g_strcmp0 ("GL_ARB_sync", ext) == 0)
|
||||
sync = TRUE;
|
||||
else if (g_strcmp0 ("GL_EXT_x11_sync_object", ext) == 0)
|
||||
x11_sync_object = TRUE;
|
||||
}
|
||||
|
||||
return sync && x11_sync_object;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_required_symbols (void)
|
||||
{
|
||||
static gboolean success = FALSE;
|
||||
|
||||
if (success)
|
||||
return TRUE;
|
||||
|
||||
/* We don't link against libGL directly because cogl may want to
|
||||
* use something else. This assumes that cogl has been initialized
|
||||
* and dynamically loaded libGL at this point.
|
||||
*/
|
||||
|
||||
if (!load_gl_symbol ("glGetIntegerv", (void **) &meta_gl_get_integerv))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glGetStringi", (void **) &meta_gl_get_stringi))
|
||||
goto out;
|
||||
|
||||
if (!check_gl_extensions ())
|
||||
{
|
||||
meta_verbose ("MetaSyncRing: couldn't find required GL extensions\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!load_gl_symbol ("glDeleteSync", (void **) &meta_gl_delete_sync))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glClientWaitSync", (void **) &meta_gl_client_wait_sync))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glWaitSync", (void **) &meta_gl_wait_sync))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync))
|
||||
goto out;
|
||||
|
||||
if (!load_gl_symbol ("glGetError", (void **) &meta_gl_get_error))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glIsSync", (void **) &meta_gl_is_sync))
|
||||
goto out;
|
||||
|
||||
success = TRUE;
|
||||
out:
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
print_gl_error (void)
|
||||
{
|
||||
GLenum e;
|
||||
switch (e = meta_gl_get_error ())
|
||||
{
|
||||
case GL_NO_ERROR:
|
||||
meta_warning ("GL_NO_ERROR\n");
|
||||
break;
|
||||
case GL_INVALID_ENUM:
|
||||
meta_warning ("GL_INVALID_ENUM\n");
|
||||
break;
|
||||
case GL_INVALID_VALUE:
|
||||
meta_warning ("GL_INVALID_VALUE\n");
|
||||
break;
|
||||
case GL_INVALID_OPERATION:
|
||||
meta_warning ("GL_INVALID_OPERATION\n");
|
||||
break;
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||
meta_warning ("GL_INVALID_FRAMEBUFFER_OPERATION\n");
|
||||
break;
|
||||
case GL_OUT_OF_MEMORY:
|
||||
meta_warning ("GL_OUT_OF_MEMORY\n");
|
||||
break;
|
||||
case GL_STACK_OVERFLOW:
|
||||
meta_warning ("GL_STACK_OVERFLOW\n");
|
||||
break;
|
||||
case GL_STACK_UNDERFLOW:
|
||||
meta_warning ("GL_STACK_UNDERFLOW\n");
|
||||
break;
|
||||
default:
|
||||
meta_warning ("GL error 0x%x\n", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_insert (MetaSync *self)
|
||||
{
|
||||
g_return_if_fail (self->state == META_SYNC_STATE_READY);
|
||||
|
||||
XSyncTriggerFence (self->xdisplay, self->xfence);
|
||||
XFlush (self->xdisplay);
|
||||
|
||||
meta_gl_wait_sync (self->glsync, 0, GL_TIMEOUT_IGNORED);
|
||||
|
||||
self->state = META_SYNC_STATE_WAITING;
|
||||
}
|
||||
|
||||
static GLenum
|
||||
meta_sync_check_update_finished (MetaSync *self,
|
||||
GLuint64 timeout)
|
||||
{
|
||||
GLenum status = GL_WAIT_FAILED;
|
||||
|
||||
switch (self->state)
|
||||
{
|
||||
case META_SYNC_STATE_DONE:
|
||||
status = GL_ALREADY_SIGNALED;
|
||||
break;
|
||||
case META_SYNC_STATE_WAITING:
|
||||
status = meta_gl_client_wait_sync (self->glsync, 0, timeout);
|
||||
if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED)
|
||||
self->state = META_SYNC_STATE_DONE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_warn_if_fail (status != GL_WAIT_FAILED);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_reset (MetaSync *self)
|
||||
{
|
||||
XSyncAlarmAttributes attrs;
|
||||
int overflow;
|
||||
|
||||
g_return_if_fail (self->state == META_SYNC_STATE_DONE);
|
||||
|
||||
XSyncResetFence (self->xdisplay, self->xfence);
|
||||
|
||||
attrs.trigger.wait_value = self->next_counter_value;
|
||||
|
||||
XSyncChangeAlarm (self->xdisplay, self->xalarm, XSyncCAValue, &attrs);
|
||||
XSyncSetCounter (self->xdisplay, self->xcounter, self->next_counter_value);
|
||||
|
||||
XSyncValueAdd (&self->next_counter_value,
|
||||
self->next_counter_value,
|
||||
SYNC_VALUE_ONE,
|
||||
&overflow);
|
||||
|
||||
self->state = META_SYNC_STATE_RESET_PENDING;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_handle_event (MetaSync *self,
|
||||
XSyncAlarmNotifyEvent *event)
|
||||
{
|
||||
g_return_if_fail (event->alarm == self->xalarm);
|
||||
g_return_if_fail (self->state == META_SYNC_STATE_RESET_PENDING);
|
||||
|
||||
self->state = META_SYNC_STATE_READY;
|
||||
}
|
||||
|
||||
static MetaSync *
|
||||
meta_sync_new (Display *xdisplay)
|
||||
{
|
||||
MetaSync *self;
|
||||
XSyncAlarmAttributes attrs;
|
||||
|
||||
self = g_malloc0 (sizeof (MetaSync));
|
||||
|
||||
self->xdisplay = xdisplay;
|
||||
|
||||
self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), FALSE);
|
||||
meta_warning ("created X fence 0x%x\n", self->xfence);
|
||||
self->glsync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0);
|
||||
print_gl_error ();
|
||||
|
||||
self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO);
|
||||
|
||||
attrs.trigger.counter = self->xcounter;
|
||||
attrs.trigger.value_type = XSyncAbsolute;
|
||||
attrs.trigger.wait_value = SYNC_VALUE_ONE;
|
||||
attrs.trigger.test_type = XSyncPositiveTransition;
|
||||
attrs.events = TRUE;
|
||||
self->xalarm = XSyncCreateAlarm (xdisplay,
|
||||
XSyncCACounter |
|
||||
XSyncCAValueType |
|
||||
XSyncCAValue |
|
||||
XSyncCATestType |
|
||||
XSyncCAEvents,
|
||||
&attrs);
|
||||
|
||||
XSyncIntToValue (&self->next_counter_value, 1);
|
||||
|
||||
self->state = META_SYNC_STATE_READY;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static Bool
|
||||
alarm_event_predicate (Display *dpy,
|
||||
XEvent *event,
|
||||
XPointer data)
|
||||
{
|
||||
int xsync_event_base;
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return False;
|
||||
|
||||
xsync_event_base = meta_display_get_sync_event_base (ring->display);
|
||||
|
||||
if (event->type == xsync_event_base + XSyncAlarmNotify)
|
||||
{
|
||||
if (((MetaSync *) data)->xalarm == ((XSyncAlarmNotifyEvent *) event)->alarm)
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_free (MetaSync *self)
|
||||
{
|
||||
/* When our assumptions don't hold, something has gone wrong but we
|
||||
* don't know what, so we reboot the ring. While doing that, we
|
||||
* trigger fences before deleting them to try to get ourselves out
|
||||
* of a potentially stuck GPU state.
|
||||
*/
|
||||
switch (self->state)
|
||||
{
|
||||
case META_SYNC_STATE_WAITING:
|
||||
case META_SYNC_STATE_DONE:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case META_SYNC_STATE_RESET_PENDING:
|
||||
{
|
||||
XEvent event;
|
||||
XIfEvent (self->xdisplay, &event, alarm_event_predicate, (XPointer) self);
|
||||
meta_sync_handle_event (self, (XSyncAlarmNotifyEvent *) &event);
|
||||
}
|
||||
/* fall through */
|
||||
case META_SYNC_STATE_READY:
|
||||
XSyncTriggerFence (self->xdisplay, self->xfence);
|
||||
XFlush (self->xdisplay);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
meta_gl_delete_sync (self->glsync);
|
||||
XSyncDestroyFence (self->xdisplay, self->xfence);
|
||||
XSyncDestroyCounter (self->xdisplay, self->xcounter);
|
||||
XSyncDestroyAlarm (self->xdisplay, self->xalarm);
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_sync_ring_init (MetaDisplay *display)
|
||||
{
|
||||
guint i;
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
g_return_val_if_fail (display != NULL, FALSE);
|
||||
g_return_val_if_fail (ring->display == NULL, FALSE);
|
||||
|
||||
if (!load_required_symbols ())
|
||||
return FALSE;
|
||||
|
||||
if (!meta_display_has_sync (display))
|
||||
return FALSE;
|
||||
|
||||
print_gl_error ();
|
||||
|
||||
XSyncIntToValue (&SYNC_VALUE_ZERO, 0);
|
||||
XSyncIntToValue (&SYNC_VALUE_ONE, 1);
|
||||
|
||||
ring->display = display;
|
||||
|
||||
ring->alarm_to_sync = g_hash_table_new (NULL, NULL);
|
||||
|
||||
for (i = 0; i < NUM_SYNCS; ++i)
|
||||
{
|
||||
MetaSync *sync = meta_sync_new (meta_display_get_xdisplay (display));
|
||||
ring->syncs_array[i] = sync;
|
||||
g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, sync);
|
||||
}
|
||||
|
||||
ring->current_sync_idx = 0;
|
||||
ring->current_sync = ring->syncs_array[0];
|
||||
ring->warmup_syncs = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_sync_ring_destroy (void)
|
||||
{
|
||||
guint i;
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return;
|
||||
|
||||
g_return_if_fail (ring->display != NULL);
|
||||
|
||||
ring->current_sync_idx = 0;
|
||||
ring->current_sync = NULL;
|
||||
ring->warmup_syncs = 0;
|
||||
|
||||
for (i = 0; i < NUM_SYNCS; ++i)
|
||||
meta_sync_free (ring->syncs_array[i]);
|
||||
|
||||
g_hash_table_destroy (ring->alarm_to_sync);
|
||||
|
||||
ring->display = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_sync_ring_reboot (MetaDisplay *display)
|
||||
{
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
meta_sync_ring_destroy ();
|
||||
|
||||
ring->reboots += 1;
|
||||
|
||||
if (!meta_sync_ring_get ())
|
||||
{
|
||||
meta_warning ("MetaSyncRing: Too many reboots -- disabling\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return meta_sync_ring_init (display);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_sync_ring_after_frame (void)
|
||||
{
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
g_return_if_fail (ring->display != NULL);
|
||||
|
||||
if (ring->warmup_syncs >= NUM_SYNCS / 2)
|
||||
{
|
||||
guint reset_sync_idx = (ring->current_sync_idx + NUM_SYNCS - (NUM_SYNCS / 2)) % NUM_SYNCS;
|
||||
MetaSync *sync_to_reset = ring->syncs_array[reset_sync_idx];
|
||||
|
||||
GLenum status = meta_sync_check_update_finished (sync_to_reset, 0);
|
||||
if (status == GL_TIMEOUT_EXPIRED)
|
||||
{
|
||||
meta_warning ("MetaSyncRing: We should never wait for a sync -- add more syncs?\n");
|
||||
status = meta_sync_check_update_finished (sync_to_reset, MAX_SYNC_WAIT_TIME);
|
||||
}
|
||||
|
||||
if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED)
|
||||
{
|
||||
meta_warning ("MetaSyncRing: Timed out waiting for sync object.\n");
|
||||
return meta_sync_ring_reboot (ring->display);
|
||||
}
|
||||
|
||||
meta_sync_reset (sync_to_reset);
|
||||
}
|
||||
else
|
||||
{
|
||||
ring->warmup_syncs += 1;
|
||||
}
|
||||
|
||||
ring->current_sync_idx += 1;
|
||||
ring->current_sync_idx %= NUM_SYNCS;
|
||||
|
||||
ring->current_sync = ring->syncs_array[ring->current_sync_idx];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_sync_ring_insert_wait (void)
|
||||
{
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
g_return_if_fail (ring->display != NULL);
|
||||
|
||||
if (ring->current_sync->state != META_SYNC_STATE_READY)
|
||||
{
|
||||
meta_warning ("MetaSyncRing: Sync object is not ready -- were events handled properly?\n");
|
||||
if (!meta_sync_ring_reboot (ring->display))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
meta_sync_insert (ring->current_sync);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_sync_ring_handle_event (XSyncAlarmNotifyEvent *event)
|
||||
{
|
||||
MetaSync *sync;
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return;
|
||||
|
||||
g_return_if_fail (ring->display != NULL);
|
||||
|
||||
sync = g_hash_table_lookup (ring->alarm_to_sync, (gpointer) event->alarm);
|
||||
if (sync)
|
||||
meta_sync_handle_event (sync, event);
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
#ifndef _META_SYNC_RING_H_
|
||||
#define _META_SYNC_RING_H_
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/sync.h>
|
||||
|
||||
#include <meta/display.h>
|
||||
|
||||
gboolean meta_sync_ring_init (MetaDisplay *dpy);
|
||||
void meta_sync_ring_destroy (void);
|
||||
gboolean meta_sync_ring_after_frame (void);
|
||||
gboolean meta_sync_ring_insert_wait (void);
|
||||
void meta_sync_ring_handle_event (XSyncAlarmNotifyEvent *event);
|
||||
|
||||
#endif /* _META_SYNC_RING_H_ */
|
@@ -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,
|
||||
|
@@ -392,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
|
||||
{
|
||||
@@ -138,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,
|
||||
|
@@ -181,7 +181,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;
|
||||
|
@@ -805,6 +805,7 @@ meta_display_open (void)
|
||||
|
||||
enable_compositor (the_display);
|
||||
|
||||
meta_screen_init_workspaces (screen);
|
||||
meta_screen_create_guard_window (screen);
|
||||
|
||||
/* We know that if mutter is running as a Wayland compositor,
|
||||
@@ -1343,23 +1344,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 +1352,7 @@ window_raise_with_delay_callback (void *data)
|
||||
window->desc);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1696,15 +1681,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 +1737,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);
|
||||
@@ -2525,21 +2510,19 @@ mru_cmp (gconstpointer a,
|
||||
* meta_display_get_tab_list:
|
||||
* @display: a #MetaDisplay
|
||||
* @type: type of tab list
|
||||
* @screen: a #MetaScreen
|
||||
* @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;
|
||||
@@ -2614,7 +2597,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;
|
||||
@@ -3120,12 +3103,6 @@ meta_display_has_shape (MetaDisplay *display)
|
||||
return META_DISPLAY_HAS_SHAPE (display);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_display_has_sync (MetaDisplay *display)
|
||||
{
|
||||
return META_DISPLAY_HAS_XSYNC (display);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_get_focus_window:
|
||||
* @display: a #MetaDisplay
|
||||
@@ -3154,12 +3131,6 @@ meta_display_get_shape_event_base (MetaDisplay *display)
|
||||
return display->shape_event_base;
|
||||
}
|
||||
|
||||
int
|
||||
meta_display_get_sync_event_base (MetaDisplay *display)
|
||||
{
|
||||
return display->xsync_event_base;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_clear_mouse_mode:
|
||||
* @display: a #MetaDisplay
|
||||
|
1786
src/core/events.c
1786
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
|
||||
|
||||
|
@@ -57,6 +57,7 @@
|
||||
|
||||
#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"
|
||||
@@ -1223,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;
|
||||
@@ -1437,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);
|
||||
|
@@ -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;
|
||||
@@ -421,6 +422,15 @@ struct _MetaWindow
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -575,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);
|
||||
|
||||
@@ -664,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,
|
||||
@@ -678,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);
|
||||
@@ -698,4 +711,6 @@ 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;
|
||||
|
||||
@@ -1275,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;
|
||||
@@ -1405,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));
|
||||
}
|
||||
|
||||
@@ -3542,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;
|
||||
@@ -3593,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;
|
||||
|
||||
@@ -3603,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);
|
||||
|
||||
@@ -3629,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3658,6 +3674,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
*/
|
||||
|
||||
gboolean did_placement;
|
||||
guint old_output_id;
|
||||
MetaRectangle unconstrained_rect;
|
||||
MetaRectangle constrained_rect;
|
||||
MetaMoveResizeResultFlags result = 0;
|
||||
@@ -3742,7 +3759,13 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
did_placement);
|
||||
}
|
||||
|
||||
meta_window_update_monitor (window);
|
||||
old_output_id = window->monitor->output_id;
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -3862,6 +3885,7 @@ 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);
|
||||
@@ -4036,26 +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;
|
||||
meta_window_frame_rect_to_client_rect ((MetaWindow *) window, rect, rect);
|
||||
}
|
||||
*rect = window->buffer_rect;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5251,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)
|
||||
{
|
||||
@@ -7654,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);
|
||||
@@ -7684,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);
|
||||
@@ -7695,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
|
||||
@@ -7784,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
|
||||
@@ -7932,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 */
|
||||
|
@@ -75,7 +75,6 @@ Display *meta_display_get_xdisplay (MetaDisplay *display);
|
||||
MetaCompositor *meta_display_get_compositor (MetaDisplay *display);
|
||||
|
||||
gboolean meta_display_has_shape (MetaDisplay *display);
|
||||
gboolean meta_display_has_sync (MetaDisplay *display);
|
||||
|
||||
MetaWindow *meta_display_get_focus_window (MetaDisplay *display);
|
||||
|
||||
@@ -84,7 +83,6 @@ gboolean meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
|
||||
|
||||
int meta_display_get_damage_event_base (MetaDisplay *display);
|
||||
int meta_display_get_shape_event_base (MetaDisplay *display);
|
||||
int meta_display_get_sync_event_base (MetaDisplay *display);
|
||||
|
||||
gboolean meta_display_xserver_time_is_before (MetaDisplay *display,
|
||||
guint32 time1,
|
||||
@@ -96,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;
|
||||
|
122
src/ui/frames.c
122
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);
|
||||
}
|
||||
|
||||
@@ -1218,30 +1216,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 &&
|
||||
@@ -1506,7 +1510,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 */
|
||||
@@ -1575,31 +1580,8 @@ 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;
|
||||
@@ -1637,9 +1619,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)
|
||||
@@ -1738,42 +1718,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;
|
||||
@@ -1932,6 +1912,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);
|
||||
|
||||
@@ -1944,6 +1926,8 @@ meta_frames_leave_notify_event (GtkWidget *widget,
|
||||
{
|
||||
MetaUIFrame *frame;
|
||||
MetaFrames *frames;
|
||||
Display *display;
|
||||
MetaGrabOp grab_op;
|
||||
|
||||
frames = META_FRAMES (widget);
|
||||
|
||||
@@ -1951,6 +1935,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;
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -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),
|
||||
|
548
src/wayland/meta-wayland-touch.c
Normal file
548
src/wayland/meta-wayland-touch.c
Normal file
@@ -0,0 +1,548 @@
|
||||
/*
|
||||
* 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 void
|
||||
touch_handle_cancel_event (MetaWaylandTouch *touch,
|
||||
struct libinput_event *event)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
touch_handle_cancel_event (touch, event);
|
||||
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));
|
||||
}
|
62
src/wayland/meta-wayland-touch.h
Normal file
62
src/wayland/meta-wayland-touch.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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);
|
||||
|
||||
#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;
|
||||
|
||||
|
1821
src/x11/events.c
Normal file
1821
src/x11/events.c
Normal file
File diff suppressed because it is too large
Load Diff
31
src/x11/events.h
Normal file
31
src/x11/events.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/* -*- 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);
|
||||
|
||||
#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;
|
||||
|
@@ -204,6 +204,8 @@ 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;
|
||||
@@ -534,11 +536,23 @@ 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.
|
||||
*/
|
||||
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;
|
||||
@@ -639,12 +653,6 @@ 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);
|
||||
@@ -652,7 +660,15 @@ meta_window_x11_unmanage (MetaWindow *window)
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
if (window->frame)
|
||||
meta_window_destroy_frame (window);
|
||||
{
|
||||
/* 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
|
||||
@@ -913,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))
|
||||
@@ -977,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
|
||||
@@ -1242,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);
|
||||
|
||||
@@ -2092,13 +2111,39 @@ 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);
|
||||
@@ -3167,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:
|
||||
@@ -3212,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);
|
||||
|
||||
@@ -3219,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.
|
||||
@@ -3401,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) &&
|
||||
@@ -3437,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