Compare commits

..

19 Commits

Author SHA1 Message Date
Owen W. Taylor
8a0de6dfd3 Avoid restacking animating hidden actors
Since the stack passed to the compositor now accurately reflects
the X stacking order, we need to treat hidden windows (which are
at the bottom of the X stacking order) specially - when the
compositor stacking order is synced, try to keep animating hidden
actors in their old positions in the stack.

http://bugzilla.gnome.org/show_bug.cgi?id=585984
2009-06-27 09:58:45 -04:00
Owen W. Taylor
2bf0b2b6de Merge branch 'master' into override-redirect-exclusion 2009-06-19 11:42:03 -04:00
Owen W. Taylor
eed2a2d324 Fix shadowing problem breaking MetaStackTracker
A variable shadowing problem introduced in cleanup was causing
queued elements to be removed too early.

http://bugzilla.gnome.org/show_bug.cgi?id=585984
2009-06-17 14:23:57 -04:00
Owen W. Taylor
9828007a02 Merge branch 'master' into override-redirect-exclusion
Conflicts:
	src/core/bell.c
2009-06-17 13:40:42 -04:00
Owen W. Taylor
1f890672bb Use MetaStackTracker to avoid a round-trip XQueryTree()
With MetaStackTracker, it's no longer necessary to XQueryTree to
get a reasonably-up-to-date view of the server stacking order.

Add some comments explaining unclear aspects of
raise_window_relative_to_managed_windows() and with future possible
improvements.

http://bugzilla.gnome.org/show_bug.cgi?id=585984
2009-06-16 09:56:43 -04:00
Owen W. Taylor
ef966854d5 Don't do stacking for override-redirect windows
Don't add override-redirect windows to MetaStack; we shouldn't
be restacking them.

Since we *aren't* stacking the override-redirect windows, we need to
be careful that to ignore them when looking for the top managed
window.

http://bugzilla.gnome.org/show_bug.cgi?id=585984
2009-06-16 09:56:42 -04:00
Owen W. Taylor
7309b6cfe3 Move compositor-stack handling to MetaStackTracker
In order to properly track the stacking order for override-redirect
windows, move meta_compositor_sync_stack() call into MetaStackTracker.
In the new location, we sync the stack as a before-redraw idle function,
rather then using the freeze-thaw facilities of MetaStack. This is
simpler, and also properly compresses multiple stack changes on
notifications received from the X server.

http://bugzilla.gnome.org/show_bug.cgi?id=585984
2009-06-16 09:56:42 -04:00
Owen W. Taylor
3705a224f0 Add better tracking of real stacking order
Wedging override-redirect windows into the constraint code in stack.c
results in Mutter getting confused about the stacking order of
these windows with respect to other windows, and may also in some
cases cause Mutter to restack override-redirect windows.

core/stack-tracker.c core/stack-tracker.h: MetaStackTracker - combine
  events received from the X server with local changes we have made
  to come up with the best possible idea of what the stacking order
  is at any one point in time.

core/screen.c core/screen-private.h: Create a MetaStackTracker for
  the screen.

core/display.c: Feed relevant events to MetaStackTracker

core/frame.c core/screen.c core/stack.c: When we make changes to the
  stacking order or add windows, record those changes immediatley
  in MetaStackTracker so we have the information without waiting
  for a round-trip.

include/ui.h ui/ui.c: meta_ui_create_frame_window add a return value
  for the X request serial used to create the window.

http://bugzilla.gnome.org/show_bug.cgi?id=585984
2009-06-16 09:56:42 -04:00
Owen W. Taylor
2ebedb822d Avoid moving and resizing override-redirect windows
Override-redirect windows should not be moved or resized by the
window manager.

- Mark override-redirect windows as already placed to avoid
  placing them when first shown.
- Don't move-resize newly created override-redirect MetaWindow
- Don't queue a resize on override-redirect windows when reading
  their WM_TRANSIENT_FOR hint.
- Add g_return_if_fail (!window->override_redirect) to catch
  unexpected code paths that might result in override-redirect
  windows being moved or resized.
http://bugzilla.gnome.org/show_bug.cgi?id=582639
2009-06-16 09:56:42 -04:00
Owen W. Taylor
d6576d9b70 Don't add override-redirect windows to workspaces
Normally a window that is "on all workspaces", is also on a particular
workspace (to deal with being unstuck.) This is pointless for
override-redirect windows.

http://bugzilla.gnome.org/show_bug.cgi?id=582639
2009-06-16 09:56:42 -04:00
Owen W. Taylor
6516c19ec5 Ignore client messages sent to override-redirect windows
If someone asks us to close, maximize, etc, an override-redirect
window, just ignore the request.

http://bugzilla.gnome.org/show_bug.cgi?id=582639
2009-06-16 09:56:42 -04:00
Owen W. Taylor
5518fee61c meta_screen_foreach_window(): Skip override-redirect windows
Don't include override-redirect windows when iterating the windows
in the screen. We don't need them for any of the current uses:

 - Queueing redraws and resizes on managed windows
 - Checking which windows should be added to a new workspace

http://bugzilla.gnome.org/show_bug.cgi?id=582639
2009-06-16 09:56:42 -04:00
Owen W. Taylor
ace0521cba meta_display_list_windows: Exclude override-redirect
Don't include override-redirect windows in the list return by
meta_display_list_windows(), since we almost never want to handle
them when considering "all window" for the display. Add a separate
meta_display_list_all_windows() that includes override-redirect
windows.

http://bugzilla.gnome.org/show_bug.cgi?id=582639
2009-06-16 09:56:42 -04:00
Owen W. Taylor
0091a3aab5 Don't read most properties for override-redirect windows
Skipping handling of properties for override redirect windows has
two advantages: first it reduces the amount of work needed to get
an override-redirect window (menu, tooltip, drag icon) onto the
screen. But more importantly, it reduces the number of code-paths
for an override-redirect to get into some code portion where it
isn't expected.

* Integrate the list of properties we load initially with the
  list of property hooks; this avoids having two separate lists
  that we have to keep in sync.

* Add a flag to MetaWindowPropHooks to indicate whether the
  property should be handled for override-redirect windows;
  currently we load a) properties that identify the window -
  useful for debugging purposes b) WM_TRANSIENT_FOR (could be
  used to associate menus with toplevels.)

* For properties that aren't always loaded through window-props.c,
  add !window->override checks to places that trigger loading,
  and add g_return_if_fail(!window->override) to the load
  functions as a double-check.

http://bugzilla.gnome.org/show_bug.cgi?id=582639
2009-06-16 09:56:42 -04:00
Owen W. Taylor
268b92a4ec Add checks against inappropriate changes to override-redirect window
Add g_return_if_fail() to check that window-management functions like
meta_window_maximize() aren't called on override-redirect windows.

This reveals that were were "unminimizing" override-redirect windows
when adding them; avoid doing that.

http://bugzilla.gnome.org/show_bug.cgi?id=582639
2009-06-16 09:56:41 -04:00
Owen W. Taylor
29bb4c27e3 Fix property notifications for certain properties
If a property has a reload function, but the standard property-fetching
mechanism isn't used (hooks->type == META_PROP_VALUE_INVALID), then the
a logic error (introduced in January) caused the hook to never be run.

This meant that changes to struts and icons weren't noticed.

Same as: http://bugzilla.gnome.org/show_bug.cgi?id=572573
The fix here is different in detail from that applied to Metacity, but
similar in spirit.

http://bugzilla.gnome.org/show_bug.cgi?id=585980
2009-06-16 09:56:41 -04:00
Owen W. Taylor
bd3bdc51b9 Load NET_WM_USER_TIME from the right window
On subsequent changes, if there is a NET_WM_USER_TIME_WINDOW, then
read the property from that rather than from the main window.
(Fix an accidental regression: the right Window was being computed
but no longer passed in.)

http://bugzilla.gnome.org/show_bug.cgi?id=585979
2009-06-16 09:56:41 -04:00
Owen W. Taylor
0123dab87a Fix missing static for meta_window_show()
Definition of meta_window_show() was missing static although it
was forward-declared with static.

http://bugzilla.gnome.org/show_bug.cgi?id=585978
2009-06-16 09:56:41 -04:00
Owen W. Taylor
413acc9574 Regularize main loop priorities
If there is a client that is continually redrawing, then
sources that are less-prioritized than CLUTTER_PRIORITY_REDRAW
will never get run. This patch sorts out how all the different
main loop sources fit in CLUTTER_PRIORITY_REDRAW.

common.h: Document all the relevant priorities and how they
  fit in with each other.
ui.h common.h: Move META_PRIORITY_RESIZE to to common.h with
  other priorities.
src/core/window.c src/core/screen.c: Change calc-showing,
  update-icon, and update-work-area idles to be prioritized above
  redraws so they don't get starved.
bell.c: Make the visual bell priority the same as the clutter
  redraw priority.
delete.c: Use a G_PRIORITY_DEFAULT idle when responding to the
  dialog response; we want to handle it as soon as practical.

http://bugzilla.gnome.org/show_bug.cgi?id=568874
2009-06-16 09:56:41 -04:00
60 changed files with 8637 additions and 4268 deletions

View File

@@ -4,7 +4,7 @@ m4_define([mutter_major_version], [2])
m4_define([mutter_minor_version], [27])
# Fibonacci sequence for micro version numbering:
# 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987
m4_define([mutter_micro_version], [1])
m4_define([mutter_micro_version], [0])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])
@@ -17,7 +17,7 @@ AC_INIT([mutter], [mutter_version],
AC_CONFIG_SRCDIR(src/core/display.c)
AC_CONFIG_HEADERS(config.h)
AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip])
AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE
MUTTER_MAJOR_VERSION=mutter_major_version
@@ -46,9 +46,6 @@ AC_HEADER_STDC
AC_LIBTOOL_WIN32_DLL
AM_PROG_LIBTOOL
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
AM_PATH_GLIB_2_0()
#### Integer sizes
AC_CHECK_SIZEOF(char)
@@ -156,7 +153,17 @@ AC_ARG_ENABLE(startup-notification,
[disable mutter's startup notification support, for embedded/size-sensitive custom non-GNOME builds]),,
enable_startup_notification=auto)
AC_ARG_WITH(introspection,
AC_ARG_ENABLE(compositor,
AC_HELP_STRING([--disable-compositor],
[disable mutter's compositing manager]),,
enable_compositor=auto)
AC_ARG_ENABLE(clutter,
AC_HELP_STRING([--without-clutter],
[disable the use of clutter for compositing]),,
with_clutter=auto)
AC_ARG_ENABLE(introspection,
AC_HELP_STRING([--without-introspection],
[disable the use of GObject introspection]),,
with_introspection=auto)
@@ -166,6 +173,11 @@ AC_ARG_ENABLE(xsync,
[disable mutter's use of the XSync extension]),,
enable_xsync=auto)
AC_ARG_ENABLE(render,
AC_HELP_STRING([--disable-render],
[disable mutter's use of the RENDER extension]),,
enable_render=auto)
AC_ARG_ENABLE(shape,
AC_HELP_STRING([--disable-shape],
[disable mutter's use of the shaped window extension]),,
@@ -179,10 +191,16 @@ AM_GLIB_GNU_GETTEXT
## here we get the flags we'll actually use
# GOptionEntry requires glib-2.6.0
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.6.0)
# gtk_window_set_icon_name requires gtk2+-2.6.0
# gtk_window_set_icon_name requires gtk2+-2.60
PKG_CHECK_MODULES(MUTTER_MESSAGE, gtk+-2.0 >= 2.6.0)
PKG_CHECK_MODULES(MUTTER_WINDOW_DEMO, gtk+-2.0 >= 2.6.0)
if $PKG_CONFIG --atleast-version 1.2.0 pangoxft; then
echo "pangoxft found"
else
AC_MSG_ERROR("Pango 1.2.0 or greater based on Xft2 is required")
fi
# Unconditionally use this dir to avoid a circular dep with gnomecc
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
AC_SUBST(GNOME_KEYBINDINGS_KEYSDIR)
@@ -213,10 +231,43 @@ else
echo "Building without libstartup-notification"
fi
XCOMPOSITE_VERSION=0.2
## init this, it gets set either in the compositor check below
## or the render-specific check later
have_xrender=no
AC_MSG_CHECKING([Xcomposite >= $XCOMPOSITE_VERSION])
if $PKG_CONFIG --atleast-version $XCOMPOSITE_VERSION xcomposite; then
XCOMPOSITE_VERSION=0.2
if test x$enable_compositor = xyes; then
have_xcomposite=yes
elif test x$enable_compositor = xauto; then
echo "Building compositing manager by default now."
have_xcomposite=yes
else
have_xcomposite=no
fi
if test x$with_clutter = xyes; then
have_xcomposite=yes
have_clutter=yes
elif test x$with_clutter = xauto; then
echo "Building clutter compositing manager by default now."
have_xcomposite=yes
have_clutter=yes
else
have_clutter=no
fi
AM_CONDITIONAL(WITH_CLUTTER, test "$have_clutter" = "yes")
if test x$have_xcomposite = xyes; then
AC_MSG_CHECKING([Xcomposite >= $XCOMPOSITE_VERSION])
if $PKG_CONFIG --atleast-version $XCOMPOSITE_VERSION xcomposite; then
AC_MSG_RESULT([yes])
else
AC_MSG_ERROR([no. Use --disable-compositor to disable.])
fi
fi
if test x$have_xcomposite = xyes; then
MUTTER_PC_MODULES="$MUTTER_PC_MODULES xcomposite >= $XCOMPOSITE_VERSION xfixes xrender xdamage"
AC_DEFINE(HAVE_COMPOSITE_EXTENSIONS, 1, [Building with compositing manager support])
echo "Building with compositing manager"
@@ -224,13 +275,42 @@ if $PKG_CONFIG --atleast-version $XCOMPOSITE_VERSION xcomposite; then
## force on render also
have_xrender=yes
else
AC_MSG_ERROR([no. Mutter requires the Xcomposite extension to build.])
echo "Building without compositing manager"
fi
## if no compositor, still possibly enable render
if test x$have_xcomposite = xno; then
XRENDER_VERSION=0.0
AC_MSG_CHECKING([xrender >= $XRENDER_VERSION])
if $PKG_CONFIG --atleast-version $XRENDER_VERSION xrender; then
have_xrender=yes
else
have_xrender=no
fi
AC_MSG_RESULT($have_xrender)
if test x$enable_render = xyes; then
have_xrender=yes
echo "Render support forced on"
elif test x$enable_render = xauto; then
true
else
have_xrender=no
fi
if test x$have_xrender = xyes; then
echo "Building with Render"
MUTTER_PC_MODULES="$MUTTER_PC_MODULES xrender >= $XRENDER_VERSION"
fi
fi ## have_composite
if test x$have_xrender = xyes; then
AC_DEFINE(HAVE_RENDER, , [Building with Render extension support])
fi
CLUTTER_VERSION=0.9.3
CLUTTER_PACKAGE=clutter-0.9
AC_SUBST(CLUTTER_PACKAGE)
if $PKG_CONFIG --atleast-version $CLUTTER_VERSION $CLUTTER_PACKAGE ; then
if test x$have_clutter = xyes; then
MUTTER_PC_MODULES="$MUTTER_PC_MODULES $CLUTTER_PACKAGE "
PKG_CHECK_MODULES(CLUTTER, $CLUTTER_PACKAGE)
AC_DEFINE(WITH_CLUTTER, , [Building with Clutter compositor])
@@ -247,8 +327,6 @@ if $PKG_CONFIG --atleast-version $CLUTTER_VERSION $CLUTTER_PACKAGE ; then
AC_DEFINE(HAVE_GLX_TEXTURE_PIXMAP, ,
[Is ClutterGLXTexturePixmap available?])
fi
else
AC_MSG_ERROR([no. Mutter requires Clutter version $CLUTTER_VERSION.])
fi
if test x$with_introspection != xno; then
@@ -500,7 +578,7 @@ src/wm-tester/Makefile
src/libmutter-private.pc
src/mutter-plugins.pc
src/tools/Makefile
src/compositor/plugins/Makefile
src/compositor/mutter/plugins/Makefile
po/Makefile.in
])
@@ -533,11 +611,15 @@ mutter-$VERSION:
XFree86 Xinerama: ${use_xfree_xinerama}
Solaris Xinerama: ${use_solaris_xinerama}
Startup notification: ${have_startup_notification}
Compositing manager: ${have_xcomposite}
Introspection: ${have_introspection}
Session management: ${found_sm}
Shape extension: ${found_shape}
Resize-and-rotate: ${found_randr}
Xsync: ${found_xsync}
Render: ${have_xrender}
Xcursor: ${have_xcursor}
Clutter: ${have_clutter}
"
MUTTER_MINOR_VERSION=mutter_minor_version

View File

@@ -1,15 +1,13 @@
lib_LTLIBRARIES = libmutter-private.la
SUBDIRS=wm-tester tools compositor/plugins
SUBDIRS=wm-tester tools
if WITH_CLUTTER
SUBDIRS += compositor/mutter/plugins
endif
INCLUDES=@MUTTER_CFLAGS@ -I $(srcdir)/include -I$(srcdir)/compositor -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_PKGLIBDIR=\"$(pkglibdir)\" -DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\"
mutter_built_sources = \
mutter-marshal.h \
mutter-marshal.c \
mutter-enum-types.h \
mutter-enum-types.c
mutter_SOURCES= \
core/async-getprop.c \
core/async-getprop.h \
@@ -23,25 +21,9 @@ mutter_SOURCES= \
include/boxes.h \
compositor/compositor.c \
compositor/compositor-private.h \
compositor/mutter-module.c \
compositor/mutter-module.h \
compositor/mutter-plugin.c \
compositor/mutter-plugin-manager.c \
compositor/mutter-plugin-manager.h \
compositor/mutter-shaped-texture.c \
compositor/mutter-window.c \
compositor/mutter-window-private.h \
compositor/mutter-window-group.c \
compositor/mutter-window-group.h \
compositor/shadow.c \
compositor/shadow.h \
compositor/mutter-shaped-texture.h \
compositor/tidy/tidy-texture-frame.c \
compositor/tidy/tidy-texture-frame.h \
compositor/compositor-xrender.c \
compositor/compositor-xrender.h \
include/compositor.h \
include/mutter-plugin.h \
include/mutter-window.h \
include/compositor-mutter.h \
core/constraints.c \
core/constraints.h \
core/core.c \
@@ -53,6 +35,8 @@ mutter_SOURCES= \
ui/draw-workspace.h \
core/edge-resistance.c \
core/edge-resistance.h \
core/effects.c \
core/effects.h \
core/errors.c \
include/errors.h \
core/eventqueue.c \
@@ -72,6 +56,7 @@ mutter_SOURCES= \
core/keybindings.c \
core/keybindings-private.h \
core/main.c \
include/main.h \
core/mutter-Xatomtype.h \
core/place.c \
core/place.h \
@@ -121,8 +106,23 @@ mutter_SOURCES= \
ui/themewidget.c \
ui/themewidget.h \
ui/ui.c \
include/all-keybindings.h \
$(mutter_built_sources)
include/all-keybindings.h
if WITH_CLUTTER
mutter_SOURCES += \
compositor/mutter/compositor-mutter.c \
compositor/mutter/mutter-shaped-texture.c \
compositor/mutter/mutter-shaped-texture.h \
compositor/mutter/mutter-plugin-manager.c \
compositor/mutter/mutter-plugin-manager.h \
compositor/mutter/tidy/tidy-texture-frame.c \
compositor/mutter/tidy/tidy-texture-frame.h \
compositor/mutter/mutter-module.c \
compositor/mutter/mutter-module.h \
compositor/mutter/mutter-plugin.c \
include/mutter-plugin.h \
include/compositor-mutter.h
endif
# by setting libmutter_private_la_CFLAGS, the files shared with
# mutter proper will be compiled with different names.
@@ -151,7 +151,6 @@ libmutterinclude_base_headers = \
include/alttabhandler.h \
include/boxes.h \
ui/gradient.h \
include/main.h \
include/util.h \
include/common.h \
ui/preview-widget.h \
@@ -167,8 +166,7 @@ libmutterinclude_base_headers = \
include/display.h \
include/group.h \
include/keybindings.h \
include/mutter-plugin.h \
include/mutter-window.h
include/mutter-plugin.h
# Excluded from scanning for introspection but installed
libmutterinclude_extra_headers = \
@@ -198,8 +196,6 @@ typelib_DATA = Meta-$(api_version).typelib
# We need to strip out the attribute that would point back to libmutter-introspect
# so that libgirepository looks for symbols in the executable instead
Meta-$(api_version).gir: $(G_IR_SCANNER) mutter $(libmutterinclude_HEADERS) $(mutter_SOURCES)
pwd=`pwd` ; \
cd $(srcdir) && \
$(G_IR_SCANNER) \
--namespace=Meta \
--nsversion=$(api_version) \
@@ -210,11 +206,11 @@ Meta-$(api_version).gir: $(G_IR_SCANNER) mutter $(libmutterinclude_HEADERS) $(mu
--pkg=clutter-0.9 \
--pkg=gtk+-2.0 \
--include=xfixes-4.0 \
--program=$$pwd/mutter \
$(filter %.c,$(mutter_SOURCES)) \
--program=./mutter \
$(filter %.c,$(mutter_SOURCES)) \
$(libmutterinclude_base_headers) \
$(INCLUDES) \
-o $$pwd/$@
-o $@
Meta-$(api_version).typelib: $(G_IR_COMPILER) Meta-$(api_version).gir
LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}. $(G_IR_COMPILER) Meta-$(api_version).gir -o $@
@@ -269,14 +265,7 @@ VARIABLES=stock_maximize_data $(srcdir)/stock_maximize.png \
stock_delete_data $(srcdir)/stock_delete.png
BUILT_SOURCES = inlinepixbufs.h
CLEANFILES = \
inlinepixbufs.h \
mutter.desktop \
mutter-wm.desktop \
mutter.schemas \
$(mutter_built_sources) \
$(typelib_DATA) \
$(gir_DATA)
CLEANFILES = inlinepixbufs.h mutter.desktop mutter-wm.desktop mutter.schemas
inlinepixbufs.h: $(IMAGES)
$(GDK_PIXBUF_CSOURCE) --raw --build-list $(VARIABLES) >$(srcdir)/inlinepixbufs.h
@@ -287,55 +276,10 @@ pkgconfig_DATA = libmutter-private.pc mutter-plugins.pc
EXTRA_DIST=$(desktopfiles_files) \
$(wmproperties_files) \
$(IMAGES) \
$(IMAGES) $(schema_DATA) \
$(desktopfiles_in_files) \
$(wmproperties_in_files) \
$(schema_in_files) \
libmutter-private.pc.in \
mutter-plugins.pc.in \
mutter-enum-types.h.in \
mutter-enum-types.c.in \
mutter-marshal.list
mutter-plugins.pc.in
BUILT_SOURCES += $(mutter_built_sources)
MUTTER_STAMP_FILES = stamp-mutter-marshal.h stamp-mutter-enum-types.h
CLEANFILES += $(MUTTER_STAMP_FILES)
mutter-marshal.h: stamp-mutter-marshal.h
@true
stamp-mutter-marshal.h: Makefile mutter-marshal.list
$(GLIB_GENMARSHAL) \
--prefix=_mutter_marshal \
--header \
$(srcdir)/mutter-marshal.list > xgen-tmh && \
(cmp -s xgen-tmh mutter-marshal.h || cp -f xgen-tmh mutter-marshal.h) && \
rm -f xgen-tmh && \
echo timestamp > $(@F)
mutter-marshal.c: Makefile mutter-marshal.list
(echo "#include \"mutter-marshal.h\"" ; \
$(GLIB_GENMARSHAL) \
--prefix=_mutter_marshal \
--body \
$(srcdir)/mutter-marshal.list ) > xgen-tmc && \
cp -f xgen-tmc mutter-marshal.c && \
rm -f xgen-tmc
mutter-enum-types.h: stamp-mutter-enum-types.h Makefile
@true
stamp-mutter-enum-types.h: $(mutter_source_h) mutter-enum-types.h.in
( cd $(srcdir) && \
$(GLIB_MKENUMS) \
--template $(srcdir)/mutter-enum-types.h.in \
$(libmutterinclude_base_headers) ) >> xgen-teth && \
(cmp xgen-teth mutter-enum-types.h || cp xgen-teth mutter-enum-types.h) && \
rm -f xgen-teth && \
echo timestamp > $(@F)
mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in
( cd $(srcdir) && \
$(GLIB_MKENUMS) \
--template $(srcdir)/mutter-enum-types.c.in \
$(libmutterinclude_base_headers) ) >> xgen-tetc && \
cp xgen-tetc mutter-enum-types.c && \
rm -f xgen-tetc

View File

@@ -1,54 +1,90 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2008 Iain Holmes
*
* 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.
*/
#ifndef META_COMPOSITOR_PRIVATE_H
#define META_COMPOSITOR_PRIVATE_H
#include <X11/extensions/Xfixes.h>
#include "compositor.h"
#include "display.h"
#include "mutter-plugin-manager.h"
#include <clutter/clutter.h>
typedef struct _MetaCompScreen MetaCompScreen;
struct _MetaCompositor
{
MetaDisplay *display;
void (* destroy) (MetaCompositor *compositor);
Atom atom_x_root_pixmap;
Atom atom_x_set_root;
Atom atom_net_wm_window_opacity;
guint repaint_func_id;
ClutterActor *shadow_src;
gboolean show_redraw : 1;
gboolean debug : 1;
gboolean no_mipmaps : 1;
void (*manage_screen) (MetaCompositor *compositor,
MetaScreen *screen);
void (*unmanage_screen) (MetaCompositor *compositor,
MetaScreen *screen);
void (*add_window) (MetaCompositor *compositor,
MetaWindow *window);
void (*remove_window) (MetaCompositor *compositor,
MetaWindow *window);
void (*set_updates) (MetaCompositor *compositor,
MetaWindow *window,
gboolean update);
gboolean (*process_event) (MetaCompositor *compositor,
XEvent *event,
MetaWindow *window);
Pixmap (*get_window_pixmap) (MetaCompositor *compositor,
MetaWindow *window);
void (*set_active_window) (MetaCompositor *compositor,
MetaScreen *screen,
MetaWindow *window);
void (*map_window) (MetaCompositor *compositor,
MetaWindow *window);
void (*unmap_window) (MetaCompositor *compositor,
MetaWindow *window);
void (*minimize_window) (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *icon_rect);
void (*unminimize_window) (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *icon_rect);
void (*maximize_window) (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *window_rect);
void (*unmaximize_window) (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *window_rect);
void (*update_workspace_geometry) (MetaCompositor *compositor,
MetaWorkspace *workspace);
void (*switch_workspace) (MetaCompositor *compositor,
MetaScreen *screen,
MetaWorkspace *from,
MetaWorkspace *to,
MetaMotionDirection direction);
void (*sync_stack) (MetaCompositor *compositor,
MetaScreen *screen,
GList *stack);
void (*set_window_hidden) (MetaCompositor *compositor,
MetaScreen *screen,
MetaWindow *window,
gboolean hidden);
void (*sync_window_geometry) (MetaCompositor *compositor,
MetaWindow *window);
void (*sync_screen_size) (MetaCompositor *compositor,
MetaScreen *screen,
guint width,
guint height);
};
struct _MetaCompScreen
{
MetaScreen *screen;
ClutterActor *stage, *window_group, *overlay_group;
ClutterActor *hidden_group;
GList *windows;
GHashTable *windows_by_xid;
Window output;
/* Before we create the output window */
XserverRegion pending_input_region;
gint switch_workspace_in_progress;
MutterPluginManager *plugin_mgr;
};
void mutter_switch_workspace_completed (MetaScreen *screen);
void mutter_set_stage_input_region (MetaScreen *screen,
XserverRegion region);
void mutter_empty_stage_input_region (MetaScreen *screen);
#endif /* META_COMPOSITOR_PRIVATE_H */
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2007 Iain Holmes
* Based on xcompmgr - (c) 2003 Keith Packard
* xfwm4 - (c) 2005-2007 Olivier Fourdan
*
* 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.
*/
#ifndef META_COMPOSITOR_XRENDER_H_
#define META_COMPOSITOR_XRENDER_H_
#include "types.h"
MetaCompositor *meta_compositor_xrender_new (MetaDisplay *display);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,194 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#define _ISOC99_SOURCE /* for roundf */
#include <math.h>
#include "mutter-window-private.h"
#include "mutter-window-group.h"
struct _MutterWindowGroupClass
{
ClutterGroupClass parent_class;
};
struct _MutterWindowGroup
{
ClutterGroup parent;
MetaScreen *screen;
};
G_DEFINE_TYPE (MutterWindowGroup, mutter_window_group, CLUTTER_TYPE_GROUP);
/* We want to find out if the window is "close enough" to
* 1:1 transform. We do that by converting the transformed coordinates
* to 24.8 fixed-point before checking if they look right.
*/
static inline int
round_to_fixed (float x)
{
return roundf (x * 256);
}
/* We can only (easily) apply our logic for figuring out what a window
* obscures if is not transformed. This function does that check and
* as a side effect gets the position of the upper-left corner of the
* actors.
*
* (We actually could handle scaled and non-integrally positioned actors
* too as long as they weren't shaped - no filtering is done at the
* edges so a rectangle stays a rectangle. But the gain from that is
* small, especally since most of our windows are shaped. The simple
* case we handle here is the case that matters when the user is just
* using the desktop normally.)
*
* If we assume that the window group is untransformed (it better not
* be!) then we could also make this determination by checking directly
* if the actor itself is rotated, scaled, or at a non-integral position.
* However, the criterion for "close enough" in that case get trickier,
* since, for example, the allowed rotation depends on the size of
* actor. The approach we take here is to just require everything
* to be within 1/256th of a pixel.
*/
static gboolean
actor_is_untransformed (ClutterActor *actor,
int *x_origin,
int *y_origin)
{
gfloat widthf, heightf;
int width, height;
ClutterVertex verts[4];
int v0x, v0y, v1x, v1y, v2x, v2y, v3x, v3y;
int x, y;
clutter_actor_get_size (actor, &widthf, &heightf);
width = round_to_fixed (widthf); height = round_to_fixed (heightf);
clutter_actor_get_abs_allocation_vertices (actor, verts);
v0x = round_to_fixed (verts[0].x); v0y = round_to_fixed (verts[0].y);
v1x = round_to_fixed (verts[1].x); v1y = round_to_fixed (verts[1].y);
v2x = round_to_fixed (verts[2].x); v2y = round_to_fixed (verts[2].y);
v3x = round_to_fixed (verts[3].x); v3y = round_to_fixed (verts[3].y);
/* Using shifting for converting fixed => int, gets things right for
* negative values. / 256. wouldn't do the same
*/
x = v0x >> 8;
y = v0y >> 8;
/* At integral coordinates? */
if (x * 256 != v0x || y * 256 != v0y)
return FALSE;
/* Not scaled? */
if (v1x - v0x != width || v2y - v0y != height)
return FALSE;
/* Not rotated/skewed? */
if (v0x != v2x || v0y != v1y ||
v3x != v1x || v3y != v2y)
return FALSE;
*x_origin = x;
*y_origin = y;
return TRUE;
}
static void
mutter_window_group_paint (ClutterActor *actor)
{
MutterWindowGroup *window_group = MUTTER_WINDOW_GROUP (actor);
GdkRegion *visible_region;
GdkRectangle screen_rect = { 0 };
GList *children, *l;
/* We walk the list from top to bottom (opposite of painting order),
* and subtract the opaque area of each window out of the visible
* region that we pass to the windows below.
*/
children = clutter_container_get_children (CLUTTER_CONTAINER (actor));
children = g_list_reverse (children);
/* Start off with the full screen area (for a multihead setup, we
* might want to use a more accurate union of the monitors to avoid
* painting in holes from mismatched monitor sizes. That's just an
* optimization, however.)
*/
meta_screen_get_size (window_group->screen, &screen_rect.width, &screen_rect.height);
visible_region = gdk_region_rectangle (&screen_rect);
for (l = children; l; l = l->next)
{
MutterWindow *cw;
gboolean x, y;
if (!MUTTER_IS_WINDOW (l->data) || !CLUTTER_ACTOR_IS_VISIBLE (l->data))
continue;
cw = l->data;
if (!actor_is_untransformed (CLUTTER_ACTOR (cw), &x, &y))
continue;
/* Temporarily move to the coordinate system of the actor */
gdk_region_offset (visible_region, - x, - y);
mutter_window_set_visible_region (cw, visible_region);
if (clutter_actor_get_paint_opacity (actor) == 0xff)
{
GdkRegion *obscured_region = mutter_window_get_obscured_region (cw);
if (obscured_region)
gdk_region_subtract (visible_region, obscured_region);
}
mutter_window_set_visible_region_beneath (cw, visible_region);
gdk_region_offset (visible_region, x, y);
}
gdk_region_destroy (visible_region);
CLUTTER_ACTOR_CLASS (mutter_window_group_parent_class)->paint (actor);
/* Now that we are done painting, unset the visible regions (they will
* mess up painting clones of our actors)
*/
for (l = children; l; l = l->next)
{
MutterWindow *cw;
if (!MUTTER_IS_WINDOW (l->data))
continue;
cw = l->data;
mutter_window_reset_visible_regions (cw);
}
g_list_free (children);
}
static void
mutter_window_group_class_init (MutterWindowGroupClass *klass)
{
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
actor_class->paint = mutter_window_group_paint;
}
static void
mutter_window_group_init (MutterWindowGroup *window_group)
{
}
ClutterActor *
mutter_window_group_new (MetaScreen *screen)
{
MutterWindowGroup *window_group;
window_group = g_object_new (MUTTER_TYPE_WINDOW_GROUP, NULL);
window_group->screen = screen;
return CLUTTER_ACTOR (window_group);
}

View File

@@ -1,52 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef MUTTER_WINDOW_GROUP_H
#define MUTTER_WINDOW_GROUP_H
#include <clutter/clutter.h>
#include "screen.h"
/**
* MutterWindowGroup:
*
* This class is a subclass of ClutterGroup with special handling for
* MutterWindow when painting the group. When we are painting a stack
* of 5-10 maximized windows, the standard bottom-to-top method of
* drawing every actor results in a tremendous amount of overdraw
* and can easily max out the available memory bandwidth on a low-end
* graphics chipset. It's even worse if window textures are being accessed
* over the AGP bus.
*
* The basic technique applied here is to do a pre-pass before painting
* where we walk window from top to bottom and compute the visible area
* at each step by subtracting out the windows above it. The visible
* area is passed to MutterWindow which uses it to clip the portion of
* the window which drawn and avoid redrawing the shadow if it is completely
* obscured.
*
* A caveat is that this is ineffective if applications are using ARGB
* visuals, since we have no way of knowing whether a window obscures
* the windows behind it or not. Alternate approaches using the depth
* or stencil buffer rather than client side regions might be able to
* handle alpha windows, but the combination of glAlphaFunc and stenciling
* tends not to be efficient except on newer cards. (And on newer cards
* we have lots of memory and bandwidth.)
*/
#define MUTTER_TYPE_WINDOW_GROUP (mutter_window_group_get_type ())
#define MUTTER_WINDOW_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTTER_TYPE_WINDOW_GROUP, MutterWindowGroup))
#define MUTTER_WINDOW_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTTER_TYPE_WINDOW_GROUP, MutterWindowGroupClass))
#define MUTTER_IS_WINDOW_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUTTER_TYPE_WINDOW_GROUP))
#define MUTTER_IS_WINDOW_GROU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTTER_TYPE_WINDOW_GROUP))
#define MUTTER_WINDOW_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTTER_TYPE_WINDOW_GROUP, MutterWindowGroupClass))
typedef struct _MutterWindowGroup MutterWindowGroup;
typedef struct _MutterWindowGroupClass MutterWindowGroupClass;
typedef struct _MutterWindowGroupPrivate MutterWindowGroupPrivate;
GType mutter_window_group_get_type (void);
ClutterActor *mutter_window_group_new (MetaScreen *screen);
#endif /* MUTTER_WINDOW_GROUP_H */

View File

@@ -1,51 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef MUTTER_WINDOW_PRIVATE_H
#define MUTTER_WINDOW_PRIVATE_H
#include <X11/extensions/Xdamage.h>
#include <gdk/gdk.h>
#include "compositor-mutter.h"
MutterWindow *mutter_window_new (MetaWindow *window);
void mutter_window_destroy (MutterWindow *cw);
void mutter_window_show (MutterWindow *cw,
MetaCompEffect effect);
void mutter_window_hide (MutterWindow *cw,
MetaCompEffect effect);
void mutter_window_maximize (MutterWindow *cw,
MetaRectangle *old_rect,
MetaRectangle *new_rect);
void mutter_window_unmaximize (MutterWindow *cw,
MetaRectangle *old_rect,
MetaRectangle *new_rect);
void mutter_window_process_damage (MutterWindow *cw,
XDamageNotifyEvent *event);
void mutter_window_pre_paint (MutterWindow *self);
gboolean mutter_window_effect_in_progress (MutterWindow *cw);
void mutter_window_sync_actor_position (MutterWindow *cw);
void mutter_window_sync_visibility (MutterWindow *cw);
void mutter_window_update_window_type (MutterWindow *cw);
void mutter_window_update_shape (MutterWindow *cw,
gboolean shaped);
void mutter_window_update_opacity (MutterWindow *cw);
void mutter_window_mapped (MutterWindow *cw);
void mutter_window_unmapped (MutterWindow *cw);
GdkRegion *mutter_window_get_obscured_region (MutterWindow *cw);
void mutter_window_set_visible_region (MutterWindow *cw,
GdkRegion *visible_region);
void mutter_window_set_visible_region_beneath (MutterWindow *cw,
GdkRegion *beneath_region);
void mutter_window_reset_visible_regions (MutterWindow *cw);
void mutter_window_effect_completed (MutterWindow *actor,
gulong event);
#endif /* MUTTER_WINDOW_PRIVATE_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -31,9 +31,6 @@
#include <X11/extensions/shape.h>
#include <clutter/x11/clutter-x11.h>
#include "compositor-private.h"
#include "mutter-window-private.h"
G_DEFINE_ABSTRACT_TYPE (MutterPlugin, mutter_plugin, G_TYPE_OBJECT);
#define MUTTER_PLUGIN_GET_PRIVATE(obj) \
@@ -392,17 +389,7 @@ mutter_plugin_effect_completed (MutterPlugin *plugin,
name ? name : "unknown");
}
if (event == MUTTER_PLUGIN_SWITCH_WORKSPACE)
{
/* The window is just used to identify the screen */
MetaWindow *window = mutter_window_get_meta_window (actor);
MetaScreen *screen = meta_window_get_screen (window);
mutter_switch_workspace_completed (screen);
}
else
{
mutter_window_effect_completed (actor, event);
}
mutter_window_effect_completed (actor, event);
}
void

View File

@@ -57,13 +57,10 @@ struct _MutterShapedTexturePrivate
{
CoglHandle mask_texture;
CoglHandle material;
CoglHandle material_unshaped;
#if 1 /* see workaround comment in mutter_shaped_texture_paint */
CoglHandle material_workaround;
#endif
GdkRegion *clip_region;
guint mask_width, mask_height;
GArray *rectangles;
@@ -109,11 +106,6 @@ mutter_shaped_texture_dispose (GObject *object)
cogl_material_unref (priv->material);
priv->material = COGL_INVALID_HANDLE;
}
if (priv->material_unshaped != COGL_INVALID_HANDLE)
{
cogl_material_unref (priv->material_unshaped);
priv->material_unshaped = COGL_INVALID_HANDLE;
}
#if 1 /* see comment in mutter_shaped_texture_paint */
if (priv->material_workaround != COGL_INVALID_HANDLE)
{
@@ -122,8 +114,6 @@ mutter_shaped_texture_dispose (GObject *object)
}
#endif
mutter_shaped_texture_set_clip_region (self, NULL);
G_OBJECT_CLASS (mutter_shaped_texture_parent_class)->dispose (object);
}
@@ -263,9 +253,6 @@ mutter_shaped_texture_paint (ClutterActor *actor)
guint depth;
#endif
if (priv->clip_region && gdk_region_empty (priv->clip_region))
return;
if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
clutter_actor_realize (CLUTTER_ACTOR (stex));
@@ -277,65 +264,61 @@ mutter_shaped_texture_paint (ClutterActor *actor)
if (tex_width == 0 || tex_width == 0) /* no contents yet */
return;
/* If there are no rectangles fallback to the regular paint
method */
if (priv->rectangles->len < 1)
{
CLUTTER_ACTOR_CLASS (mutter_shaped_texture_parent_class)
->paint (actor);
return;
}
if (paint_tex == COGL_INVALID_HANDLE)
return;
if (priv->rectangles->len < 1)
mutter_shaped_texture_ensure_mask (stex);
if (priv->material == COGL_INVALID_HANDLE)
{
/* If there are no rectangles use a single-layer texture */
priv->material = cogl_material_new ();
if (priv->material_unshaped == COGL_INVALID_HANDLE)
priv->material_unshaped = cogl_material_new ();
material = priv->material_unshaped;
cogl_material_set_layer_combine (priv->material, 1,
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
NULL);
}
else
{
mutter_shaped_texture_ensure_mask (stex);
if (priv->material == COGL_INVALID_HANDLE)
{
priv->material = cogl_material_new ();
cogl_material_set_layer_combine (priv->material, 1,
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
NULL);
}
material = priv->material;
material = priv->material;
#if 1
/* This was added as a workaround. It seems that with the intel
* drivers when multi-texturing using an RGB TFP texture, the
* texture is actually setup internally as an RGBA texture, where
* the alpha channel is mostly 0.0 so you only see a shimmer of the
* window. This workaround forcibly defines the alpha channel as
* 1.0. Maybe there is some clutter/cogl state that is interacting
* with this that is being overlooked, but for now this seems to
* work. */
g_object_get (stex, "pixmap-depth", &depth, NULL);
if (depth == 24)
{
if (priv->material_workaround == COGL_INVALID_HANDLE)
{
material = priv->material_workaround = cogl_material_new ();
/* This was added as a workaround. It seems that with the intel
* drivers when multi-texturing using an RGB TFP texture, the
* texture is actually setup internally as an RGBA texture, where
* the alpha channel is mostly 0.0 so you only see a shimmer of the
* window. This workaround forcibly defines the alpha channel as
* 1.0. Maybe there is some clutter/cogl state that is interacting
* with this that is being overlooked, but for now this seems to
* work. */
g_object_get (stex, "pixmap-depth", &depth, NULL);
if (depth == 24)
{
if (priv->material_workaround == COGL_INVALID_HANDLE)
{
material = priv->material_workaround = cogl_material_new ();
cogl_material_set_layer_combine (material, 0,
"RGB = MODULATE (TEXTURE, PREVIOUS)"
"A = REPLACE (PREVIOUS)",
NULL);
cogl_material_set_layer_combine (material, 1,
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
NULL);
}
cogl_material_set_layer_combine (material, 0,
"RGB = MODULATE (TEXTURE, PREVIOUS)"
"A = REPLACE (PREVIOUS)",
NULL);
cogl_material_set_layer_combine (material, 1,
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
NULL);
}
material = priv->material_workaround;
}
material = priv->material_workaround;
}
#endif
cogl_material_set_layer (material, 1, priv->mask_texture);
}
cogl_material_set_layer (material, 0, paint_tex);
cogl_material_set_layer (material, 1, priv->mask_texture);
{
CoglColor color;
@@ -347,51 +330,9 @@ mutter_shaped_texture_paint (ClutterActor *actor)
cogl_set_source (material);
clutter_actor_get_allocation_box (actor, &alloc);
if (priv->clip_region)
{
GdkRectangle *rects;
int n_rects;
int i;
/* Limit to how many separate rectangles we'll draw; beyond this just
* fall back and draw the whole thing */
# define MAX_RECTS 16
/* Would be nice to be able to check the number of rects first */
gdk_region_get_rectangles (priv->clip_region, &rects, &n_rects);
if (n_rects > MAX_RECTS)
{
g_free (rects);
/* Fall through to following code */
}
else
{
float coords[MAX_RECTS * 8];
for (i = 0; i < n_rects; i++)
{
GdkRectangle *rect = &rects[i];
coords[i * 8 + 0] = rect->x;
coords[i * 8 + 1] = rect->y;
coords[i * 8 + 2] = rect->x + rect->width;
coords[i * 8 + 3] = rect->y + rect->height;
coords[i * 8 + 4] = rect->x / (alloc.x2 - alloc.x1);
coords[i * 8 + 5] = rect->y / (alloc.y2 - alloc.y1);
coords[i * 8 + 6] = (rect->x + rect->width) / (alloc.x2 - alloc.x1);
coords[i * 8 + 7] = (rect->y + rect->height) / (alloc.y2 - alloc.y1);
}
g_free (rects);
cogl_rectangles_with_texture_coords (coords, n_rects);
return;
}
}
cogl_rectangle (0, 0,
alloc.x2 - alloc.x1,
alloc.y2 - alloc.y1);
alloc.x2 - alloc.x1,
alloc.y2 - alloc.y1);
}
static void
@@ -485,37 +426,3 @@ mutter_shaped_texture_add_rectangles (MutterShapedTexture *stex,
mutter_shaped_texture_dirty_mask (stex);
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
}
/**
* mutter_shaped_texture_set_clip_region:
* @frame: a #TidyTextureframe
* @clip_region: (transfer full): the region of the texture that
* is visible and should be painted. OWNERSHIP IS ASSUMED BY
* THE FUNCTION (for efficiency to avoid a copy.)
*
* Provides a hint to the texture about what areas of the texture
* are not completely obscured and thus need to be painted. This
* is an optimization and is not supposed to have any effect on
* the output.
*
* Typically a parent container will set the clip region before
* painting its children, and then unset it afterwards.
*/
void
mutter_shaped_texture_set_clip_region (MutterShapedTexture *stex,
GdkRegion *clip_region)
{
MutterShapedTexturePrivate *priv;
g_return_if_fail (MUTTER_IS_SHAPED_TEXTURE (stex));
priv = stex->priv;
if (priv->clip_region)
{
gdk_region_destroy (priv->clip_region);
priv->clip_region = NULL;
}
priv->clip_region = clip_region;
}

View File

@@ -31,8 +31,6 @@
#include <clutter/glx/clutter-glx.h>
#endif /* HAVE_GLX_TEXTURE_PIXMAP */
#include <gdk/gdkregion.h>
G_BEGIN_DECLS
#define MUTTER_TYPE_SHAPED_TEXTURE \
@@ -92,10 +90,6 @@ void mutter_shaped_texture_add_rectangles (MutterShapedTexture *stex,
size_t num_rects,
const XRectangle *rects);
/* Assumes ownership of clip_region */
void mutter_shaped_texture_set_clip_region (MutterShapedTexture *stex,
GdkRegion *clip_region);
G_END_DECLS
#endif /* __MUTTER_SHAPED_TEXTURE_H__ */

View File

@@ -1,6 +1,8 @@
pkglibdir=@MUTTER_PLUGIN_DIR@
if WITH_CLUTTER
INCLUDES=@MUTTER_CFLAGS@ -I $(top_srcdir)/src/include -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@\"
default_la_CFLAGS = -fPIC
@@ -16,3 +18,5 @@ pkglib_LTLIBRARIES = default.la
install-exec-hook:
-rm $(DESTDIR)$(pkglibdir)/*.a
-rm $(DESTDIR)$(pkglibdir)/*.la
endif

View File

@@ -64,8 +64,6 @@ struct _TidyTextureFramePrivate
gfloat bottom;
CoglHandle material;
guint needs_paint : 1;
};
static void
@@ -177,9 +175,6 @@ tidy_texture_frame_paint (ClutterActor *self)
if (G_UNLIKELY (priv->parent_texture == NULL))
return;
if (!priv->needs_paint)
return;
/* parent texture may have been hidden, so need to make sure it gets
* realized
*/
@@ -613,29 +608,3 @@ tidy_texture_frame_get_frame (TidyTextureFrame *frame,
if (left)
*left = priv->left;
}
/**
* tidy_texture_frame_set_needs_paint:
* @frame: a #TidyTextureframe
* @needs_paint: if %FALSE, the paint will be skipped
*
* Provides a hint to the texture frame that it is totally obscured
* and doesn't need to be painted. This would typically be called
* by a parent container if it detects the condition prior to
* painting its children and then unset afterwards.
*
* Since it is not supposed to have any effect on display, it does
* not queue a repaint.
*/
void
tidy_texture_frame_set_needs_paint (TidyTextureFrame *frame,
gboolean needs_paint)
{
TidyTextureFramePrivate *priv;
g_return_if_fail (TIDY_IS_TEXTURE_FRAME (frame));
priv = frame->priv;
priv->needs_paint = needs_paint;
}

View File

@@ -76,9 +76,6 @@ void tidy_texture_frame_get_frame (TidyTextureFrame *frame,
gfloat *bottom,
gfloat *left);
void tidy_texture_frame_set_needs_paint (TidyTextureFrame *frame,
gboolean needs_paint);
G_END_DECLS
#endif /* _HAVE_TIDY_TEXTURE_FRAME_H */

View File

@@ -1,350 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#define _GNU_SOURCE /* For M_PI */
#include <math.h>
#include "compositor-private.h"
#include "shadow.h"
#include "tidy/tidy-texture-frame.h"
#define SHADOW_RADIUS 8
#define SHADOW_OPACITY 0.9
#define SHADOW_OFFSET_X (SHADOW_RADIUS)
#define SHADOW_OFFSET_Y (SHADOW_RADIUS)
#define MAX_TILE_SZ 8 /* Must be <= shaddow radius */
#define TILE_WIDTH (3*MAX_TILE_SZ)
#define TILE_HEIGHT (3*MAX_TILE_SZ)
static unsigned char* shadow_gaussian_make_tile (void);
ClutterActor *
mutter_create_shadow_frame (MetaCompositor *compositor)
{
ClutterActor *frame;
if (!compositor->shadow_src)
{
guchar *data;
data = shadow_gaussian_make_tile ();
compositor->shadow_src = clutter_texture_new ();
clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (compositor->shadow_src),
data,
TRUE,
TILE_WIDTH,
TILE_HEIGHT,
TILE_WIDTH*4,
4,
0,
NULL);
g_free (data);
}
frame = tidy_texture_frame_new (CLUTTER_TEXTURE (compositor->shadow_src),
MAX_TILE_SZ,
MAX_TILE_SZ,
MAX_TILE_SZ,
MAX_TILE_SZ);
clutter_actor_set_position (frame,
SHADOW_OFFSET_X , SHADOW_OFFSET_Y);
return frame;
}
typedef struct GaussianMap
{
int size;
double * data;
} GaussianMap;
static double
gaussian (double r, double x, double y)
{
return ((1 / (sqrt (2 * M_PI * r))) *
exp ((- (x * x + y * y)) / (2 * r * r)));
}
static GaussianMap *
make_gaussian_map (double r)
{
GaussianMap *c;
int size = ((int) ceil ((r * 3)) + 1) & ~1;
int center = size / 2;
int x, y;
double t = 0.0;
double g;
c = g_malloc (sizeof (GaussianMap) + size * size * sizeof (double));
c->size = size;
c->data = (double *) (c + 1);
for (y = 0; y < size; y++)
for (x = 0; x < size; x++)
{
g = gaussian (r, (double) (x - center), (double) (y - center));
t += g;
c->data[y * size + x] = g;
}
for (y = 0; y < size; y++)
for (x = 0; x < size; x++)
c->data[y*size + x] /= t;
return c;
}
static unsigned char
sum_gaussian (GaussianMap * map, double opacity,
int x, int y, int width, int height)
{
int fx, fy;
double * g_data;
double * g_line = map->data;
int g_size = map->size;
int center = g_size / 2;
int fx_start, fx_end;
int fy_start, fy_end;
double v;
unsigned int r;
/*
* Compute set of filter values which are "in range",
* that's the set with:
* 0 <= x + (fx-center) && x + (fx-center) < width &&
* 0 <= y + (fy-center) && y + (fy-center) < height
*
* 0 <= x + (fx - center) x + fx - center < width
* center - x <= fx fx < width + center - x
*/
fx_start = center - x;
if (fx_start < 0)
fx_start = 0;
fx_end = width + center - x;
if (fx_end > g_size)
fx_end = g_size;
fy_start = center - y;
if (fy_start < 0)
fy_start = 0;
fy_end = height + center - y;
if (fy_end > g_size)
fy_end = g_size;
g_line = g_line + fy_start * g_size + fx_start;
v = 0;
for (fy = fy_start; fy < fy_end; fy++)
{
g_data = g_line;
g_line += g_size;
for (fx = fx_start; fx < fx_end; fx++)
v += *g_data++;
}
if (v > 1)
v = 1;
v *= (opacity * 255.0);
r = (unsigned int) v;
return (unsigned char) r;
}
static unsigned char *
shadow_gaussian_make_tile ()
{
unsigned char * data;
int size;
int center;
int x, y;
unsigned char d;
int pwidth, pheight;
double opacity = SHADOW_OPACITY;
static GaussianMap * gaussian_map = NULL;
struct _mypixel
{
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
} * _d;
if (!gaussian_map)
gaussian_map =
make_gaussian_map (SHADOW_RADIUS);
size = gaussian_map->size;
center = size / 2;
/* Top & bottom */
pwidth = MAX_TILE_SZ;
pheight = MAX_TILE_SZ;
data = g_malloc0 (4 * TILE_WIDTH * TILE_HEIGHT);
_d = (struct _mypixel*) data;
/* N */
for (y = 0; y < pheight; y++)
{
d = sum_gaussian (gaussian_map, opacity,
center, y - center,
TILE_WIDTH, TILE_HEIGHT);
for (x = 0; x < pwidth; x++)
{
_d[y*3*pwidth + x + pwidth].r = 0;
_d[y*3*pwidth + x + pwidth].g = 0;
_d[y*3*pwidth + x + pwidth].b = 0;
_d[y*3*pwidth + x + pwidth].a = d;
}
}
/* S */
pwidth = MAX_TILE_SZ;
pheight = MAX_TILE_SZ;
for (y = 0; y < pheight; y++)
{
d = sum_gaussian (gaussian_map, opacity,
center, y - center,
TILE_WIDTH, TILE_HEIGHT);
for (x = 0; x < pwidth; x++)
{
_d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].r = 0;
_d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].g = 0;
_d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].b = 0;
_d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x + pwidth].a = d;
}
}
/* w */
pwidth = MAX_TILE_SZ;
pheight = MAX_TILE_SZ;
for (x = 0; x < pwidth; x++)
{
d = sum_gaussian (gaussian_map, opacity,
x - center, center,
TILE_WIDTH, TILE_HEIGHT);
for (y = 0; y < pheight; y++)
{
_d[y*3*pwidth + 3*pwidth*pheight + x].r = 0;
_d[y*3*pwidth + 3*pwidth*pheight + x].g = 0;
_d[y*3*pwidth + 3*pwidth*pheight + x].b = 0;
_d[y*3*pwidth + 3*pwidth*pheight + x].a = d;
}
}
/* E */
for (x = 0; x < pwidth; x++)
{
d = sum_gaussian (gaussian_map, opacity,
x - center, center,
TILE_WIDTH, TILE_HEIGHT);
for (y = 0; y < pheight; y++)
{
_d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].r = 0;
_d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].g = 0;
_d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].b = 0;
_d[y*3*pwidth + 3*pwidth*pheight + (pwidth-x-1) + 2*pwidth].a = d;
}
}
/* NW */
pwidth = MAX_TILE_SZ;
pheight = MAX_TILE_SZ;
for (x = 0; x < pwidth; x++)
for (y = 0; y < pheight; y++)
{
d = sum_gaussian (gaussian_map, opacity,
x-center, y-center,
TILE_WIDTH, TILE_HEIGHT);
_d[y*3*pwidth + x].r = 0;
_d[y*3*pwidth + x].g = 0;
_d[y*3*pwidth + x].b = 0;
_d[y*3*pwidth + x].a = d;
}
/* SW */
for (x = 0; x < pwidth; x++)
for (y = 0; y < pheight; y++)
{
d = sum_gaussian (gaussian_map, opacity,
x-center, y-center,
TILE_WIDTH, TILE_HEIGHT);
_d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].r = 0;
_d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].g = 0;
_d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].b = 0;
_d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + x].a = d;
}
/* SE */
for (x = 0; x < pwidth; x++)
for (y = 0; y < pheight; y++)
{
d = sum_gaussian (gaussian_map, opacity,
x-center, y-center,
TILE_WIDTH, TILE_HEIGHT);
_d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) +
2*pwidth].r = 0;
_d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) +
2*pwidth].g = 0;
_d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) +
2*pwidth].b = 0;
_d[(pheight-y-1)*3*pwidth + 6*pwidth*pheight + (pwidth-x-1) +
2*pwidth].a = d;
}
/* NE */
for (x = 0; x < pwidth; x++)
for (y = 0; y < pheight; y++)
{
d = sum_gaussian (gaussian_map, opacity,
x-center, y-center,
TILE_WIDTH, TILE_HEIGHT);
_d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].r = 0;
_d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].g = 0;
_d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].b = 0;
_d[y*3*pwidth + (pwidth - x - 1) + 2*pwidth].a = d;
}
/* center */
pwidth = MAX_TILE_SZ;
pheight = MAX_TILE_SZ;
d = sum_gaussian (gaussian_map, opacity,
center, center, TILE_WIDTH, TILE_HEIGHT);
for (x = 0; x < pwidth; x++)
for (y = 0; y < pheight; y++)
{
_d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].r = 0;
_d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].g = 0;
_d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].b = 0;
_d[y*3*pwidth + 3*pwidth*pheight + x + pwidth].a = 0;
}
return data;
}

View File

@@ -1,9 +0,0 @@
#ifndef SHADOW_H
#define SHADOW_H
#include <clutter/clutter.h>
#include "compositor.h"
ClutterActor *mutter_create_shadow_frame (MetaCompositor *compositor);
#endif /* SHADOW_H */

View File

@@ -766,7 +766,7 @@ meta_invalidate_default_icons (void)
if (display == NULL)
return; /* We can validly be called before the display is opened. */
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
windows = meta_display_list_windows (display);
for (l = windows; l != NULL; l = l->next)
{
MetaWindow *window = (MetaWindow*)l->data;

View File

@@ -253,7 +253,7 @@ meta_window_present_delete_dialog (MetaWindow *window, guint32 timestamp)
* mutter-dialog
*/
windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
windows = meta_display_list_windows (window->display);
tmp = windows;
while (tmp != NULL)
{

View File

@@ -61,10 +61,6 @@ typedef void (* MetaWindowPingFunc) (MetaDisplay *display,
guint32 timestamp,
gpointer user_data);
typedef enum {
META_LIST_DEFAULT = 0, /* normal windows */
META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */
} MetaListWindowsFlags;
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
#define _NET_WM_STATE_ADD 1 /* add/set property */
@@ -174,13 +170,19 @@ struct _MetaDisplay
gulong grab_mask;
guint grab_have_pointer : 1;
guint grab_have_keyboard : 1;
guint grab_wireframe_active : 1;
guint grab_was_cancelled : 1; /* Only used in wireframe mode */
guint grab_frame_action : 1;
MetaRectangle grab_wireframe_rect;
MetaRectangle grab_wireframe_last_xor_rect;
MetaRectangle grab_initial_window_pos;
int grab_initial_x, grab_initial_y; /* These are only relevant for */
gboolean grab_threshold_movement_reached; /* raise_on_click == FALSE. */
MetaResizePopup *grab_resize_popup;
GTimeVal grab_last_moveresize_time;
guint32 grab_motion_notify_time;
int grab_wireframe_last_display_width;
int grab_wireframe_last_display_height;
GList* grab_old_window_stacking;
MetaEdgeResistanceData *grab_edge_resistance_data;
unsigned int grab_last_user_action_was_snap;
@@ -243,18 +245,6 @@ struct _MetaDisplay
/* Managed by compositor.c */
MetaCompositor *compositor;
int render_event_base;
int render_error_base;
int composite_event_base;
int composite_error_base;
int composite_major_version;
int composite_minor_version;
int damage_event_base;
int damage_error_base;
int xfixes_event_base;
int xfixes_error_base;
#ifdef HAVE_STARTUP_NOTIFICATION
SnDisplay *sn_display;
@@ -267,6 +257,20 @@ struct _MetaDisplay
int shape_event_base;
int shape_error_base;
#endif
#ifdef HAVE_RENDER
int render_event_base;
int render_error_base;
#endif
#ifdef HAVE_COMPOSITE_EXTENSIONS
int composite_event_base;
int composite_error_base;
int composite_major_version;
int composite_minor_version;
int damage_event_base;
int damage_error_base;
int xfixes_event_base;
int xfixes_error_base;
#endif
#ifdef HAVE_XSYNC
unsigned int have_xsync : 1;
#define META_DISPLAY_HAS_XSYNC(display) ((display)->have_xsync)
@@ -279,14 +283,24 @@ struct _MetaDisplay
#else
#define META_DISPLAY_HAS_SHAPE(display) FALSE
#endif
#ifdef HAVE_RENDER
unsigned int have_render : 1;
#define META_DISPLAY_HAS_RENDER(display) ((display)->have_render)
#else
#define META_DISPLAY_HAS_RENDER(display) FALSE
#endif
#ifdef HAVE_COMPOSITE_EXTENSIONS
unsigned int have_composite : 1;
unsigned int have_damage : 1;
unsigned int have_xfixes : 1;
#define META_DISPLAY_HAS_COMPOSITE(display) ((display)->have_composite)
#define META_DISPLAY_HAS_DAMAGE(display) ((display)->have_damage)
#define META_DISPLAY_HAS_XFIXES(display) ((display)->have_xfixes)
#else
#define META_DISPLAY_HAS_COMPOSITE(display) FALSE
#define META_DISPLAY_HAS_DAMAGE(display) FALSE
#define META_DISPLAY_HAS_XFIXES(display) FALSE
#endif
};
struct _MetaDisplayClass
@@ -352,8 +366,8 @@ void meta_display_unregister_x_window (MetaDisplay *display,
gboolean meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
Window xwindow);
GSList* meta_display_list_windows (MetaDisplay *display,
MetaListWindowsFlags flags);
GSList* meta_display_list_windows (MetaDisplay *display);
GSList* meta_display_list_all_windows (MetaDisplay *display);
MetaDisplay* meta_display_for_x_display (Display *xdisplay);
MetaDisplay* meta_get_display (void);

View File

@@ -46,6 +46,7 @@
#include "xprops.h"
#include "workspace-private.h"
#include "bell.h"
#include "effects.h"
#include "compositor.h"
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
@@ -61,16 +62,20 @@
#ifdef HAVE_SHAPE
#include <X11/extensions/shape.h>
#endif
#ifdef HAVE_RENDER
#include <X11/extensions/Xrender.h>
#endif
#ifdef HAVE_XKB
#include <X11/XKBlib.h>
#endif
#ifdef HAVE_XCURSOR
#include <X11/Xcursor/Xcursor.h>
#endif
#include <X11/extensions/Xrender.h>
#ifdef HAVE_COMPOSITE_EXTENSIONS
#include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xdamage.h>
#include <X11/extensions/Xfixes.h>
#endif
#include <string.h>
#define GRAB_OP_IS_WINDOW_SWITCH(g) \
@@ -474,6 +479,7 @@ meta_display_open (void)
#endif
the_display->grab_op = META_GRAB_OP_NONE;
the_display->grab_wireframe_active = FALSE;
the_display->grab_window = NULL;
the_display->grab_screen = NULL;
the_display->grab_resize_popup = NULL;
@@ -540,6 +546,7 @@ meta_display_open (void)
meta_verbose ("Not compiled with Shape support\n");
#endif /* !HAVE_SHAPE */
#ifdef HAVE_RENDER
{
the_display->have_render = FALSE;
@@ -560,7 +567,11 @@ meta_display_open (void)
the_display->render_error_base,
the_display->render_event_base);
}
#else /* HAVE_RENDER */
meta_verbose ("Not compiled with Render support\n");
#endif /* !HAVE_RENDER */
#ifdef HAVE_COMPOSITE_EXTENSIONS
{
the_display->have_composite = FALSE;
@@ -636,6 +647,9 @@ meta_display_open (void)
the_display->xfixes_error_base,
the_display->xfixes_event_base);
}
#else /* HAVE_COMPOSITE_EXTENSIONS */
meta_verbose ("Not compiled with Composite support\n");
#endif /* !HAVE_COMPOSITE_EXTENSIONS */
#ifdef HAVE_XCURSOR
{
@@ -798,6 +812,21 @@ meta_display_open (void)
return TRUE;
}
typedef struct {
GSList *winlist;
gboolean include_override_redirect;
} ListifyClosure;
static void
listify_func (gpointer key, gpointer value, gpointer data)
{
ListifyClosure *closure = data;
MetaWindow *window = value;
if (closure->include_override_redirect || !window->override_redirect)
closure->winlist = g_slist_prepend (closure->winlist, window);
}
static gint
ptrcmp (gconstpointer a, gconstpointer b)
{
@@ -809,38 +838,21 @@ ptrcmp (gconstpointer a, gconstpointer b)
return 0;
}
/**
* meta_display_list_windows:
* @display: a #MetaDisplay
* @flags: options for listing
*
* Lists windows for the display, the @flags parameter for
* now determines whether override-redirect windows will be
* included.
*
* Return value: (transfer container): the list of windows.
*/
GSList*
meta_display_list_windows (MetaDisplay *display,
MetaListWindowsFlags flags)
static GSList*
list_windows (MetaDisplay *display,
gboolean include_override_redirect)
{
ListifyClosure closure;
GSList *winlist;
GSList *tmp;
GSList *prev;
GHashTableIter iter;
gpointer key, value;
winlist = NULL;
g_hash_table_iter_init (&iter, display->window_ids);
while (g_hash_table_iter_next (&iter, &key, &value))
{
MetaWindow *window = value;
if (!window->override_redirect ||
(flags & META_LIST_INCLUDE_OVERRIDE_REDIRECT) != 0)
winlist = g_slist_prepend (winlist, window);
}
closure.winlist = NULL;
closure.include_override_redirect = include_override_redirect;
g_hash_table_foreach (display->window_ids,
listify_func,
&closure);
winlist = closure.winlist;
/* Uniquify the list, since both frame windows and plain
* windows are in the hash
@@ -881,6 +893,40 @@ meta_display_list_windows (MetaDisplay *display,
return winlist;
}
/**
* meta_display_list_windows:
* @display: a #MetaDisplay
*
* Lists windows for the display, excluding override-redirect
* windows.
*
* Return value: (transfer container): the list of windows.
*/
GSList*
meta_display_list_windows (MetaDisplay *display)
{
return list_windows (display, FALSE);
}
/**
* meta_display_list_all_windows:
* @display: a #MetaDisplay
*
* Lists windows for the display, including override-redirect
* windows. You usually want to use meta_display_list_windows()
* instead, since override-redirect windows are by definition
* outside the scope of window management. This function is most
* useful if you are interested in how things are displayed on
* the screen.
*
* Return value: (transfer container): the list of windows.
*/
GSList*
meta_display_list_all_windows (MetaDisplay *display)
{
return list_windows (display, TRUE);
}
void
meta_display_close (MetaDisplay *display,
guint32 timestamp)
@@ -2078,6 +2124,9 @@ event_callback (XEvent *event,
"Window %s withdrawn\n",
window->desc);
if (!window->override_redirect)
meta_effect_run_close (window, NULL, NULL);
/* Unmanage withdrawn window */
window->withdrawn = TRUE;
meta_window_unmanage (window, timestamp);
@@ -3338,6 +3387,16 @@ meta_display_begin_grab_op (MetaDisplay *display,
{
Window grab_xwindow;
if (grab_op_is_mouse (op) && meta_grab_op_is_moving (op))
{
if (display->compositor)
{
meta_compositor_begin_move (display->compositor,
window, &window->rect,
root_x, root_y);
}
}
meta_topic (META_DEBUG_WINDOW_OPS,
"Doing grab op %u on window %s button %d pointer already grabbed: %d pointer pos %d,%d\n",
op, window ? window->desc : "none", button, pointer_already_grabbed,
@@ -3430,6 +3489,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
display->grab_sync_request_alarm = None;
display->grab_last_user_action_was_snap = FALSE;
#endif
display->grab_was_cancelled = FALSE;
display->grab_frame_action = frame_action;
if (display->grab_resize_timeout_id)
@@ -3444,8 +3504,20 @@ meta_display_begin_grab_op (MetaDisplay *display,
&display->grab_initial_window_pos);
display->grab_anchor_window_pos = display->grab_initial_window_pos;
display->grab_wireframe_active =
(meta_prefs_get_reduced_resources () && !meta_prefs_get_gnome_accessibility ()) &&
(meta_grab_op_is_resizing (display->grab_op) ||
meta_grab_op_is_moving (display->grab_op));
if (display->grab_wireframe_active)
{
meta_window_calc_showing (display->grab_window);
meta_window_begin_wireframe (window);
}
#ifdef HAVE_XSYNC
if ( meta_grab_op_is_resizing (display->grab_op) &&
if (!display->grab_wireframe_active &&
meta_grab_op_is_resizing (display->grab_op) &&
display->grab_window->sync_request_counter != None)
{
XSyncAlarmAttributes values;
@@ -3596,6 +3668,37 @@ meta_display_end_grab_op (MetaDisplay *display,
display->grab_old_window_stacking = NULL;
}
if (display->grab_wireframe_active)
{
display->grab_wireframe_active = FALSE;
meta_window_end_wireframe (display->grab_window);
if (!display->grab_was_cancelled)
{
if (meta_grab_op_is_moving (display->grab_op))
meta_window_move (display->grab_window,
TRUE,
display->grab_wireframe_rect.x,
display->grab_wireframe_rect.y);
if (meta_grab_op_is_resizing (display->grab_op))
meta_window_resize_with_gravity (display->grab_window,
TRUE,
display->grab_wireframe_rect.width,
display->grab_wireframe_rect.height,
meta_resize_gravity_from_grab_op (display->grab_op));
}
meta_window_calc_showing (display->grab_window);
}
if (display->compositor &&
display->grab_window &&
grab_op_is_mouse (display->grab_op) &&
meta_grab_op_is_moving (display->grab_op))
{
meta_compositor_end_move (display->compositor,
display->grab_window);
}
if (display->grab_have_pointer)
{
meta_topic (META_DEBUG_WINDOW_OPS,
@@ -3912,7 +4015,7 @@ meta_display_queue_retheme_all_windows (MetaDisplay *display)
GSList* windows;
GSList *tmp;
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
windows = meta_display_list_windows (display);
tmp = windows;
while (tmp != NULL)
{
@@ -4422,7 +4525,7 @@ meta_display_get_tab_list (MetaDisplay *display,
GSList *tmp;
MetaWindow *l_window;
tmp = meta_display_list_windows (display, META_LIST_DEFAULT);
tmp = meta_display_list_windows (display);
/* Go through all windows */
while (tmp != NULL)
@@ -4805,8 +4908,7 @@ meta_display_unmanage_windows_for_screen (MetaDisplay *display,
GSList *tmp;
GSList *winlist;
winlist = meta_display_list_windows (display,
META_LIST_INCLUDE_OVERRIDE_REDIRECT);
winlist = meta_display_list_all_windows (display);
winlist = g_slist_sort (winlist, meta_display_stack_cmp);
/* Unmanage all windows */
@@ -4898,7 +5000,7 @@ prefs_changed_callback (MetaPreference pref,
GSList *windows;
GSList *tmp;
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
windows = meta_display_list_windows (display);
/* Ungrab all */
tmp = windows;
@@ -5000,7 +5102,7 @@ sanity_check_timestamps (MetaDisplay *display,
display->last_user_time, timestamp);
display->last_user_time = timestamp;
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
windows = meta_display_list_windows (display);
tmp = windows;
while (tmp != NULL)
{
@@ -5133,6 +5235,7 @@ meta_display_overlay_key_activate (MetaDisplay *display)
g_signal_emit (display, display_signals[OVERLAY_KEY], 0);
}
#ifdef HAVE_COMPOSITE_EXTENSIONS
void
meta_display_get_compositor_version (MetaDisplay *display,
int *major,
@@ -5141,6 +5244,7 @@ meta_display_get_compositor_version (MetaDisplay *display,
*major = display->composite_major_version;
*minor = display->composite_minor_version;
}
#endif
Display *
meta_display_get_xdisplay (MetaDisplay *display)
@@ -5184,12 +5288,15 @@ meta_display_get_focus_window (MetaDisplay *display)
return display->focus_window;
}
#ifdef HAVE_COMPOSITE_EXTENSIONS
int
meta_display_get_damage_event_base (MetaDisplay *display)
{
return display->damage_event_base;
}
#endif
#ifdef HAVE_COMPOSITE_EXTENSIONS
#ifdef HAVE_SHAPE
int
meta_display_get_shape_event_base (MetaDisplay *display)
@@ -5197,6 +5304,7 @@ meta_display_get_shape_event_base (MetaDisplay *display)
return display->shape_event_base;
}
#endif
#endif
Atom meta_display_get_atom (MetaDisplay *display, MetaAtom meta_atom)
{

View File

@@ -1141,8 +1141,17 @@ meta_window_edge_resistance_for_move (MetaWindow *window,
MetaRectangle old_outer, proposed_outer, new_outer;
gboolean is_resize;
meta_window_get_outer_rect (window, &old_outer);
if (window == window->display->grab_window &&
window->display->grab_wireframe_active)
{
meta_window_get_xor_rect (window,
&window->display->grab_wireframe_rect,
&old_outer);
}
else
{
meta_window_get_outer_rect (window, &old_outer);
}
proposed_outer = old_outer;
proposed_outer.x += (*new_x - old_x);
proposed_outer.y += (*new_y - old_y);
@@ -1227,7 +1236,17 @@ meta_window_edge_resistance_for_resize (MetaWindow *window,
int proposed_outer_width, proposed_outer_height;
gboolean is_resize;
meta_window_get_outer_rect (window, &old_outer);
if (window == window->display->grab_window &&
window->display->grab_wireframe_active)
{
meta_window_get_xor_rect (window,
&window->display->grab_wireframe_rect,
&old_outer);
}
else
{
meta_window_get_outer_rect (window, &old_outer);
}
proposed_outer_width = old_outer.width + (*new_width - old_width);
proposed_outer_height = old_outer.height + (*new_height - old_height);
meta_rectangle_resize_with_gravity (&old_outer,

735
src/core/effects.c Normal file
View File

@@ -0,0 +1,735 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/**
* \file effects.c "Special effects" other than compositor effects.
*
* Before we had a serious compositor, we supported swooping
* rectangles for minimising and so on. These are still supported
* today, even when the compositor is enabled. The file contains two
* parts:
*
* 1) A set of functions, each of which implements a special effect.
* (Only the minimize function does anything interesting; we should
* probably get rid of the rest.)
*
* 2) A set of functions for moving a highlighted wireframe box around
* the screen, optionally with height and width shown in the middle.
* This is used for moving and resizing when reduced_resources is set.
*
* There was formerly a system which allowed callers to drop in their
* own handlers for various things; it was never used (people who want
* their own handlers can just modify this file, after all) and it added
* a good deal of extra complexity, so it has been removed. If you want it,
* it can be found in svn r3769.
*
* Once upon a time there were three different ways of drawing the box
* animation: window wireframe, window opaque, and root. People who had
* the shape extension theoretically had the choice of all three, and
* people who didn't weren't given the choice of the wireframe option.
* In practice, though, the opaque animation was never perfect, so it came
* down to the wireframe option for those who had the extension and
* the root option for those who didn't; there was actually no way of choosing
* any other option anyway. Work on the opaque animation stopped in 2002;
* anyone who wants something like that these days will be using the
* compositor anyway.
*
* In svn r3769 this was made explicit.
*/
/*
* Copyright (C) 2001 Anders Carlsson, Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* 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.
*/
#include <config.h>
#include "effects.h"
#include "display-private.h"
#include "ui.h"
#include "window-private.h"
#include "prefs.h"
#ifdef HAVE_SHAPE
#include <X11/extensions/shape.h>
#endif
#define META_MINIMIZE_ANIMATION_LENGTH 0.25
#define META_SHADE_ANIMATION_LENGTH 0.2
#include <string.h>
typedef struct MetaEffect MetaEffect;
typedef struct MetaEffectPriv MetaEffectPriv;
typedef struct
{
MetaScreen *screen;
double millisecs_duration;
GTimeVal start_time;
#ifdef HAVE_SHAPE
/** For wireframe window */
Window wireframe_xwindow;
#else
/** Rectangle to erase */
MetaRectangle last_rect;
/** First time we've plotted anything in this animation? */
gboolean first_time;
/** For wireframe drawn on root window */
GC gc;
#endif
MetaRectangle start_rect;
MetaRectangle end_rect;
} BoxAnimationContext;
/**
* Information we need to know during a maximise or minimise effect.
*/
typedef struct
{
/** This is the normal-size window. */
MetaRectangle window_rect;
/** This is the size of the window when it's an icon. */
MetaRectangle icon_rect;
} MetaMinimizeEffect, MetaUnminimizeEffect;
struct MetaEffectPriv
{
MetaEffectFinished finished;
gpointer finished_data;
};
struct MetaEffect
{
/** The window the effect is applied to. */
MetaWindow *window;
/** Which effect is happening here. */
MetaEffectType type;
/** The effect handler can hang data here. */
gpointer info;
union
{
MetaMinimizeEffect minimize;
/* ... and theoretically anything else */
} u;
MetaEffectPriv *priv;
};
static void run_default_effect_handler (MetaEffect *effect);
static void run_handler (MetaEffect *effect);
static void effect_free (MetaEffect *effect);
static MetaEffect *
create_effect (MetaEffectType type,
MetaWindow *window,
MetaEffectFinished finished,
gpointer finished_data);
static void
draw_box_animation (MetaScreen *screen,
MetaRectangle *initial_rect,
MetaRectangle *destination_rect,
double seconds_duration);
/**
* Creates an effect.
*
*/
static MetaEffect*
create_effect (MetaEffectType type,
MetaWindow *window,
MetaEffectFinished finished,
gpointer finished_data)
{
MetaEffect *effect = g_new (MetaEffect, 1);
effect->type = type;
effect->window = window;
effect->priv = g_new (MetaEffectPriv, 1);
effect->priv->finished = finished;
effect->priv->finished_data = finished_data;
return effect;
}
/**
* Destroys an effect. If the effect has a "finished" hook, it will be
* called before cleanup.
*
* \param effect The effect.
*/
static void
effect_free (MetaEffect *effect)
{
if (effect->priv->finished)
effect->priv->finished (effect->priv->finished_data);
g_free (effect->priv);
g_free (effect);
}
void
meta_effect_run_focus (MetaWindow *window,
MetaEffectFinished finished,
gpointer data)
{
MetaEffect *effect;
g_return_if_fail (window != NULL);
effect = create_effect (META_EFFECT_FOCUS, window, finished, data);
run_handler (effect);
}
void
meta_effect_run_minimize (MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *icon_rect,
MetaEffectFinished finished,
gpointer data)
{
MetaEffect *effect;
g_return_if_fail (window != NULL);
g_return_if_fail (icon_rect != NULL);
effect = create_effect (META_EFFECT_MINIMIZE, window, finished, data);
effect->u.minimize.window_rect = *window_rect;
effect->u.minimize.icon_rect = *icon_rect;
run_handler (effect);
}
void
meta_effect_run_unminimize (MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *icon_rect,
MetaEffectFinished finished,
gpointer data)
{
MetaEffect *effect;
g_return_if_fail (window != NULL);
g_return_if_fail (icon_rect != NULL);
effect = create_effect (META_EFFECT_UNMINIMIZE, window, finished, data);
effect->u.minimize.window_rect = *window_rect;
effect->u.minimize.icon_rect = *icon_rect;
run_handler (effect);
}
void
meta_effect_run_close (MetaWindow *window,
MetaEffectFinished finished,
gpointer data)
{
MetaEffect *effect;
g_return_if_fail (window != NULL);
effect = create_effect (META_EFFECT_CLOSE, window,
finished, data);
run_handler (effect);
}
/* old ugly minimization effect */
#ifdef HAVE_SHAPE
static void
update_wireframe_window (MetaDisplay *display,
Window xwindow,
const MetaRectangle *rect)
{
XMoveResizeWindow (display->xdisplay,
xwindow,
rect->x, rect->y,
rect->width, rect->height);
#define OUTLINE_WIDTH 3
if (rect->width > OUTLINE_WIDTH * 2 &&
rect->height > OUTLINE_WIDTH * 2)
{
XRectangle xrect;
Region inner_xregion;
Region outer_xregion;
inner_xregion = XCreateRegion ();
outer_xregion = XCreateRegion ();
xrect.x = 0;
xrect.y = 0;
xrect.width = rect->width;
xrect.height = rect->height;
XUnionRectWithRegion (&xrect, outer_xregion, outer_xregion);
xrect.x += OUTLINE_WIDTH;
xrect.y += OUTLINE_WIDTH;
xrect.width -= OUTLINE_WIDTH * 2;
xrect.height -= OUTLINE_WIDTH * 2;
XUnionRectWithRegion (&xrect, inner_xregion, inner_xregion);
XSubtractRegion (outer_xregion, inner_xregion, outer_xregion);
XShapeCombineRegion (display->xdisplay, xwindow,
ShapeBounding, 0, 0, outer_xregion, ShapeSet);
XDestroyRegion (outer_xregion);
XDestroyRegion (inner_xregion);
}
else
{
/* Unset the shape */
XShapeCombineMask (display->xdisplay, xwindow,
ShapeBounding, 0, 0, None, ShapeSet);
}
}
#endif
/**
* A hack to force the X server to synchronize with the
* graphics hardware.
*/
static void
graphics_sync (BoxAnimationContext *context)
{
XImage *image;
image = XGetImage (context->screen->display->xdisplay,
context->screen->xroot,
0, 0, 1, 1,
AllPlanes, ZPixmap);
XDestroyImage (image);
}
static gboolean
effects_draw_box_animation_timeout (BoxAnimationContext *context)
{
double elapsed;
GTimeVal current_time;
MetaRectangle draw_rect;
double fraction;
#ifndef HAVE_SHAPE
if (!context->first_time)
{
/* Restore the previously drawn background */
XDrawRectangle (context->screen->display->xdisplay,
context->screen->xroot,
context->gc,
context->last_rect.x, context->last_rect.y,
context->last_rect.width, context->last_rect.height);
}
else
context->first_time = FALSE;
#endif /* !HAVE_SHAPE */
g_get_current_time (&current_time);
/* We use milliseconds for all times */
elapsed =
((((double)current_time.tv_sec - context->start_time.tv_sec) * G_USEC_PER_SEC +
(current_time.tv_usec - context->start_time.tv_usec))) / 1000.0;
if (elapsed < 0)
{
/* Probably the system clock was set backwards? */
meta_warning ("System clock seemed to go backwards?\n");
elapsed = G_MAXDOUBLE; /* definitely done. */
}
if (elapsed > context->millisecs_duration)
{
/* All done */
#ifdef HAVE_SHAPE
XDestroyWindow (context->screen->display->xdisplay,
context->wireframe_xwindow);
#else
meta_display_ungrab (context->screen->display);
meta_ui_pop_delay_exposes (context->screen->ui);
XFreeGC (context->screen->display->xdisplay,
context->gc);
#endif /* !HAVE_SHAPE */
graphics_sync (context);
g_free (context);
return FALSE;
}
g_assert (context->millisecs_duration > 0.0);
fraction = elapsed / context->millisecs_duration;
draw_rect = context->start_rect;
/* Now add a delta proportional to elapsed time. */
draw_rect.x += (context->end_rect.x - context->start_rect.x) * fraction;
draw_rect.y += (context->end_rect.y - context->start_rect.y) * fraction;
draw_rect.width += (context->end_rect.width - context->start_rect.width) * fraction;
draw_rect.height += (context->end_rect.height - context->start_rect.height) * fraction;
/* don't confuse X or gdk-pixbuf with bogus rectangles */
if (draw_rect.width < 1)
draw_rect.width = 1;
if (draw_rect.height < 1)
draw_rect.height = 1;
#ifdef HAVE_SHAPE
update_wireframe_window (context->screen->display,
context->wireframe_xwindow,
&draw_rect);
#else
context->last_rect = draw_rect;
/* Draw the rectangle */
XDrawRectangle (context->screen->display->xdisplay,
context->screen->xroot,
context->gc,
draw_rect.x, draw_rect.y,
draw_rect.width, draw_rect.height);
#endif /* !HAVE_SHAPE */
/* kick changes onto the server */
graphics_sync (context);
return TRUE;
}
void
draw_box_animation (MetaScreen *screen,
MetaRectangle *initial_rect,
MetaRectangle *destination_rect,
double seconds_duration)
{
BoxAnimationContext *context;
#ifdef HAVE_SHAPE
XSetWindowAttributes attrs;
#else
XGCValues gc_values;
#endif
g_return_if_fail (seconds_duration > 0.0);
if (g_getenv ("MUTTER_DEBUG_EFFECTS"))
seconds_duration *= 10; /* slow things down */
/* Create the animation context */
context = g_new0 (BoxAnimationContext, 1);
context->screen = screen;
context->millisecs_duration = seconds_duration * 1000.0;
context->start_rect = *initial_rect;
context->end_rect = *destination_rect;
#ifdef HAVE_SHAPE
attrs.override_redirect = True;
attrs.background_pixel = BlackPixel (screen->display->xdisplay,
screen->number);
context->wireframe_xwindow = XCreateWindow (screen->display->xdisplay,
screen->xroot,
initial_rect->x,
initial_rect->y,
initial_rect->width,
initial_rect->height,
0,
CopyFromParent,
CopyFromParent,
(Visual *)CopyFromParent,
CWOverrideRedirect | CWBackPixel,
&attrs);
update_wireframe_window (screen->display,
context->wireframe_xwindow,
initial_rect);
XMapWindow (screen->display->xdisplay,
context->wireframe_xwindow);
#else /* !HAVE_SHAPE */
context->first_time = TRUE;
gc_values.subwindow_mode = IncludeInferiors;
gc_values.function = GXinvert;
context->gc = XCreateGC (screen->display->xdisplay,
screen->xroot,
GCSubwindowMode | GCFunction,
&gc_values);
/* Grab the X server to avoid screen dirt */
meta_display_grab (context->screen->display);
meta_ui_push_delay_exposes (context->screen->ui);
#endif
/* Do this only after we get the pixbuf from the server,
* so that the animation doesn't get truncated.
*/
g_get_current_time (&context->start_time);
/* Add the timeout - a short one, could even use an idle,
* but this is maybe more CPU-friendly.
*/
g_timeout_add (15,
(GSourceFunc)effects_draw_box_animation_timeout,
context);
/* kick changes onto the server */
XFlush (context->screen->display->xdisplay);
}
void
meta_effects_begin_wireframe (MetaScreen *screen,
const MetaRectangle *rect,
int width,
int height)
{
/* Grab the X server to avoid screen dirt */
meta_display_grab (screen->display);
meta_ui_push_delay_exposes (screen->ui);
meta_effects_update_wireframe (screen,
NULL, -1, -1,
rect, width, height);
}
static void
draw_xor_rect (MetaScreen *screen,
const MetaRectangle *rect,
int width,
int height)
{
/* The lines in the center can't overlap the rectangle or each
* other, or the XOR gets reversed. So we have to draw things
* a bit oddly.
*/
XSegment segments[8];
MetaRectangle shrunk_rect;
int i;
#define LINE_WIDTH META_WIREFRAME_XOR_LINE_WIDTH
/* We don't want the wireframe going outside the window area.
* It makes it harder for the user to position windows and it exposes other
* annoying bugs.
*/
shrunk_rect = *rect;
shrunk_rect.x += LINE_WIDTH / 2 + LINE_WIDTH % 2;
shrunk_rect.y += LINE_WIDTH / 2 + LINE_WIDTH % 2;
shrunk_rect.width -= LINE_WIDTH + 2 * (LINE_WIDTH % 2);
shrunk_rect.height -= LINE_WIDTH + 2 * (LINE_WIDTH % 2);
XDrawRectangle (screen->display->xdisplay,
screen->xroot,
screen->root_xor_gc,
shrunk_rect.x, shrunk_rect.y,
shrunk_rect.width, shrunk_rect.height);
/* Don't put lines inside small rectangles where they won't fit */
if (shrunk_rect.width < (LINE_WIDTH * 4) ||
shrunk_rect.height < (LINE_WIDTH * 4))
return;
if ((width >= 0) && (height >= 0))
{
XGCValues gc_values = { 0 };
if (XGetGCValues (screen->display->xdisplay,
screen->root_xor_gc,
GCFont, &gc_values))
{
char *text;
int text_length;
XFontStruct *font_struct;
int text_width, text_height;
int box_x, box_y;
int box_width, box_height;
font_struct = XQueryFont (screen->display->xdisplay,
gc_values.font);
if (font_struct != NULL)
{
text = g_strdup_printf ("%d x %d", width, height);
text_length = strlen (text);
text_width = text_length * font_struct->max_bounds.width;
text_height = font_struct->max_bounds.descent +
font_struct->max_bounds.ascent;
box_width = text_width + 2 * LINE_WIDTH;
box_height = text_height + 2 * LINE_WIDTH;
box_x = shrunk_rect.x + (shrunk_rect.width - box_width) / 2;
box_y = shrunk_rect.y + (shrunk_rect.height - box_height) / 2;
if ((box_width < shrunk_rect.width) &&
(box_height < shrunk_rect.height))
{
XFillRectangle (screen->display->xdisplay,
screen->xroot,
screen->root_xor_gc,
box_x, box_y,
box_width, box_height);
XDrawString (screen->display->xdisplay,
screen->xroot,
screen->root_xor_gc,
box_x + LINE_WIDTH,
box_y + LINE_WIDTH + font_struct->max_bounds.ascent,
text, text_length);
}
g_free (text);
XFreeFontInfo (NULL, font_struct, 1);
if ((box_width + LINE_WIDTH) >= (shrunk_rect.width / 3))
return;
if ((box_height + LINE_WIDTH) >= (shrunk_rect.height / 3))
return;
}
}
}
/* Two vertical lines at 1/3 and 2/3 */
segments[0].x1 = shrunk_rect.x + shrunk_rect.width / 3;
segments[0].y1 = shrunk_rect.y + LINE_WIDTH / 2 + LINE_WIDTH % 2;
segments[0].x2 = segments[0].x1;
segments[0].y2 = shrunk_rect.y + shrunk_rect.height - LINE_WIDTH / 2;
segments[1] = segments[0];
segments[1].x1 = shrunk_rect.x + (shrunk_rect.width / 3) * 2;
segments[1].x2 = segments[1].x1;
/* Now make two horizontal lines at 1/3 and 2/3, but not
* overlapping the verticals
*/
segments[2].x1 = shrunk_rect.x + LINE_WIDTH / 2 + LINE_WIDTH % 2;
segments[2].x2 = segments[0].x1 - LINE_WIDTH / 2;
segments[2].y1 = shrunk_rect.y + shrunk_rect.height / 3;
segments[2].y2 = segments[2].y1;
segments[3] = segments[2];
segments[3].x1 = segments[2].x2 + LINE_WIDTH;
segments[3].x2 = segments[1].x1 - LINE_WIDTH / 2;
segments[4] = segments[3];
segments[4].x1 = segments[3].x2 + LINE_WIDTH;
segments[4].x2 = shrunk_rect.x + shrunk_rect.width - LINE_WIDTH / 2;
/* Second horizontal line is just like the first, but
* shifted down
*/
i = 5;
while (i < 8)
{
segments[i] = segments[i - 3];
segments[i].y1 = shrunk_rect.y + (shrunk_rect.height / 3) * 2;
segments[i].y2 = segments[i].y1;
++i;
}
XDrawSegments (screen->display->xdisplay,
screen->xroot,
screen->root_xor_gc,
segments,
G_N_ELEMENTS (segments));
}
void
meta_effects_update_wireframe (MetaScreen *screen,
const MetaRectangle *old_rect,
int old_width,
int old_height,
const MetaRectangle *new_rect,
int new_width,
int new_height)
{
if (old_rect)
draw_xor_rect (screen, old_rect, old_width, old_height);
if (new_rect)
draw_xor_rect (screen, new_rect, new_width, new_height);
XFlush (screen->display->xdisplay);
}
void
meta_effects_end_wireframe (MetaScreen *screen,
const MetaRectangle *old_rect,
int old_width,
int old_height)
{
meta_effects_update_wireframe (screen,
old_rect, old_width, old_height,
NULL, -1, -1);
meta_display_ungrab (screen->display);
meta_ui_pop_delay_exposes (screen->ui);
}
static void
run_default_effect_handler (MetaEffect *effect)
{
switch (effect->type)
{
case META_EFFECT_MINIMIZE:
draw_box_animation (effect->window->screen,
&(effect->u.minimize.window_rect),
&(effect->u.minimize.icon_rect),
META_MINIMIZE_ANIMATION_LENGTH);
break;
default:
break;
}
}
static void
run_handler (MetaEffect *effect)
{
if (meta_prefs_get_gnome_animations ())
run_default_effect_handler (effect);
effect_free (effect);
}

170
src/core/effects.h Normal file
View File

@@ -0,0 +1,170 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/**
* \file effects.h "Special effects" other than compositor effects.
*
* Before we had a serious compositor, we supported swooping
* rectangles for minimising and so on. These are still supported
* today, even when the compositor is enabled. The file contains two
* parts:
*
* 1) A set of functions, each of which implements a special effect.
* (Only the minimize function does anything interesting; we should
* probably get rid of the rest.)
*
* 2) A set of functions for moving a highlighted wireframe box around
* the screen, optionally with height and width shown in the middle.
* This is used for moving and resizing when reduced_resources is set.
*
* There was formerly a system which allowed callers to drop in their
* own handlers for various things; it was never used (people who want
* their own handlers can just modify this file, after all) and it added
* a good deal of extra complexity, so it has been removed. If you want it,
* it can be found in svn r3769.
*/
/*
* Copyright (C) 2001 Anders Carlsson, Havoc Pennington
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* 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.
*/
#ifndef META_EFFECTS_H
#define META_EFFECTS_H
#include "util.h"
#include "screen-private.h"
typedef enum
{
META_EFFECT_MINIMIZE,
META_EFFECT_UNMINIMIZE,
META_EFFECT_FOCUS,
META_EFFECT_CLOSE,
META_NUM_EFFECTS
} MetaEffectType;
/**
* A callback which will be called when the effect has finished.
*/
typedef void (* MetaEffectFinished) (gpointer data);
/**
* Performs the minimize effect.
*
* \param window The window we're moving
* \param window_rect Its current state
* \param target Where it should end up
* \param finished Callback for when it's finished
* \param data Data for callback
*/
void meta_effect_run_minimize (MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *target,
MetaEffectFinished finished,
gpointer data);
/**
* Performs the unminimize effect. There is no such effect.
* FIXME: delete this.
*
* \param window The window we're moving
* \param icon_rect Its current state
* \param window_rect Where it should end up
* \param finished Callback for when it's finished
* \param data Data for callback
*/
void meta_effect_run_unminimize (MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *icon_rect,
MetaEffectFinished finished,
gpointer data);
/**
* Performs the close effect. There is no such effect.
* FIXME: delete this.
*
* \param window The window we're moving
* \param finished Callback for when it's finished
* \param data Data for callback
*/
void meta_effect_run_close (MetaWindow *window,
MetaEffectFinished finished,
gpointer data);
/**
* Performs the focus effect. There is no such effect.
* FIXME: delete this.
*
* \param window The window we're moving
* \param finished Callback for when it's finished
* \param data Data for callback
*/
void meta_effect_run_focus (MetaWindow *window,
MetaEffectFinished finished,
gpointer data);
/**
* Grabs the server and paints a wireframe rectangle on the screen.
* Since this involves starting a grab, please be considerate of other
* users and don't keep the grab for long. You may move the wireframe
* around using meta_effects_update_wireframe() and remove it, and undo
* the grab, using meta_effects_end_wireframe().
*
* \param screen The screen to draw the rectangle on.
* \param rect The size of the rectangle to draw.
* \param width The width to display in the middle (or 0 not to)
* \param height The width to display in the middle (or 0 not to)
*/
void meta_effects_begin_wireframe (MetaScreen *screen,
const MetaRectangle *rect,
int width,
int height);
/**
* Moves a wireframe rectangle around after its creation by
* meta_effects_begin_wireframe(). (Perhaps we ought to remember the old
* positions and not require people to pass them in?)
*
* \param old_rect Where the rectangle is now
* \param old_width The width that was displayed on it (or 0 if there wasn't)
* \param old_height The height that was displayed on it (or 0 if there wasn't)
* \param new_rect Where the rectangle is going
* \param new_width The width that will be displayed on it (or 0 not to)
* \param new_height The height that will be displayed on it (or 0 not to)
*/
void meta_effects_update_wireframe (MetaScreen *screen,
const MetaRectangle *old_rect,
int old_width,
int old_height,
const MetaRectangle *new_rect,
int new_width,
int new_height);
/**
* Removes a wireframe rectangle from the screen and ends the grab started by
* meta_effects_begin_wireframe().
*
* \param old_rect Where the rectangle is now
* \param old_width The width that was displayed on it (or 0 if there wasn't)
* \param old_height The height that was displayed on it (or 0 if there wasn't)
*/
void meta_effects_end_wireframe (MetaScreen *screen,
const MetaRectangle *old_rect,
int width,
int height);
#endif /* META_EFFECTS_H */

View File

@@ -29,7 +29,9 @@
#include "errors.h"
#include "keybindings-private.h"
#ifdef HAVE_RENDER
#include <X11/extensions/Xrender.h>
#endif
#define EVENT_MASK (SubstructureRedirectMask | \
StructureNotifyMask | SubstructureNotifyMask | \

View File

@@ -35,6 +35,7 @@
#include "frame-private.h"
#include "place.h"
#include "prefs.h"
#include "effects.h"
#include "util.h"
#include <X11/keysym.h>
@@ -459,7 +460,7 @@ regrab_key_bindings (MetaDisplay *display)
tmp = tmp->next;
}
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
windows = meta_display_list_windows (display);
tmp = windows;
while (tmp != NULL)
{
@@ -1446,19 +1447,23 @@ process_mouse_move_resize_grab (MetaDisplay *display,
/* End move or resize and restore to original state. If the
* window was a maximized window that had been "shaken loose" we
* need to remaximize it. In normal cases, we need to do a
* moveresize now to get the position back to the original.
* moveresize now to get the position back to the original. In
* wireframe mode, we just need to set grab_was_cancelled to tru
* to avoid avoid moveresizing to the position of the wireframe.
*/
if (window->shaken_loose)
meta_window_maximize (window,
META_MAXIMIZE_HORIZONTAL |
META_MAXIMIZE_VERTICAL);
else
else if (!display->grab_wireframe_active)
meta_window_move_resize (display->grab_window,
TRUE,
display->grab_initial_window_pos.x,
display->grab_initial_window_pos.y,
display->grab_initial_window_pos.width,
display->grab_initial_window_pos.height);
else
display->grab_was_cancelled = TRUE;
/* End grab */
return FALSE;
@@ -1489,7 +1494,15 @@ process_keyboard_move_grab (MetaDisplay *display,
if (is_modifier (display, event->xkey.keycode))
return TRUE;
meta_window_get_position (window, &x, &y);
if (display->grab_wireframe_active)
{
x = display->grab_wireframe_rect.x;
y = display->grab_wireframe_rect.y;
}
else
{
meta_window_get_position (window, &x, &y);
}
smart_snap = (event->xkey.state & ShiftMask) != 0;
@@ -1508,19 +1521,23 @@ process_keyboard_move_grab (MetaDisplay *display,
/* End move and restore to original state. If the window was a
* maximized window that had been "shaken loose" we need to
* remaximize it. In normal cases, we need to do a moveresize
* now to get the position back to the original.
* now to get the position back to the original. In wireframe
* mode, we just need to set grab_was_cancelled to tru to avoid
* avoid moveresizing to the position of the wireframe.
*/
if (window->shaken_loose)
meta_window_maximize (window,
META_MAXIMIZE_HORIZONTAL |
META_MAXIMIZE_VERTICAL);
else
else if (!display->grab_wireframe_active)
meta_window_move_resize (display->grab_window,
TRUE,
display->grab_initial_window_pos.x,
display->grab_initial_window_pos.y,
display->grab_initial_window_pos.width,
display->grab_initial_window_pos.height);
else
display->grab_was_cancelled = TRUE;
}
/* When moving by increments, we still snap to edges if the move
@@ -1571,7 +1588,10 @@ process_keyboard_move_grab (MetaDisplay *display,
"Computed new window location %d,%d due to keypress\n",
x, y);
meta_window_get_client_root_coords (window, &old_rect);
if (display->grab_wireframe_active)
old_rect = display->grab_wireframe_rect;
else
meta_window_get_client_root_coords (window, &old_rect);
meta_window_edge_resistance_for_move (window,
old_rect.x,
@@ -1582,7 +1602,17 @@ process_keyboard_move_grab (MetaDisplay *display,
smart_snap,
TRUE);
meta_window_move (window, TRUE, x, y);
if (display->grab_wireframe_active)
{
meta_window_update_wireframe (window, x, y,
display->grab_wireframe_rect.width,
display->grab_wireframe_rect.height);
}
else
{
meta_window_move (window, TRUE, x, y);
}
meta_window_update_keyboard_move (window);
}
@@ -1737,13 +1767,21 @@ process_keyboard_resize_grab (MetaDisplay *display,
if (keysym == XK_Escape)
{
/* End resize and restore to original state. */
meta_window_move_resize (display->grab_window,
TRUE,
display->grab_initial_window_pos.x,
display->grab_initial_window_pos.y,
display->grab_initial_window_pos.width,
display->grab_initial_window_pos.height);
/* End resize and restore to original state. If not in
* wireframe mode, we need to do a moveresize now to get the
* position back to the original. If we are in wireframe mode,
* we need to avoid moveresizing to the position of the
* wireframe.
*/
if (!display->grab_wireframe_active)
meta_window_move_resize (display->grab_window,
TRUE,
display->grab_initial_window_pos.x,
display->grab_initial_window_pos.y,
display->grab_initial_window_pos.width,
display->grab_initial_window_pos.height);
else
display->grab_was_cancelled = TRUE;
return FALSE;
}
@@ -1752,8 +1790,16 @@ process_keyboard_resize_grab (MetaDisplay *display,
event, keysym))
return TRUE;
width = window->rect.width;
height = window->rect.height;
if (display->grab_wireframe_active)
{
width = display->grab_wireframe_rect.width;
height = display->grab_wireframe_rect.height;
}
else
{
width = window->rect.width;
height = window->rect.height;
}
gravity = meta_resize_gravity_from_grab_op (display->grab_op);
@@ -1918,7 +1964,10 @@ process_keyboard_resize_grab (MetaDisplay *display,
"%dx%d, gravity %s\n",
width, height, meta_gravity_to_string (gravity));
old_rect = window->rect; /* Don't actually care about x,y */
if (display->grab_wireframe_active)
old_rect = display->grab_wireframe_rect;
else
old_rect = window->rect; /* Don't actually care about x,y */
/* Do any edge resistance/snapping */
meta_window_edge_resistance_for_resize (window,
@@ -1931,16 +1980,32 @@ process_keyboard_resize_grab (MetaDisplay *display,
smart_snap,
TRUE);
/* We don't need to update unless the specified width and height
* are actually different from what we had before.
*/
if (window->rect.width != width || window->rect.height != height)
meta_window_resize_with_gravity (window,
TRUE,
width,
height,
gravity);
if (display->grab_wireframe_active)
{
MetaRectangle new_position;
meta_rectangle_resize_with_gravity (&display->grab_wireframe_rect,
&new_position,
gravity,
width,
height);
meta_window_update_wireframe (window,
new_position.x,
new_position.y,
new_position.width,
new_position.height);
}
else
{
/* We don't need to update unless the specified width and height
* are actually different from what we had before.
*/
if (window->rect.width != width || window->rect.height != height)
meta_window_resize_with_gravity (window,
TRUE,
width,
height,
gravity);
}
meta_window_update_keyboard_resize (window, FALSE);
}

View File

@@ -69,12 +69,14 @@
#include <locale.h>
#include <time.h>
#ifdef WITH_CLUTTER
#include <clutter/clutter.h>
#include <clutter/x11/clutter-x11.h>
#endif
#ifdef HAVE_INTROSPECTION
#include <girepository.h>
#include "compositor/mutter-plugin-manager.h"
#include "compositor/mutter/mutter-plugin-manager.h"
#endif
/**
@@ -176,6 +178,11 @@ meta_print_compilation_info (void)
#else
meta_verbose ("Compiled without startup notification\n");
#endif
#ifdef HAVE_COMPOSITE_EXTENSIONS
meta_verbose ("Compiled with composite extensions\n");
#else
meta_verbose ("Compiled without composite extensions\n");
#endif
}
/**
@@ -230,7 +237,12 @@ typedef struct
gchar *introspect;
} MetaArguments;
#ifdef HAVE_COMPOSITE_EXTENSIONS
#define COMPOSITE_OPTS_FLAGS 0
#else /* HAVE_COMPOSITE_EXTENSIONS */
/* No compositor, so don't show the arguments in --help */
#define COMPOSITE_OPTS_FLAGS G_OPTION_FLAG_HIDDEN
#endif /* HAVE_COMPOSITE_EXTENSIONS */
/**
* Parses argc and argv and returns the
@@ -304,12 +316,14 @@ meta_parse_options (int *argc, char ***argv,
N_("Turn compositing off"),
NULL
},
#ifdef WITH_CLUTTER
{
"mutter-plugins", 0, 0, G_OPTION_ARG_STRING,
&my_args.mutter_plugins,
N_("Comma-separated list of compositor plugins"),
"PLUGINS"
},
#endif
{
"no-tab-popup", 0, 0, G_OPTION_ARG_NONE,
&my_args.no_tab_popup,
@@ -330,7 +344,15 @@ meta_parse_options (int *argc, char ***argv,
ctx = g_option_context_new (NULL);
g_option_context_add_main_entries (ctx, options, "mutter");
#ifdef WITH_CLUTTER
/*
* This function is only available in clutter >= 0.8.2
*/
#if CLUTTER_CHECK_VERSION(0,8,2)
g_option_context_add_group (ctx, clutter_get_option_group_without_init ());
#endif
#endif
if (!g_option_context_parse (ctx, argc, argv, &error))
{
@@ -343,6 +365,8 @@ meta_parse_options (int *argc, char ***argv,
return ctx;
}
#ifdef WITH_CLUTTER
/* Mutter is responsible for pulling events off the X queue, so Clutter
* doesn't need (and shouldn't) run its normal event source which polls
* the X fd, but we do have to deal with dispatching events that accumulate
@@ -395,15 +419,19 @@ meta_clutter_init (GOptionContext *ctx, int *argc, char ***argv)
if (CLUTTER_INIT_SUCCESS == clutter_init (argc, argv))
{
meta_compositor_can_use_clutter__ = 1;
GSource *source = g_source_new (&event_funcs, sizeof (GSource));
g_source_attach (source, NULL);
g_source_unref (source);
}
else
{
meta_fatal ("Unable to initialize Clutter.\n");
g_message ("Unable to initialize Clutter.\n");
meta_compositor_can_use_clutter__ = 0;
}
}
#endif
/**
* Selects which display Mutter should use. It first tries to use
@@ -553,6 +581,7 @@ main (int argc, char **argv)
/* Parse command line arguments.*/
ctx = meta_parse_options (&argc, &argv, &meta_args);
#ifdef WITH_CLUTTER
/* This must come before the introspect below, so we load all the plugins
* in order to get their get_type functions.
*/
@@ -574,6 +603,7 @@ main (int argc, char **argv)
g_slist_free(plugins_list);
g_strfreev (plugins);
}
#endif /* WITH_CLUTTER */
#ifdef HAVE_INTROSPECTION
g_irepository_prepend_search_path (MUTTER_PKGLIBDIR);
@@ -618,10 +648,12 @@ main (int argc, char **argv)
meta_ui_init (&argc, &argv);
#ifdef WITH_CLUTTER
/*
* Clutter can only be initialized after the UI.
*/
meta_clutter_init (ctx, &argc, &argv);
#endif
g_option_context_free (ctx);

View File

@@ -839,7 +839,7 @@ meta_window_place (MetaWindow *window,
GSList *all_windows;
GSList *tmp;
all_windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
all_windows = meta_display_list_windows (window->display);
tmp = all_windows;
while (tmp != NULL)

View File

@@ -64,7 +64,10 @@
#define KEY_WORKSPACE_NAME_PREFIX "/apps/metacity/workspace_names/name_"
#ifdef WITH_CLUTTER
#define KEY_CLUTTER_DISABLED "/apps/mutter/general/clutter_disabled"
#define KEY_CLUTTER_PLUGINS "/apps/mutter/general/clutter_plugins"
#endif
#define KEY_LIVE_HIDDEN_WINDOWS "/apps/mutter/general/live_hidden_windows"
@@ -94,6 +97,7 @@ static gboolean auto_raise = FALSE;
static gboolean auto_raise_delay = 500;
static gboolean provide_visual_bell = FALSE;
static gboolean bell_is_audible = TRUE;
static gboolean reduced_resources = FALSE;
static gboolean gnome_accessibility = FALSE;
static gboolean gnome_animations = TRUE;
static char *cursor_theme = NULL;
@@ -111,8 +115,11 @@ static char *terminal_command = NULL;
static char *workspace_names[MAX_REASONABLE_WORKSPACES] = { NULL, };
#ifdef WITH_CLUTTER
static gboolean clutter_disabled = FALSE;
static gboolean clutter_plugins_overridden = FALSE;
static GSList *clutter_plugins = NULL;
#endif
static gboolean live_hidden_windows = FALSE;
@@ -396,6 +403,11 @@ static MetaBoolPreference preferences_bool[] =
&bell_is_audible, /* FIXME: change the name: it's confusing */
FALSE,
},
{ "/apps/metacity/general/reduced_resources",
META_PREF_REDUCED_RESOURCES,
&reduced_resources,
FALSE,
},
{ "/desktop/gnome/interface/accessibility",
META_PREF_GNOME_ACCESSIBILITY,
&gnome_accessibility,
@@ -416,6 +428,13 @@ static MetaBoolPreference preferences_bool[] =
&resize_with_right_button,
FALSE,
},
#ifdef WITH_CLUTTER
{ "/apps/mutter/general/clutter_disabled",
META_PREF_CLUTTER_DISABLED,
&clutter_disabled,
FALSE,
},
#endif
{ "/apps/mutter/general/live_hidden_windows",
META_PREF_LIVE_HIDDEN_WINDOWS,
&live_hidden_windows,
@@ -1049,11 +1068,13 @@ meta_prefs_init (void)
handle_preference_init_string ();
handle_preference_init_int ();
#ifdef WITH_CLUTTER
if (!clutter_plugins_overridden)
clutter_plugins = gconf_client_get_list (default_client, KEY_CLUTTER_PLUGINS,
GCONF_VALUE_STRING, &err);
cleanup_error (&err);
#endif
/* @@@ Is there any reason we don't do the add_dir here? */
for (gconf_dir_cursor=gconf_dirs_we_are_interested_in;
@@ -1202,6 +1223,7 @@ change_notify (GConfClient *client,
{
queue_changed (META_PREF_KEYBINDINGS);
}
#ifdef WITH_CLUTTER
else if (g_str_equal (key, KEY_CLUTTER_PLUGINS) && !clutter_plugins_overridden)
{
GError *err = NULL;
@@ -1219,6 +1241,7 @@ change_notify (GConfClient *client,
clutter_plugins = l;
queue_changed (META_PREF_CLUTTER_PLUGINS);
}
#endif
else
{
meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Mutter\n",
@@ -1782,6 +1805,9 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_VISUAL_BELL_TYPE:
return "VISUAL_BELL_TYPE";
case META_PREF_REDUCED_RESOURCES:
return "REDUCED_RESOURCES";
case META_PREF_GNOME_ACCESSIBILITY:
return "GNOME_ACCESSIBILTY";
@@ -1799,13 +1825,14 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_RESIZE_WITH_RIGHT_BUTTON:
return "RESIZE_WITH_RIGHT_BUTTON";
#ifdef WITH_CLUTTER
case META_PREF_CLUTTER_DISABLED:
return "CLUTTER_DISABLED";
case META_PREF_CLUTTER_PLUGINS:
return "CLUTTER_PLUGINS";
#endif
case META_PREF_LIVE_HIDDEN_WINDOWS:
return "LIVE_HIDDEN_WINDOWS";
case META_PREF_NO_TAB_POPUP:
return "NO_TAB_POPUP";
}
@@ -2701,6 +2728,12 @@ meta_prefs_get_auto_raise_delay (void)
return auto_raise_delay;
}
gboolean
meta_prefs_get_reduced_resources (void)
{
return reduced_resources;
}
gboolean
meta_prefs_get_gnome_accessibility ()
{
@@ -2814,6 +2847,35 @@ meta_prefs_set_compositing_manager (gboolean whether)
#endif
}
#ifdef WITH_CLUTTER
gboolean
meta_prefs_get_clutter_disabled (void)
{
return clutter_disabled;
}
void
meta_prefs_set_clutter_disabled (gboolean whether)
{
#ifdef HAVE_GCONF
GError *err = NULL;
gconf_client_set_bool (default_client,
KEY_CLUTTER_DISABLED,
whether,
&err);
if (err)
{
meta_warning (_("Error setting clutter status status: %s\n"),
err->message);
g_error_free (err);
}
#else
clutter_disabled = whether;
#endif
}
GSList *
meta_prefs_get_clutter_plugins (void)
{
@@ -2852,6 +2914,7 @@ meta_prefs_override_clutter_plugins (GSList *list)
clutter_plugins = g_slist_reverse (clutter_plugins);
}
#endif
gboolean
meta_prefs_get_live_hidden_windows (void)

View File

@@ -117,7 +117,9 @@ struct _MetaScreen
guint startup_sequence_timeout;
#endif
#ifdef HAVE_COMPOSITE_EXTENSIONS
Window wm_cm_selection_window;
#endif
guint work_area_idle;
@@ -246,9 +248,4 @@ void meta_screen_composite_all_windows (MetaScreen *screen);
void meta_screen_restacked (MetaScreen *screen);
void meta_screen_workspace_switched (MetaScreen *screen,
int from,
int to,
MetaMotionDirection direction);
#endif

View File

@@ -39,8 +39,6 @@
#include "xprops.h"
#include "compositor.h"
#include "alttabhandlerdefault.h"
#include "mutter-marshal.h"
#include "mutter-enum-types.h"
#ifdef HAVE_SOLARIS_XINERAMA
#include <X11/extensions/xinerama.h>
@@ -82,9 +80,6 @@ enum
{
RESTACKED,
TOGGLE_RECORDING,
WORKSPACE_ADDED,
WORKSPACE_REMOVED,
WORKSPACE_SWITCHED,
LAST_SIGNAL
};
@@ -164,41 +159,6 @@ meta_screen_class_init (MetaScreenClass *klass)
1, G_MAXINT, 1,
G_PARAM_READABLE);
screen_signals[WORKSPACE_ADDED] =
g_signal_new ("workspace-added",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__INT,
G_TYPE_NONE,
1,
G_TYPE_INT);
screen_signals[WORKSPACE_REMOVED] =
g_signal_new ("workspace-removed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__INT,
G_TYPE_NONE,
1,
G_TYPE_INT);
screen_signals[WORKSPACE_SWITCHED] =
g_signal_new ("workspace-switched",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
_mutter_marshal_VOID__INT_INT_ENUM,
G_TYPE_NONE,
3,
G_TYPE_INT,
G_TYPE_INT,
MUTTER_TYPE_MOTION_DIRECTION);
screen_signals[TOGGLE_RECORDING] =
g_signal_new ("toggle-recording",
G_TYPE_FROM_CLASS (klass),
@@ -479,15 +439,11 @@ create_guard_window (Display *xdisplay, MetaScreen *screen)
{
XSetWindowAttributes attributes;
Window guard_window;
gulong create_serial;
attributes.event_mask = NoEventMask;
attributes.override_redirect = True;
attributes.background_pixel = BlackPixel (xdisplay, screen->number);
/* We have to call record_add() after we have the new window ID,
* so save the serial for the CreateWindow request until then */
create_serial = XNextRequest(xdisplay);
guard_window =
XCreateWindow (xdisplay,
screen->xroot,
@@ -503,11 +459,8 @@ create_guard_window (Display *xdisplay, MetaScreen *screen)
&attributes);
meta_stack_tracker_record_add (screen->stack_tracker,
guard_window,
create_serial);
XNextRequest(xdisplay) - 1);
meta_stack_tracker_record_lower (screen->stack_tracker,
guard_window,
XNextRequest (xdisplay));
XLowerWindow (xdisplay, guard_window);
XMapWindow (xdisplay, guard_window);
return guard_window;
@@ -644,7 +597,10 @@ meta_screen_new (MetaDisplay *display,
LeaveWindowMask | EnterWindowMask |
KeyPressMask | KeyReleaseMask |
FocusChangeMask | StructureNotifyMask |
ExposureMask | attr.your_event_mask);
#ifdef HAVE_COMPOSITE_EXTENSIONS
ExposureMask |
#endif
attr.your_event_mask);
if (meta_error_trap_pop_with_return (display, FALSE) != Success)
{
meta_warning (_("Screen %d on display \"%s\" already has a window manager\n"),
@@ -675,9 +631,11 @@ meta_screen_new (MetaDisplay *display,
screen->wm_sn_atom = wm_sn_atom;
screen->wm_sn_timestamp = manager_timestamp;
#ifdef HAVE_COMPOSITE_EXTENSIONS
screen->wm_cm_selection_window = meta_create_offscreen_window (xdisplay,
xroot,
NoEventMask);
#endif
screen->work_area_idle = 0;
screen->active_workspace = NULL;
@@ -961,7 +919,6 @@ meta_screen_manage_all_windows (MetaScreen *screen)
MetaWindow *window;
window = meta_window_new_with_attrs (screen->display, info->xwindow, TRUE,
META_COMP_EFFECT_NONE,
&info->attrs);
}
meta_stack_thaw (screen->stack);
@@ -975,6 +932,7 @@ meta_screen_manage_all_windows (MetaScreen *screen)
void
meta_screen_composite_all_windows (MetaScreen *screen)
{
#ifdef HAVE_COMPOSITE_EXTENSIONS
MetaDisplay *display;
GSList *windows, *tmp;
@@ -982,14 +940,14 @@ meta_screen_composite_all_windows (MetaScreen *screen)
if (!display->compositor)
return;
windows = meta_display_list_windows (display,
META_LIST_INCLUDE_OVERRIDE_REDIRECT);
windows = meta_display_list_all_windows (display);
for (tmp = windows; tmp != NULL; tmp = tmp->next)
meta_compositor_add_window (display->compositor, tmp->data);
g_slist_free (windows);
/* initialize the compositor's view of the stacking order */
meta_stack_tracker_sync_stack (screen->stack_tracker);
#endif
}
/**
@@ -1282,7 +1240,6 @@ meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace,
GList *l;
MetaWorkspace *neighbour = NULL;
GList *next = NULL;
int index;
l = screen->workspaces;
while (l)
@@ -1318,9 +1275,6 @@ meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace,
if (workspace == screen->active_workspace)
meta_workspace_activate (neighbour, timestamp);
/* To emit the signal after removing the workspace */
index = meta_workspace_index (workspace);
/* This also removes the workspace from the screens list */
meta_workspace_remove (workspace);
@@ -1338,7 +1292,6 @@ meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace,
meta_screen_queue_workarea_recalc (screen);
g_signal_emit (screen, screen_signals[WORKSPACE_REMOVED], 0, index);
g_object_notify (G_OBJECT (screen), "n-workspaces");
}
@@ -1374,8 +1327,6 @@ meta_screen_append_new_workspace (MetaScreen *screen, gboolean activate,
meta_screen_queue_workarea_recalc (screen);
g_signal_emit (screen, screen_signals[WORKSPACE_ADDED],
0, meta_workspace_index (w));
g_object_notify (G_OBJECT (screen), "n-workspaces");
return w;
@@ -2539,7 +2490,7 @@ queue_windows_showing (MetaScreen *screen)
* active_workspace's window list, because the active_workspace's
* window list may not contain the on_all_workspace windows.
*/
windows = meta_display_list_windows (screen->display, META_LIST_DEFAULT);
windows = meta_display_list_windows (screen->display);
tmp = windows;
while (tmp != NULL)
@@ -3008,6 +2959,7 @@ meta_screen_set_compositor_data (MetaScreen *screen,
screen->compositor_data = compositor;
}
#ifdef HAVE_COMPOSITE_EXTENSIONS
void
meta_screen_set_cm_selection (MetaScreen *screen)
{
@@ -3031,6 +2983,7 @@ meta_screen_unset_cm_selection (MetaScreen *screen)
a = XInternAtom (screen->display->xdisplay, selection, FALSE);
XSetSelectionOwner (screen->display->xdisplay, a, None, CurrentTime);
}
#endif /* HAVE_COMPOSITE_EXTENSIONS */
GList *
meta_screen_get_workspaces (MetaScreen *screen)
@@ -3060,14 +3013,3 @@ meta_screen_restacked (MetaScreen *screen)
{
g_signal_emit (screen, screen_signals[RESTACKED], 0);
}
void
meta_screen_workspace_switched (MetaScreen *screen,
int from,
int to,
MetaMotionDirection direction)
{
g_signal_emit (screen, screen_signals[WORKSPACE_SWITCHED], 0,
from, to, direction);
}

View File

@@ -889,7 +889,7 @@ save_state (void)
fprintf (outfile, "<mutter_session id=\"%s\">\n",
client_id);
windows = meta_display_list_windows (meta_get_display (), META_LIST_DEFAULT);
windows = meta_display_list_windows (meta_get_display ());
stack_position = 0;
windows = g_slist_sort (windows, meta_display_stack_cmp);
@@ -1768,7 +1768,7 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown)
GSList *tmp;
GSList *columns = NULL;
windows = meta_display_list_windows (meta_get_display (), META_LIST_DEFAULT);
windows = meta_display_list_windows (meta_get_display ());
tmp = windows;
while (tmp != NULL)
{

View File

@@ -686,10 +686,9 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
meta_windows = g_list_prepend (meta_windows, meta_window);
}
if (tracker->screen->display->compositor)
meta_compositor_sync_stack (tracker->screen->display->compositor,
tracker->screen,
meta_windows);
meta_compositor_sync_stack (tracker->screen->display->compositor,
tracker->screen,
meta_windows);
g_list_free (meta_windows);
meta_screen_restacked (tracker->screen);

View File

@@ -241,6 +241,12 @@ get_standalone_layer (MetaWindow *window)
MetaStackLayer layer;
gboolean focused_transient = FALSE;
if (window->hidden)
{
layer = META_LAYER_DESKTOP;
return layer;
}
switch (window->type)
{
case META_WINDOW_DESKTOP:

View File

@@ -35,7 +35,6 @@
#define META_WINDOW_PRIVATE_H
#include <config.h>
#include "compositor.h"
#include "window.h"
#include "screen-private.h"
#include "util.h"
@@ -153,6 +152,7 @@ struct _MetaWindow
/* Minimize is the state controlled by the minimize button */
guint minimized : 1;
guint was_minimized : 1;
guint tab_unminimized : 1;
/* Whether the window is mapped; actual server-side state
@@ -165,15 +165,6 @@ struct _MetaWindow
*/
guint hidden : 1;
/* Whether the compositor thinks the window is visible
*/
guint visible_to_compositor : 1;
/* When we next show or hide the window, what effect we should
* tell the compositor to perform.
*/
guint pending_compositor_effect : 4; /* MetaCompEffect */
/* Iconic is the state in WM_STATE; happens for workspaces/shading
* in addition to minimize
*/
@@ -367,7 +358,9 @@ struct _MetaWindow
/* maintained by group.c */
MetaGroup *group;
#ifdef HAVE_COMPOSITE_EXTENSIONS
GObject *compositor_private;
#endif
};
struct _MetaWindowClass
@@ -398,10 +391,9 @@ struct _MetaWindowClass
MetaWindow* meta_window_new (MetaDisplay *display,
Window xwindow,
gboolean must_be_viewable);
MetaWindow* meta_window_new_with_attrs (MetaDisplay *display,
Window xwindow,
gboolean must_be_viewable,
MetaCompEffect effect,
MetaWindow* meta_window_new_with_attrs (MetaDisplay *display,
Window xwindow,
gboolean must_be_viewable,
XWindowAttributes *attrs);
void meta_window_unmanage (MetaWindow *window,
guint32 timestamp);
@@ -456,8 +448,6 @@ void meta_window_resize_with_gravity (MetaWindow *window,
/* Return whether the window should be currently mapped */
gboolean meta_window_should_be_showing (MetaWindow *window);
gboolean meta_window_toplevel_is_mapped (MetaWindow *window);
/* See warning in window.c about this function */
gboolean __window_is_terminal (MetaWindow *window);
@@ -491,6 +481,16 @@ void meta_window_get_geometry (MetaWindow *window,
int *y,
int *width,
int *height);
void meta_window_get_xor_rect (MetaWindow *window,
const MetaRectangle *grab_wireframe_rect,
MetaRectangle *xor_rect);
void meta_window_begin_wireframe (MetaWindow *window);
void meta_window_update_wireframe (MetaWindow *window,
int x,
int y,
int width,
int height);
void meta_window_end_wireframe (MetaWindow *window);
void meta_window_kill (MetaWindow *window);
void meta_window_focus (MetaWindow *window,

View File

@@ -179,7 +179,7 @@ meta_window_load_initial_properties (MetaWindow *window)
{
/* If we didn't actually manage to load anything then we don't need
* to call the reload function; this is different from a notification
* where disappearance of a previously present value is significant.
* where disappearance of a previously value is significant.
*/
if (values[j].type != META_PROP_VALUE_INVALID)
reload_prop_value (window, hooks, &values[j], TRUE);
@@ -1481,6 +1481,9 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
*
* - properties that identify the window: useful for debugging
* purposes.
* - WM_TRANSIENT_FOR: could be used to associate menus or other
* override-redirect transients with their parent windows if
* the app sets the property (GTK+ does set this for menus.)
* - NET_WM_WINDOW_TYPE: can be used to do appropriate handling
* for different types of override-redirect windows.
*/
@@ -1496,12 +1499,12 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
{ display->atom__NET_STARTUP_ID, META_PROP_VALUE_UTF8, reload_net_startup_id, TRUE, FALSE },
{ display->atom__NET_WM_SYNC_REQUEST_COUNTER, META_PROP_VALUE_SYNC_COUNTER, reload_update_counter, TRUE, FALSE },
{ XA_WM_NORMAL_HINTS, META_PROP_VALUE_SIZE_HINTS, reload_normal_hints, TRUE, FALSE },
{ display->atom_WM_PROTOCOLS, META_PROP_VALUE_ATOM_LIST, reload_wm_protocols, TRUE, FALSE },
{ display->atom_WM_PROTOCOLS, META_PROP_VALUE_ATOM_LIST, reload_wm_protocols, TRUE, TRUE },
{ XA_WM_HINTS, META_PROP_VALUE_WM_HINTS, reload_wm_hints, TRUE, FALSE },
{ display->atom__NET_WM_USER_TIME, META_PROP_VALUE_CARDINAL, reload_net_wm_user_time, TRUE, FALSE },
{ display->atom__NET_WM_STATE, META_PROP_VALUE_ATOM_LIST, reload_net_wm_state, TRUE, FALSE },
{ display->atom__MOTIF_WM_HINTS, META_PROP_VALUE_MOTIF_HINTS, reload_mwm_hints, TRUE, FALSE },
{ XA_WM_TRANSIENT_FOR, META_PROP_VALUE_WINDOW, reload_transient_for, TRUE, FALSE },
{ XA_WM_TRANSIENT_FOR, META_PROP_VALUE_WINDOW, reload_transient_for, TRUE, TRUE },
{ display->atom__NET_WM_USER_TIME_WINDOW, META_PROP_VALUE_WINDOW, reload_net_wm_user_time_window, TRUE, FALSE },
{ display->atom_WM_STATE, META_PROP_VALUE_INVALID, NULL, FALSE, FALSE },
{ display->atom__NET_WM_ICON, META_PROP_VALUE_INVALID, reload_net_wm_icon, FALSE, FALSE },

View File

@@ -36,12 +36,15 @@
#include "ui.h"
#include "place.h"
#include "session.h"
#include "effects.h"
#include "prefs.h"
#include "resizepopup.h"
#include "xprops.h"
#include "group.h"
#include "window-props.h"
#include "constraints.h"
#include "compositor.h"
#include "effects.h"
#include <X11/Xatom.h>
#include <string.h>
@@ -50,7 +53,9 @@
#include <X11/extensions/shape.h>
#endif
#ifdef HAVE_COMPOSITE_EXTENSIONS
#include <X11/extensions/Xcomposite.h>
#endif
static int destroying_windows_disallowed = 0;
@@ -390,9 +395,7 @@ meta_window_new (MetaDisplay *display,
return NULL;
}
window = meta_window_new_with_attrs (display, xwindow,
must_be_viewable,
META_COMP_EFFECT_CREATE,
&attrs);
must_be_viewable, &attrs);
}
else
{
@@ -415,7 +418,6 @@ MetaWindow*
meta_window_new_with_attrs (MetaDisplay *display,
Window xwindow,
gboolean must_be_viewable,
MetaCompEffect effect,
XWindowAttributes *attrs)
{
MetaWindow *window;
@@ -461,12 +463,14 @@ meta_window_new_with_attrs (MetaDisplay *display,
/* any windows created via meta_create_offscreen_window: */
(attrs->x == -100 && attrs->y == -100
&& attrs->width == 1 && attrs->height == 1) ||
#ifdef HAVE_COMPOSITE_EXTENSIONS
xwindow == screen->wm_cm_selection_window ||
xwindow == screen->guard_window ||
(display->compositor &&
xwindow == XCompositeGetOverlayWindow (display->xdisplay,
screen->xroot)
)
#endif
)
) {
meta_verbose ("Not managing our own windows\n");
@@ -667,12 +671,11 @@ meta_window_new_with_attrs (MetaDisplay *display,
window->shaded = FALSE;
window->initially_iconic = FALSE;
window->minimized = FALSE;
window->was_minimized = FALSE;
window->tab_unminimized = FALSE;
window->iconic = FALSE;
window->mapped = attrs->map_state != IsUnmapped;
window->hidden = FALSE;
window->visible_to_compositor = FALSE;
window->pending_compositor_effect = effect;
window->hidden = 0;
/* if already mapped, no need to worry about focus-on-first-time-showing */
window->showing_for_first_time = !window->mapped;
/* if already mapped we don't want to do the placement thing;
@@ -1189,13 +1192,7 @@ meta_window_unmanage (MetaWindow *window,
meta_verbose ("Unmanaging 0x%lx\n", window->xwindow);
if (window->display->compositor)
{
if (window->visible_to_compositor)
meta_compositor_hide_window (window->display->compositor, window,
META_COMP_EFFECT_DESTROY);
meta_compositor_remove_window (window->display->compositor, window);
}
meta_compositor_remove_window (window->display->compositor, window);
if (window->display->window_with_menu == window)
{
@@ -1279,7 +1276,11 @@ meta_window_unmanage (MetaWindow *window,
g_assert (window->display->grab_window != window);
if (window->display->focus_window == window)
window->display->focus_window = NULL;
{
window->display->focus_window = NULL;
meta_compositor_set_active_window (window->display->compositor,
window->screen, NULL);
}
if (window->maximized_horizontally || window->maximized_vertically)
unmaximize_window_before_freeing (window);
@@ -1609,6 +1610,14 @@ meta_window_showing_on_its_workspace (MetaWindow *window)
showing = FALSE;
}
#if 0
/* 4. See if we're drawing wireframe
*/
if (window->display->grab_window == window &&
window->display->grab_wireframe_active)
showing = FALSE;
#endif
return showing;
}
@@ -1638,6 +1647,41 @@ meta_window_should_be_showing (MetaWindow *window)
return on_workspace && meta_window_showing_on_its_workspace (window);
}
static void
finish_minimize (gpointer data)
{
MetaWindow *window = data;
/* FIXME: It really sucks to put timestamp pinging here; it'd
* probably make more sense in implement_showing() so that it's at
* least not duplicated in meta_window_show; but since
* finish_minimize is a callback making things just slightly icky, I
* haven't done that yet.
*/
guint32 timestamp = meta_display_get_current_time_roundtrip (window->display);
meta_window_hide (window);
if (window->has_focus)
{
MetaWindow *not_this_one = NULL;
MetaWorkspace *my_workspace = meta_window_get_workspace (window);
/*
* If this window is modal, passing the not_this_one window to
* _focus_default_window() makes the focus to be given to this window's
* ancestor. This can only be the case if the window is on the currently
* active workspace; when it is not, we need to pass in NULL, so as to
* focus the default window for the active workspace (this scenario
* arises when we are switching workspaces).
*/
if (my_workspace == window->screen->active_workspace)
not_this_one = window;
meta_workspace_focus_default_window (window->screen->active_workspace,
not_this_one,
timestamp);
}
}
static void
implement_showing (MetaWindow *window,
gboolean showing)
@@ -1647,11 +1691,64 @@ implement_showing (MetaWindow *window,
showing, window->desc);
if (!showing)
meta_window_hide (window);
else
meta_window_show (window);
{
gboolean on_workspace;
window->pending_compositor_effect = META_COMP_EFFECT_NONE;
on_workspace = meta_window_located_on_workspace (window,
window->screen->active_workspace);
/* Really this effects code should probably
* be in meta_window_hide so the window->mapped
* test isn't duplicated here. Anyhow, we animate
* if we are mapped now, we are supposed to
* be minimized, and we are on the current workspace.
*/
if (on_workspace && window->minimized && window->mapped &&
!window->hidden && !meta_prefs_get_reduced_resources ())
{
MetaRectangle icon_rect, window_rect;
gboolean result;
/* Check if the window has an icon geometry */
result = meta_window_get_icon_geometry (window, &icon_rect);
if (!result)
{
/* just animate into the corner somehow - maybe
* not a good idea...
*/
icon_rect.x = window->screen->rect.width;
icon_rect.y = window->screen->rect.height;
icon_rect.width = 1;
icon_rect.height = 1;
}
meta_window_get_outer_rect (window, &window_rect);
if (window->display->compositor)
{
meta_compositor_minimize_window (window->display->compositor,
window,
&window_rect,
&icon_rect);
finish_minimize (window);
}
else
meta_effect_run_minimize (window,
&window_rect,
&icon_rect,
finish_minimize,
window);
}
else
{
finish_minimize (window);
}
}
else
{
meta_window_show (window);
}
}
void
@@ -1881,7 +1978,7 @@ meta_window_queue (MetaWindow *window, guint queuebits)
guint queuenum;
/* Easier to debug by checking here rather than in the idle */
g_return_if_fail (!window->override_redirect || (queuebits & META_QUEUE_MOVE_RESIZE) == 0);
g_return_if_fail (!((queuebits & META_QUEUE_MOVE_RESIZE) != 0 && window->override_redirect));
for (queuenum=0; queuenum<NUMBER_OF_QUEUES; queuenum++)
{
@@ -2254,7 +2351,6 @@ map_client_window (MetaWindow *window)
meta_error_trap_push (window->display);
XMapWindow (window->display->xdisplay, window->xwindow);
meta_error_trap_pop (window->display, FALSE);
return TRUE;
}
else
@@ -2278,32 +2374,13 @@ unmap_client_window (MetaWindow *window,
meta_error_trap_push (window->display);
XUnmapWindow (window->display->xdisplay, window->xwindow);
meta_error_trap_pop (window->display, FALSE);
return TRUE;
}
else
return FALSE;
}
/**
* meta_window_toplevel_is_mapped:
* @window: a #MetaWindow
*
* Determines whether the toplevel X window for the MetaWindow is
* mapped. (The frame window is mapped even without the client window
* when a window is shaded.)
*
* Return Value: %TRUE if the toplevel is mapped.
*/
gboolean
meta_window_toplevel_is_mapped (MetaWindow *window)
{
/* The frame is mapped but not the client window when the window
* is shaded.
*/
return window->mapped || (window->frame && window->frame->mapped);
}
/* XXX META_EFFECT_*_MAP */
static void
meta_window_show (MetaWindow *window)
{
@@ -2312,15 +2389,18 @@ meta_window_show (MetaWindow *window)
gboolean place_on_top_on_map;
gboolean needs_stacking_adjustment;
MetaWindow *focus_window;
gboolean toplevel_was_mapped;
gboolean toplevel_now_mapped;
guint32 timestamp;
/* FIXME: It really sucks to put timestamp pinging here; it'd
* probably make more sense in implement_showing() so that it's at
* least not duplicated in finish_minimize. *shrug*
*/
timestamp = meta_display_get_current_time_roundtrip (window->display);
meta_topic (META_DEBUG_WINDOW_STATE,
"Showing window %s, shaded: %d iconic: %d placed: %d\n",
window->desc, window->shaded, window->iconic, window->placed);
toplevel_was_mapped = meta_window_toplevel_is_mapped (window);
focus_window = window->display->focus_window; /* May be NULL! */
did_show = FALSE;
window_state_on_map (window, &takes_focus_on_map, &place_on_top_on_map);
@@ -2349,10 +2429,6 @@ meta_window_show (MetaWindow *window)
) {
if (meta_window_is_ancestor_of_transient (focus_window, window))
{
guint32 timestamp;
timestamp = meta_display_get_current_time_roundtrip (window->display);
/* This happens for error dialogs or alerts; these need to remain on
* top, but it would be confusing to have its ancestor remain
* focused.
@@ -2477,11 +2553,50 @@ meta_window_show (MetaWindow *window)
{
meta_stack_freeze (window->screen->stack);
window->hidden = FALSE;
/* Inform the compositor that the window isn't hidden */
meta_compositor_set_window_hidden (window->display->compositor,
window->screen,
window,
window->hidden);
meta_stack_thaw (window->screen->stack);
did_show = TRUE;
}
}
if (did_show)
{
MetaRectangle icon_rect;
if (window->was_minimized
&& meta_window_get_icon_geometry (window, &icon_rect))
{
MetaRectangle window_rect;
meta_window_get_outer_rect (window, &window_rect);
if (window->display->compositor)
meta_compositor_unminimize_window (window->display->compositor,
window,
&window_rect,
&icon_rect);
else
meta_effect_run_unminimize (window,
&window_rect,
&icon_rect,
NULL, NULL);
}
else
meta_compositor_map_window (window->display->compositor,
window);
window->was_minimized = FALSE;
}
else
{
if (window->display->compositor)
meta_compositor_map_window (window->display->compositor, window);
}
if (window->iconic)
{
window->iconic = FALSE;
@@ -2489,38 +2604,6 @@ meta_window_show (MetaWindow *window)
}
}
toplevel_now_mapped = meta_window_toplevel_is_mapped (window);
if (toplevel_now_mapped != toplevel_was_mapped)
{
if (window->display->compositor)
meta_compositor_window_mapped (window->display->compositor, window);
}
if (!window->visible_to_compositor)
{
if (window->display->compositor)
{
MetaCompEffect effect = META_COMP_EFFECT_NONE;
switch (window->pending_compositor_effect)
{
case META_COMP_EFFECT_CREATE:
case META_COMP_EFFECT_UNMINIMIZE:
effect = window->pending_compositor_effect;
break;
case META_COMP_EFFECT_NONE:
case META_COMP_EFFECT_DESTROY:
case META_COMP_EFFECT_MINIMIZE:
break;
}
meta_compositor_show_window (window->display->compositor,
window, effect);
}
window->visible_to_compositor = TRUE;
}
/* We don't want to worry about all cases from inside
* implement_showing(); we only want to worry about focus if this
* window has not been shown before.
@@ -2530,10 +2613,6 @@ meta_window_show (MetaWindow *window)
window->showing_for_first_time = FALSE;
if (takes_focus_on_map)
{
guint32 timestamp;
timestamp = meta_display_get_current_time_roundtrip (window->display);
meta_window_focus (window, timestamp);
}
else
@@ -2559,64 +2638,47 @@ meta_window_show (MetaWindow *window)
}
}
/* XXX META_EFFECT_*_UNMAP */
static void
meta_window_hide (MetaWindow *window)
{
gboolean did_hide;
gboolean toplevel_was_mapped;
gboolean toplevel_now_mapped;
meta_topic (META_DEBUG_WINDOW_STATE,
"Hiding window %s\n", window->desc);
toplevel_was_mapped = meta_window_toplevel_is_mapped (window);
if (window->visible_to_compositor)
{
if (window->display->compositor)
{
MetaCompEffect effect = META_COMP_EFFECT_NONE;
switch (window->pending_compositor_effect)
{
case META_COMP_EFFECT_CREATE:
case META_COMP_EFFECT_UNMINIMIZE:
case META_COMP_EFFECT_NONE:
break;
case META_COMP_EFFECT_DESTROY:
case META_COMP_EFFECT_MINIMIZE:
effect = window->pending_compositor_effect;
break;
}
meta_compositor_hide_window (window->display->compositor,
window, effect);
}
window->visible_to_compositor = FALSE;
}
did_hide = FALSE;
if (meta_prefs_get_live_hidden_windows ())
{
if (window->hidden)
return;
/* If this is the first time that we've calculating the showing
* state of the window, the frame and client window might not
* yet be mapped, so we need to map them now */
map_frame (window);
map_client_window (window);
if (!window->hidden)
{
meta_stack_freeze (window->screen->stack);
window->hidden = TRUE;
meta_stack_thaw (window->screen->stack);
meta_stack_freeze (window->screen->stack);
window->hidden = TRUE;
/* Tell the compositor this window is now hidden */
meta_compositor_set_window_hidden (window->display->compositor,
window->screen,
window,
window->hidden);
meta_stack_thaw (window->screen->stack);
did_hide = TRUE;
}
meta_compositor_unmap_window (window->display->compositor,
window);
did_hide = TRUE;
}
else
{
meta_compositor_unmap_window (window->display->compositor,
window);
/* Unmapping the frame is enough to make the window disappear,
* but we need to hide the window itself so the client knows
* it has been hidden */
@@ -2632,19 +2694,6 @@ meta_window_hide (MetaWindow *window)
set_wm_state (window, IconicState);
}
toplevel_now_mapped = meta_window_toplevel_is_mapped (window);
if (toplevel_now_mapped != toplevel_was_mapped)
{
if (window->display->compositor)
{
/* As above, we may be *mapping* live hidden windows */
if (toplevel_now_mapped)
meta_compositor_window_mapped (window->display->compositor, window);
else
meta_compositor_window_unmapped (window->display->compositor, window);
}
}
set_net_wm_state (window);
if (did_hide && window->struts)
@@ -2654,28 +2703,6 @@ meta_window_hide (MetaWindow *window)
window->desc);
invalidate_work_areas (window);
}
if (window->has_focus)
{
MetaWindow *not_this_one = NULL;
MetaWorkspace *my_workspace = meta_window_get_workspace (window);
guint32 timestamp = meta_display_get_current_time_roundtrip (window->display);
/*
* If this window is modal, passing the not_this_one window to
* _focus_default_window() makes the focus to be given to this window's
* ancestor. This can only be the case if the window is on the currently
* active workspace; when it is not, we need to pass in NULL, so as to
* focus the default window for the active workspace (this scenario
* arises when we are switching workspaces).
*/
if (my_workspace == window->screen->active_workspace)
not_this_one = window;
meta_workspace_focus_default_window (window->screen->active_workspace,
not_this_one,
timestamp);
}
}
static gboolean
@@ -2694,7 +2721,6 @@ meta_window_minimize (MetaWindow *window)
if (!window->minimized)
{
window->minimized = TRUE;
window->pending_compositor_effect = META_COMP_EFFECT_MINIMIZE;
meta_window_queue(window, META_QUEUE_CALC_SHOWING);
meta_window_foreach_transient (window,
@@ -2724,7 +2750,7 @@ meta_window_unminimize (MetaWindow *window)
if (window->minimized)
{
window->minimized = FALSE;
window->pending_compositor_effect = META_COMP_EFFECT_UNMINIMIZE;
window->was_minimized = TRUE;
meta_window_queue(window, META_QUEUE_CALC_SHOWING);
meta_window_foreach_transient (window,
@@ -2918,18 +2944,14 @@ meta_window_maximize (MetaWindow *window,
if (window->display->compositor)
{
MetaRectangle old_rect;
MetaRectangle new_rect;
meta_window_get_outer_rect (window, &old_rect);
MetaRectangle window_rect;
meta_window_move_resize_now (window);
meta_window_get_outer_rect (window, &new_rect);
meta_window_get_outer_rect (window, &window_rect);
meta_compositor_maximize_window (window->display->compositor,
window,
&old_rect,
&new_rect);
&window_rect);
}
else
{
@@ -3038,9 +3060,7 @@ meta_window_unmaximize (MetaWindow *window,
if (window->display->compositor)
{
MetaRectangle old_rect, new_rect;
meta_window_get_outer_rect (window, &old_rect);
MetaRectangle window_rect;
meta_window_move_resize (window,
FALSE,
@@ -3048,12 +3068,13 @@ meta_window_unmaximize (MetaWindow *window,
target_rect.y,
target_rect.width,
target_rect.height);
meta_window_move_resize_now (window);
meta_window_get_outer_rect (window, &window_rect);
meta_window_get_outer_rect (window, &new_rect);
meta_compositor_unmaximize_window (window->display->compositor,
window,
&old_rect,
&new_rect);
&window_rect);
}
else
{
@@ -3065,6 +3086,11 @@ meta_window_unmaximize (MetaWindow *window,
target_rect.height);
}
if (window->display->grab_wireframe_active)
{
window->display->grab_wireframe_rect = target_rect;
}
recalc_window_features (window);
set_net_wm_state (window);
}
@@ -3997,16 +4023,18 @@ meta_window_move_resize_internal (MetaWindow *window,
newx, newy, window->rect.width, window->rect.height,
window->user_rect.x, window->user_rect.y,
window->user_rect.width, window->user_rect.height);
if (window->display->compositor)
meta_compositor_sync_window_geometry (window->display->compositor,
window);
meta_compositor_sync_window_geometry (window->display->compositor,
window);
}
else
{
meta_topic (META_DEBUG_GEOMETRY, "Size/position not modified\n");
}
meta_window_refresh_resize_popup (window);
if (window->display->grab_wireframe_active)
meta_window_update_wireframe (window, root_x_nw, root_y_nw, w, h);
else
meta_window_refresh_resize_popup (window);
/* Invariants leaving this function are:
* a) window->rect and frame->rect reflect the actual
@@ -4164,8 +4192,7 @@ meta_window_configure_notify (MetaWindow *window, XConfigureEvent *event)
if (!event->override_redirect && !event->send_event)
meta_warning ("Unhandled change of windows override redirect status\n");
if (window->display->compositor)
meta_compositor_sync_window_geometry (window->display->compositor, window);
meta_compositor_sync_window_geometry (window->display->compositor, window);
}
void
@@ -4309,6 +4336,120 @@ meta_window_get_outer_rect (const MetaWindow *window,
*rect = window->rect;
}
void
meta_window_get_xor_rect (MetaWindow *window,
const MetaRectangle *grab_wireframe_rect,
MetaRectangle *xor_rect)
{
if (window->frame)
{
xor_rect->x = grab_wireframe_rect->x - window->frame->child_x;
xor_rect->y = grab_wireframe_rect->y - window->frame->child_y;
xor_rect->width = grab_wireframe_rect->width + window->frame->child_x + window->frame->right_width;
if (window->shaded)
xor_rect->height = window->frame->child_y;
else
xor_rect->height = grab_wireframe_rect->height + window->frame->child_y + window->frame->bottom_height;
}
else
*xor_rect = *grab_wireframe_rect;
}
/* Figure out the numbers that show up in the
* resize popup when in reduced resources mode.
*/
static void
meta_window_get_wireframe_geometry (MetaWindow *window,
int *width,
int *height)
{
if (!window->display->grab_wireframe_active)
return;
if ((width == NULL) || (height == NULL))
return;
if ((window->display->grab_window->size_hints.width_inc <= 1) ||
(window->display->grab_window->size_hints.height_inc <= 1))
{
*width = -1;
*height = -1;
return;
}
*width = window->display->grab_wireframe_rect.width -
window->display->grab_window->size_hints.base_width;
*width /= window->display->grab_window->size_hints.width_inc;
*height = window->display->grab_wireframe_rect.height -
window->display->grab_window->size_hints.base_height;
*height /= window->display->grab_window->size_hints.height_inc;
}
/* XXX META_EFFECT_ALT_TAB, well, this and others */
void
meta_window_begin_wireframe (MetaWindow *window)
{
MetaRectangle new_xor;
int display_width, display_height;
meta_window_get_client_root_coords (window,
&window->display->grab_wireframe_rect);
meta_window_get_xor_rect (window, &window->display->grab_wireframe_rect,
&new_xor);
meta_window_get_wireframe_geometry (window, &display_width, &display_height);
meta_effects_begin_wireframe (window->screen,
&new_xor, display_width, display_height);
window->display->grab_wireframe_last_xor_rect = new_xor;
window->display->grab_wireframe_last_display_width = display_width;
window->display->grab_wireframe_last_display_height = display_height;
}
void
meta_window_update_wireframe (MetaWindow *window,
int x,
int y,
int width,
int height)
{
MetaRectangle new_xor;
int display_width, display_height;
window->display->grab_wireframe_rect.x = x;
window->display->grab_wireframe_rect.y = y;
window->display->grab_wireframe_rect.width = width;
window->display->grab_wireframe_rect.height = height;
meta_window_get_xor_rect (window, &window->display->grab_wireframe_rect,
&new_xor);
meta_window_get_wireframe_geometry (window, &display_width, &display_height);
meta_effects_update_wireframe (window->screen,
&window->display->grab_wireframe_last_xor_rect,
window->display->grab_wireframe_last_display_width,
window->display->grab_wireframe_last_display_height,
&new_xor, display_width, display_height);
window->display->grab_wireframe_last_xor_rect = new_xor;
window->display->grab_wireframe_last_display_width = display_width;
window->display->grab_wireframe_last_display_height = display_height;
}
void
meta_window_end_wireframe (MetaWindow *window)
{
meta_effects_end_wireframe (window->display->grab_window->screen,
&window->display->grab_wireframe_last_xor_rect,
window->display->grab_wireframe_last_display_width,
window->display->grab_wireframe_last_display_height);
}
const char*
meta_window_get_startup_id (MetaWindow *window)
{
@@ -4338,7 +4479,7 @@ get_modal_transient (MetaWindow *window)
*/
modal_transient = window;
windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
windows = meta_display_list_windows (window->display);
tmp = windows;
while (tmp != NULL)
{
@@ -4457,7 +4598,7 @@ meta_window_focus (MetaWindow *window,
if (window->wm_state_demands_attention)
meta_window_unset_demands_attention(window);
/* meta_effect_run_focus(window, NULL, NULL); */
meta_effect_run_focus(window, NULL, NULL);
}
static void
@@ -5680,6 +5821,8 @@ meta_window_notify_focus (MetaWindow *window,
"* Focus --> %s\n", window->desc);
window->display->focus_window = window;
window->has_focus = TRUE;
meta_compositor_set_active_window (window->display->compositor,
window->screen, window);
/* Move to the front of the focusing workspace's MRU list.
* We should only be "removing" it from the MRU list if it's
@@ -5767,6 +5910,9 @@ meta_window_notify_focus (MetaWindow *window,
if (window->frame)
meta_frame_queue_draw (window->frame);
meta_compositor_set_active_window (window->display->compositor,
window->screen, NULL);
meta_error_trap_push (window->display);
XUninstallColormap (window->display->xdisplay,
window->colormap);
@@ -7385,7 +7531,10 @@ update_move (MetaWindow *window,
}
}
meta_window_get_client_root_coords (window, &old);
if (display->grab_wireframe_active)
old = display->grab_wireframe_rect;
else
meta_window_get_client_root_coords (window, &old);
/* Don't allow movement in the maximized directions */
if (window->maximized_horizontally)
@@ -7403,7 +7552,21 @@ update_move (MetaWindow *window,
snap,
FALSE);
meta_window_move (window, TRUE, new_x, new_y);
if (display->compositor)
{
int root_x = new_x - display->grab_anchor_window_pos.x + display->grab_anchor_root_x;
int root_y = new_y - display->grab_anchor_window_pos.y + display->grab_anchor_root_y;
meta_compositor_update_move (display->compositor,
window, root_x, root_y);
}
if (display->grab_wireframe_active)
meta_window_update_wireframe (window, new_x, new_y,
display->grab_wireframe_rect.width,
display->grab_wireframe_rect.height);
else
meta_window_move (window, TRUE, new_x, new_y);
}
static gboolean
@@ -7429,6 +7592,7 @@ update_resize (MetaWindow *window,
int new_w, new_h;
int gravity;
MetaRectangle old;
int new_x, new_y;
double remaining;
window->display->grab_latest_motion_x = x;
@@ -7447,6 +7611,10 @@ update_resize (MetaWindow *window,
if (dx == 0 && dy == 0)
return;
/* FIXME this is only used in wireframe mode */
new_x = window->display->grab_anchor_window_pos.x;
new_y = window->display->grab_anchor_window_pos.y;
if (window->display->grab_op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN)
{
if ((dx > 0) && (dy > 0))
@@ -7491,6 +7659,11 @@ update_resize (MetaWindow *window,
}
}
/* FIXME: This stupidity only needed because of wireframe mode and
* the fact that wireframe isn't making use of
* meta_rectangle_resize_with_gravity(). If we were to use that, we
* could just increment new_w and new_h by dx and dy in all cases.
*/
switch (window->display->grab_op)
{
case META_GRAB_OP_RESIZING_SE:
@@ -7509,10 +7682,12 @@ update_resize (MetaWindow *window,
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
case META_GRAB_OP_KEYBOARD_RESIZING_W:
new_w -= dx;
new_x += dx;
break;
default:
break;
}
default:
break;
}
switch (window->display->grab_op)
{
@@ -7532,6 +7707,7 @@ update_resize (MetaWindow *window,
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
new_h -= dy;
new_y += dy;
break;
default:
break;
@@ -7564,7 +7740,10 @@ update_resize (MetaWindow *window,
window->display->grab_resize_timeout_id = 0;
}
old = window->rect; /* Don't actually care about x,y */
if (window->display->grab_wireframe_active)
old = window->display->grab_wireframe_rect;
else
old = window->rect; /* Don't actually care about x,y */
/* One sided resizing ought to actually be one-sided, despite the fact that
* aspect ratio windows don't interact nicely with the above stuff. So,
@@ -7601,11 +7780,28 @@ update_resize (MetaWindow *window,
snap,
FALSE);
/* We don't need to update unless the specified width and height
* are actually different from what we had before.
*/
if (old.width != new_w || old.height != new_h)
meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
if (window->display->grab_wireframe_active)
{
if ((new_x + new_w <= new_x) || (new_y + new_h <= new_y))
return;
/* FIXME This is crap. For example, the wireframe isn't
* constrained in the way that a real resize would be. An
* obvious elegant solution is to unmap the window during
* wireframe, but still resize it; however, that probably
* confuses broken clients that have problems with opaque
* resize, they probably don't track their visibility.
*/
meta_window_update_wireframe (window, new_x, new_y, new_w, new_h);
}
else
{
/* We don't need to update unless the specified width and height
* are actually different from what we had before.
*/
if (old.width != new_w || old.height != new_h)
meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
}
/* Store the latest resize time, if we actually resized. */
if (window->rect.width != old.width || window->rect.height != old.height)
@@ -7938,6 +8134,42 @@ meta_window_refresh_resize_popup (MetaWindow *window)
if (window->display->grab_window != window)
return;
/* We shouldn't ever get called when the wireframe is active
* because that's handled by a different code path in effects.c
*/
if (window->display->grab_wireframe_active)
{
meta_topic (META_DEBUG_WINDOW_OPS,
"refresh_resize_popup called when wireframe active\n");
return;
}
switch (window->display->grab_op)
{
case META_GRAB_OP_RESIZING_SE:
case META_GRAB_OP_RESIZING_S:
case META_GRAB_OP_RESIZING_SW:
case META_GRAB_OP_RESIZING_N:
case META_GRAB_OP_RESIZING_NE:
case META_GRAB_OP_RESIZING_NW:
case META_GRAB_OP_RESIZING_W:
case META_GRAB_OP_RESIZING_E:
case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
case META_GRAB_OP_KEYBOARD_RESIZING_S:
case META_GRAB_OP_KEYBOARD_RESIZING_N:
case META_GRAB_OP_KEYBOARD_RESIZING_W:
case META_GRAB_OP_KEYBOARD_RESIZING_E:
case META_GRAB_OP_KEYBOARD_RESIZING_SE:
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
break;
default:
/* Not resizing */
return;
}
if (window->display->grab_resize_popup == NULL)
{
if (window->size_hints.width_inc > 1 ||
@@ -7951,7 +8183,10 @@ meta_window_refresh_resize_popup (MetaWindow *window)
{
MetaRectangle rect;
meta_window_get_client_root_coords (window, &rect);
if (window->display->grab_wireframe_active)
rect = window->display->grab_wireframe_rect;
else
meta_window_get_client_root_coords (window, &rect);
meta_ui_resize_popup_set (window->display->grab_resize_popup,
rect,
@@ -7973,7 +8208,7 @@ meta_window_foreach_transient (MetaWindow *window,
GSList *windows;
GSList *tmp;
windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
windows = meta_display_list_windows (window->display);
tmp = windows;
while (tmp != NULL)
@@ -8092,7 +8327,14 @@ warp_grab_pointer (MetaWindow *window,
/* We may not have done begin_grab_op yet, i.e. may not be in a grab
*/
meta_window_get_outer_rect (window, &rect);
if (window == display->grab_window && display->grab_wireframe_active)
{
meta_window_get_xor_rect (window, &display->grab_wireframe_rect, &rect);
}
else
{
meta_window_get_outer_rect (window, &rect);
}
switch (grab_op)
{
@@ -8167,8 +8409,11 @@ warp_grab_pointer (MetaWindow *window,
display->grab_anchor_root_y = *y;
display->grab_latest_motion_x = *x;
display->grab_latest_motion_y = *y;
meta_window_get_client_root_coords (window,
&display->grab_anchor_window_pos);
if (display->grab_wireframe_active)
display->grab_anchor_window_pos = display->grab_wireframe_rect;
else
meta_window_get_client_root_coords (window,
&display->grab_anchor_window_pos);
XWarpPointer (display->xdisplay,
None,

View File

@@ -73,6 +73,7 @@ void meta_workspace_remove_window (MetaWorkspace *workspace,
MetaWindow *window);
void meta_workspace_relocate_windows (MetaWorkspace *workspace,
MetaWorkspace *new_home);
GList* meta_workspace_list_windows (MetaWorkspace *workspace);
void meta_workspace_invalidate_work_area (MetaWorkspace *workspace);

View File

@@ -29,7 +29,9 @@
#include "errors.h"
#include "prefs.h"
#ifdef HAVE_COMPOSITE_EXTENSIONS
#include "compositor.h"
#endif
#include <X11/Xatom.h>
#include <string.h>
@@ -433,7 +435,19 @@ meta_workspace_queue_calc_showing (MetaWorkspace *workspace)
tmp = workspace->windows;
while (tmp != NULL)
{
meta_window_queue (tmp->data, META_QUEUE_CALC_SHOWING);
if (meta_prefs_get_live_hidden_windows ())
{
/*
* When we hide rather than unmap windows, we need the show/hide
* status of the window to be recalculated *before* we call the
* compositor switch_workspace hook.
*/
meta_window_calc_showing (tmp->data);
}
else
{
meta_window_queue (tmp->data, META_QUEUE_CALC_SHOWING);
}
tmp = tmp->next;
}
@@ -444,14 +458,8 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
MetaWindow *focus_this,
guint32 timestamp)
{
MetaWorkspace *old;
MetaWindow *move_window;
MetaScreen *screen;
MetaDisplay *display;
MetaCompositor *comp;
MetaWorkspaceLayout layout1, layout2;
gint num_workspaces, current_space, new_space;
MetaMotionDirection direction;
MetaWorkspace *old;
MetaWindow *move_window;
meta_verbose ("Activating workspace %d\n",
meta_workspace_index (workspace));
@@ -461,7 +469,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
/* Note that old can be NULL; e.g. when starting up */
old = workspace->screen->active_workspace;
workspace->screen->active_workspace = workspace;
set_active_space_hint (workspace->screen);
@@ -508,58 +516,6 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
/* Removes window from other spaces */
meta_window_change_workspace (move_window, workspace);
/*
* Notify the compositor that the active workspace is changing.
*/
screen = workspace->screen;
display = meta_screen_get_display (screen);
comp = meta_display_get_compositor (display);
direction = 0;
current_space = meta_workspace_index (old);
new_space = meta_workspace_index (workspace);
num_workspaces = meta_screen_get_n_workspaces (workspace->screen);
meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
current_space, &layout1);
meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
new_space, &layout2);
if (layout1.current_col < layout2.current_col)
direction = META_MOTION_RIGHT;
if (layout1.current_col > layout2.current_col)
direction = META_MOTION_LEFT;
if (layout1.current_row < layout2.current_row)
{
if (!direction)
direction = META_MOTION_DOWN;
else if (direction == META_MOTION_RIGHT)
direction = META_MOTION_DOWN_RIGHT;
else
direction = META_MOTION_DOWN_LEFT;
}
if (layout1.current_row > layout2.current_row)
{
if (!direction)
direction = META_MOTION_UP;
else if (direction == META_MOTION_RIGHT)
direction = META_MOTION_UP_RIGHT;
else
direction = META_MOTION_UP_LEFT;
}
meta_screen_free_workspace_layout (&layout1);
meta_screen_free_workspace_layout (&layout2);
meta_compositor_switch_workspace (comp, screen, old, workspace, direction);
/* This needs to be done after telling the compositor we are switching
* workspaces since focusing a window will cause it to be immediately
* shown and that would confuse the compositor if it didn't know we
* were in a workspace switch.
*/
if (focus_this)
{
meta_window_focus (focus_this, timestamp);
@@ -575,8 +531,59 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
meta_workspace_focus_default_window (workspace, NULL, timestamp);
}
/* Emit switched signal from screen.c */
meta_screen_workspace_switched (screen, current_space, new_space, direction);
#ifdef HAVE_COMPOSITE_EXTENSIONS
{
/*
* Notify the compositor that the active workspace changed.
*/
MetaScreen *screen = workspace->screen;
MetaDisplay *display = meta_screen_get_display (screen);
MetaCompositor *comp = meta_display_get_compositor (display);
MetaWorkspaceLayout layout1, layout2;
gint num_workspaces, current_space, new_space;
MetaMotionDirection direction = 0;
current_space = meta_workspace_index (old);
new_space = meta_workspace_index (workspace);
num_workspaces = meta_screen_get_n_workspaces (workspace->screen);
meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
current_space, &layout1);
meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
new_space, &layout2);
if (layout1.current_col < layout2.current_col)
direction = META_MOTION_RIGHT;
if (layout1.current_col > layout2.current_col)
direction = META_MOTION_LEFT;
if (layout1.current_row < layout2.current_row)
{
if (!direction)
direction = META_MOTION_DOWN;
else if (direction == META_MOTION_RIGHT)
direction = META_MOTION_DOWN_RIGHT;
else
direction = META_MOTION_DOWN_LEFT;
}
if (layout1.current_row > layout2.current_row)
{
if (!direction)
direction = META_MOTION_UP;
else if (direction == META_MOTION_RIGHT)
direction = META_MOTION_UP_RIGHT;
else
direction = META_MOTION_UP_LEFT;
}
meta_screen_free_workspace_layout (&layout1);
meta_screen_free_workspace_layout (&layout2);
meta_compositor_switch_workspace (comp, screen, old, workspace, direction);
}
#endif
}
void
@@ -614,7 +621,7 @@ meta_workspace_update_window_hints (MetaWorkspace *workspace)
}
/**
* meta_workspace_list_windows:
* meta_display_list_windows:
* @display: a #MetaDisplay
*
* Gets windows contained on the workspace, including workspace->windows
@@ -629,8 +636,7 @@ meta_workspace_list_windows (MetaWorkspace *workspace)
GSList *tmp;
GList *workspace_windows;
display_windows = meta_display_list_windows (workspace->screen->display,
META_LIST_DEFAULT);
display_windows = meta_display_list_windows (workspace->screen->display);
workspace_windows = NULL;
tmp = display_windows;
@@ -919,6 +925,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
/* We're all done, YAAY! Record that everything has been validated. */
workspace->work_areas_invalid = FALSE;
#ifdef HAVE_COMPOSITE_EXTENSIONS
{
/*
* Notify the compositor that the workspace geometry has changed.
@@ -927,9 +934,9 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
MetaDisplay *display = meta_screen_get_display (screen);
MetaCompositor *comp = meta_display_get_compositor (display);
if (comp)
meta_compositor_update_workspace_geometry (comp, workspace);
meta_compositor_update_workspace_geometry (comp, workspace);
}
#endif
}
/**

View File

@@ -233,22 +233,6 @@ typedef enum
META_DIRECTION_VERTICAL = META_DIRECTION_UP | META_DIRECTION_DOWN,
} MetaDirection;
/* Negative to avoid conflicting with real workspace
* numbers
*/
typedef enum
{
META_MOTION_UP = -1,
META_MOTION_DOWN = -2,
META_MOTION_LEFT = -3,
META_MOTION_RIGHT = -4,
/* These are only used for effects */
META_MOTION_UP_LEFT = -5,
META_MOTION_UP_RIGHT = -6,
META_MOTION_DOWN_LEFT = -7,
META_MOTION_DOWN_RIGHT = -8
} MetaMotionDirection;
/* Sometimes we want to talk about sides instead of directions; note
* that the values must be as follows or meta_window_update_struts()
* won't work. Using these values also is a safety blanket since

View File

@@ -0,0 +1,77 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2008 Matthew Allum
* Copyright (C) 2007 Iain Holmes
* Based on xcompmgr - (c) 2003 Keith Packard
* xfwm4 - (c) 2005-2007 Olivier Fourdan
*
* 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.
*/
#ifndef META_COMPOSITOR_CLUTTER_H_
#define META_COMPOSITOR_CLUTTER_H_
#include <clutter/clutter.h>
#include <xlib/xlib.h>
#include "types.h"
/*
* MetaCompWindow object (ClutterGroup sub-class)
*/
#define META_TYPE_COMP_WINDOW (meta_comp_window_get_type ())
#define META_COMP_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_COMP_WINDOW, MetaCompWindow))
#define META_COMP_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_COMP_WINDOW, MetaCompWindowClass))
#define IS_META_COMP_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_COMP_WINDOW_TYPE))
#define META_IS_COMP_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_COMP_WINDOW))
#define META_COMP_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_COMP_WINDOW, MetaCompWindowClass))
typedef struct _MetaCompWindow MetaCompWindow;
typedef struct _MetaCompWindowClass MetaCompWindowClass;
typedef struct _MetaCompWindowPrivate MetaCompWindowPrivate;
struct _MetaCompWindowClass
{
ClutterGroupClass parent_class;
};
struct _MetaCompWindow
{
ClutterGroup parent;
MetaCompWindowPrivate *priv;
};
GType meta_comp_window_get_type (void);
Window meta_comp_window_get_x_window (MetaCompWindow *mcw);
MetaCompWindowType meta_comp_window_get_window_type (MetaCompWindow *mcw);
gint meta_comp_window_get_workspace (MetaCompWindow *mcw);
/* Compositor API */
MetaCompositor *meta_compositor_clutter_new (MetaDisplay *display);
void meta_compositor_clutter_window_effect_completed (MetaCompWindow *actor, gulong event);
ClutterActor * meta_compositor_clutter_get_stage_for_screen (MetaScreen *screen);
ClutterActor * meta_compositor_clutter_get_overlay_group_for_screen (MetaScreen *screen);
Window meta_compositor_clutter_get_overlay_window (MetaScreen *screen);
#endif

View File

@@ -26,17 +26,63 @@
#define MUTTER_H_
#include <clutter/clutter.h>
#include <X11/extensions/Xfixes.h>
#include <X11/Xlib.h>
#include "types.h"
#include "compositor.h"
#include "mutter-window.h"
/* Public compositor API */
/*
* MutterWindow object (ClutterGroup sub-class)
*/
#define MUTTER_TYPE_COMP_WINDOW (mutter_window_get_type ())
#define MUTTER_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTTER_TYPE_COMP_WINDOW, MutterWindow))
#define MUTTER_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTTER_TYPE_COMP_WINDOW, MutterWindowClass))
#define MUTTER_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUTTER_TYPE_COMP_WINDOW))
#define MUTTER_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTTER_TYPE_COMP_WINDOW))
#define MUTTER_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTTER_TYPE_COMP_WINDOW, MutterWindowClass))
typedef struct _MutterWindow MutterWindow;
typedef struct _MutterWindowClass MutterWindowClass;
typedef struct _MutterWindowPrivate MutterWindowPrivate;
struct _MutterWindowClass
{
ClutterGroupClass parent_class;
};
struct _MutterWindow
{
ClutterGroup parent;
MutterWindowPrivate *priv;
};
GType mutter_window_get_type (void);
Window mutter_window_get_x_window (MutterWindow *mcw);
MetaCompWindowType mutter_window_get_window_type (MutterWindow *mcw);
gint mutter_window_get_workspace (MutterWindow *mcw);
gboolean mutter_window_is_hidden (MutterWindow *mcw);
MetaWindow * mutter_window_get_meta_window (MutterWindow *mcw);
ClutterActor * mutter_window_get_texture (MutterWindow *mcw);
gboolean mutter_window_is_override_redirect (MutterWindow *mcw);
const char * mutter_window_get_description (MutterWindow *mcw);
gboolean mutter_window_showing_on_its_workspace (MutterWindow *mcw);
/* Compositor API */
MetaCompositor *mutter_new (MetaDisplay *display);
void mutter_window_effect_completed (MutterWindow *actor, gulong event);
ClutterActor * mutter_get_stage_for_screen (MetaScreen *screen);
ClutterActor * mutter_get_overlay_group_for_screen (MetaScreen *screen);
Window mutter_get_overlay_window (MetaScreen *screen);
GList * mutter_get_windows (MetaScreen *screen);
ClutterActor * mutter_get_window_group_for_screen (MetaScreen *screen);
void mutter_set_stage_input_region (MetaScreen *screen,
XserverRegion region);
void mutter_empty_stage_input_region (MetaScreen *screen);
#endif

View File

@@ -53,134 +53,110 @@ typedef enum _MetaCompWindowType
} MetaCompWindowType;
/**
* MetaCompEffect:
* @META_COMP_EFFECT_CREATE: The window is newly created
* (also used for a window that was previously on a different
* workspace and is changed to become visible on the active
* workspace.)
* @META_COMP_EFFECT_UNMINIMIZE: The window should be shown
* as unminimizing from its icon geometry.
* @META_COMP_EFFECT_DESTROY: The window is being destroyed
* @META_COMP_EFFECT_MINIMIZE: The window should be shown
* as minimizing to its icon geometry.
* @META_COMP_EFFECT_NONE: No effect, the window should be
* shown or hidden immediately.
*
* Indicates the appropriate effect to show the user for
* meta_compositor_show_window() and meta_compositor_hide_window()
*/
typedef enum
{
META_COMP_EFFECT_CREATE,
META_COMP_EFFECT_UNMINIMIZE,
META_COMP_EFFECT_DESTROY,
META_COMP_EFFECT_MINIMIZE,
META_COMP_EFFECT_NONE
} MetaCompEffect;
#ifdef WITH_CLUTTER
extern int meta_compositor_can_use_clutter__;
#endif
MetaCompositor *meta_compositor_new (MetaDisplay *display);
void meta_compositor_destroy (MetaCompositor *compositor);
MetaCompositor *meta_compositor_new (MetaDisplay *display);
void meta_compositor_destroy (MetaCompositor *compositor);
void meta_compositor_manage_screen (MetaCompositor *compositor,
MetaScreen *screen);
void meta_compositor_manage_screen (MetaCompositor *compositor,
MetaScreen *screen);
void meta_compositor_unmanage_screen (MetaCompositor *compositor,
MetaScreen *screen);
void meta_compositor_add_window (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_remove_window (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_set_updates (MetaCompositor *compositor,
MetaWindow *window,
gboolean updates);
gboolean meta_compositor_process_event (MetaCompositor *compositor,
XEvent *event,
MetaWindow *window);
Pixmap meta_compositor_get_window_pixmap (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_set_active_window (MetaCompositor *compositor,
MetaScreen *screen,
MetaWindow *window);
/* At a high-level, a window is not-visible or visible. When a
* window is added (with add_window()) it is not visible.
* show_window() indicates a transition from not-visible to
* visible. Some of the reasons for this:
*
* - Window newly created
* - Window is unminimized
* - Window is moved to the current desktop
* - Window was made sticky
*
* hide_window() indicates that the window has transitioned from
* visible to not-visible. Some reasons include:
*
* - Window was destroyed
* - Window is minimized
* - Window is moved to a different desktop
* - Window no longer sticky.
*
* Note that combinations are possible - a window might have first
* been minimized and then moved to a different desktop. The
* 'effect' parameter to show_window() and hide_window() is a hint
* as to the appropriate effect to show the user and should not
* be considered to be indicative of a state change.
*
* When the active workspace is changed, switch_workspace() is called
* first, then show_window() and hide_window() are called individually
* for each window affected, with an effect of META_COMP_EFFECT_NONE.
* If hiding windows will affect the switch workspace animation, the
* compositor needs to delay hiding the windows until the switch
* workspace animation completes.
*
* maximize_window() and unmaximize_window() are transitions within
* the visible state. The window is resized *before* the call, so
* it may be necessary to readjust the display based on the old_rect
* to start the animation.
*
* window_mapped() and window_unmapped() are notifications when the
* toplevel window (frame or client window) is mapped or unmapped.
* That is, when the result of meta_window_toplevel_is_mapped()
* changes. The main use of this is to drop resources when a window
* is unmapped. A window will always be mapped before show_window()
* is called and will not be unmapped until after hide_window() is
* called. If the live_hidden_windows preference is set, windows will
* never be unmapped.
*/
void meta_compositor_begin_move (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *initial,
int grab_x, int grab_y);
void meta_compositor_update_move (MetaCompositor *compositor,
MetaWindow *window,
int x, int y);
void meta_compositor_end_move (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_free_window (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_add_window (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_remove_window (MetaCompositor *compositor,
MetaWindow *window);
void
meta_compositor_map_window (MetaCompositor *compositor,
MetaWindow *window);
void
meta_compositor_unmap_window (MetaCompositor *compositor,
MetaWindow *window);
void
meta_compositor_minimize_window (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *icon_rect);
void
meta_compositor_unminimize_window (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *icon_rect);
void
meta_compositor_maximize_window (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *window_rect);
void
meta_compositor_unmaximize_window (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *window_rect);
void
meta_compositor_update_workspace_geometry (MetaCompositor *compositor,
MetaWorkspace *workspace);
void
meta_compositor_switch_workspace (MetaCompositor *compositor,
MetaScreen *screen,
MetaWorkspace *from,
MetaWorkspace *to,
MetaMotionDirection direction);
void
meta_compositor_sync_stack (MetaCompositor *compositor,
MetaScreen *screen,
GList *stack);
void
meta_compositor_set_window_hidden (MetaCompositor *compositor,
MetaScreen *screen,
MetaWindow *window,
gboolean hidden);
void
meta_compositor_sync_window_geometry (MetaCompositor *compositor,
MetaWindow *window);
void
meta_compositor_sync_screen_size (MetaCompositor *compositor,
MetaScreen *screen,
guint width,
guint height);
#endif
void meta_compositor_show_window (MetaCompositor *compositor,
MetaWindow *window,
MetaCompEffect effect);
void meta_compositor_hide_window (MetaCompositor *compositor,
MetaWindow *window,
MetaCompEffect effect);
void meta_compositor_switch_workspace (MetaCompositor *compositor,
MetaScreen *screen,
MetaWorkspace *from,
MetaWorkspace *to,
MetaMotionDirection direction);
void meta_compositor_maximize_window (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *old_rect,
MetaRectangle *new_rect);
void meta_compositor_unmaximize_window (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *old_rect,
MetaRectangle *new_rect);
void meta_compositor_window_mapped (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_window_unmapped (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_sync_window_geometry (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_set_updates (MetaCompositor *compositor,
MetaWindow *window,
gboolean updates);
void meta_compositor_update_workspace_geometry (MetaCompositor *compositor,
MetaWorkspace *workspace);
void meta_compositor_sync_stack (MetaCompositor *compositor,
MetaScreen *screen,
GList *stack);
void meta_compositor_sync_screen_size (MetaCompositor *compositor,
MetaScreen *screen,
guint width,
guint height);
#endif /* META_COMPOSITOR_H */

View File

@@ -48,7 +48,7 @@
#define MUTTER_TYPE_PLUGIN (mutter_plugin_get_type ())
#define MUTTER_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTTER_TYPE_PLUGIN, MutterPlugin))
#define MUTTER_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTTER_TYPE_PLUGIN, MutterPluginClass))
#define MUTTER_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUTTER_TYPE_PLUGIN))
#define MUTTER_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUTTER_PLUGIN_TYPE))
#define MUTTER_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTTER_TYPE_PLUGIN))
#define MUTTER_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTTER_TYPE_PLUGIN, MutterPluginClass))

View File

@@ -1,71 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2008 Matthew Allum
* Copyright (C) 2007 Iain Holmes
* Based on xcompmgr - (c) 2003 Keith Packard
* xfwm4 - (c) 2005-2007 Olivier Fourdan
*
* 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.
*/
#ifndef MUTTER_WINDOW_H_
#define MUTTER_WINDOW_H_
#include <clutter/clutter.h>
#include <X11/Xlib.h>
#include "compositor.h"
/*
* MutterWindow object (ClutterGroup sub-class)
*/
#define MUTTER_TYPE_COMP_WINDOW (mutter_window_get_type ())
#define MUTTER_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTTER_TYPE_COMP_WINDOW, MutterWindow))
#define MUTTER_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTTER_TYPE_COMP_WINDOW, MutterWindowClass))
#define MUTTER_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUTTER_TYPE_COMP_WINDOW))
#define MUTTER_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTTER_TYPE_COMP_WINDOW))
#define MUTTER_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTTER_TYPE_COMP_WINDOW, MutterWindowClass))
typedef struct _MutterWindow MutterWindow;
typedef struct _MutterWindowClass MutterWindowClass;
typedef struct _MutterWindowPrivate MutterWindowPrivate;
struct _MutterWindowClass
{
ClutterGroupClass parent_class;
};
struct _MutterWindow
{
ClutterGroup parent;
MutterWindowPrivate *priv;
};
GType mutter_window_get_type (void);
Window mutter_window_get_x_window (MutterWindow *mcw);
MetaCompWindowType mutter_window_get_window_type (MutterWindow *mcw);
gint mutter_window_get_workspace (MutterWindow *mcw);
gboolean mutter_window_is_hidden (MutterWindow *mcw);
MetaWindow * mutter_window_get_meta_window (MutterWindow *mcw);
ClutterActor * mutter_window_get_texture (MutterWindow *mcw);
gboolean mutter_window_is_override_redirect (MutterWindow *mcw);
const char * mutter_window_get_description (MutterWindow *mcw);
gboolean mutter_window_showing_on_its_workspace (MutterWindow *mcw);
#endif /* MUTTER_WINDOW_H */

View File

@@ -53,13 +53,17 @@ typedef enum
META_PREF_VISUAL_BELL,
META_PREF_AUDIBLE_BELL,
META_PREF_VISUAL_BELL_TYPE,
META_PREF_REDUCED_RESOURCES,
META_PREF_GNOME_ACCESSIBILITY,
META_PREF_GNOME_ANIMATIONS,
META_PREF_CURSOR_THEME,
META_PREF_CURSOR_SIZE,
META_PREF_COMPOSITING_MANAGER,
META_PREF_RESIZE_WITH_RIGHT_BUTTON,
#ifdef WITH_CLUTTER
META_PREF_CLUTTER_DISABLED,
META_PREF_CLUTTER_PLUGINS,
#endif
META_PREF_LIVE_HIDDEN_WINDOWS,
META_PREF_NO_TAB_POPUP,
} MetaPreference;
@@ -89,6 +93,7 @@ gboolean meta_prefs_get_application_based (void);
gboolean meta_prefs_get_disable_workarounds (void);
gboolean meta_prefs_get_auto_raise (void);
int meta_prefs_get_auto_raise_delay (void);
gboolean meta_prefs_get_reduced_resources (void);
gboolean meta_prefs_get_gnome_accessibility (void);
gboolean meta_prefs_get_gnome_animations (void);
@@ -123,6 +128,11 @@ gboolean meta_prefs_get_compositing_manager (void);
*/
void meta_prefs_set_compositing_manager (gboolean whether);
#ifdef WITH_CLUTTER
gboolean meta_prefs_get_clutter_disabled (void);
void meta_prefs_set_clutter_disabled (gboolean whether);
GSList * meta_prefs_get_clutter_plugins (void);
/**
@@ -140,6 +150,8 @@ void meta_prefs_set_clutter_plugins (GSList *list);
*/
void meta_prefs_override_clutter_plugins (GSList *list);
#endif
gboolean meta_prefs_get_live_hidden_windows (void);
void meta_prefs_set_live_hidden_windows (gboolean whether);

View File

@@ -25,7 +25,6 @@
#include <X11/Xlib.h>
#include <glib-object.h>
#include "types.h"
#include "workspace.h"
#define META_TYPE_SCREEN (meta_screen_get_type ())
#define META_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SCREEN, MetaScreen))
@@ -52,8 +51,10 @@ void meta_screen_set_compositor_data (MetaScreen *screen,
MetaScreen *meta_screen_for_x_screen (Screen *xscreen);
#ifdef HAVE_COMPOSITE_EXTENSIONS
void meta_screen_set_cm_selection (MetaScreen *screen);
void meta_screen_unset_cm_selection (MetaScreen *screen);
#endif
GList *meta_screen_get_workspaces (MetaScreen *screen);

View File

@@ -37,6 +37,22 @@
#include "boxes.h"
#include "screen.h"
/* Negative to avoid conflicting with real workspace
* numbers
*/
typedef enum
{
META_MOTION_UP = -1,
META_MOTION_DOWN = -2,
META_MOTION_LEFT = -3,
META_MOTION_RIGHT = -4,
/* These are only used for effects */
META_MOTION_UP_LEFT = -5,
META_MOTION_UP_RIGHT = -6,
META_MOTION_DOWN_LEFT = -7,
META_MOTION_DOWN_RIGHT = -8
} MetaMotionDirection;
#define META_TYPE_WORKSPACE (meta_workspace_get_type ())
#define META_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WORKSPACE, MetaWorkspace))
#define META_WORKSPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WORKSPACE, MetaWorkspaceClass))
@@ -50,7 +66,6 @@ GType meta_workspace_get_type (void);
int meta_workspace_index (MetaWorkspace *workspace);
MetaScreen *meta_workspace_get_screen (MetaWorkspace *workspace);
GList* meta_workspace_list_windows (MetaWorkspace *workspace);
void meta_workspace_get_work_area_all_xineramas (MetaWorkspace *workspace,
MetaRectangle *area);
void meta_workspace_activate (MetaWorkspace *workspace, guint32 timestamp);

View File

@@ -1,40 +0,0 @@
/*** BEGIN file-header ***/
#include "mutter-enum-types.h"
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@filename@" */
#include "@filename@"
/*** END file-production ***/
/*** BEGIN value-header ***/
GType
@enum_name@_get_type (void)
{
static volatile gsize g_enum_type_id__volatile = 0;
if (g_once_init_enter (&g_enum_type_id__volatile))
{
static const G@Type@Value values[] = {
/*** END value-header ***/
/*** BEGIN value-production ***/
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
/*** END value-production ***/
/*** BEGIN value-tail ***/
{ 0, NULL, NULL }
};
GType g_enum_type_id;
g_enum_type_id =
g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
g_once_init_leave (&g_enum_type_id__volatile, g_enum_type_id);
}
return g_enum_type_id__volatile;
}
/*** END value-tail ***/

View File

@@ -1,26 +0,0 @@
/*** BEGIN file-header ***/
#ifndef __MUTTER_ENUM_TYPES_H__
#define __MUTTER_ENUM_TYPES_H__
#include <glib-object.h>
G_BEGIN_DECLS
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@filename@" */
/*** END file-production ***/
/*** BEGIN file-tail ***/
G_END_DECLS
#endif /* !__MUTTER_ENUM_TYPES_H__ */
/*** END file-tail ***/
/*** BEGIN value-header ***/
GType @enum_name@_get_type (void) G_GNUC_CONST;
#define MUTTER_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
/*** END value-header ***/

View File

@@ -1 +0,0 @@
VOID:INT,INT,ENUM